Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Unified Diff: tools/viewer/sk_app/android/surface_glue_android.cpp

Issue 1952323004: Initial commit of our new Android app to demo Skia. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Style Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/viewer/sk_app/android/surface_glue_android.cpp
diff --git a/tools/viewer/sk_app/android/surface_glue_android.cpp b/tools/viewer/sk_app/android/surface_glue_android.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e287afa43b43ea385985ca2c65e70450d01d7464
--- /dev/null
+++ b/tools/viewer/sk_app/android/surface_glue_android.cpp
@@ -0,0 +1,169 @@
+/*
+* 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 "surface_glue_android.h"
+
+#include <jni.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <android/native_window_jni.h>
+#include <android_native_app_glue.h>
djsollen 2016/05/06 18:45:26 we should not need this include.
liyuqian 2016/05/06 20:42:30 This is needed for LOOPER_ID_USER
djsollen 2016/05/09 13:29:44 you don't need LOOPER_ID_USER as that was somethin
liyuqian 2016/05/09 14:27:27 Done.
+
+#include "../Application.h"
+#include "SkTypes.h"
+#include "SkUtils.h"
+#include "Window_android.h"
+
+namespace sk_app {
+
+static const int LOOPER_ID_MESSAGEPIPE = LOOPER_ID_USER;
+
+void* pthread_main(void* arg);
+
+AppThread::AppThread() {
+ nativeWindow = nullptr;
+ pthread_create(&thread, nullptr, pthread_main, this);
+}
+
+AppThread::~AppThread() {
+ if (window) {
+ window->detach();
+ }
+ if (nativeWindow) {
+ ANativeWindow_release(this->nativeWindow);
+ this->nativeWindow = nullptr;
+ }
+ if (app) {
+ delete app;
+ }
+}
+
+void AppThread::postMessage(const Message& message) {
+ auto writeSize = write(pipes[1], &message, sizeof(message));
+ SkASSERT(writeSize == sizeof(message));
+}
+
+void AppThread::readMessage(Message* message) {
+ auto readSize = read(pipes[0], message, sizeof(Message));
+ SkASSERT(readSize == sizeof(Message));
+}
+
+static int message_callback(int fd, int events, void* data) {
+ auto appThread = (AppThread*)data;
+ Message message;
+ appThread->readMessage(&message);
+ SkDebugf("message_callback %d", message.type);
+
+ switch (message.type) {
+ case kDestroyApp: {
+ delete appThread;
+ pthread_exit(nullptr);
+ return 0;
+ }
+ case kSurfaceCreated: {
+ auto window_android = (Window_android*)appThread->window;
+ window_android->initDisplay(appThread->nativeWindow);
+ window_android->paintIfNeeded();
+ break;
+ }
+ case kSurfaceChanged: {
+ int width = ANativeWindow_getWidth(appThread->nativeWindow);
+ int height = ANativeWindow_getHeight(appThread->nativeWindow);
+ appThread->window->onResize(width, height);
+ auto window_android = (Window_android*)appThread->window;
+ window_android->setContentRect(0, 0, width, height);
+ window_android->paintIfNeeded();
+ break;
+ }
+ default: {
+ // do nothing
+ }
+ }
+
+ return 1; // continue receiving callbacks
+}
+
+void* pthread_main(void* arg) {
+ SkDebugf("pthread_main begins");
+
+ auto appThread = (AppThread*)arg;
+
+ ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
+ pipe(appThread->pipes);
+ ALooper_addFd(looper, appThread->pipes[0], LOOPER_ID_MESSAGEPIPE, ALOOPER_EVENT_INPUT,
+ message_callback, appThread);
+
+ int ident;
+ int events;
+ struct android_poll_source* source;
+
+ appThread->app = Application::Create(0, nullptr, appThread);
+
+ while ((ident = ALooper_pollAll(-1, nullptr, &events, (void**)&source)) >= 0) {
+ SkDebugf("ALooper_pollAll ident=%d", ident);
+ }
+
+ return nullptr;
+}
+
+extern "C" // extern "C" is needed for JNI (although the method itself is in C++)
+ JNIEXPORT jlong JNICALL
+ Java_org_skia_viewer_ViewerApplication_createNativeApp(JNIEnv* env, jobject activity) {
+ AppThread* appThread = new AppThread;
+ return (jlong)((size_t)appThread);
+}
+
+extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerApplication_destroyNativeApp(
+ JNIEnv* env, jobject activity, jlong handle) {
+ auto appThread = (AppThread*)handle;
+ Message message(kDestroyApp);
+ appThread->postMessage(message);
+ pthread_join(appThread->thread, nullptr);
+}
+
+extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_MainActivity_onSurfaceCreated(
+ JNIEnv* env, jobject activity, jlong handle, jobject surface) {
+ auto appThread = (AppThread*)handle;
+
+ SkASSERT(!appThread->nativeWindow);
+ ANativeWindow* nativeWindow = ANativeWindow_fromSurface(env, surface);
+ appThread->nativeWindow = nativeWindow;
+
+ Message message(kSurfaceCreated);
+ appThread->postMessage(message);
+}
+
+extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_MainActivity_onSurfaceChanged(
+ JNIEnv* env, jobject activity, jlong handle, jobject surface) {
+ auto appThread = (AppThread*)handle;
+
+ ANativeWindow* nativeWindow = ANativeWindow_fromSurface(env, surface);
+ if (nativeWindow != appThread->nativeWindow) {
+ ANativeWindow_release(appThread->nativeWindow);
+ appThread->nativeWindow = nativeWindow;
+ }
+
+ Message message(kSurfaceChanged);
+ appThread->postMessage(message);
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_org_skia_viewer_MainActivity_onSurfaceDestroyed(JNIEnv* env, jobject activity, jlong handle) {
+ auto appThread = (AppThread*)handle;
+
+ if (appThread->nativeWindow) {
+ ANativeWindow_release(appThread->nativeWindow);
+ appThread->nativeWindow = nullptr;
+ }
+
+ Message message(kSurfaceDestroyed);
+ appThread->postMessage(message);
+}
+
+} // namespace sk_app

Powered by Google App Engine
This is Rietveld 408576698