android_view_ThreadedRenderer.cpp revision f7d9c1dc84671d4e99657ef071d275700d85bb11
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "ThreadedRenderer" 18 19#include "jni.h" 20#include <nativehelper/JNIHelp.h> 21#include <android_runtime/AndroidRuntime.h> 22 23#include <utils/StrongPointer.h> 24#include <android_runtime/android_view_Surface.h> 25#include <system/window.h> 26 27#include <renderthread/RenderProxy.h> 28#include <renderthread/RenderTask.h> 29#include <renderthread/RenderThread.h> 30 31namespace android { 32 33#ifdef USE_OPENGL_RENDERER 34 35using namespace android::uirenderer; 36using namespace android::uirenderer::renderthread; 37 38static jmethodID gRunnableMethod; 39 40class JavaTask : public RenderTask { 41public: 42 JavaTask(JNIEnv* env, jobject jrunnable) { 43 env->GetJavaVM(&mVm); 44 mRunnable = env->NewGlobalRef(jrunnable); 45 } 46 47 virtual void run() { 48 env()->CallVoidMethod(mRunnable, gRunnableMethod); 49 env()->DeleteGlobalRef(mRunnable); 50 delete this; 51 }; 52 53private: 54 JNIEnv* env() { 55 JNIEnv* env; 56 if (mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { 57 return 0; 58 } 59 return env; 60 } 61 62 JavaVM* mVm; 63 jobject mRunnable; 64}; 65 66static void android_view_ThreadedRenderer_postToRenderThread(JNIEnv* env, jobject clazz, 67 jobject jrunnable) { 68 RenderTask* task = new JavaTask(env, jrunnable); 69 RenderThread::getInstance().queue(task); 70} 71 72static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz, 73 jboolean translucent) { 74 return (jlong) new RenderProxy(translucent); 75} 76 77static void android_view_ThreadedRenderer_deleteProxy(JNIEnv* env, jobject clazz, 78 jlong proxyPtr) { 79 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 80 delete proxy; 81} 82 83static jboolean android_view_ThreadedRenderer_initialize(JNIEnv* env, jobject clazz, 84 jlong proxyPtr, jobject jsurface) { 85 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 86 sp<ANativeWindow> window = android_view_Surface_getNativeWindow(env, jsurface); 87 return proxy->initialize(window); 88} 89 90static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject clazz, 91 jlong proxyPtr, jobject jsurface) { 92 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 93 sp<ANativeWindow> window; 94 if (jsurface) { 95 window = android_view_Surface_getNativeWindow(env, jsurface); 96 } 97 proxy->updateSurface(window); 98} 99 100static void android_view_ThreadedRenderer_pauseSurface(JNIEnv* env, jobject clazz, 101 jlong proxyPtr, jobject jsurface) { 102 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 103 sp<ANativeWindow> window; 104 if (jsurface) { 105 window = android_view_Surface_getNativeWindow(env, jsurface); 106 } 107 proxy->pauseSurface(window); 108} 109 110static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, 111 jlong proxyPtr, jint width, jint height) { 112 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 113 proxy->setup(width, height); 114} 115 116static void android_view_ThreadedRenderer_setDisplayListData(JNIEnv* env, jobject clazz, 117 jlong proxyPtr, jlong displayListPtr, jlong newDataPtr) { 118 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 119 RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); 120 DisplayListData* newData = reinterpret_cast<DisplayListData*>(newDataPtr); 121 proxy->setDisplayListData(displayList, newData); 122} 123 124static void android_view_ThreadedRenderer_drawDisplayList(JNIEnv* env, jobject clazz, 125 jlong proxyPtr, jlong displayListPtr, jint dirtyLeft, jint dirtyTop, 126 jint dirtyRight, jint dirtyBottom) { 127 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 128 RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); 129 proxy->drawDisplayList(displayList, dirtyLeft, dirtyTop, dirtyRight, dirtyBottom); 130} 131 132static void android_view_ThreadedRenderer_destroyCanvas(JNIEnv* env, jobject clazz, 133 jlong proxyPtr) { 134 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 135 proxy->destroyCanvas(); 136} 137 138static void android_view_ThreadedRenderer_attachFunctor(JNIEnv* env, jobject clazz, 139 jlong proxyPtr, jlong functorPtr) { 140 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 141 Functor* functor = reinterpret_cast<Functor*>(functorPtr); 142 proxy->attachFunctor(functor); 143} 144 145static void android_view_ThreadedRenderer_detachFunctor(JNIEnv* env, jobject clazz, 146 jlong proxyPtr, jlong functorPtr) { 147 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 148 Functor* functor = reinterpret_cast<Functor*>(functorPtr); 149 proxy->detachFunctor(functor); 150} 151 152static void android_view_ThreadedRenderer_invokeFunctor(JNIEnv* env, jobject clazz, 153 jlong proxyPtr, jlong functorPtr, jboolean waitForCompletion) { 154 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 155 Functor* functor = reinterpret_cast<Functor*>(functorPtr); 156 proxy->invokeFunctor(functor, waitForCompletion); 157} 158 159static void android_view_ThreadedRenderer_runWithGlContext(JNIEnv* env, jobject clazz, 160 jlong proxyPtr, jobject jrunnable) { 161 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 162 RenderTask* task = new JavaTask(env, jrunnable); 163 proxy->runWithGlContext(task); 164} 165 166static jlong android_view_ThreadedRenderer_createDisplayListLayer(JNIEnv* env, jobject clazz, 167 jlong proxyPtr, jint width, jint height) { 168 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 169 DeferredLayerUpdater* layer = proxy->createDisplayListLayer(width, height); 170 return reinterpret_cast<jlong>(layer); 171} 172 173static jlong android_view_ThreadedRenderer_createTextureLayer(JNIEnv* env, jobject clazz, 174 jlong proxyPtr) { 175 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 176 DeferredLayerUpdater* layer = proxy->createTextureLayer(); 177 return reinterpret_cast<jlong>(layer); 178} 179 180static jboolean android_view_ThreadedRenderer_copyLayerInto(JNIEnv* env, jobject clazz, 181 jlong proxyPtr, jlong layerPtr, jlong bitmapPtr) { 182 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 183 DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr); 184 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); 185 return proxy->copyLayerInto(layer, bitmap); 186} 187 188static void android_view_ThreadedRenderer_destroyLayer(JNIEnv* env, jobject clazz, 189 jlong proxyPtr, jlong layerPtr) { 190 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 191 DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr); 192 proxy->destroyLayer(layer); 193} 194 195static void android_view_ThreadedRenderer_fence(JNIEnv* env, jobject clazz, 196 jlong proxyPtr) { 197 RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); 198 proxy->fence(); 199} 200 201#endif 202 203// ---------------------------------------------------------------------------- 204// JNI Glue 205// ---------------------------------------------------------------------------- 206 207const char* const kClassPathName = "android/view/ThreadedRenderer"; 208 209static JNINativeMethod gMethods[] = { 210#ifdef USE_OPENGL_RENDERER 211 { "postToRenderThread", "(Ljava/lang/Runnable;)V", (void*) android_view_ThreadedRenderer_postToRenderThread }, 212 { "nCreateProxy", "(Z)J", (void*) android_view_ThreadedRenderer_createProxy }, 213 { "nDeleteProxy", "(J)V", (void*) android_view_ThreadedRenderer_deleteProxy }, 214 { "nInitialize", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_initialize }, 215 { "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface }, 216 { "nPauseSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_pauseSurface }, 217 { "nSetup", "(JII)V", (void*) android_view_ThreadedRenderer_setup }, 218 { "nSetDisplayListData", "(JJJ)V", (void*) android_view_ThreadedRenderer_setDisplayListData }, 219 { "nDrawDisplayList", "(JJIIII)V", (void*) android_view_ThreadedRenderer_drawDisplayList }, 220 { "nDestroyCanvas", "(J)V", (void*) android_view_ThreadedRenderer_destroyCanvas }, 221 { "nAttachFunctor", "(JJ)V", (void*) android_view_ThreadedRenderer_attachFunctor }, 222 { "nDetachFunctor", "(JJ)V", (void*) android_view_ThreadedRenderer_detachFunctor }, 223 { "nInvokeFunctor", "(JJZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor }, 224 { "nRunWithGlContext", "(JLjava/lang/Runnable;)V", (void*) android_view_ThreadedRenderer_runWithGlContext }, 225 { "nCreateDisplayListLayer", "(JII)J", (void*) android_view_ThreadedRenderer_createDisplayListLayer }, 226 { "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer }, 227 { "nCopyLayerInto", "(JJJ)Z", (void*) android_view_ThreadedRenderer_copyLayerInto }, 228 { "nDestroyLayer", "(JJ)V", (void*) android_view_ThreadedRenderer_destroyLayer }, 229 { "nFence", "(J)V", (void*) android_view_ThreadedRenderer_fence }, 230#endif 231}; 232 233int register_android_view_ThreadedRenderer(JNIEnv* env) { 234#ifdef USE_OPENGL_RENDERER 235 jclass cls = env->FindClass("java/lang/Runnable"); 236 gRunnableMethod = env->GetMethodID(cls, "run", "()V"); 237 env->DeleteLocalRef(cls); 238#endif 239 return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); 240} 241 242}; // namespace android 243