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