• 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 ATRACE_TAG ATRACE_TAG_VIEW
18 
19 #include <FrameInfo.h>
20 #include <GraphicsJNI.h>
21 #include <Picture.h>
22 #include <Properties.h>
23 #include <RootRenderNode.h>
24 #include <SkBitmap.h>
25 #include <SkColorSpace.h>
26 #include <SkData.h>
27 #include <SkImage.h>
28 #ifdef __ANDROID__
29 #include <SkImageAndroid.h>
30 #else
31 #include <SkImagePriv.h>
32 #endif
33 #include <SkPicture.h>
34 #include <SkPixmap.h>
35 #include <SkSerialProcs.h>
36 #include <SkStream.h>
37 #include <SkTypeface.h>
38 #include <gui/TraceUtils.h>
39 #include <include/encode/SkPngEncoder.h>
40 #include <inttypes.h>
41 #include <log/log.h>
42 #include <media/NdkImage.h>
43 #include <media/NdkImageReader.h>
44 #include <nativehelper/JNIPlatformHelp.h>
45 #ifdef __ANDROID__
46 #include <pipeline/skia/ShaderCache.h>
47 #include <private/EGL/cache.h>
48 #endif
49 #include <renderthread/CanvasContext.h>
50 #include <renderthread/RenderProxy.h>
51 #include <renderthread/RenderTask.h>
52 #include <renderthread/RenderThread.h>
53 #include <src/image/SkImage_Base.h>
54 #include <thread/CommonPool.h>
55 #ifdef __ANDROID__
56 #include <gui/SurfaceControl.h>
57 #include <ui/GraphicBufferAllocator.h>
58 #endif
59 #include <utils/Color.h>
60 #include <utils/RefBase.h>
61 #include <utils/StrongPointer.h>
62 #include <utils/Timers.h>
63 
64 #include <algorithm>
65 #include <atomic>
66 #include <vector>
67 
68 #include "JvmErrorReporter.h"
69 #include "android_graphics_HardwareRendererObserver.h"
70 #include "utils/ForceDark.h"
71 #include "utils/SharedLib.h"
72 
73 namespace android {
74 
75 using namespace android::uirenderer;
76 using namespace android::uirenderer::renderthread;
77 
78 struct {
79     jclass clazz;
80     jmethodID invokePictureCapturedCallback;
81 } gHardwareRenderer;
82 
83 struct {
84     jmethodID onMergeTransaction;
85 } gASurfaceTransactionCallback;
86 
87 struct {
88     jmethodID prepare;
89 } gPrepareSurfaceControlForWebviewCallback;
90 
91 struct {
92     jmethodID onFrameDraw;
93 } gFrameDrawingCallback;
94 
95 struct {
96     jmethodID onFrameCommit;
97 } gFrameCommitCallback;
98 
99 struct {
100     jmethodID onFrameComplete;
101 } gFrameCompleteCallback;
102 
103 struct {
104     jmethodID onCopyFinished;
105     jmethodID getDestinationBitmap;
106 } gCopyRequest;
107 
getenv(JavaVM * vm)108 static JNIEnv* getenv(JavaVM* vm) {
109     JNIEnv* env;
110     if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
111         LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm);
112     }
113     return env;
114 }
115 
116 typedef ANativeWindow* (*ANW_fromSurface)(JNIEnv* env, jobject surface);
117 ANW_fromSurface fromSurface;
118 
119 class FrameCommitWrapper : public LightRefBase<FrameCommitWrapper> {
120 public:
FrameCommitWrapper(JNIEnv * env,jobject jobject)121     explicit FrameCommitWrapper(JNIEnv* env, jobject jobject) {
122         env->GetJavaVM(&mVm);
123         mObject = env->NewGlobalRef(jobject);
124         LOG_ALWAYS_FATAL_IF(!mObject, "Failed to make global ref");
125     }
126 
~FrameCommitWrapper()127     ~FrameCommitWrapper() { releaseObject(); }
128 
onFrameCommit(bool didProduceBuffer)129     void onFrameCommit(bool didProduceBuffer) {
130         if (mObject) {
131             ATRACE_FORMAT("frameCommit success=%d", didProduceBuffer);
132             getenv(mVm)->CallVoidMethod(mObject, gFrameCommitCallback.onFrameCommit,
133                                         didProduceBuffer);
134             releaseObject();
135         }
136     }
137 
138 private:
139     JavaVM* mVm;
140     jobject mObject;
141 
releaseObject()142     void releaseObject() {
143         if (mObject) {
144             getenv(mVm)->DeleteGlobalRef(mObject);
145             mObject = nullptr;
146         }
147     }
148 };
149 
android_view_ThreadedRenderer_rotateProcessStatsBuffer(JNIEnv * env,jobject clazz)150 static void android_view_ThreadedRenderer_rotateProcessStatsBuffer(JNIEnv* env, jobject clazz) {
151     RenderProxy::rotateProcessStatsBuffer();
152 }
153 
android_view_ThreadedRenderer_setProcessStatsBuffer(JNIEnv * env,jobject clazz,jint fd)154 static void android_view_ThreadedRenderer_setProcessStatsBuffer(JNIEnv* env, jobject clazz,
155         jint fd) {
156     RenderProxy::setProcessStatsBuffer(fd);
157 }
158 
android_view_ThreadedRenderer_getRenderThreadTid(JNIEnv * env,jobject clazz,jlong proxyPtr)159 static jint android_view_ThreadedRenderer_getRenderThreadTid(JNIEnv* env, jobject clazz,
160         jlong proxyPtr) {
161     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
162     return proxy->getRenderThreadTid();
163 }
164 
android_view_ThreadedRenderer_createRootRenderNode(JNIEnv * env,jobject clazz)165 static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, jobject clazz) {
166     RootRenderNode* node = new RootRenderNode(std::make_unique<JvmErrorReporter>(env));
167     node->incStrong(0);
168     node->setName("RootRenderNode");
169     return reinterpret_cast<jlong>(node);
170 }
171 
android_view_ThreadedRenderer_createProxy(JNIEnv * env,jobject clazz,jboolean translucent,jlong rootRenderNodePtr)172 static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz,
173         jboolean translucent, jlong rootRenderNodePtr) {
174     RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootRenderNodePtr);
175     ContextFactoryImpl factory(rootRenderNode);
176     RenderProxy* proxy = new RenderProxy(translucent, rootRenderNode, &factory);
177     return (jlong) proxy;
178 }
179 
android_view_ThreadedRenderer_deleteProxy(JNIEnv * env,jobject clazz,jlong proxyPtr)180 static void android_view_ThreadedRenderer_deleteProxy(JNIEnv* env, jobject clazz,
181         jlong proxyPtr) {
182     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
183     delete proxy;
184 }
185 
android_view_ThreadedRenderer_loadSystemProperties(JNIEnv * env,jobject clazz,jlong proxyPtr)186 static jboolean android_view_ThreadedRenderer_loadSystemProperties(JNIEnv* env, jobject clazz,
187         jlong proxyPtr) {
188     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
189     return proxy->loadSystemProperties();
190 }
191 
android_view_ThreadedRenderer_setName(JNIEnv * env,jobject clazz,jlong proxyPtr,jstring jname)192 static void android_view_ThreadedRenderer_setName(JNIEnv* env, jobject clazz,
193         jlong proxyPtr, jstring jname) {
194     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
195     const char* name = env->GetStringUTFChars(jname, NULL);
196     proxy->setName(name);
197     env->ReleaseStringUTFChars(jname, name);
198 }
199 
android_view_ThreadedRenderer_setSurface(JNIEnv * env,jobject clazz,jlong proxyPtr,jobject jsurface,jboolean discardBuffer)200 static void android_view_ThreadedRenderer_setSurface(JNIEnv* env, jobject clazz,
201         jlong proxyPtr, jobject jsurface, jboolean discardBuffer) {
202     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
203     ANativeWindow* window = nullptr;
204     if (jsurface) {
205         window = fromSurface(env, jsurface);
206     }
207     bool enableTimeout = true;
208     if (discardBuffer) {
209         // Currently only Surface#lockHardwareCanvas takes this path
210         enableTimeout = false;
211         proxy->setSwapBehavior(SwapBehavior::kSwap_discardBuffer);
212     }
213     proxy->setSurface(window, enableTimeout);
214     if (window) {
215         ANativeWindow_release(window);
216     }
217 }
218 
android_view_ThreadedRenderer_setSurfaceControl(JNIEnv * env,jobject clazz,jlong proxyPtr,jlong surfaceControlPtr)219 static void android_view_ThreadedRenderer_setSurfaceControl(JNIEnv* env, jobject clazz,
220         jlong proxyPtr, jlong surfaceControlPtr) {
221 #ifdef __ANDROID__
222     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
223     SurfaceControl* surfaceControl = reinterpret_cast<SurfaceControl*>(surfaceControlPtr);
224     proxy->setSurfaceControl(sp<SurfaceControl>::fromExisting(surfaceControl));
225 #endif
226 }
227 
android_view_ThreadedRenderer_pause(JNIEnv * env,jobject clazz,jlong proxyPtr)228 static jboolean android_view_ThreadedRenderer_pause(JNIEnv* env, jobject clazz,
229         jlong proxyPtr) {
230     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
231     return proxy->pause();
232 }
233 
android_view_ThreadedRenderer_setStopped(JNIEnv * env,jobject clazz,jlong proxyPtr,jboolean stopped)234 static void android_view_ThreadedRenderer_setStopped(JNIEnv* env, jobject clazz,
235         jlong proxyPtr, jboolean stopped) {
236     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
237     proxy->setStopped(stopped);
238 }
239 
android_view_ThreadedRenderer_setLightAlpha(JNIEnv * env,jobject clazz,jlong proxyPtr,jfloat ambientShadowAlpha,jfloat spotShadowAlpha)240 static void android_view_ThreadedRenderer_setLightAlpha(JNIEnv* env, jobject clazz, jlong proxyPtr,
241         jfloat ambientShadowAlpha, jfloat spotShadowAlpha) {
242     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
243     proxy->setLightAlpha((uint8_t) (255 * ambientShadowAlpha), (uint8_t) (255 * spotShadowAlpha));
244 }
245 
android_view_ThreadedRenderer_setLightGeometry(JNIEnv * env,jobject clazz,jlong proxyPtr,jfloat lightX,jfloat lightY,jfloat lightZ,jfloat lightRadius)246 static void android_view_ThreadedRenderer_setLightGeometry(JNIEnv* env, jobject clazz,
247         jlong proxyPtr, jfloat lightX, jfloat lightY, jfloat lightZ, jfloat lightRadius) {
248     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
249     proxy->setLightGeometry((Vector3){lightX, lightY, lightZ}, lightRadius);
250 }
251 
android_view_ThreadedRenderer_setOpaque(JNIEnv * env,jobject clazz,jlong proxyPtr,jboolean opaque)252 static void android_view_ThreadedRenderer_setOpaque(JNIEnv* env, jobject clazz,
253         jlong proxyPtr, jboolean opaque) {
254     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
255     proxy->setOpaque(opaque);
256 }
257 
android_view_ThreadedRenderer_setColorMode(JNIEnv * env,jobject clazz,jlong proxyPtr,jint colorMode)258 static jfloat android_view_ThreadedRenderer_setColorMode(JNIEnv* env, jobject clazz, jlong proxyPtr,
259                                                          jint colorMode) {
260     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
261     return proxy->setColorMode(static_cast<ColorMode>(colorMode));
262 }
263 
android_view_ThreadedRenderer_setTargetSdrHdrRatio(JNIEnv * env,jobject clazz,jlong proxyPtr,jfloat ratio)264 static void android_view_ThreadedRenderer_setTargetSdrHdrRatio(JNIEnv* env, jobject clazz,
265                                                                jlong proxyPtr, jfloat ratio) {
266     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
267     return proxy->setRenderSdrHdrRatio(ratio);
268 }
269 
android_view_ThreadedRenderer_setSdrWhitePoint(JNIEnv * env,jobject clazz,jlong proxyPtr,jfloat sdrWhitePoint)270 static void android_view_ThreadedRenderer_setSdrWhitePoint(JNIEnv* env, jobject clazz,
271         jlong proxyPtr, jfloat sdrWhitePoint) {
272     Properties::defaultSdrWhitePoint = sdrWhitePoint;
273 }
274 
android_view_ThreadedRenderer_setIsHighEndGfx(JNIEnv * env,jobject clazz,jboolean jIsHighEndGfx)275 static void android_view_ThreadedRenderer_setIsHighEndGfx(JNIEnv* env, jobject clazz,
276         jboolean jIsHighEndGfx) {
277     Properties::setIsHighEndGfx(jIsHighEndGfx);
278 }
279 
android_view_ThreadedRenderer_setIsLowRam(JNIEnv * env,jobject clazz,jboolean isLowRam)280 static void android_view_ThreadedRenderer_setIsLowRam(JNIEnv* env, jobject clazz,
281                                                       jboolean isLowRam) {
282     Properties::setIsLowRam(isLowRam);
283 }
284 
android_view_ThreadedRenderer_setIsSystemOrPersistent(JNIEnv * env,jobject clazz,jboolean isSystemOrPersistent)285 static void android_view_ThreadedRenderer_setIsSystemOrPersistent(JNIEnv* env, jobject clazz,
286                                                                   jboolean isSystemOrPersistent) {
287     Properties::setIsSystemOrPersistent(isSystemOrPersistent);
288 }
289 
android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv * env,jobject clazz,jlong proxyPtr,jlongArray frameInfo,jint frameInfoSize)290 static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
291                                                           jlong proxyPtr, jlongArray frameInfo,
292                                                           jint frameInfoSize) {
293     LOG_ALWAYS_FATAL_IF(frameInfoSize != UI_THREAD_FRAME_INFO_SIZE,
294                         "Mismatched size expectations, given %d expected %zu", frameInfoSize,
295                         UI_THREAD_FRAME_INFO_SIZE);
296     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
297     env->GetLongArrayRegion(frameInfo, 0, frameInfoSize, proxy->frameInfo());
298     return proxy->syncAndDrawFrame();
299 }
300 
android_view_ThreadedRenderer_destroy(JNIEnv * env,jobject clazz,jlong proxyPtr,jlong rootNodePtr)301 static void android_view_ThreadedRenderer_destroy(JNIEnv* env, jobject clazz,
302         jlong proxyPtr, jlong rootNodePtr) {
303     RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
304     rootRenderNode->destroy();
305     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
306     proxy->destroy();
307 }
308 
android_view_ThreadedRenderer_registerAnimatingRenderNode(JNIEnv * env,jobject clazz,jlong rootNodePtr,jlong animatingNodePtr)309 static void android_view_ThreadedRenderer_registerAnimatingRenderNode(JNIEnv* env, jobject clazz,
310         jlong rootNodePtr, jlong animatingNodePtr) {
311     RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
312     RenderNode* animatingNode = reinterpret_cast<RenderNode*>(animatingNodePtr);
313     rootRenderNode->attachAnimatingNode(animatingNode);
314 }
315 
android_view_ThreadedRenderer_registerVectorDrawableAnimator(JNIEnv * env,jobject clazz,jlong rootNodePtr,jlong animatorPtr)316 static void android_view_ThreadedRenderer_registerVectorDrawableAnimator(JNIEnv* env, jobject clazz,
317         jlong rootNodePtr, jlong animatorPtr) {
318     RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
319     PropertyValuesAnimatorSet* animator = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorPtr);
320     rootRenderNode->addVectorDrawableAnimator(animator);
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;
342     bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
343     return proxy->copyLayerInto(layer, bitmap);
344 }
345 
android_view_ThreadedRenderer_pushLayerUpdate(JNIEnv * env,jobject clazz,jlong proxyPtr,jlong layerPtr)346 static void android_view_ThreadedRenderer_pushLayerUpdate(JNIEnv* env, jobject clazz,
347         jlong proxyPtr, jlong layerPtr) {
348     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
349     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
350     proxy->pushLayerUpdate(layer);
351 }
352 
android_view_ThreadedRenderer_cancelLayerUpdate(JNIEnv * env,jobject clazz,jlong proxyPtr,jlong layerPtr)353 static void android_view_ThreadedRenderer_cancelLayerUpdate(JNIEnv* env, jobject clazz,
354         jlong proxyPtr, jlong layerPtr) {
355     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
356     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
357     proxy->cancelLayerUpdate(layer);
358 }
359 
android_view_ThreadedRenderer_detachSurfaceTexture(JNIEnv * env,jobject clazz,jlong proxyPtr,jlong layerPtr)360 static void android_view_ThreadedRenderer_detachSurfaceTexture(JNIEnv* env, jobject clazz,
361         jlong proxyPtr, jlong layerPtr) {
362     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
363     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
364     proxy->detachSurfaceTexture(layer);
365 }
366 
android_view_ThreadedRenderer_destroyHardwareResources(JNIEnv * env,jobject clazz,jlong proxyPtr)367 static void android_view_ThreadedRenderer_destroyHardwareResources(JNIEnv* env, jobject clazz,
368         jlong proxyPtr) {
369     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
370     proxy->destroyHardwareResources();
371 }
372 
android_view_ThreadedRenderer_trimMemory(JNIEnv * env,jobject clazz,jint level)373 static void android_view_ThreadedRenderer_trimMemory(JNIEnv* env, jobject clazz,
374         jint level) {
375     RenderProxy::trimMemory(level);
376 }
377 
android_view_ThreadedRenderer_trimCaches(JNIEnv * env,jobject clazz,jint level)378 static void android_view_ThreadedRenderer_trimCaches(JNIEnv* env, jobject clazz, jint level) {
379     RenderProxy::trimCaches(level);
380 }
381 
android_view_ThreadedRenderer_overrideProperty(JNIEnv * env,jobject clazz,jstring name,jstring value)382 static void android_view_ThreadedRenderer_overrideProperty(JNIEnv* env, jobject clazz,
383         jstring name, jstring value) {
384     const char* nameCharArray = env->GetStringUTFChars(name, NULL);
385     const char* valueCharArray = env->GetStringUTFChars(value, NULL);
386     RenderProxy::overrideProperty(nameCharArray, valueCharArray);
387     env->ReleaseStringUTFChars(name, nameCharArray);
388     env->ReleaseStringUTFChars(name, valueCharArray);
389 }
390 
android_view_ThreadedRenderer_fence(JNIEnv * env,jobject clazz,jlong proxyPtr)391 static void android_view_ThreadedRenderer_fence(JNIEnv* env, jobject clazz,
392         jlong proxyPtr) {
393     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
394     proxy->fence();
395 }
396 
android_view_ThreadedRenderer_stopDrawing(JNIEnv * env,jobject clazz,jlong proxyPtr)397 static void android_view_ThreadedRenderer_stopDrawing(JNIEnv* env, jobject clazz,
398         jlong proxyPtr) {
399     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
400     proxy->stopDrawing();
401 }
402 
android_view_ThreadedRenderer_notifyFramePending(JNIEnv * env,jobject clazz,jlong proxyPtr)403 static void android_view_ThreadedRenderer_notifyFramePending(JNIEnv* env, jobject clazz,
404         jlong proxyPtr) {
405     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
406     proxy->notifyFramePending();
407 }
408 
android_view_ThreadedRenderer_dumpProfileInfo(JNIEnv * env,jobject clazz,jlong proxyPtr,jobject javaFileDescriptor,jint dumpFlags)409 static void android_view_ThreadedRenderer_dumpProfileInfo(JNIEnv* env, jobject clazz,
410         jlong proxyPtr, jobject javaFileDescriptor, jint dumpFlags) {
411     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
412     int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
413     proxy->dumpProfileInfo(fd, dumpFlags);
414 }
415 
android_view_ThreadedRenderer_dumpGlobalProfileInfo(JNIEnv * env,jobject clazz,jobject javaFileDescriptor,jint dumpFlags)416 static void android_view_ThreadedRenderer_dumpGlobalProfileInfo(JNIEnv* env, jobject clazz,
417                                                                 jobject javaFileDescriptor,
418                                                                 jint dumpFlags) {
419     int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
420     RenderProxy::dumpGraphicsMemory(fd, true, dumpFlags & DumpFlags::Reset);
421 }
422 
android_view_ThreadedRenderer_addRenderNode(JNIEnv * env,jobject clazz,jlong proxyPtr,jlong renderNodePtr,jboolean placeFront)423 static void android_view_ThreadedRenderer_addRenderNode(JNIEnv* env, jobject clazz,
424         jlong proxyPtr, jlong renderNodePtr, jboolean placeFront) {
425     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
426     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
427     proxy->addRenderNode(renderNode, placeFront);
428 }
429 
android_view_ThreadedRenderer_removeRenderNode(JNIEnv * env,jobject clazz,jlong proxyPtr,jlong renderNodePtr)430 static void android_view_ThreadedRenderer_removeRenderNode(JNIEnv* env, jobject clazz,
431         jlong proxyPtr, jlong renderNodePtr) {
432     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
433     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
434     proxy->removeRenderNode(renderNode);
435 }
436 
android_view_ThreadedRendererd_drawRenderNode(JNIEnv * env,jobject clazz,jlong proxyPtr,jlong renderNodePtr)437 static void android_view_ThreadedRendererd_drawRenderNode(JNIEnv* env, jobject clazz,
438         jlong proxyPtr, jlong renderNodePtr) {
439     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
440     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
441     proxy->drawRenderNode(renderNode);
442 }
443 
android_view_ThreadedRenderer_setContentDrawBounds(JNIEnv * env,jobject clazz,jlong proxyPtr,jint left,jint top,jint right,jint bottom)444 static void android_view_ThreadedRenderer_setContentDrawBounds(JNIEnv* env,
445         jobject clazz, jlong proxyPtr, jint left, jint top, jint right, jint bottom) {
446     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
447     proxy->setContentDrawBounds(left, top, right, bottom);
448 }
449 
android_view_ThreadedRenderer_forceDrawNextFrame(JNIEnv * env,jobject clazz,jlong proxyPtr)450 static void android_view_ThreadedRenderer_forceDrawNextFrame(JNIEnv* env, jobject clazz,
451                                                              jlong proxyPtr) {
452     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
453     proxy->forceDrawNextFrame();
454 }
455 
456 using TextureMap = std::unordered_map<uint32_t, sk_sp<SkImage>>;
457 
458 struct PictureCaptureState {
459     // Each frame we move from the active map to the previous map, essentially an LRU of 1 frame
460     // This avoids repeated readbacks of the same image, but avoids artificially extending the
461     // lifetime of any particular image.
462     TextureMap mActiveMap;
463     TextureMap mPreviousActiveMap;
464 };
465 
466 // TODO: This & Multi-SKP & Single-SKP should all be de-duped into
467 // a single "make a SkPicture serializable-safe" utility somewhere
468 class PictureWrapper : public Picture {
469 public:
PictureWrapper(sk_sp<SkPicture> && src,const std::shared_ptr<PictureCaptureState> & state)470     PictureWrapper(sk_sp<SkPicture>&& src, const std::shared_ptr<PictureCaptureState>& state)
471             : Picture(), mPicture(std::move(src)) {
472         ATRACE_NAME("Preparing SKP for capture");
473         // Move the active to previous active
474         state->mPreviousActiveMap = std::move(state->mActiveMap);
475         state->mActiveMap.clear();
476         SkSerialProcs tempProc;
477         tempProc.fImageCtx = state.get();
478         tempProc.fImageProc = collectNonTextureImagesProc;
479         auto ns = SkNullWStream();
480         mPicture->serialize(&ns, &tempProc);
481         state->mPreviousActiveMap.clear();
482 
483         // Now snapshot a copy of the active map so this PictureWrapper becomes self-sufficient
484         mTextureMap = state->mActiveMap;
485     }
486 
imageForCache(SkImage * img)487     static sk_sp<SkImage> imageForCache(SkImage* img) {
488         const SkBitmap* bitmap = as_IB(img)->onPeekBitmap();
489         // This is a mutable bitmap pretending to be an immutable SkImage. As we're going to
490         // actually cross thread boundaries here, make a copy so it's immutable proper
491         if (bitmap && !bitmap->isImmutable()) {
492             ATRACE_NAME("Copying mutable bitmap");
493             return SkImages::RasterFromBitmap(*bitmap);
494         }
495         if (img->isTextureBacked()) {
496             ATRACE_NAME("Readback of texture image");
497             return img->makeNonTextureImage();
498         }
499         SkPixmap pm;
500         if (img->isLazyGenerated() && !img->peekPixels(&pm)) {
501             ATRACE_NAME("Readback of HW bitmap");
502             // This is a hardware bitmap probably
503             SkBitmap bm;
504             if (!bm.tryAllocPixels(img->imageInfo())) {
505                 // Failed to allocate, just see what happens
506                 return sk_ref_sp(img);
507             }
508             if (RenderProxy::copyImageInto(sk_ref_sp(img), &bm)) {
509                 // Failed to readback
510                 return sk_ref_sp(img);
511             }
512             bm.setImmutable();
513 #ifdef __ANDROID__
514             return SkImages::PinnableRasterFromBitmap(bm);
515 #else
516             return SkMakeImageFromRasterBitmap(bm, kNever_SkCopyPixelsMode);
517 #endif
518         }
519         return sk_ref_sp(img);
520     }
521 
collectNonTextureImagesProc(SkImage * img,void * ctx)522     static sk_sp<SkData> collectNonTextureImagesProc(SkImage* img, void* ctx) {
523         PictureCaptureState* context = reinterpret_cast<PictureCaptureState*>(ctx);
524         const uint32_t originalId = img->uniqueID();
525         auto it = context->mActiveMap.find(originalId);
526         if (it == context->mActiveMap.end()) {
527             auto pit = context->mPreviousActiveMap.find(originalId);
528             if (pit == context->mPreviousActiveMap.end()) {
529                 context->mActiveMap[originalId] = imageForCache(img);
530             } else {
531                 context->mActiveMap[originalId] = pit->second;
532             }
533         }
534         return SkData::MakeEmpty();
535     }
536 
serializeImage(SkImage * img,void * ctx)537     static sk_sp<SkData> serializeImage(SkImage* img, void* ctx) {
538         PictureWrapper* context = reinterpret_cast<PictureWrapper*>(ctx);
539         const uint32_t id = img->uniqueID();
540         auto iter = context->mTextureMap.find(id);
541         if (iter != context->mTextureMap.end()) {
542             img = iter->second.get();
543         }
544         if (!img) {
545             return nullptr;
546         }
547         // The following encode (specifically the pixel readback) will fail on a
548         // texture-backed image. They should already be raster images, but on
549         // the off-chance they aren't, we will just serialize it as nothing.
550         if (img->isTextureBacked()) {
551             return SkData::MakeEmpty();
552         }
553         return SkPngEncoder::Encode(nullptr, img, {});
554     }
555 
serialize(SkWStream * stream) const556     void serialize(SkWStream* stream) const override {
557         SkSerialProcs procs;
558         procs.fImageProc = serializeImage;
559         procs.fImageCtx = const_cast<PictureWrapper*>(this);
560         procs.fTypefaceProc = [](SkTypeface* tf, void* ctx) {
561             return tf->serialize(SkTypeface::SerializeBehavior::kDoIncludeData);
562         };
563         mPicture->serialize(stream, &procs);
564     }
565 
566 private:
567     sk_sp<SkPicture> mPicture;
568     TextureMap mTextureMap;
569 };
570 
android_view_ThreadedRenderer_setPictureCapturedCallbackJNI(JNIEnv * env,jobject clazz,jlong proxyPtr,jobject pictureCallback)571 static void android_view_ThreadedRenderer_setPictureCapturedCallbackJNI(JNIEnv* env,
572         jobject clazz, jlong proxyPtr, jobject pictureCallback) {
573     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
574     if (!pictureCallback) {
575         proxy->setPictureCapturedCallback(nullptr);
576     } else {
577         JavaVM* vm = nullptr;
578         LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
579         auto globalCallbackRef = std::make_shared<JGlobalRefHolder>(vm,
580                 env->NewGlobalRef(pictureCallback));
581         auto pictureState = std::make_shared<PictureCaptureState>();
582         proxy->setPictureCapturedCallback([globalCallbackRef,
583                                            pictureState](sk_sp<SkPicture>&& picture) {
584             Picture* wrapper = new PictureWrapper{std::move(picture), pictureState};
585             globalCallbackRef->env()->CallStaticVoidMethod(
586                     gHardwareRenderer.clazz, gHardwareRenderer.invokePictureCapturedCallback,
587                     static_cast<jlong>(reinterpret_cast<intptr_t>(wrapper)),
588                     globalCallbackRef->object());
589         });
590     }
591 }
592 
android_view_ThreadedRenderer_setASurfaceTransactionCallback(JNIEnv * env,jobject clazz,jlong proxyPtr,jobject aSurfaceTransactionCallback)593 static void android_view_ThreadedRenderer_setASurfaceTransactionCallback(
594         JNIEnv* env, jobject clazz, jlong proxyPtr, jobject aSurfaceTransactionCallback) {
595     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
596     if (!aSurfaceTransactionCallback) {
597         proxy->setASurfaceTransactionCallback(nullptr);
598     } else {
599         JavaVM* vm = nullptr;
600         LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
601         auto globalCallbackRef = std::make_shared<JGlobalRefHolder>(
602                 vm, env->NewGlobalRef(aSurfaceTransactionCallback));
603         proxy->setASurfaceTransactionCallback([globalCallbackRef](int64_t transObj, int64_t scObj,
604                                                                   int64_t frameNr) -> bool {
605             jboolean ret = globalCallbackRef->env()->CallBooleanMethod(
606                     globalCallbackRef->object(), gASurfaceTransactionCallback.onMergeTransaction,
607                     static_cast<jlong>(transObj), static_cast<jlong>(scObj),
608                     static_cast<jlong>(frameNr));
609             return ret;
610         });
611     }
612 }
613 
android_view_ThreadedRenderer_setPrepareSurfaceControlForWebviewCallback(JNIEnv * env,jobject clazz,jlong proxyPtr,jobject callback)614 static void android_view_ThreadedRenderer_setPrepareSurfaceControlForWebviewCallback(
615         JNIEnv* env, jobject clazz, jlong proxyPtr, jobject callback) {
616     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
617     if (!callback) {
618         proxy->setPrepareSurfaceControlForWebviewCallback(nullptr);
619     } else {
620         JavaVM* vm = nullptr;
621         LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
622         auto globalCallbackRef =
623                 std::make_shared<JGlobalRefHolder>(vm, env->NewGlobalRef(callback));
624         proxy->setPrepareSurfaceControlForWebviewCallback([globalCallbackRef]() {
625             globalCallbackRef->env()->CallVoidMethod(
626                     globalCallbackRef->object(), gPrepareSurfaceControlForWebviewCallback.prepare);
627         });
628     }
629 }
630 
android_view_ThreadedRenderer_setFrameCallback(JNIEnv * env,jobject clazz,jlong proxyPtr,jobject frameCallback)631 static void android_view_ThreadedRenderer_setFrameCallback(JNIEnv* env,
632         jobject clazz, jlong proxyPtr, jobject frameCallback) {
633     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
634     if (!frameCallback) {
635         proxy->setFrameCallback(nullptr);
636     } else {
637         JavaVM* vm = nullptr;
638         LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
639         auto globalCallbackRef = std::make_shared<JGlobalRefHolder>(vm,
640                 env->NewGlobalRef(frameCallback));
641         proxy->setFrameCallback([globalCallbackRef](int32_t syncResult,
642                                                     int64_t frameNr) -> std::function<void(bool)> {
643             JNIEnv* env = globalCallbackRef->env();
644             ScopedLocalRef<jobject> frameCommitCallback(
645                     env, env->CallObjectMethod(
646                                  globalCallbackRef->object(), gFrameDrawingCallback.onFrameDraw,
647                                  static_cast<jint>(syncResult), static_cast<jlong>(frameNr)));
648             if (frameCommitCallback == nullptr) {
649                 return nullptr;
650             }
651             sp<FrameCommitWrapper> wrapper =
652                     sp<FrameCommitWrapper>::make(env, frameCommitCallback.get());
653             return [wrapper](bool didProduceBuffer) { wrapper->onFrameCommit(didProduceBuffer); };
654         });
655     }
656 }
657 
android_view_ThreadedRenderer_setFrameCommitCallback(JNIEnv * env,jobject clazz,jlong proxyPtr,jobject callback)658 static void android_view_ThreadedRenderer_setFrameCommitCallback(JNIEnv* env, jobject clazz,
659                                                                  jlong proxyPtr, jobject callback) {
660     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
661     if (!callback) {
662         proxy->setFrameCommitCallback(nullptr);
663     } else {
664         sp<FrameCommitWrapper> wrapper = sp<FrameCommitWrapper>::make(env, callback);
665         proxy->setFrameCommitCallback(
666                 [wrapper](bool didProduceBuffer) { wrapper->onFrameCommit(didProduceBuffer); });
667     }
668 }
669 
android_view_ThreadedRenderer_setFrameCompleteCallback(JNIEnv * env,jobject clazz,jlong proxyPtr,jobject callback)670 static void android_view_ThreadedRenderer_setFrameCompleteCallback(JNIEnv* env,
671         jobject clazz, jlong proxyPtr, jobject callback) {
672     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
673     if (!callback) {
674         proxy->setFrameCompleteCallback(nullptr);
675     } else {
676         RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
677         JavaVM* vm = nullptr;
678         LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
679         auto globalCallbackRef =
680                 std::make_shared<JGlobalRefHolder>(vm, env->NewGlobalRef(callback));
681         proxy->setFrameCompleteCallback([globalCallbackRef]() {
682             globalCallbackRef->env()->CallVoidMethod(globalCallbackRef->object(),
683                                                      gFrameCompleteCallback.onFrameComplete);
684         });
685     }
686 }
687 
688 class CopyRequestAdapter : public CopyRequest {
689 public:
CopyRequestAdapter(JavaVM * vm,jobject jCopyRequest,::android::uirenderer::Rect srcRect)690     CopyRequestAdapter(JavaVM* vm, jobject jCopyRequest, ::android::uirenderer::Rect srcRect)
691             : CopyRequest(srcRect), mRefHolder(vm, jCopyRequest) {}
692 
getDestinationBitmap(int srcWidth,int srcHeight)693     virtual SkBitmap getDestinationBitmap(int srcWidth, int srcHeight) override {
694         jlong bitmapPtr = mRefHolder.env()->CallLongMethod(
695                 mRefHolder.object(), gCopyRequest.getDestinationBitmap, srcWidth, srcHeight);
696         SkBitmap bitmap;
697         bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
698         return bitmap;
699     }
700 
onCopyFinished(CopyResult result)701     virtual void onCopyFinished(CopyResult result) override {
702         mRefHolder.env()->CallVoidMethod(mRefHolder.object(), gCopyRequest.onCopyFinished,
703                                          static_cast<jint>(result));
704     }
705 
706 private:
707     JGlobalRefHolder mRefHolder;
708 };
709 
android_view_ThreadedRenderer_copySurfaceInto(JNIEnv * env,jobject clazz,jobject jsurface,jint left,jint top,jint right,jint bottom,jobject jCopyRequest)710 static void android_view_ThreadedRenderer_copySurfaceInto(JNIEnv* env, jobject clazz,
711                                                           jobject jsurface, jint left, jint top,
712                                                           jint right, jint bottom,
713                                                           jobject jCopyRequest) {
714     JavaVM* vm = nullptr;
715     LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
716     auto copyRequest = std::make_shared<CopyRequestAdapter>(
717             vm, env->NewGlobalRef(jCopyRequest),
718             ::android::uirenderer::Rect(left, top, right, bottom));
719     ANativeWindow* window = fromSurface(env, jsurface);
720     RenderProxy::copySurfaceInto(window, std::move(copyRequest));
721     ANativeWindow_release(window);
722 }
723 
724 class ContextFactory : public IContextFactory {
725 public:
createAnimationContext(renderthread::TimeLord & clock)726     virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) {
727         return new AnimationContext(clock);
728     }
729 };
730 
android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode(JNIEnv * env,jobject clazz,jlong renderNodePtr,jint jwidth,jint jheight)731 static jobject android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode(JNIEnv* env,
732         jobject clazz, jlong renderNodePtr, jint jwidth, jint jheight) {
733 #ifdef __ANDROID__
734     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
735     if (jwidth <= 0 || jheight <= 0) {
736         ALOGW("Invalid width %d or height %d", jwidth, jheight);
737         return nullptr;
738     }
739 
740     uint32_t width = jwidth;
741     uint32_t height = jheight;
742 
743     // Create an ImageReader wired up to a BufferItemConsumer
744     AImageReader* rawReader;
745     constexpr auto usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
746                            AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER |
747                            AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY;
748     media_status_t result =
749             AImageReader_newWithUsage(width, height, AIMAGE_FORMAT_RGBA_8888, usage, 2, &rawReader);
750     std::unique_ptr<AImageReader, decltype(&AImageReader_delete)> reader(rawReader,
751                                                                          AImageReader_delete);
752 
753     if (result != AMEDIA_OK) {
754         ALOGW("Error creating image reader!");
755         return nullptr;
756     }
757 
758     // Note that ownership of this window is maintained by AImageReader, so we
759     // shouldn't need to wrap around a smart pointer.
760     ANativeWindow* window;
761     result = AImageReader_getWindow(rawReader, &window);
762 
763     if (result != AMEDIA_OK) {
764         ALOGW("Error retrieving the native window!");
765         return nullptr;
766     }
767 
768     // Render into the surface
769     {
770         ContextFactory factory;
771         RenderProxy proxy{true, renderNode, &factory};
772         proxy.setSwapBehavior(SwapBehavior::kSwap_discardBuffer);
773         proxy.setSurface(window);
774         // Shadows can't be used via this interface, so just set the light source
775         // to all 0s.
776         proxy.setLightAlpha(0, 0);
777         proxy.setLightGeometry((Vector3){0, 0, 0}, 0);
778         nsecs_t vsync = systemTime(SYSTEM_TIME_MONOTONIC);
779         UiFrameInfoBuilder(proxy.frameInfo())
780                 .setVsync(vsync, vsync, UiFrameInfoBuilder::INVALID_VSYNC_ID,
781                     UiFrameInfoBuilder::UNKNOWN_DEADLINE,
782                     UiFrameInfoBuilder::UNKNOWN_FRAME_INTERVAL)
783                 .addFlag(FrameInfoFlags::SurfaceCanvas);
784         proxy.syncAndDrawFrame();
785     }
786 
787     AImage* rawImage;
788     result = AImageReader_acquireNextImage(rawReader, &rawImage);
789     std::unique_ptr<AImage, decltype(&AImage_delete)> image(rawImage, AImage_delete);
790     if (result != AMEDIA_OK) {
791         ALOGW("Error reading image: %d!", result);
792         return nullptr;
793     }
794 
795     AHardwareBuffer* buffer;
796     result = AImage_getHardwareBuffer(rawImage, &buffer);
797 
798     AHardwareBuffer_Desc desc;
799     AHardwareBuffer_describe(buffer, &desc);
800 
801     if (desc.width != width || desc.height != height) {
802         ALOGW("AHardwareBuffer size mismatch, got %dx%d expected %dx%d", desc.width, desc.height,
803               width, height);
804         // Continue I guess?
805     }
806 
807     sk_sp<SkColorSpace> cs = uirenderer::DataSpaceToColorSpace(
808             static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(window)));
809     if (cs == nullptr) {
810         // nullptr is treated as SRGB in Skia, thus explicitly use SRGB in order to make sure
811         // the returned bitmap has a color space.
812         cs = SkColorSpace::MakeSRGB();
813     }
814     sk_sp<Bitmap> bitmap = Bitmap::createFrom(buffer, cs);
815     return bitmap::createBitmap(env, bitmap.release(),
816             android::bitmap::kBitmapCreateFlag_Premultiplied);
817 #else
818     return nullptr;
819 #endif
820 }
821 
android_view_ThreadedRenderer_disableVsync(JNIEnv *,jclass)822 static void android_view_ThreadedRenderer_disableVsync(JNIEnv*, jclass) {
823     RenderProxy::disableVsync();
824 }
825 
android_view_ThreadedRenderer_setHighContrastText(JNIEnv *,jclass,jboolean enable)826 static void android_view_ThreadedRenderer_setHighContrastText(JNIEnv*, jclass, jboolean enable) {
827     Properties::enableHighContrastText = enable;
828 }
829 
android_view_ThreadedRenderer_setDebuggingEnabled(JNIEnv *,jclass,jboolean enable)830 static void android_view_ThreadedRenderer_setDebuggingEnabled(JNIEnv*, jclass, jboolean enable) {
831     Properties::debuggingEnabled = enable;
832 }
833 
android_view_ThreadedRenderer_setIsolatedProcess(JNIEnv *,jclass,jboolean isolated)834 static void android_view_ThreadedRenderer_setIsolatedProcess(JNIEnv*, jclass, jboolean isolated) {
835     Properties::isolatedProcess = isolated;
836 }
837 
android_view_ThreadedRenderer_setContextPriority(JNIEnv *,jclass,jint contextPriority)838 static void android_view_ThreadedRenderer_setContextPriority(JNIEnv*, jclass,
839         jint contextPriority) {
840     Properties::contextPriority = contextPriority;
841 }
842 
android_view_ThreadedRenderer_allocateBuffers(JNIEnv * env,jobject clazz,jlong proxyPtr)843 static void android_view_ThreadedRenderer_allocateBuffers(JNIEnv* env, jobject clazz,
844         jlong proxyPtr) {
845     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
846     proxy->allocateBuffers();
847 }
848 
android_view_ThreadedRenderer_setForceDark(JNIEnv * env,jobject clazz,jlong proxyPtr,jint type)849 static void android_view_ThreadedRenderer_setForceDark(JNIEnv* env, jobject clazz, jlong proxyPtr,
850                                                        jint type) {
851     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
852     proxy->setForceDark(static_cast<ForceDarkType>(type));
853 }
854 
android_view_ThreadedRenderer_preload(JNIEnv *,jclass)855 static void android_view_ThreadedRenderer_preload(JNIEnv*, jclass) {
856     RenderProxy::preload();
857 }
858 
android_view_ThreadedRenderer_preInitBufferAllocator(JNIEnv *,jclass)859 static void android_view_ThreadedRenderer_preInitBufferAllocator(JNIEnv*, jclass) {
860 #ifdef __ANDROID__
861     CommonPool::async([] {
862         ATRACE_NAME("preInitBufferAllocator:GraphicBufferAllocator");
863         // This involves several binder calls which we do not want blocking
864         // critical path of the activity that is launching.
865         GraphicBufferAllocator::getInstance();
866     });
867 #endif
868 }
869 
android_view_ThreadedRenderer_setRtAnimationsEnabled(JNIEnv * env,jobject clazz,jboolean enabled)870 static void android_view_ThreadedRenderer_setRtAnimationsEnabled(JNIEnv* env, jobject clazz,
871                                                                  jboolean enabled) {
872     RenderProxy::setRtAnimationsEnabled(enabled);
873 }
874 
android_view_ThreadedRenderer_notifyCallbackPending(JNIEnv *,jclass,jlong proxyPtr)875 static void android_view_ThreadedRenderer_notifyCallbackPending(JNIEnv*, jclass, jlong proxyPtr) {
876     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
877     proxy->notifyCallbackPending();
878 }
879 
android_view_ThreadedRenderer_notifyExpensiveFrame(JNIEnv *,jclass,jlong proxyPtr)880 static void android_view_ThreadedRenderer_notifyExpensiveFrame(JNIEnv*, jclass, jlong proxyPtr) {
881     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
882     proxy->notifyExpensiveFrame();
883 }
884 
885 // Plumbs the display density down to DeviceInfo.
android_view_ThreadedRenderer_setDisplayDensityDpi(JNIEnv *,jclass,jint densityDpi)886 static void android_view_ThreadedRenderer_setDisplayDensityDpi(JNIEnv*, jclass, jint densityDpi) {
887     // Convert from dpi to density-independent pixels.
888     const float density = densityDpi / 160.0;
889     DeviceInfo::setDensity(density);
890 }
891 
android_view_ThreadedRenderer_initDisplayInfo(JNIEnv * env,jclass,jint physicalWidth,jint physicalHeight,jfloat refreshRate,jint wideColorDataspace,jlong appVsyncOffsetNanos,jlong presentationDeadlineNanos,jboolean supportFp16ForHdr,jboolean supportRgba10101010ForHdr,jboolean supportMixedColorSpaces)892 static void android_view_ThreadedRenderer_initDisplayInfo(
893         JNIEnv* env, jclass, jint physicalWidth, jint physicalHeight, jfloat refreshRate,
894         jint wideColorDataspace, jlong appVsyncOffsetNanos, jlong presentationDeadlineNanos,
895         jboolean supportFp16ForHdr, jboolean supportRgba10101010ForHdr,
896         jboolean supportMixedColorSpaces) {
897     DeviceInfo::setWidth(physicalWidth);
898     DeviceInfo::setHeight(physicalHeight);
899     DeviceInfo::setRefreshRate(refreshRate);
900     DeviceInfo::setWideColorDataspace(static_cast<ADataSpace>(wideColorDataspace));
901     DeviceInfo::setAppVsyncOffsetNanos(appVsyncOffsetNanos);
902     DeviceInfo::setPresentationDeadlineNanos(presentationDeadlineNanos);
903     DeviceInfo::setSupportFp16ForHdr(supportFp16ForHdr);
904     DeviceInfo::setSupportRgba10101010ForHdr(supportRgba10101010ForHdr);
905     DeviceInfo::setSupportMixedColorSpaces(supportMixedColorSpaces);
906 }
907 
android_view_ThreadedRenderer_setDrawingEnabled(JNIEnv *,jclass,jboolean enabled)908 static void android_view_ThreadedRenderer_setDrawingEnabled(JNIEnv*, jclass, jboolean enabled) {
909     Properties::setDrawingEnabled(enabled);
910 }
911 
android_view_ThreadedRenderer_isDrawingEnabled(JNIEnv *,jclass)912 static jboolean android_view_ThreadedRenderer_isDrawingEnabled(JNIEnv*, jclass) {
913     return Properties::isDrawingEnabled();
914 }
915 
916 // ----------------------------------------------------------------------------
917 // HardwareRendererObserver
918 // ----------------------------------------------------------------------------
919 
android_view_ThreadedRenderer_addObserver(JNIEnv * env,jclass clazz,jlong proxyPtr,jlong observerPtr)920 static void android_view_ThreadedRenderer_addObserver(JNIEnv* env, jclass clazz,
921         jlong proxyPtr, jlong observerPtr) {
922     FrameMetricsObserver* rawObserver = reinterpret_cast<FrameMetricsObserver*>(observerPtr);
923     sp<FrameMetricsObserver> observer = sp<FrameMetricsObserver>::fromExisting(rawObserver);
924     renderthread::RenderProxy* renderProxy =
925             reinterpret_cast<renderthread::RenderProxy*>(proxyPtr);
926 
927     renderProxy->addFrameMetricsObserver(std::move(observer));
928 }
929 
android_view_ThreadedRenderer_removeObserver(JNIEnv * env,jclass clazz,jlong proxyPtr,jlong observerPtr)930 static void android_view_ThreadedRenderer_removeObserver(JNIEnv* env, jclass clazz,
931         jlong proxyPtr, jlong observerPtr) {
932     FrameMetricsObserver* rawObserver = reinterpret_cast<FrameMetricsObserver*>(observerPtr);
933     sp<FrameMetricsObserver> observer = sp<FrameMetricsObserver>::fromExisting(rawObserver);
934     renderthread::RenderProxy* renderProxy =
935             reinterpret_cast<renderthread::RenderProxy*>(proxyPtr);
936 
937     renderProxy->removeFrameMetricsObserver(std::move(observer));
938 }
939 
940 // ----------------------------------------------------------------------------
941 // Shaders
942 // ----------------------------------------------------------------------------
943 
android_view_ThreadedRenderer_setupShadersDiskCache(JNIEnv * env,jobject clazz,jstring diskCachePath,jstring skiaDiskCachePath)944 static void android_view_ThreadedRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz,
945         jstring diskCachePath, jstring skiaDiskCachePath) {
946 #ifdef __ANDROID__
947     const char* cacheArray = env->GetStringUTFChars(diskCachePath, NULL);
948     android::egl_set_cache_filename(cacheArray);
949     env->ReleaseStringUTFChars(diskCachePath, cacheArray);
950 
951     const char* skiaCacheArray = env->GetStringUTFChars(skiaDiskCachePath, NULL);
952     uirenderer::skiapipeline::ShaderCache::get().setFilename(skiaCacheArray);
953     env->ReleaseStringUTFChars(skiaDiskCachePath, skiaCacheArray);
954 #endif
955 }
956 
android_view_ThreadedRenderer_isWebViewOverlaysEnabled(JNIEnv * env,jobject clazz)957 static jboolean android_view_ThreadedRenderer_isWebViewOverlaysEnabled(JNIEnv* env, jobject clazz) {
958     // this value is valid only after loadSystemProperties() is called
959     return Properties::enableWebViewOverlays;
960 }
961 
962 // ----------------------------------------------------------------------------
963 // JNI Glue
964 // ----------------------------------------------------------------------------
965 
966 const char* const kClassPathName = "android/graphics/HardwareRenderer";
967 
968 static const JNINativeMethod gMethods[] = {
nRotateProcessStatsBuffer()969         {"nRotateProcessStatsBuffer", "()V",
970          (void*)android_view_ThreadedRenderer_rotateProcessStatsBuffer},
nSetProcessStatsBuffer(I)971         {"nSetProcessStatsBuffer", "(I)V",
972          (void*)android_view_ThreadedRenderer_setProcessStatsBuffer},
nGetRenderThreadTid(J)973         {"nGetRenderThreadTid", "(J)I", (void*)android_view_ThreadedRenderer_getRenderThreadTid},
nCreateRootRenderNode()974         {"nCreateRootRenderNode", "()J", (void*)android_view_ThreadedRenderer_createRootRenderNode},
nCreateProxy(ZJ)975         {"nCreateProxy", "(ZJ)J", (void*)android_view_ThreadedRenderer_createProxy},
nDeleteProxy(J)976         {"nDeleteProxy", "(J)V", (void*)android_view_ThreadedRenderer_deleteProxy},
nLoadSystemProperties(J)977         {"nLoadSystemProperties", "(J)Z",
978          (void*)android_view_ThreadedRenderer_loadSystemProperties},
nSetName(JLjava/lang/String;)979         {"nSetName", "(JLjava/lang/String;)V", (void*)android_view_ThreadedRenderer_setName},
nSetSurface(JLandroid/view/Surface;Z)980         {"nSetSurface", "(JLandroid/view/Surface;Z)V",
981          (void*)android_view_ThreadedRenderer_setSurface},
nSetSurfaceControl(JJ)982         {"nSetSurfaceControl", "(JJ)V", (void*)android_view_ThreadedRenderer_setSurfaceControl},
nPause(J)983         {"nPause", "(J)Z", (void*)android_view_ThreadedRenderer_pause},
nSetStopped(JZ)984         {"nSetStopped", "(JZ)V", (void*)android_view_ThreadedRenderer_setStopped},
nSetLightAlpha(JFF)985         {"nSetLightAlpha", "(JFF)V", (void*)android_view_ThreadedRenderer_setLightAlpha},
nSetLightGeometry(JFFFF)986         {"nSetLightGeometry", "(JFFFF)V", (void*)android_view_ThreadedRenderer_setLightGeometry},
nSetOpaque(JZ)987         {"nSetOpaque", "(JZ)V", (void*)android_view_ThreadedRenderer_setOpaque},
nSetColorMode(JI)988         {"nSetColorMode", "(JI)F", (void*)android_view_ThreadedRenderer_setColorMode},
nSetTargetSdrHdrRatio(JF)989         {"nSetTargetSdrHdrRatio", "(JF)V",
990          (void*)android_view_ThreadedRenderer_setTargetSdrHdrRatio},
nSetSdrWhitePoint(JF)991         {"nSetSdrWhitePoint", "(JF)V", (void*)android_view_ThreadedRenderer_setSdrWhitePoint},
nSetIsHighEndGfx(Z)992         {"nSetIsHighEndGfx", "(Z)V", (void*)android_view_ThreadedRenderer_setIsHighEndGfx},
nSetIsLowRam(Z)993         {"nSetIsLowRam", "(Z)V", (void*)android_view_ThreadedRenderer_setIsLowRam},
nSetIsSystemOrPersistent(Z)994         {"nSetIsSystemOrPersistent", "(Z)V",
995          (void*)android_view_ThreadedRenderer_setIsSystemOrPersistent},
nSyncAndDrawFrame(J[JI)996         {"nSyncAndDrawFrame", "(J[JI)I", (void*)android_view_ThreadedRenderer_syncAndDrawFrame},
nDestroy(JJ)997         {"nDestroy", "(JJ)V", (void*)android_view_ThreadedRenderer_destroy},
nRegisterAnimatingRenderNode(JJ)998         {"nRegisterAnimatingRenderNode", "(JJ)V",
999          (void*)android_view_ThreadedRenderer_registerAnimatingRenderNode},
nRegisterVectorDrawableAnimator(JJ)1000         {"nRegisterVectorDrawableAnimator", "(JJ)V",
1001          (void*)android_view_ThreadedRenderer_registerVectorDrawableAnimator},
nCreateTextureLayer(J)1002         {"nCreateTextureLayer", "(J)J", (void*)android_view_ThreadedRenderer_createTextureLayer},
nBuildLayer(JJ)1003         {"nBuildLayer", "(JJ)V", (void*)android_view_ThreadedRenderer_buildLayer},
nCopyLayerInto(JJJ)1004         {"nCopyLayerInto", "(JJJ)Z", (void*)android_view_ThreadedRenderer_copyLayerInto},
nPushLayerUpdate(JJ)1005         {"nPushLayerUpdate", "(JJ)V", (void*)android_view_ThreadedRenderer_pushLayerUpdate},
nCancelLayerUpdate(JJ)1006         {"nCancelLayerUpdate", "(JJ)V", (void*)android_view_ThreadedRenderer_cancelLayerUpdate},
nDetachSurfaceTexture(JJ)1007         {"nDetachSurfaceTexture", "(JJ)V",
1008          (void*)android_view_ThreadedRenderer_detachSurfaceTexture},
nDestroyHardwareResources(J)1009         {"nDestroyHardwareResources", "(J)V",
1010          (void*)android_view_ThreadedRenderer_destroyHardwareResources},
nTrimMemory(I)1011         {"nTrimMemory", "(I)V", (void*)android_view_ThreadedRenderer_trimMemory},
nOverrideProperty(Ljava/lang/String;Ljava/lang/String;)1012         {"nOverrideProperty", "(Ljava/lang/String;Ljava/lang/String;)V",
1013          (void*)android_view_ThreadedRenderer_overrideProperty},
nFence(J)1014         {"nFence", "(J)V", (void*)android_view_ThreadedRenderer_fence},
nStopDrawing(J)1015         {"nStopDrawing", "(J)V", (void*)android_view_ThreadedRenderer_stopDrawing},
nNotifyFramePending(J)1016         {"nNotifyFramePending", "(J)V", (void*)android_view_ThreadedRenderer_notifyFramePending},
nDumpProfileInfo(JLjava/io/FileDescriptor;I)1017         {"nDumpProfileInfo", "(JLjava/io/FileDescriptor;I)V",
1018          (void*)android_view_ThreadedRenderer_dumpProfileInfo},
nDumpGlobalProfileInfo(Ljava/io/FileDescriptor;I)1019         {"nDumpGlobalProfileInfo", "(Ljava/io/FileDescriptor;I)V",
1020          (void*)android_view_ThreadedRenderer_dumpGlobalProfileInfo},
setupShadersDiskCache(Ljava/lang/String;Ljava/lang/String;)1021         {"setupShadersDiskCache", "(Ljava/lang/String;Ljava/lang/String;)V",
1022          (void*)android_view_ThreadedRenderer_setupShadersDiskCache},
nAddRenderNode(JJZ)1023         {"nAddRenderNode", "(JJZ)V", (void*)android_view_ThreadedRenderer_addRenderNode},
nRemoveRenderNode(JJ)1024         {"nRemoveRenderNode", "(JJ)V", (void*)android_view_ThreadedRenderer_removeRenderNode},
nDrawRenderNode(JJ)1025         {"nDrawRenderNode", "(JJ)V", (void*)android_view_ThreadedRendererd_drawRenderNode},
nSetContentDrawBounds(JIIII)1026         {"nSetContentDrawBounds", "(JIIII)V",
1027          (void*)android_view_ThreadedRenderer_setContentDrawBounds},
nForceDrawNextFrame(J)1028         {"nForceDrawNextFrame", "(J)V", (void*)android_view_ThreadedRenderer_forceDrawNextFrame},
nSetPictureCaptureCallback(JLandroid/graphics/HardwareRenderer$PictureCapturedCallback;)1029         {"nSetPictureCaptureCallback",
1030          "(JLandroid/graphics/HardwareRenderer$PictureCapturedCallback;)V",
1031          (void*)android_view_ThreadedRenderer_setPictureCapturedCallbackJNI},
nSetASurfaceTransactionCallback(JLandroid/graphics/HardwareRenderer$ASurfaceTransactionCallback;)1032         {"nSetASurfaceTransactionCallback",
1033          "(JLandroid/graphics/HardwareRenderer$ASurfaceTransactionCallback;)V",
1034          (void*)android_view_ThreadedRenderer_setASurfaceTransactionCallback},
nSetPrepareSurfaceControlForWebviewCallback(JLandroid/graphics/HardwareRenderer$PrepareSurfaceControlForWebviewCallback;)1035         {"nSetPrepareSurfaceControlForWebviewCallback",
1036          "(JLandroid/graphics/HardwareRenderer$PrepareSurfaceControlForWebviewCallback;)V",
1037          (void*)android_view_ThreadedRenderer_setPrepareSurfaceControlForWebviewCallback},
nSetFrameCallback(JLandroid/graphics/HardwareRenderer$FrameDrawingCallback;)1038         {"nSetFrameCallback", "(JLandroid/graphics/HardwareRenderer$FrameDrawingCallback;)V",
1039          (void*)android_view_ThreadedRenderer_setFrameCallback},
nSetFrameCommitCallback(JLandroid/graphics/HardwareRenderer$FrameCommitCallback;)1040         {"nSetFrameCommitCallback", "(JLandroid/graphics/HardwareRenderer$FrameCommitCallback;)V",
1041          (void*)android_view_ThreadedRenderer_setFrameCommitCallback},
nSetFrameCompleteCallback(JLandroid/graphics/HardwareRenderer$FrameCompleteCallback;)1042         {"nSetFrameCompleteCallback",
1043          "(JLandroid/graphics/HardwareRenderer$FrameCompleteCallback;)V",
1044          (void*)android_view_ThreadedRenderer_setFrameCompleteCallback},
nAddObserver(JJ)1045         {"nAddObserver", "(JJ)V", (void*)android_view_ThreadedRenderer_addObserver},
nRemoveObserver(JJ)1046         {"nRemoveObserver", "(JJ)V", (void*)android_view_ThreadedRenderer_removeObserver},
nCopySurfaceInto(Landroid/view/Surface;IIIILandroid/graphics/HardwareRenderer$CopyRequest;)1047         {"nCopySurfaceInto",
1048          "(Landroid/view/Surface;IIIILandroid/graphics/HardwareRenderer$CopyRequest;)V",
1049          (void*)android_view_ThreadedRenderer_copySurfaceInto},
nCreateHardwareBitmap(JII)1050         {"nCreateHardwareBitmap", "(JII)Landroid/graphics/Bitmap;",
1051          (void*)android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode},
disableVsync()1052         {"disableVsync", "()V", (void*)android_view_ThreadedRenderer_disableVsync},
nSetHighContrastText(Z)1053         {"nSetHighContrastText", "(Z)V", (void*)android_view_ThreadedRenderer_setHighContrastText},
nSetDebuggingEnabled(Z)1054         {"nSetDebuggingEnabled", "(Z)V", (void*)android_view_ThreadedRenderer_setDebuggingEnabled},
nSetIsolatedProcess(Z)1055         {"nSetIsolatedProcess", "(Z)V", (void*)android_view_ThreadedRenderer_setIsolatedProcess},
nSetContextPriority(I)1056         {"nSetContextPriority", "(I)V", (void*)android_view_ThreadedRenderer_setContextPriority},
nAllocateBuffers(J)1057         {"nAllocateBuffers", "(J)V", (void*)android_view_ThreadedRenderer_allocateBuffers},
nSetForceDark(JI)1058         {"nSetForceDark", "(JI)V", (void*)android_view_ThreadedRenderer_setForceDark},
nSetDisplayDensityDpi(I)1059         {"nSetDisplayDensityDpi", "(I)V",
1060          (void*)android_view_ThreadedRenderer_setDisplayDensityDpi},
nInitDisplayInfo(IIFIJJZZZ)1061         {"nInitDisplayInfo", "(IIFIJJZZZ)V", (void*)android_view_ThreadedRenderer_initDisplayInfo},
preload()1062         {"preload", "()V", (void*)android_view_ThreadedRenderer_preload},
preInitBufferAllocator()1063         {"preInitBufferAllocator", "()V",
1064          (void*)android_view_ThreadedRenderer_preInitBufferAllocator},
isWebViewOverlaysEnabled()1065         {"isWebViewOverlaysEnabled", "()Z",
1066          (void*)android_view_ThreadedRenderer_isWebViewOverlaysEnabled},
nSetDrawingEnabled(Z)1067         {"nSetDrawingEnabled", "(Z)V", (void*)android_view_ThreadedRenderer_setDrawingEnabled},
nIsDrawingEnabled()1068         {"nIsDrawingEnabled", "()Z", (void*)android_view_ThreadedRenderer_isDrawingEnabled},
nSetRtAnimationsEnabled(Z)1069         {"nSetRtAnimationsEnabled", "(Z)V",
1070          (void*)android_view_ThreadedRenderer_setRtAnimationsEnabled},
nNotifyCallbackPending(J)1071         {"nNotifyCallbackPending", "(J)V",
1072          (void*)android_view_ThreadedRenderer_notifyCallbackPending},
nNotifyExpensiveFrame(J)1073         {"nNotifyExpensiveFrame", "(J)V",
1074          (void*)android_view_ThreadedRenderer_notifyExpensiveFrame},
nTrimCaches(I)1075         {"nTrimCaches", "(I)V", (void*)android_view_ThreadedRenderer_trimCaches},
1076 };
1077 
1078 static JavaVM* mJvm = nullptr;
1079 
attachRenderThreadToJvm(const char * name)1080 static void attachRenderThreadToJvm(const char* name) {
1081     LOG_ALWAYS_FATAL_IF(!mJvm, "No jvm but we set the hook??");
1082 
1083     JavaVMAttachArgs args;
1084     args.version = JNI_VERSION_1_4;
1085     args.name = name;
1086     args.group = NULL;
1087     JNIEnv* env;
1088     mJvm->AttachCurrentThreadAsDaemon(&env, (void*) &args);
1089 }
1090 
register_android_view_ThreadedRenderer(JNIEnv * env)1091 int register_android_view_ThreadedRenderer(JNIEnv* env) {
1092     env->GetJavaVM(&mJvm);
1093     RenderThread::setOnStartHook(&attachRenderThreadToJvm);
1094 
1095     jclass hardwareRenderer = FindClassOrDie(env,
1096             "android/graphics/HardwareRenderer");
1097     gHardwareRenderer.clazz = reinterpret_cast<jclass>(env->NewGlobalRef(hardwareRenderer));
1098     gHardwareRenderer.invokePictureCapturedCallback = GetStaticMethodIDOrDie(env, hardwareRenderer,
1099             "invokePictureCapturedCallback",
1100             "(JLandroid/graphics/HardwareRenderer$PictureCapturedCallback;)V");
1101 
1102     jclass aSurfaceTransactionCallbackClass =
1103             FindClassOrDie(env, "android/graphics/HardwareRenderer$ASurfaceTransactionCallback");
1104     gASurfaceTransactionCallback.onMergeTransaction =
1105             GetMethodIDOrDie(env, aSurfaceTransactionCallbackClass, "onMergeTransaction", "(JJJ)Z");
1106 
1107     jclass prepareSurfaceControlForWebviewCallbackClass = FindClassOrDie(
1108             env, "android/graphics/HardwareRenderer$PrepareSurfaceControlForWebviewCallback");
1109     gPrepareSurfaceControlForWebviewCallback.prepare =
1110             GetMethodIDOrDie(env, prepareSurfaceControlForWebviewCallbackClass, "prepare", "()V");
1111 
1112     jclass frameCallbackClass = FindClassOrDie(env,
1113             "android/graphics/HardwareRenderer$FrameDrawingCallback");
1114     gFrameDrawingCallback.onFrameDraw =
1115             GetMethodIDOrDie(env, frameCallbackClass, "onFrameDraw",
1116                              "(IJ)Landroid/graphics/HardwareRenderer$FrameCommitCallback;");
1117 
1118     jclass frameCommitClass =
1119             FindClassOrDie(env, "android/graphics/HardwareRenderer$FrameCommitCallback");
1120     gFrameCommitCallback.onFrameCommit =
1121             GetMethodIDOrDie(env, frameCommitClass, "onFrameCommit", "(Z)V");
1122 
1123     jclass frameCompleteClass = FindClassOrDie(env,
1124             "android/graphics/HardwareRenderer$FrameCompleteCallback");
1125     gFrameCompleteCallback.onFrameComplete =
1126             GetMethodIDOrDie(env, frameCompleteClass, "onFrameComplete", "()V");
1127 
1128     jclass copyRequest = FindClassOrDie(env, "android/graphics/HardwareRenderer$CopyRequest");
1129     gCopyRequest.onCopyFinished = GetMethodIDOrDie(env, copyRequest, "onCopyFinished", "(I)V");
1130     gCopyRequest.getDestinationBitmap =
1131             GetMethodIDOrDie(env, copyRequest, "getDestinationBitmap", "(II)J");
1132 
1133 #ifdef __ANDROID__
1134     void* handle_ = SharedLib::openSharedLib("libandroid");
1135 #else
1136     void* handle_ = SharedLib::openSharedLib("libandroid_runtime");
1137 #endif
1138     fromSurface = (ANW_fromSurface)SharedLib::getSymbol(handle_, "ANativeWindow_fromSurface");
1139     LOG_ALWAYS_FATAL_IF(fromSurface == nullptr,
1140                         "Failed to find required symbol ANativeWindow_fromSurface!");
1141 
1142     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
1143 }
1144 
1145 }; // namespace android
1146