• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <algorithm>
20 
21 #include "jni.h"
22 #include <nativehelper/JNIHelp.h>
23 #include <android_runtime/AndroidRuntime.h>
24 
25 #include <EGL/egl.h>
26 #include <EGL/eglext.h>
27 #include <EGL/egl_cache.h>
28 
29 #include <utils/StrongPointer.h>
30 #include <android_runtime/android_view_Surface.h>
31 #include <system/window.h>
32 
33 #include "android_view_GraphicBuffer.h"
34 
35 #include <Animator.h>
36 #include <AnimationContext.h>
37 #include <IContextFactory.h>
38 #include <RenderNode.h>
39 #include <renderthread/CanvasContext.h>
40 #include <renderthread/RenderProxy.h>
41 #include <renderthread/RenderTask.h>
42 #include <renderthread/RenderThread.h>
43 #include <Vector.h>
44 
45 namespace android {
46 
47 #ifdef USE_OPENGL_RENDERER
48 
49 using namespace android::uirenderer;
50 using namespace android::uirenderer::renderthread;
51 
getenv(JavaVM * vm)52 static JNIEnv* getenv(JavaVM* vm) {
53     JNIEnv* env;
54     if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
55         LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm);
56     }
57     return env;
58 }
59 
60 class OnFinishedEvent {
61 public:
OnFinishedEvent(BaseRenderNodeAnimator * animator,AnimationListener * listener)62     OnFinishedEvent(BaseRenderNodeAnimator* animator, AnimationListener* listener)
63             : animator(animator), listener(listener) {}
64     sp<BaseRenderNodeAnimator> animator;
65     sp<AnimationListener> listener;
66 };
67 
68 class InvokeAnimationListeners : public MessageHandler {
69 public:
InvokeAnimationListeners(std::vector<OnFinishedEvent> & events)70     InvokeAnimationListeners(std::vector<OnFinishedEvent>& events) {
71         mOnFinishedEvents.swap(events);
72     }
73 
callOnFinished(OnFinishedEvent & event)74     static void callOnFinished(OnFinishedEvent& event) {
75         event.listener->onAnimationFinished(event.animator.get());
76     }
77 
handleMessage(const Message & message)78     virtual void handleMessage(const Message& message) {
79         std::for_each(mOnFinishedEvents.begin(), mOnFinishedEvents.end(), callOnFinished);
80         mOnFinishedEvents.clear();
81     }
82 
83 private:
84     std::vector<OnFinishedEvent> mOnFinishedEvents;
85 };
86 
87 class RenderingException : public MessageHandler {
88 public:
RenderingException(JavaVM * vm,const std::string & message)89     RenderingException(JavaVM* vm, const std::string& message)
90             : mVm(vm)
91             , mMessage(message) {
92     }
93 
handleMessage(const Message &)94     virtual void handleMessage(const Message&) {
95         throwException(mVm, mMessage);
96     }
97 
throwException(JavaVM * vm,const std::string & message)98     static void throwException(JavaVM* vm, const std::string& message) {
99         JNIEnv* env = getenv(vm);
100         jniThrowException(env, "java/lang/IllegalStateException", message.c_str());
101     }
102 
103 private:
104     JavaVM* mVm;
105     std::string mMessage;
106 };
107 
108 class RootRenderNode : public RenderNode, ErrorHandler {
109 public:
RootRenderNode(JNIEnv * env)110     RootRenderNode(JNIEnv* env) : RenderNode() {
111         mLooper = Looper::getForThread();
112         LOG_ALWAYS_FATAL_IF(!mLooper.get(),
113                 "Must create RootRenderNode on a thread with a looper!");
114         env->GetJavaVM(&mVm);
115     }
116 
~RootRenderNode()117     virtual ~RootRenderNode() {}
118 
onError(const std::string & message)119     virtual void onError(const std::string& message) {
120         mLooper->sendMessage(new RenderingException(mVm, message), 0);
121     }
122 
prepareTree(TreeInfo & info)123     virtual void prepareTree(TreeInfo& info) {
124         info.errorHandler = this;
125         RenderNode::prepareTree(info);
126         info.errorHandler = NULL;
127     }
128 
sendMessage(const sp<MessageHandler> & handler)129     void sendMessage(const sp<MessageHandler>& handler) {
130         mLooper->sendMessage(handler, 0);
131     }
132 
attachAnimatingNode(RenderNode * animatingNode)133     void attachAnimatingNode(RenderNode* animatingNode) {
134         mPendingAnimatingRenderNodes.push_back(animatingNode);
135     }
136 
doAttachAnimatingNodes(AnimationContext * context)137     void doAttachAnimatingNodes(AnimationContext* context) {
138         for (size_t i = 0; i < mPendingAnimatingRenderNodes.size(); i++) {
139             RenderNode* node = mPendingAnimatingRenderNodes[i].get();
140             context->addAnimatingRenderNode(*node);
141         }
142         mPendingAnimatingRenderNodes.clear();
143     }
144 
145 private:
146     sp<Looper> mLooper;
147     JavaVM* mVm;
148     std::vector< sp<RenderNode> > mPendingAnimatingRenderNodes;
149 };
150 
151 class AnimationContextBridge : public AnimationContext {
152 public:
AnimationContextBridge(renderthread::TimeLord & clock,RootRenderNode * rootNode)153     AnimationContextBridge(renderthread::TimeLord& clock, RootRenderNode* rootNode)
154             : AnimationContext(clock), mRootNode(rootNode) {
155     }
156 
~AnimationContextBridge()157     virtual ~AnimationContextBridge() {}
158 
159     // Marks the start of a frame, which will update the frame time and move all
160     // next frame animations into the current frame
startFrame(TreeInfo::TraversalMode mode)161     virtual void startFrame(TreeInfo::TraversalMode mode) {
162         if (mode == TreeInfo::MODE_FULL) {
163             mRootNode->doAttachAnimatingNodes(this);
164         }
165         AnimationContext::startFrame(mode);
166     }
167 
168     // Runs any animations still left in mCurrentFrameAnimations
runRemainingAnimations(TreeInfo & info)169     virtual void runRemainingAnimations(TreeInfo& info) {
170         AnimationContext::runRemainingAnimations(info);
171         postOnFinishedEvents();
172     }
173 
callOnFinished(BaseRenderNodeAnimator * animator,AnimationListener * listener)174     virtual void callOnFinished(BaseRenderNodeAnimator* animator, AnimationListener* listener) {
175         OnFinishedEvent event(animator, listener);
176         mOnFinishedEvents.push_back(event);
177     }
178 
destroy()179     virtual void destroy() {
180         AnimationContext::destroy();
181         postOnFinishedEvents();
182     }
183 
184 private:
185     sp<RootRenderNode> mRootNode;
186     std::vector<OnFinishedEvent> mOnFinishedEvents;
187 
postOnFinishedEvents()188     void postOnFinishedEvents() {
189         if (mOnFinishedEvents.size()) {
190             sp<InvokeAnimationListeners> message
191                     = new InvokeAnimationListeners(mOnFinishedEvents);
192             mRootNode->sendMessage(message);
193         }
194     }
195 };
196 
197 class ContextFactoryImpl : public IContextFactory {
198 public:
ContextFactoryImpl(RootRenderNode * rootNode)199     ContextFactoryImpl(RootRenderNode* rootNode) : mRootNode(rootNode) {}
200 
createAnimationContext(renderthread::TimeLord & clock)201     virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) {
202         return new AnimationContextBridge(clock, mRootNode);
203     }
204 
205 private:
206     RootRenderNode* mRootNode;
207 };
208 
android_view_ThreadedRenderer_setAtlas(JNIEnv * env,jobject clazz,jlong proxyPtr,jobject graphicBuffer,jlongArray atlasMapArray)209 static void android_view_ThreadedRenderer_setAtlas(JNIEnv* env, jobject clazz,
210         jlong proxyPtr, jobject graphicBuffer, jlongArray atlasMapArray) {
211     sp<GraphicBuffer> buffer = graphicBufferForJavaObject(env, graphicBuffer);
212     jsize len = env->GetArrayLength(atlasMapArray);
213     if (len <= 0) {
214         ALOGW("Failed to initialize atlas, invalid map length: %d", len);
215         return;
216     }
217     int64_t* map = new int64_t[len];
218     env->GetLongArrayRegion(atlasMapArray, 0, len, map);
219 
220     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
221     proxy->setTextureAtlas(buffer, map, len);
222 }
223 
android_view_ThreadedRenderer_createRootRenderNode(JNIEnv * env,jobject clazz)224 static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, jobject clazz) {
225     RootRenderNode* node = new RootRenderNode(env);
226     node->incStrong(0);
227     node->setName("RootRenderNode");
228     return reinterpret_cast<jlong>(node);
229 }
230 
android_view_ThreadedRenderer_createProxy(JNIEnv * env,jobject clazz,jboolean translucent,jlong rootRenderNodePtr)231 static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz,
232         jboolean translucent, jlong rootRenderNodePtr) {
233     RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootRenderNodePtr);
234     ContextFactoryImpl factory(rootRenderNode);
235     return (jlong) new RenderProxy(translucent, rootRenderNode, &factory);
236 }
237 
android_view_ThreadedRenderer_deleteProxy(JNIEnv * env,jobject clazz,jlong proxyPtr)238 static void android_view_ThreadedRenderer_deleteProxy(JNIEnv* env, jobject clazz,
239         jlong proxyPtr) {
240     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
241     delete proxy;
242 }
243 
android_view_ThreadedRenderer_setFrameInterval(JNIEnv * env,jobject clazz,jlong proxyPtr,jlong frameIntervalNanos)244 static void android_view_ThreadedRenderer_setFrameInterval(JNIEnv* env, jobject clazz,
245         jlong proxyPtr, jlong frameIntervalNanos) {
246     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
247     proxy->setFrameInterval(frameIntervalNanos);
248 }
249 
android_view_ThreadedRenderer_loadSystemProperties(JNIEnv * env,jobject clazz,jlong proxyPtr)250 static jboolean android_view_ThreadedRenderer_loadSystemProperties(JNIEnv* env, jobject clazz,
251         jlong proxyPtr) {
252     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
253     return proxy->loadSystemProperties();
254 }
255 
android_view_ThreadedRenderer_initialize(JNIEnv * env,jobject clazz,jlong proxyPtr,jobject jsurface)256 static jboolean android_view_ThreadedRenderer_initialize(JNIEnv* env, jobject clazz,
257         jlong proxyPtr, jobject jsurface) {
258     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
259     sp<ANativeWindow> window = android_view_Surface_getNativeWindow(env, jsurface);
260     return proxy->initialize(window);
261 }
262 
android_view_ThreadedRenderer_updateSurface(JNIEnv * env,jobject clazz,jlong proxyPtr,jobject jsurface)263 static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject clazz,
264         jlong proxyPtr, jobject jsurface) {
265     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
266     sp<ANativeWindow> window;
267     if (jsurface) {
268         window = android_view_Surface_getNativeWindow(env, jsurface);
269     }
270     proxy->updateSurface(window);
271 }
272 
android_view_ThreadedRenderer_pauseSurface(JNIEnv * env,jobject clazz,jlong proxyPtr,jobject jsurface)273 static jboolean android_view_ThreadedRenderer_pauseSurface(JNIEnv* env, jobject clazz,
274         jlong proxyPtr, jobject jsurface) {
275     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
276     sp<ANativeWindow> window;
277     if (jsurface) {
278         window = android_view_Surface_getNativeWindow(env, jsurface);
279     }
280     return proxy->pauseSurface(window);
281 }
282 
android_view_ThreadedRenderer_setup(JNIEnv * env,jobject clazz,jlong proxyPtr,jint width,jint height,jfloat lightX,jfloat lightY,jfloat lightZ,jfloat lightRadius,jint ambientShadowAlpha,jint spotShadowAlpha)283 static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, jlong proxyPtr,
284         jint width, jint height,
285         jfloat lightX, jfloat lightY, jfloat lightZ, jfloat lightRadius,
286         jint ambientShadowAlpha, jint spotShadowAlpha) {
287     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
288     proxy->setup(width, height, (Vector3){lightX, lightY, lightZ}, lightRadius,
289             ambientShadowAlpha, spotShadowAlpha);
290 }
291 
android_view_ThreadedRenderer_setOpaque(JNIEnv * env,jobject clazz,jlong proxyPtr,jboolean opaque)292 static void android_view_ThreadedRenderer_setOpaque(JNIEnv* env, jobject clazz,
293         jlong proxyPtr, jboolean opaque) {
294     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
295     proxy->setOpaque(opaque);
296 }
297 
android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv * env,jobject clazz,jlong proxyPtr,jlong frameTimeNanos,jlong recordDuration,jfloat density)298 static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
299         jlong proxyPtr, jlong frameTimeNanos, jlong recordDuration, jfloat density) {
300     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
301     return proxy->syncAndDrawFrame(frameTimeNanos, recordDuration, density);
302 }
303 
android_view_ThreadedRenderer_destroy(JNIEnv * env,jobject clazz,jlong proxyPtr)304 static void android_view_ThreadedRenderer_destroy(JNIEnv* env, jobject clazz,
305         jlong proxyPtr) {
306     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
307     proxy->destroy();
308 }
309 
android_view_ThreadedRenderer_registerAnimatingRenderNode(JNIEnv * env,jobject clazz,jlong rootNodePtr,jlong animatingNodePtr)310 static void android_view_ThreadedRenderer_registerAnimatingRenderNode(JNIEnv* env, jobject clazz,
311         jlong rootNodePtr, jlong animatingNodePtr) {
312     RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
313     RenderNode* animatingNode = reinterpret_cast<RenderNode*>(animatingNodePtr);
314     rootRenderNode->attachAnimatingNode(animatingNode);
315 }
316 
android_view_ThreadedRenderer_invokeFunctor(JNIEnv * env,jobject clazz,jlong functorPtr,jboolean waitForCompletion)317 static void android_view_ThreadedRenderer_invokeFunctor(JNIEnv* env, jobject clazz,
318         jlong functorPtr, jboolean waitForCompletion) {
319     Functor* functor = reinterpret_cast<Functor*>(functorPtr);
320     RenderProxy::invokeFunctor(functor, waitForCompletion);
321 }
322 
android_view_ThreadedRenderer_createTextureLayer(JNIEnv * env,jobject clazz,jlong proxyPtr)323 static jlong android_view_ThreadedRenderer_createTextureLayer(JNIEnv* env, jobject clazz,
324         jlong proxyPtr) {
325     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
326     DeferredLayerUpdater* layer = proxy->createTextureLayer();
327     return reinterpret_cast<jlong>(layer);
328 }
329 
android_view_ThreadedRenderer_buildLayer(JNIEnv * env,jobject clazz,jlong proxyPtr,jlong nodePtr)330 static void android_view_ThreadedRenderer_buildLayer(JNIEnv* env, jobject clazz,
331         jlong proxyPtr, jlong nodePtr) {
332     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
333     RenderNode* node = reinterpret_cast<RenderNode*>(nodePtr);
334     proxy->buildLayer(node);
335 }
336 
android_view_ThreadedRenderer_copyLayerInto(JNIEnv * env,jobject clazz,jlong proxyPtr,jlong layerPtr,jlong bitmapPtr)337 static jboolean android_view_ThreadedRenderer_copyLayerInto(JNIEnv* env, jobject clazz,
338         jlong proxyPtr, jlong layerPtr, jlong bitmapPtr) {
339     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
340     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
341     SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
342     return proxy->copyLayerInto(layer, bitmap);
343 }
344 
android_view_ThreadedRenderer_pushLayerUpdate(JNIEnv * env,jobject clazz,jlong proxyPtr,jlong layerPtr)345 static void android_view_ThreadedRenderer_pushLayerUpdate(JNIEnv* env, jobject clazz,
346         jlong proxyPtr, jlong layerPtr) {
347     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
348     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
349     proxy->pushLayerUpdate(layer);
350 }
351 
android_view_ThreadedRenderer_cancelLayerUpdate(JNIEnv * env,jobject clazz,jlong proxyPtr,jlong layerPtr)352 static void android_view_ThreadedRenderer_cancelLayerUpdate(JNIEnv* env, jobject clazz,
353         jlong proxyPtr, jlong layerPtr) {
354     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
355     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
356     proxy->cancelLayerUpdate(layer);
357 }
358 
android_view_ThreadedRenderer_detachSurfaceTexture(JNIEnv * env,jobject clazz,jlong proxyPtr,jlong layerPtr)359 static void android_view_ThreadedRenderer_detachSurfaceTexture(JNIEnv* env, jobject clazz,
360         jlong proxyPtr, jlong layerPtr) {
361     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
362     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
363     proxy->detachSurfaceTexture(layer);
364 }
365 
android_view_ThreadedRenderer_destroyHardwareResources(JNIEnv * env,jobject clazz,jlong proxyPtr)366 static void android_view_ThreadedRenderer_destroyHardwareResources(JNIEnv* env, jobject clazz,
367         jlong proxyPtr) {
368     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
369     proxy->destroyHardwareResources();
370 }
371 
android_view_ThreadedRenderer_trimMemory(JNIEnv * env,jobject clazz,jint level)372 static void android_view_ThreadedRenderer_trimMemory(JNIEnv* env, jobject clazz,
373         jint level) {
374     RenderProxy::trimMemory(level);
375 }
376 
android_view_ThreadedRenderer_fence(JNIEnv * env,jobject clazz,jlong proxyPtr)377 static void android_view_ThreadedRenderer_fence(JNIEnv* env, jobject clazz,
378         jlong proxyPtr) {
379     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
380     proxy->fence();
381 }
382 
android_view_ThreadedRenderer_stopDrawing(JNIEnv * env,jobject clazz,jlong proxyPtr)383 static void android_view_ThreadedRenderer_stopDrawing(JNIEnv* env, jobject clazz,
384         jlong proxyPtr) {
385     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
386     proxy->stopDrawing();
387 }
388 
android_view_ThreadedRenderer_notifyFramePending(JNIEnv * env,jobject clazz,jlong proxyPtr)389 static void android_view_ThreadedRenderer_notifyFramePending(JNIEnv* env, jobject clazz,
390         jlong proxyPtr) {
391     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
392     proxy->notifyFramePending();
393 }
394 
android_view_ThreadedRenderer_dumpProfileInfo(JNIEnv * env,jobject clazz,jlong proxyPtr,jobject javaFileDescriptor)395 static void android_view_ThreadedRenderer_dumpProfileInfo(JNIEnv* env, jobject clazz,
396         jlong proxyPtr, jobject javaFileDescriptor) {
397     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
398     int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
399     proxy->dumpProfileInfo(fd);
400 }
401 
402 #endif
403 
404 // ----------------------------------------------------------------------------
405 // Shaders
406 // ----------------------------------------------------------------------------
407 
android_view_ThreadedRenderer_setupShadersDiskCache(JNIEnv * env,jobject clazz,jstring diskCachePath)408 static void android_view_ThreadedRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz,
409         jstring diskCachePath) {
410 
411     const char* cacheArray = env->GetStringUTFChars(diskCachePath, NULL);
412     egl_cache_t::get()->setCacheFilename(cacheArray);
413     env->ReleaseStringUTFChars(diskCachePath, cacheArray);
414 }
415 
416 // ----------------------------------------------------------------------------
417 // JNI Glue
418 // ----------------------------------------------------------------------------
419 
420 const char* const kClassPathName = "android/view/ThreadedRenderer";
421 
422 static JNINativeMethod gMethods[] = {
423 #ifdef USE_OPENGL_RENDERER
424     { "nSetAtlas", "(JLandroid/view/GraphicBuffer;[J)V",   (void*) android_view_ThreadedRenderer_setAtlas },
425     { "nCreateRootRenderNode", "()J", (void*) android_view_ThreadedRenderer_createRootRenderNode },
426     { "nCreateProxy", "(ZJ)J", (void*) android_view_ThreadedRenderer_createProxy },
427     { "nDeleteProxy", "(J)V", (void*) android_view_ThreadedRenderer_deleteProxy },
428     { "nSetFrameInterval", "(JJ)V", (void*) android_view_ThreadedRenderer_setFrameInterval },
429     { "nLoadSystemProperties", "(J)Z", (void*) android_view_ThreadedRenderer_loadSystemProperties },
430     { "nInitialize", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_initialize },
431     { "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface },
432     { "nPauseSurface", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_pauseSurface },
433     { "nSetup", "(JIIFFFFII)V", (void*) android_view_ThreadedRenderer_setup },
434     { "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
435     { "nSyncAndDrawFrame", "(JJJF)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
436     { "nDestroy", "(J)V", (void*) android_view_ThreadedRenderer_destroy },
437     { "nRegisterAnimatingRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_registerAnimatingRenderNode },
438     { "nInvokeFunctor", "(JZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
439     { "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer },
440     { "nBuildLayer", "(JJ)V", (void*) android_view_ThreadedRenderer_buildLayer },
441     { "nCopyLayerInto", "(JJJ)Z", (void*) android_view_ThreadedRenderer_copyLayerInto },
442     { "nPushLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_pushLayerUpdate },
443     { "nCancelLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_cancelLayerUpdate },
444     { "nDetachSurfaceTexture", "(JJ)V", (void*) android_view_ThreadedRenderer_detachSurfaceTexture },
445     { "nDestroyHardwareResources", "(J)V", (void*) android_view_ThreadedRenderer_destroyHardwareResources },
446     { "nTrimMemory", "(I)V", (void*) android_view_ThreadedRenderer_trimMemory },
447     { "nFence", "(J)V", (void*) android_view_ThreadedRenderer_fence },
448     { "nStopDrawing", "(J)V", (void*) android_view_ThreadedRenderer_stopDrawing },
449     { "nNotifyFramePending", "(J)V", (void*) android_view_ThreadedRenderer_notifyFramePending },
450     { "nDumpProfileInfo", "(JLjava/io/FileDescriptor;)V", (void*) android_view_ThreadedRenderer_dumpProfileInfo },
451 #endif
452     { "setupShadersDiskCache", "(Ljava/lang/String;)V",
453                 (void*) android_view_ThreadedRenderer_setupShadersDiskCache },
454 };
455 
register_android_view_ThreadedRenderer(JNIEnv * env)456 int register_android_view_ThreadedRenderer(JNIEnv* env) {
457     return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
458 }
459 
460 }; // namespace android
461