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