diff options
author | jvanverth <jvanverth@google.com> | 2016-05-05 12:32:03 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-05-05 12:32:03 -0700 |
commit | a8d0d6c8bad00e713bc33e5f0d47ca4fec104433 (patch) | |
tree | 8f78250c57c9c9d96f8e2fac7864630c97fe3cb9 /tools/viewer/sk_app/android | |
parent | 2d1ee7936e3536e45c963db004e3b512bb415fd8 (diff) |
More refactoring for Viewer
* Move support files into sk_app and main files up to top directory
* Rename VulkanTestContext and create WindowContext parent class
* Place VulkanWindowContext et al. in sk_app namespace.
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1944413005
Review-Url: https://codereview.chromium.org/1944413005
Diffstat (limited to 'tools/viewer/sk_app/android')
-rw-r--r-- | tools/viewer/sk_app/android/VulkanWindowContext_android.cpp | 47 | ||||
-rw-r--r-- | tools/viewer/sk_app/android/VulkanWindowContext_android.h | 26 | ||||
-rw-r--r-- | tools/viewer/sk_app/android/Window_android.cpp | 183 | ||||
-rw-r--r-- | tools/viewer/sk_app/android/Window_android.h | 52 | ||||
-rw-r--r-- | tools/viewer/sk_app/android/main_android.cpp | 69 |
5 files changed, 377 insertions, 0 deletions
diff --git a/tools/viewer/sk_app/android/VulkanWindowContext_android.cpp b/tools/viewer/sk_app/android/VulkanWindowContext_android.cpp new file mode 100644 index 0000000000..1ef994aa3f --- /dev/null +++ b/tools/viewer/sk_app/android/VulkanWindowContext_android.cpp @@ -0,0 +1,47 @@ + +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "VulkanWindowContext_android.h" + +#include "vk/GrVkInterface.h" +#include "vk/GrVkUtil.h" + +namespace sk_app { + +VkSurfaceKHR VulkanWindowContext::createVkSurface(VkInstance instance, void* platformData) { + static PFN_vkCreateAndroidSurfaceKHR createAndroidSurfaceKHR = nullptr; + if (!createAndroidSurfaceKHR) { + createAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR)vkGetInstanceProcAddr(instance, + "vkCreateAndroidSurfaceKHR"); + } + + if (!platformData) { + return VK_NULL_HANDLE; + } + ContextPlatformData_android* androidPlatformData = + reinterpret_cast<ContextPlatformData_android*>(platformData); + VkSurfaceKHR surface; + + VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo; + memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR)); + surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; + surfaceCreateInfo.pNext = nullptr; + surfaceCreateInfo.flags = 0; + surfaceCreateInfo.window = androidPlatformData->fNativeWindow; + + VkResult res = createAndroidSurfaceKHR(instance, &surfaceCreateInfo, + nullptr, &surface); + return (VK_SUCCESS == res) ? surface : VK_NULL_HANDLE; +} + +bool VulkanWindowContext::canPresent(VkInstance instance, VkPhysicalDevice physDev, + uint32_t queueFamilyIndex) { + return true; +} + +} // namespace sk_app diff --git a/tools/viewer/sk_app/android/VulkanWindowContext_android.h b/tools/viewer/sk_app/android/VulkanWindowContext_android.h new file mode 100644 index 0000000000..dd53e13b69 --- /dev/null +++ b/tools/viewer/sk_app/android/VulkanWindowContext_android.h @@ -0,0 +1,26 @@ + +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef VULKANTESTCONTEXT_ANDROID_DEFINED +#define VULKANTESTCONTEXT_ANDROID_DEFINED + +#ifdef SK_VULKAN + +#include "../VulkanWindowContext.h" + +struct ANativeWindow; + +namespace sk_app { + +struct ContextPlatformData_android { + ANativeWindow* fNativeWindow; +}; + +} +#endif // SK_VULKAN + +#endif diff --git a/tools/viewer/sk_app/android/Window_android.cpp b/tools/viewer/sk_app/android/Window_android.cpp new file mode 100644 index 0000000000..94be02c933 --- /dev/null +++ b/tools/viewer/sk_app/android/Window_android.cpp @@ -0,0 +1,183 @@ +/* +* Copyright 2016 Google Inc. +* +* Use of this source code is governed by a BSD-style license that can be +* found in the LICENSE file. +*/ + +#include "Window_android.h" + +#include "VulkanWindowContext_android.h" + +namespace sk_app { + +Window* Window::CreateNativeWindow(void* platformData) { + Window_android* window = new Window_android(); + if (!window->init((android_app*)platformData)) { + delete window; + return nullptr; + } + return window; +} + +static void handle_cmd(struct android_app* app, int32_t cmd); +static int32_t handle_input(struct android_app* app, AInputEvent* event); + +bool Window_android::init(android_app* app) { + SkASSERT(app); + mApp = app; + mApp->userData = this; + mApp->onAppCmd = handle_cmd; + mApp->onInputEvent = handle_input; + return true; +} + +void Window_android::setTitle(const char* title) { + //todo + SkDebugf("Title: %s", title); +} + +bool Window_android::attach(BackEndType attachType, int msaaSampleCount) { + if (kVulkan_BackendType != attachType) { + return false; + } + + mSampleCount = msaaSampleCount; + + // We delay the creation of fTestContext until Android informs us that + // the native window is ready to use. + return true; +} + +void Window_android::initDisplay(ANativeWindow* window) { + SkASSERT(window); + ContextPlatformData_android platformData; + platformData.fNativeWindow = window; + fWindowContext = VulkanWindowContext::Create((void*)&platformData, mSampleCount); +} + +static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) { + if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) { + SkDebugf("Failure writing android_app cmd: %s\n", strerror(errno)); + } +} + +void Window_android::inval() { + android_app_write_cmd(mApp, APP_CMD_INVAL_WINDOW); +} + +void Window_android::paintIfNeeded() { + if (mApp->window || !mContentRect.isEmpty()) { + this->onPaint(); + } +} + +/** + * Process the next main command. + */ +static void handle_cmd(struct android_app* app, int32_t cmd) { + Window_android* window = (Window_android*)app->userData; + switch (cmd) { + case APP_CMD_INIT_WINDOW: + // The window is being shown, get it ready. + SkASSERT(app->window); + window->initDisplay(app->window); + window->paintIfNeeded(); + break; + case APP_CMD_WINDOW_RESIZED: { + int width = ANativeWindow_getWidth(app->window); + int height = ANativeWindow_getHeight(app->window); + window->onResize(width, height); + break; + } + case APP_CMD_CONTENT_RECT_CHANGED: + window->setContentRect(app->contentRect.left, app->contentRect.top, + app->contentRect.right, app->contentRect.bottom); + window->paintIfNeeded(); + break; + case APP_CMD_TERM_WINDOW: + // The window is being hidden or closed, clean it up. + window->detach(); + break; + case APP_CMD_INVAL_WINDOW: + window->paintIfNeeded(); + break; + } +} + +static Window::Key get_key(int32_t keycode) { + static const struct { + int32_t fAndroidKey; + Window::Key fWindowKey; + } gPair[] = { + { AKEYCODE_BACK, Window::kBack_Key }, + { AKEYCODE_VOLUME_UP, Window::kLeft_Key }, + { AKEYCODE_VOLUME_DOWN, Window::kRight_Key } + }; + for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) { + if (gPair[i].fAndroidKey == keycode) { + return gPair[i].fWindowKey; + } + } + return Window::kNONE_Key; +} + +static Window::InputState get_action(int32_t action) { + static const struct { + int32_t fAndroidAction; + Window::InputState fInputState; + } gPair[] = { + { AKEY_STATE_DOWN, Window::kDown_InputState }, + { AKEY_STATE_UP, Window::kUp_InputState }, + }; + for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) { + if (gPair[i].fAndroidAction == action) { + return gPair[i].fInputState; + } + } + return Window::kMove_InputState; +} + +static int32_t get_key_modifiers(AInputEvent* event) { + static const struct { + int32_t fAndroidState; + int32_t fWindowModifier; + } gPair[] = { + { AMETA_SHIFT_ON, Window::kShift_ModifierKey }, + { AMETA_CTRL_ON, Window::kControl_ModifierKey }, + }; + + int32_t metaState = AKeyEvent_getMetaState(event); + int32_t modifiers = 0; + + if (AKeyEvent_getRepeatCount(event) == 0) { + modifiers |= Window::kFirstPress_ModifierKey; + } + + for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) { + if (gPair[i].fAndroidState == metaState) { + modifiers |= gPair[i].fWindowModifier; + } + } + return modifiers; +} + +/** + * Process the next input event. + */ +static int32_t handle_input(struct android_app* app, AInputEvent* event) { + Window_android* window = (Window_android*)app->userData; + switch(AInputEvent_getType(event)) { + case AINPUT_EVENT_TYPE_MOTION: + break; + case AINPUT_EVENT_TYPE_KEY: + Window::Key key = get_key(AKeyEvent_getKeyCode(event)); + Window::InputState state = get_action(AKeyEvent_getAction(event)); + int32_t mod = get_key_modifiers(event); + window->onKey(key, state, mod); + return true; // eat all key events + } + return 0; +} + +} // namespace sk_app diff --git a/tools/viewer/sk_app/android/Window_android.h b/tools/viewer/sk_app/android/Window_android.h new file mode 100644 index 0000000000..d41f0a54c2 --- /dev/null +++ b/tools/viewer/sk_app/android/Window_android.h @@ -0,0 +1,52 @@ +/* +* Copyright 2016 Google Inc. +* +* Use of this source code is governed by a BSD-style license that can be +* found in the LICENSE file. +*/ + +#ifndef Window_android_DEFINED +#define Window_android_DEFINED + +#include "../Window.h" +#include <android_native_app_glue.h> + +namespace sk_app { + +enum { + /** + * Leave plenty of space between this item and the ones defined in the glue layer + */ + APP_CMD_INVAL_WINDOW = 64, +}; + +class Window_android : public Window { +public: + Window_android() : Window() {} + ~Window_android() override {} + + bool init(android_app* app_state); + void initDisplay(ANativeWindow* window); + + void setTitle(const char*) override; + void show() override {} + + bool attach(BackEndType attachType, int msaaSampleCount, bool deepColor) override; + void inval() override; + + void paintIfNeeded(); + + bool scaleContentToFit() const override { return true; } + bool supportsContentRect() const override { return true; } + SkRect getContentRect() override { return mContentRect; } + void setContentRect(int l, int t, int r, int b) { mContentRect.set(l,t,r,b); } + +private: + android_app* mApp = nullptr; + SkRect mContentRect; + int mSampleCount = 0; +}; + +} // namespace sk_app + +#endif diff --git a/tools/viewer/sk_app/android/main_android.cpp b/tools/viewer/sk_app/android/main_android.cpp new file mode 100644 index 0000000000..9334f0ccd3 --- /dev/null +++ b/tools/viewer/sk_app/android/main_android.cpp @@ -0,0 +1,69 @@ +/* +* Copyright 2016 Google Inc. +* +* Use of this source code is governed by a BSD-style license that can be +* found in the LICENSE file. +*/ + +#include <jni.h> +#include <errno.h> + +#include <android_native_app_glue.h> + +#include "../Application.h" +#include "Timer.h" + +static double now_ms() { return SkTime::GetNSecs() * 1e-6; } + +using sk_app::Application; + +/** + * This is the main entry point of a native application that is using + * android_native_app_glue. It runs in its own thread, with its own + * event loop for receiving input events and doing other things. + */ +void android_main(struct android_app* state) { + // Make sure glue isn't stripped. + app_dummy(); + + static const char* gCmdLine[] = { + "viewer", + "--skps", + "/data/local/tmp/skp", + }; + + std::unique_ptr<Application> vkApp(Application::Create(SK_ARRAY_COUNT(gCmdLine), + const_cast<char**>(gCmdLine), + state)); + + double currentTime = 0.0; + double previousTime = 0.0; + + // loop waiting for stuff to do. + while (1) { + // Read all pending events. + int ident; + int events; + struct android_poll_source* source; + + // block forever waiting for events. + while ((ident=ALooper_pollAll(-1, NULL, &events, + (void**)&source)) >= 0) { + + // Process this event. + if (source != NULL) { + source->process(state, source); + } + + // Check if we are exiting. + if (state->destroyRequested != 0) { + return; + } + + previousTime = currentTime; + currentTime = now_ms(); + vkApp->onIdle(currentTime - previousTime); + } + } +} +//END_INCLUDE(all) |