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