aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
authorGravatar liyuqian <liyuqian@google.com>2016-06-02 12:16:25 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-06-02 12:16:25 -0700
commit6cb70251829a467b146da9bc8925064f33608e48 (patch)
treebbd9e5d31aceebaf0a96684e68a421ef56cf7269 /tools
parent0dd9f2cbc445c477a840743420a6b2867ebbe120 (diff)
Implement OpenGL backend in Android viewer app
Diffstat (limited to 'tools')
-rw-r--r--tools/viewer/Viewer.cpp25
-rw-r--r--tools/viewer/sk_app/GLWindowContext.h2
-rw-r--r--tools/viewer/sk_app/android/GLWindowContext_android.cpp122
-rw-r--r--tools/viewer/sk_app/android/GLWindowContext_android.h40
-rw-r--r--tools/viewer/sk_app/android/VulkanWindowContext_android.cpp3
-rw-r--r--tools/viewer/sk_app/android/VulkanWindowContext_android.h26
-rw-r--r--tools/viewer/sk_app/android/Window_android.cpp29
-rw-r--r--tools/viewer/sk_app/android/Window_android.h10
8 files changed, 219 insertions, 38 deletions
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp
index 5228a0fd12..c73b1ba9ce 100644
--- a/tools/viewer/Viewer.cpp
+++ b/tools/viewer/Viewer.cpp
@@ -424,9 +424,11 @@ void Viewer::updateUIState() {
// We will be able to change the backend too.
Json::Value backendState(Json::objectValue);
backendState[kName] = kBackendStateName;
- backendState[kValue] = fBackendType == sk_app::Window::kVulkan_BackendType ?
- "Vulkan" : "Other than Vulkan";
+ backendState[kValue] = kBackendTypeStrings[fBackendType];
backendState[kOptions] = Json::Value(Json::arrayValue);
+ for(auto str : kBackendTypeStrings) {
+ backendState[kOptions].append(Json::Value(str));
+ }
Json::Value state(Json::arrayValue);
state.append(slideState);
@@ -436,7 +438,10 @@ void Viewer::updateUIState() {
}
void Viewer::onUIStateChanged(const SkString& stateName, const SkString& stateValue) {
- // Currently, we only recognize the Slide state
+ // For those who will add more features to handle the state change in this function:
+ // After the change, please call updateUIState no notify the frontend (e.g., Android app).
+ // For example, after slide change, updateUIState is called inside setupCurrentSlide;
+ // after backend change, updateUIState is called in this function.
if (stateName.equals(kSlideStateName)) {
int previousSlide = fCurrentSlide;
fCurrentSlide = 0;
@@ -451,6 +456,20 @@ void Viewer::onUIStateChanged(const SkString& stateName, const SkString& stateVa
fCurrentSlide = previousSlide;
SkDebugf("Slide not found: %s", stateValue.c_str());
}
+ } else if (stateName.equals(kBackendStateName)) {
+ for (int i = 0; i < sk_app::Window::kBackendTypeCount; i++) {
+ if (stateValue.equals(kBackendTypeStrings[i])) {
+ if (fBackendType != i) {
+ fBackendType = (sk_app::Window::BackendType)i;
+ fWindow->detach();
+ fWindow->attach(fBackendType, DisplayParams());
+ fWindow->inval();
+ updateTitle();
+ updateUIState();
+ }
+ break;
+ }
+ }
} else {
SkDebugf("Unknown stateName: %s", stateName.c_str());
}
diff --git a/tools/viewer/sk_app/GLWindowContext.h b/tools/viewer/sk_app/GLWindowContext.h
index 6fb5e09889..acf15a332e 100644
--- a/tools/viewer/sk_app/GLWindowContext.h
+++ b/tools/viewer/sk_app/GLWindowContext.h
@@ -52,6 +52,8 @@ protected:
sk_sp<SkSurface> fSurface;
// parameters obtained from the native window
+ // Note that the platform .cpp file is responsible for
+ // initializing fSampleCount, fStencilBits, and fColorBits!
int fSampleCount;
int fStencilBits;
int fColorBits;
diff --git a/tools/viewer/sk_app/android/GLWindowContext_android.cpp b/tools/viewer/sk_app/android/GLWindowContext_android.cpp
new file mode 100644
index 0000000000..a98b5553f8
--- /dev/null
+++ b/tools/viewer/sk_app/android/GLWindowContext_android.cpp
@@ -0,0 +1,122 @@
+
+/*
+ * 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 <GLES/gl.h>
+
+#include "GLWindowContext_android.h"
+
+#include <android/native_window_jni.h>
+
+namespace sk_app {
+
+// Most of the following 3 functions (GLWindowContext::Create, constructor, desctructor)
+// are copied from Unix/Win platform with unix/win changed to android
+
+// platform-dependent create
+GLWindowContext* GLWindowContext::Create(void* platformData, const DisplayParams& params) {
+ GLWindowContext_android* ctx = new GLWindowContext_android(platformData, params);
+ if (!ctx->isValid()) {
+ delete ctx;
+ return nullptr;
+ }
+ return ctx;
+}
+
+GLWindowContext_android::GLWindowContext_android(void* platformData, const DisplayParams& params)
+ : GLWindowContext(platformData, params)
+ , fDisplay(EGL_NO_DISPLAY)
+ , fEGLContext(EGL_NO_CONTEXT)
+ , fSurface(EGL_NO_SURFACE) {
+
+ // any config code here (particularly for msaa)?
+
+ this->initializeContext(platformData, params);
+}
+
+GLWindowContext_android::~GLWindowContext_android() {
+ this->destroyContext();
+}
+
+void GLWindowContext_android::onInitializeContext(void* platformData, const DisplayParams& params) {
+ ContextPlatformData_android* androidPlatformData =
+ reinterpret_cast<ContextPlatformData_android*>(platformData);
+
+ fWidth = ANativeWindow_getWidth(androidPlatformData->fNativeWindow);
+ fHeight = ANativeWindow_getHeight(androidPlatformData->fNativeWindow);
+
+ fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+
+ EGLint majorVersion;
+ EGLint minorVersion;
+ eglInitialize(fDisplay, &majorVersion, &minorVersion);
+
+ SkAssertResult(eglBindAPI(EGL_OPENGL_ES_API));
+
+ EGLint numConfigs = 0;
+ const EGLint configAttribs[] = {
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_NONE
+ };
+
+ EGLConfig surfaceConfig;
+ SkAssertResult(eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs));
+ SkASSERT(numConfigs > 0);
+
+ static const EGLint kEGLContextAttribsForOpenGLES[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+ fEGLContext = eglCreateContext(
+ fDisplay, surfaceConfig, nullptr, kEGLContextAttribsForOpenGLES);
+ SkASSERT(EGL_NO_CONTEXT != fEGLContext);
+
+ fSurface = eglCreateWindowSurface(
+ fDisplay, surfaceConfig, androidPlatformData->fNativeWindow, nullptr);
+ SkASSERT(EGL_NO_SURFACE != fSurface);
+
+ SkAssertResult(eglMakeCurrent(fDisplay, fSurface, fSurface, fEGLContext));
+ // GLWindowContext::initializeContext will call GrGLCreateNativeInterface so we
+ // won't call it here.
+
+ glClearStencil(0);
+ glClearColor(0, 0, 0, 0);
+ glStencilMask(0xffffffff);
+ glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+
+ int redBits, greenBits, blueBits;
+ eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_RED_SIZE, &redBits);
+ eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_GREEN_SIZE, &greenBits);
+ eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_BLUE_SIZE, &blueBits);
+ fColorBits = redBits + greenBits + blueBits;
+ eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_STENCIL_SIZE, &fStencilBits);
+ eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_SAMPLES, &fSampleCount);
+}
+
+void GLWindowContext_android::onDestroyContext() {
+ if (!fDisplay || !fEGLContext || !fSurface) {
+ return;
+ }
+ eglMakeCurrent(fDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ SkAssertResult(eglDestroySurface(fDisplay, fSurface));
+ SkAssertResult(eglDestroyContext(fDisplay, fEGLContext));
+ fEGLContext = EGL_NO_CONTEXT;
+ fSurface = EGL_NO_SURFACE;
+}
+
+void GLWindowContext_android::onSwapBuffers() {
+ if (fDisplay && fEGLContext && fSurface) {
+ eglSwapBuffers(fDisplay, fSurface);
+ }
+}
+
+}
diff --git a/tools/viewer/sk_app/android/GLWindowContext_android.h b/tools/viewer/sk_app/android/GLWindowContext_android.h
new file mode 100644
index 0000000000..85e65beaa2
--- /dev/null
+++ b/tools/viewer/sk_app/android/GLWindowContext_android.h
@@ -0,0 +1,40 @@
+
+/*
+ * 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 GLWindowContext_android_DEFINED
+#define GLWindowContext_android_DEFINED
+
+#include "../GLWindowContext.h"
+#include "Window_android.h"
+
+#include <EGL/egl.h>
+
+namespace sk_app {
+
+class GLWindowContext_android : public GLWindowContext {
+public:
+ friend GLWindowContext* GLWindowContext::Create(void* platformData, const DisplayParams&);
+
+ ~GLWindowContext_android() override;
+
+ void onSwapBuffers() override;
+
+ void onInitializeContext(void*, const DisplayParams&) override;
+ void onDestroyContext() override;
+
+private:
+ GLWindowContext_android(void*, const DisplayParams&);
+
+ EGLDisplay fDisplay;
+ EGLContext fEGLContext;
+ EGLSurface fSurface;
+};
+
+
+}
+
+#endif
diff --git a/tools/viewer/sk_app/android/VulkanWindowContext_android.cpp b/tools/viewer/sk_app/android/VulkanWindowContext_android.cpp
index 555f8a692b..5c6b7416a2 100644
--- a/tools/viewer/sk_app/android/VulkanWindowContext_android.cpp
+++ b/tools/viewer/sk_app/android/VulkanWindowContext_android.cpp
@@ -6,7 +6,8 @@
* found in the LICENSE file.
*/
-#include "VulkanWindowContext_android.h"
+#include "Window_android.h"
+#include "../VulkanWindowContext.h"
#include "vk/GrVkInterface.h"
#include "vk/GrVkUtil.h"
diff --git a/tools/viewer/sk_app/android/VulkanWindowContext_android.h b/tools/viewer/sk_app/android/VulkanWindowContext_android.h
deleted file mode 100644
index dd53e13b69..0000000000
--- a/tools/viewer/sk_app/android/VulkanWindowContext_android.h
+++ /dev/null
@@ -1,26 +0,0 @@
-
-/*
- * 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
index 4f33870c1a..926c7cd17d 100644
--- a/tools/viewer/sk_app/android/Window_android.cpp
+++ b/tools/viewer/sk_app/android/Window_android.cpp
@@ -6,8 +6,8 @@
*/
#include "Window_android.h"
-
-#include "VulkanWindowContext_android.h"
+#include "../GLWindowContext.h"
+#include "../VulkanWindowContext.h"
namespace sk_app {
@@ -46,26 +46,39 @@ void Window_android::setUIState(const Json::Value& state) {
}
bool Window_android::attach(BackendType attachType, const DisplayParams& params) {
- if (kVulkan_BackendType != attachType) {
- return false;
- }
-
+ fBackendType = attachType;
fDisplayParams = params;
- // We delay the creation of fTestContext until Android informs us that
+ if (fNativeWindow) {
+ this->initDisplay(fNativeWindow);
+ }
+ // If fNativeWindow is not set,
+ // we delay the creation of fWindowContext until Android informs us that
// the native window is ready to use.
+ // The creation will be done in initDisplay, which is initiated by kSurfaceCreated event.
return true;
}
void Window_android::initDisplay(ANativeWindow* window) {
SkASSERT(window);
+ fNativeWindow = window;
ContextPlatformData_android platformData;
platformData.fNativeWindow = window;
- fWindowContext = VulkanWindowContext::Create((void*)&platformData, fDisplayParams);
+ switch (fBackendType) {
+ case kNativeGL_BackendType:
+ fWindowContext = GLWindowContext::Create((void*)&platformData, fDisplayParams);
+ break;
+
+ case kVulkan_BackendType:
+ default:
+ fWindowContext = VulkanWindowContext::Create((void*)&platformData, fDisplayParams);
+ break;
+ }
}
void Window_android::onDisplayDestroyed() {
detach();
+ fNativeWindow = nullptr;
}
void Window_android::onInval() {
diff --git a/tools/viewer/sk_app/android/Window_android.h b/tools/viewer/sk_app/android/Window_android.h
index f1c079835b..2a7ff4730a 100644
--- a/tools/viewer/sk_app/android/Window_android.h
+++ b/tools/viewer/sk_app/android/Window_android.h
@@ -8,11 +8,17 @@
#ifndef Window_android_DEFINED
#define Window_android_DEFINED
+#include <android/native_window_jni.h>
+
#include "../Window.h"
#include "surface_glue_android.h"
namespace sk_app {
+struct ContextPlatformData_android {
+ ANativeWindow* fNativeWindow;
+};
+
class Window_android : public Window {
public:
Window_android() : Window() {}
@@ -38,9 +44,13 @@ public:
void setContentRect(int l, int t, int r, int b) { fContentRect.set(l,t,r,b); }
private:
+ // We need fNativeWindow for attaching with another backend.
+ // (in that case, attach is called without initDisplay being called later)
+ ANativeWindow* fNativeWindow = nullptr;
SkiaAndroidApp* fSkiaAndroidApp = nullptr;
SkRect fContentRect;
DisplayParams fDisplayParams;
+ BackendType fBackendType;
};
} // namespace sk_app