aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/viewer/sk_app/android
diff options
context:
space:
mode:
authorGravatar jvanverth <jvanverth@google.com>2016-05-05 12:32:03 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-05-05 12:32:03 -0700
commita8d0d6c8bad00e713bc33e5f0d47ca4fec104433 (patch)
tree8f78250c57c9c9d96f8e2fac7864630c97fe3cb9 /tools/viewer/sk_app/android
parent2d1ee7936e3536e45c963db004e3b512bb415fd8 (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.cpp47
-rw-r--r--tools/viewer/sk_app/android/VulkanWindowContext_android.h26
-rw-r--r--tools/viewer/sk_app/android/Window_android.cpp183
-rw-r--r--tools/viewer/sk_app/android/Window_android.h52
-rw-r--r--tools/viewer/sk_app/android/main_android.cpp69
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)