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