Loading core/java/android/view/ThreadedRenderer.java +121 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.content.Context; import android.content.res.TypedArray; import android.graphics.BLASTBufferQueue; import android.graphics.FrameInfo; import android.graphics.HardwareRenderer; import android.graphics.Picture; Loading Loading @@ -257,6 +258,76 @@ public final class ThreadedRenderer extends HardwareRenderer { private boolean mEnabled; private boolean mRequested = true; /** * This child class exists to break ownership cycles. ViewRootImpl owns a ThreadedRenderer * which owns a WebViewOverlayProvider. WebViewOverlayProvider will in turn be set as * the listener for HardwareRenderer callbacks. By keeping this a child class, there are * no cycles in the chain. The ThreadedRenderer will remain GC-able if any callbacks are * still outstanding, which will in turn release any JNI references to WebViewOverlayProvider. */ private static final class WebViewOverlayProvider implements PrepareSurfaceControlForWebviewCallback, ASurfaceTransactionCallback { private static final boolean sOverlaysAreEnabled = HardwareRenderer.isWebViewOverlaysEnabled(); private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction(); private boolean mHasWebViewOverlays = false; private BLASTBufferQueue mBLASTBufferQueue; private SurfaceControl mSurfaceControl; public boolean setSurfaceControlOpaque(boolean opaque) { synchronized (this) { if (mHasWebViewOverlays) return false; mTransaction.setOpaque(mSurfaceControl, opaque).apply(); } return opaque; } public boolean shouldEnableOverlaySupport() { return sOverlaysAreEnabled && mSurfaceControl != null && mBLASTBufferQueue != null; } public void setSurfaceControl(SurfaceControl surfaceControl) { synchronized (this) { mSurfaceControl = surfaceControl; if (mSurfaceControl != null && mHasWebViewOverlays) { mTransaction.setOpaque(surfaceControl, false).apply(); } } } public void setBLASTBufferQueue(BLASTBufferQueue bufferQueue) { synchronized (this) { mBLASTBufferQueue = bufferQueue; } } @Override public void prepare() { synchronized (this) { mHasWebViewOverlays = true; if (mSurfaceControl != null) { mTransaction.setOpaque(mSurfaceControl, false).apply(); } } } @Override public boolean onMergeTransaction(long nativeTransactionObj, long aSurfaceControlNativeObj, long frameNr) { synchronized (this) { if (mBLASTBufferQueue == null) { return false; } else { mBLASTBufferQueue.mergeWithNextTransaction(nativeTransactionObj, frameNr); return true; } } } } private final WebViewOverlayProvider mWebViewOverlayProvider = new WebViewOverlayProvider(); private boolean mWebViewOverlaysEnabled = false; @Nullable private ArrayList<FrameDrawingCallback> mNextRtFrameCallbacks; Loading Loading @@ -454,6 +525,56 @@ public final class ThreadedRenderer extends HardwareRenderer { setLightCenter(attachInfo); } /** * Whether or not the renderer owns the SurfaceControl's opacity. If true, use * {@link #setSurfaceControlOpaque(boolean)} to update the opacity */ public boolean rendererOwnsSurfaceControlOpacity() { return mWebViewOverlayProvider.mSurfaceControl != null; } /** * Sets the SurfaceControl's opacity that this HardwareRenderer is rendering onto. The renderer * may opt to override the opacity, and will return the value that is ultimately set * * @return true if the surface is opaque, false otherwise * * @hide */ public boolean setSurfaceControlOpaque(boolean opaque) { return mWebViewOverlayProvider.setSurfaceControlOpaque(opaque); } private void updateWebViewOverlayCallbacks() { boolean shouldEnable = mWebViewOverlayProvider.shouldEnableOverlaySupport(); if (shouldEnable != mWebViewOverlaysEnabled) { mWebViewOverlaysEnabled = shouldEnable; if (shouldEnable) { setASurfaceTransactionCallback(mWebViewOverlayProvider); setPrepareSurfaceControlForWebviewCallback(mWebViewOverlayProvider); } else { setASurfaceTransactionCallback(null); setPrepareSurfaceControlForWebviewCallback(null); } } } @Override public void setSurfaceControl(@Nullable SurfaceControl surfaceControl) { super.setSurfaceControl(surfaceControl); mWebViewOverlayProvider.setSurfaceControl(surfaceControl); updateWebViewOverlayCallbacks(); } /** * Sets the BLASTBufferQueue being used for rendering. This is required to be specified * for WebView overlay support */ public void setBlastBufferQueue(@Nullable BLASTBufferQueue blastBufferQueue) { mWebViewOverlayProvider.setBLASTBufferQueue(blastBufferQueue); updateWebViewOverlayCallbacks(); } /** * Updates the light position based on the position of the window. * Loading core/java/android/view/ViewRootImpl.java +7 −52 Original line number Diff line number Diff line Loading @@ -485,9 +485,6 @@ public final class ViewRootImpl implements ViewParent, protected final ViewFrameInfo mViewFrameInfo = new ViewFrameInfo(); private final InputEventAssigner mInputEventAssigner = new InputEventAssigner(); // Set to true if mSurfaceControl is used for Webview Overlay private boolean mIsForWebviewOverlay; /** * Update the Choreographer's FrameInfo object with the timing information for the current * ViewRootImpl instance. Erase the data in the current ViewFrameInfo to prepare for the next Loading Loading @@ -1386,42 +1383,6 @@ public final class ViewRootImpl implements ViewParent, } } /** * Register a callback to be executed when Webview overlay needs to merge a transaction. * This callback will be executed on RenderThread worker thread, and released inside native code * when CanvasContext is destroyed. */ private void addASurfaceTransactionCallback() { HardwareRenderer.ASurfaceTransactionCallback callback = (nativeTransactionObj, nativeSurfaceControlObj, frameNr) -> { if (mBlastBufferQueue == null) { return false; } else { mBlastBufferQueue.mergeWithNextTransaction(nativeTransactionObj, frameNr); return true; } }; mAttachInfo.mThreadedRenderer.setASurfaceTransactionCallback(callback); } /** * Register a callback to be executed when Webview overlay needs a surface control. * This callback will be executed on RenderThread worker thread, and released inside native code * when CanvasContext is destroyed. */ private void addPrepareSurfaceControlForWebviewCallback() { HardwareRenderer.PrepareSurfaceControlForWebviewCallback callback = () -> { // make mSurfaceControl transparent, so child surface controls are visible if (mIsForWebviewOverlay) return; synchronized (ViewRootImpl.this) { mIsForWebviewOverlay = true; } mTransaction.setOpaque(mSurfaceControl, false).apply(); }; mAttachInfo.mThreadedRenderer.setPrepareSurfaceControlForWebviewCallback(callback); } @UnsupportedAppUsage private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) { mAttachInfo.mHardwareAccelerated = false; Loading Loading @@ -1466,11 +1427,8 @@ public final class ViewRootImpl implements ViewParent, if (mHardwareRendererObserver != null) { mAttachInfo.mThreadedRenderer.addObserver(mHardwareRendererObserver); } if (HardwareRenderer.isWebViewOverlaysEnabled()) { addPrepareSurfaceControlForWebviewCallback(); addASurfaceTransactionCallback(); } mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl); mAttachInfo.mThreadedRenderer.setBlastBufferQueue(mBlastBufferQueue); } } } Loading Loading @@ -2041,6 +1999,7 @@ public final class ViewRootImpl implements ViewParent, if (mAttachInfo.mThreadedRenderer != null) { mAttachInfo.mThreadedRenderer.setSurfaceControl(null); mAttachInfo.mThreadedRenderer.setBlastBufferQueue(null); } } Loading Loading @@ -7823,11 +7782,8 @@ public final class ViewRootImpl implements ViewParent, } } if (mAttachInfo.mThreadedRenderer != null) { if (HardwareRenderer.isWebViewOverlaysEnabled()) { addPrepareSurfaceControlForWebviewCallback(); addASurfaceTransactionCallback(); } mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl); mAttachInfo.mThreadedRenderer.setBlastBufferQueue(mBlastBufferQueue); } } else { destroySurface(); Loading Loading @@ -7873,11 +7829,10 @@ public final class ViewRootImpl implements ViewParent, return; } synchronized (this) { if (mIsForWebviewOverlay) { mIsSurfaceOpaque = false; return; } final ThreadedRenderer renderer = mAttachInfo.mThreadedRenderer; if (renderer != null && renderer.rendererOwnsSurfaceControlOpacity()) { opaque = renderer.setSurfaceControlOpaque(opaque); } else { mTransaction.setOpaque(mSurfaceControl, opaque).apply(); } Loading graphics/java/android/graphics/HardwareRenderer.java +3 −11 Original line number Diff line number Diff line Loading @@ -752,22 +752,14 @@ public class HardwareRenderer { nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater()); } private ASurfaceTransactionCallback mASurfaceTransactionCallback; /** @hide */ public void setASurfaceTransactionCallback(ASurfaceTransactionCallback callback) { // ensure callback is kept alive on the java side since weak ref is used in native code mASurfaceTransactionCallback = callback; protected void setASurfaceTransactionCallback(ASurfaceTransactionCallback callback) { nSetASurfaceTransactionCallback(mNativeProxy, callback); } private PrepareSurfaceControlForWebviewCallback mAPrepareSurfaceControlForWebviewCallback; /** @hide */ public void setPrepareSurfaceControlForWebviewCallback( protected void setPrepareSurfaceControlForWebviewCallback( PrepareSurfaceControlForWebviewCallback callback) { // ensure callback is kept alive on the java side since weak ref is used in native code mAPrepareSurfaceControlForWebviewCallback = callback; nSetPrepareSurfaceControlForWebviewCallback(mNativeProxy, callback); } Loading Loading @@ -1299,7 +1291,7 @@ public class HardwareRenderer { /** * @hide */ public static native boolean isWebViewOverlaysEnabled(); protected static native boolean isWebViewOverlaysEnabled(); /** @hide */ protected static native void setupShadersDiskCache(String cacheFile, String skiaCacheFile); Loading libs/hwui/jni/android_graphics_HardwareRenderer.cpp +7 −37 Original line number Diff line number Diff line Loading @@ -423,28 +423,6 @@ private: jobject mObject; }; class JWeakGlobalRefHolder { public: JWeakGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm) { mWeakRef = getenv(vm)->NewWeakGlobalRef(object); } virtual ~JWeakGlobalRefHolder() { if (mWeakRef != nullptr) getenv(mVm)->DeleteWeakGlobalRef(mWeakRef); mWeakRef = nullptr; } jobject ref() { return mWeakRef; } JavaVM* vm() { return mVm; } private: JWeakGlobalRefHolder(const JWeakGlobalRefHolder&) = delete; void operator=(const JWeakGlobalRefHolder&) = delete; JavaVM* mVm; jobject mWeakRef; }; using TextureMap = std::unordered_map<uint32_t, sk_sp<SkImage>>; struct PictureCaptureState { Loading Loading @@ -578,20 +556,16 @@ static void android_view_ThreadedRenderer_setASurfaceTransactionCallback( } else { JavaVM* vm = nullptr; LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM"); auto globalCallbackRef = std::make_shared<JWeakGlobalRefHolder>(vm, aSurfaceTransactionCallback); auto globalCallbackRef = std::make_shared<JGlobalRefHolder>( vm, env->NewGlobalRef(aSurfaceTransactionCallback)); proxy->setASurfaceTransactionCallback( [globalCallbackRef](int64_t transObj, int64_t scObj, int64_t frameNr) -> bool { JNIEnv* env = getenv(globalCallbackRef->vm()); jobject localref = env->NewLocalRef(globalCallbackRef->ref()); if (CC_UNLIKELY(!localref)) { return false; } jboolean ret = env->CallBooleanMethod( localref, gASurfaceTransactionCallback.onMergeTransaction, globalCallbackRef->object(), gASurfaceTransactionCallback.onMergeTransaction, static_cast<jlong>(transObj), static_cast<jlong>(scObj), static_cast<jlong>(frameNr)); env->DeleteLocalRef(localref); return ret; }); } Loading @@ -606,15 +580,11 @@ static void android_view_ThreadedRenderer_setPrepareSurfaceControlForWebviewCall JavaVM* vm = nullptr; LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM"); auto globalCallbackRef = std::make_shared<JWeakGlobalRefHolder>(vm, callback); std::make_shared<JGlobalRefHolder>(vm, env->NewGlobalRef(callback)); proxy->setPrepareSurfaceControlForWebviewCallback([globalCallbackRef]() { JNIEnv* env = getenv(globalCallbackRef->vm()); jobject localref = env->NewLocalRef(globalCallbackRef->ref()); if (CC_UNLIKELY(!localref)) { return; } env->CallVoidMethod(localref, gPrepareSurfaceControlForWebviewCallback.prepare); env->DeleteLocalRef(localref); env->CallVoidMethod(globalCallbackRef->object(), gPrepareSurfaceControlForWebviewCallback.prepare); }); } } Loading Loading
core/java/android/view/ThreadedRenderer.java +121 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.content.Context; import android.content.res.TypedArray; import android.graphics.BLASTBufferQueue; import android.graphics.FrameInfo; import android.graphics.HardwareRenderer; import android.graphics.Picture; Loading Loading @@ -257,6 +258,76 @@ public final class ThreadedRenderer extends HardwareRenderer { private boolean mEnabled; private boolean mRequested = true; /** * This child class exists to break ownership cycles. ViewRootImpl owns a ThreadedRenderer * which owns a WebViewOverlayProvider. WebViewOverlayProvider will in turn be set as * the listener for HardwareRenderer callbacks. By keeping this a child class, there are * no cycles in the chain. The ThreadedRenderer will remain GC-able if any callbacks are * still outstanding, which will in turn release any JNI references to WebViewOverlayProvider. */ private static final class WebViewOverlayProvider implements PrepareSurfaceControlForWebviewCallback, ASurfaceTransactionCallback { private static final boolean sOverlaysAreEnabled = HardwareRenderer.isWebViewOverlaysEnabled(); private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction(); private boolean mHasWebViewOverlays = false; private BLASTBufferQueue mBLASTBufferQueue; private SurfaceControl mSurfaceControl; public boolean setSurfaceControlOpaque(boolean opaque) { synchronized (this) { if (mHasWebViewOverlays) return false; mTransaction.setOpaque(mSurfaceControl, opaque).apply(); } return opaque; } public boolean shouldEnableOverlaySupport() { return sOverlaysAreEnabled && mSurfaceControl != null && mBLASTBufferQueue != null; } public void setSurfaceControl(SurfaceControl surfaceControl) { synchronized (this) { mSurfaceControl = surfaceControl; if (mSurfaceControl != null && mHasWebViewOverlays) { mTransaction.setOpaque(surfaceControl, false).apply(); } } } public void setBLASTBufferQueue(BLASTBufferQueue bufferQueue) { synchronized (this) { mBLASTBufferQueue = bufferQueue; } } @Override public void prepare() { synchronized (this) { mHasWebViewOverlays = true; if (mSurfaceControl != null) { mTransaction.setOpaque(mSurfaceControl, false).apply(); } } } @Override public boolean onMergeTransaction(long nativeTransactionObj, long aSurfaceControlNativeObj, long frameNr) { synchronized (this) { if (mBLASTBufferQueue == null) { return false; } else { mBLASTBufferQueue.mergeWithNextTransaction(nativeTransactionObj, frameNr); return true; } } } } private final WebViewOverlayProvider mWebViewOverlayProvider = new WebViewOverlayProvider(); private boolean mWebViewOverlaysEnabled = false; @Nullable private ArrayList<FrameDrawingCallback> mNextRtFrameCallbacks; Loading Loading @@ -454,6 +525,56 @@ public final class ThreadedRenderer extends HardwareRenderer { setLightCenter(attachInfo); } /** * Whether or not the renderer owns the SurfaceControl's opacity. If true, use * {@link #setSurfaceControlOpaque(boolean)} to update the opacity */ public boolean rendererOwnsSurfaceControlOpacity() { return mWebViewOverlayProvider.mSurfaceControl != null; } /** * Sets the SurfaceControl's opacity that this HardwareRenderer is rendering onto. The renderer * may opt to override the opacity, and will return the value that is ultimately set * * @return true if the surface is opaque, false otherwise * * @hide */ public boolean setSurfaceControlOpaque(boolean opaque) { return mWebViewOverlayProvider.setSurfaceControlOpaque(opaque); } private void updateWebViewOverlayCallbacks() { boolean shouldEnable = mWebViewOverlayProvider.shouldEnableOverlaySupport(); if (shouldEnable != mWebViewOverlaysEnabled) { mWebViewOverlaysEnabled = shouldEnable; if (shouldEnable) { setASurfaceTransactionCallback(mWebViewOverlayProvider); setPrepareSurfaceControlForWebviewCallback(mWebViewOverlayProvider); } else { setASurfaceTransactionCallback(null); setPrepareSurfaceControlForWebviewCallback(null); } } } @Override public void setSurfaceControl(@Nullable SurfaceControl surfaceControl) { super.setSurfaceControl(surfaceControl); mWebViewOverlayProvider.setSurfaceControl(surfaceControl); updateWebViewOverlayCallbacks(); } /** * Sets the BLASTBufferQueue being used for rendering. This is required to be specified * for WebView overlay support */ public void setBlastBufferQueue(@Nullable BLASTBufferQueue blastBufferQueue) { mWebViewOverlayProvider.setBLASTBufferQueue(blastBufferQueue); updateWebViewOverlayCallbacks(); } /** * Updates the light position based on the position of the window. * Loading
core/java/android/view/ViewRootImpl.java +7 −52 Original line number Diff line number Diff line Loading @@ -485,9 +485,6 @@ public final class ViewRootImpl implements ViewParent, protected final ViewFrameInfo mViewFrameInfo = new ViewFrameInfo(); private final InputEventAssigner mInputEventAssigner = new InputEventAssigner(); // Set to true if mSurfaceControl is used for Webview Overlay private boolean mIsForWebviewOverlay; /** * Update the Choreographer's FrameInfo object with the timing information for the current * ViewRootImpl instance. Erase the data in the current ViewFrameInfo to prepare for the next Loading Loading @@ -1386,42 +1383,6 @@ public final class ViewRootImpl implements ViewParent, } } /** * Register a callback to be executed when Webview overlay needs to merge a transaction. * This callback will be executed on RenderThread worker thread, and released inside native code * when CanvasContext is destroyed. */ private void addASurfaceTransactionCallback() { HardwareRenderer.ASurfaceTransactionCallback callback = (nativeTransactionObj, nativeSurfaceControlObj, frameNr) -> { if (mBlastBufferQueue == null) { return false; } else { mBlastBufferQueue.mergeWithNextTransaction(nativeTransactionObj, frameNr); return true; } }; mAttachInfo.mThreadedRenderer.setASurfaceTransactionCallback(callback); } /** * Register a callback to be executed when Webview overlay needs a surface control. * This callback will be executed on RenderThread worker thread, and released inside native code * when CanvasContext is destroyed. */ private void addPrepareSurfaceControlForWebviewCallback() { HardwareRenderer.PrepareSurfaceControlForWebviewCallback callback = () -> { // make mSurfaceControl transparent, so child surface controls are visible if (mIsForWebviewOverlay) return; synchronized (ViewRootImpl.this) { mIsForWebviewOverlay = true; } mTransaction.setOpaque(mSurfaceControl, false).apply(); }; mAttachInfo.mThreadedRenderer.setPrepareSurfaceControlForWebviewCallback(callback); } @UnsupportedAppUsage private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) { mAttachInfo.mHardwareAccelerated = false; Loading Loading @@ -1466,11 +1427,8 @@ public final class ViewRootImpl implements ViewParent, if (mHardwareRendererObserver != null) { mAttachInfo.mThreadedRenderer.addObserver(mHardwareRendererObserver); } if (HardwareRenderer.isWebViewOverlaysEnabled()) { addPrepareSurfaceControlForWebviewCallback(); addASurfaceTransactionCallback(); } mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl); mAttachInfo.mThreadedRenderer.setBlastBufferQueue(mBlastBufferQueue); } } } Loading Loading @@ -2041,6 +1999,7 @@ public final class ViewRootImpl implements ViewParent, if (mAttachInfo.mThreadedRenderer != null) { mAttachInfo.mThreadedRenderer.setSurfaceControl(null); mAttachInfo.mThreadedRenderer.setBlastBufferQueue(null); } } Loading Loading @@ -7823,11 +7782,8 @@ public final class ViewRootImpl implements ViewParent, } } if (mAttachInfo.mThreadedRenderer != null) { if (HardwareRenderer.isWebViewOverlaysEnabled()) { addPrepareSurfaceControlForWebviewCallback(); addASurfaceTransactionCallback(); } mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl); mAttachInfo.mThreadedRenderer.setBlastBufferQueue(mBlastBufferQueue); } } else { destroySurface(); Loading Loading @@ -7873,11 +7829,10 @@ public final class ViewRootImpl implements ViewParent, return; } synchronized (this) { if (mIsForWebviewOverlay) { mIsSurfaceOpaque = false; return; } final ThreadedRenderer renderer = mAttachInfo.mThreadedRenderer; if (renderer != null && renderer.rendererOwnsSurfaceControlOpacity()) { opaque = renderer.setSurfaceControlOpaque(opaque); } else { mTransaction.setOpaque(mSurfaceControl, opaque).apply(); } Loading
graphics/java/android/graphics/HardwareRenderer.java +3 −11 Original line number Diff line number Diff line Loading @@ -752,22 +752,14 @@ public class HardwareRenderer { nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater()); } private ASurfaceTransactionCallback mASurfaceTransactionCallback; /** @hide */ public void setASurfaceTransactionCallback(ASurfaceTransactionCallback callback) { // ensure callback is kept alive on the java side since weak ref is used in native code mASurfaceTransactionCallback = callback; protected void setASurfaceTransactionCallback(ASurfaceTransactionCallback callback) { nSetASurfaceTransactionCallback(mNativeProxy, callback); } private PrepareSurfaceControlForWebviewCallback mAPrepareSurfaceControlForWebviewCallback; /** @hide */ public void setPrepareSurfaceControlForWebviewCallback( protected void setPrepareSurfaceControlForWebviewCallback( PrepareSurfaceControlForWebviewCallback callback) { // ensure callback is kept alive on the java side since weak ref is used in native code mAPrepareSurfaceControlForWebviewCallback = callback; nSetPrepareSurfaceControlForWebviewCallback(mNativeProxy, callback); } Loading Loading @@ -1299,7 +1291,7 @@ public class HardwareRenderer { /** * @hide */ public static native boolean isWebViewOverlaysEnabled(); protected static native boolean isWebViewOverlaysEnabled(); /** @hide */ protected static native void setupShadersDiskCache(String cacheFile, String skiaCacheFile); Loading
libs/hwui/jni/android_graphics_HardwareRenderer.cpp +7 −37 Original line number Diff line number Diff line Loading @@ -423,28 +423,6 @@ private: jobject mObject; }; class JWeakGlobalRefHolder { public: JWeakGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm) { mWeakRef = getenv(vm)->NewWeakGlobalRef(object); } virtual ~JWeakGlobalRefHolder() { if (mWeakRef != nullptr) getenv(mVm)->DeleteWeakGlobalRef(mWeakRef); mWeakRef = nullptr; } jobject ref() { return mWeakRef; } JavaVM* vm() { return mVm; } private: JWeakGlobalRefHolder(const JWeakGlobalRefHolder&) = delete; void operator=(const JWeakGlobalRefHolder&) = delete; JavaVM* mVm; jobject mWeakRef; }; using TextureMap = std::unordered_map<uint32_t, sk_sp<SkImage>>; struct PictureCaptureState { Loading Loading @@ -578,20 +556,16 @@ static void android_view_ThreadedRenderer_setASurfaceTransactionCallback( } else { JavaVM* vm = nullptr; LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM"); auto globalCallbackRef = std::make_shared<JWeakGlobalRefHolder>(vm, aSurfaceTransactionCallback); auto globalCallbackRef = std::make_shared<JGlobalRefHolder>( vm, env->NewGlobalRef(aSurfaceTransactionCallback)); proxy->setASurfaceTransactionCallback( [globalCallbackRef](int64_t transObj, int64_t scObj, int64_t frameNr) -> bool { JNIEnv* env = getenv(globalCallbackRef->vm()); jobject localref = env->NewLocalRef(globalCallbackRef->ref()); if (CC_UNLIKELY(!localref)) { return false; } jboolean ret = env->CallBooleanMethod( localref, gASurfaceTransactionCallback.onMergeTransaction, globalCallbackRef->object(), gASurfaceTransactionCallback.onMergeTransaction, static_cast<jlong>(transObj), static_cast<jlong>(scObj), static_cast<jlong>(frameNr)); env->DeleteLocalRef(localref); return ret; }); } Loading @@ -606,15 +580,11 @@ static void android_view_ThreadedRenderer_setPrepareSurfaceControlForWebviewCall JavaVM* vm = nullptr; LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM"); auto globalCallbackRef = std::make_shared<JWeakGlobalRefHolder>(vm, callback); std::make_shared<JGlobalRefHolder>(vm, env->NewGlobalRef(callback)); proxy->setPrepareSurfaceControlForWebviewCallback([globalCallbackRef]() { JNIEnv* env = getenv(globalCallbackRef->vm()); jobject localref = env->NewLocalRef(globalCallbackRef->ref()); if (CC_UNLIKELY(!localref)) { return; } env->CallVoidMethod(localref, gPrepareSurfaceControlForWebviewCallback.prepare); env->DeleteLocalRef(localref); env->CallVoidMethod(globalCallbackRef->object(), gPrepareSurfaceControlForWebviewCallback.prepare); }); } } Loading