summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/ThreadedRenderer.java121
-rw-r--r--core/java/android/view/ViewRootImpl.java59
-rw-r--r--graphics/java/android/graphics/HardwareRenderer.java14
-rw-r--r--libs/hwui/jni/android_graphics_HardwareRenderer.cpp44
4 files changed, 138 insertions, 100 deletions
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index d839e3532b64..bee0709556e7 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -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;
@@ -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;
@@ -455,6 +526,56 @@ public final class ThreadedRenderer extends HardwareRenderer {
}
/**
+ * 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.
*
* @param attachInfo Information about the window.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 501d2512dd2b..0280be4f720b 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -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
@@ -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;
@@ -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);
}
}
}
@@ -2041,6 +1999,7 @@ public final class ViewRootImpl implements ViewParent,
if (mAttachInfo.mThreadedRenderer != null) {
mAttachInfo.mThreadedRenderer.setSurfaceControl(null);
+ mAttachInfo.mThreadedRenderer.setBlastBufferQueue(null);
}
}
@@ -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();
@@ -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();
}
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index ac2d0c45cc60..8894fa32b480 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -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);
}
@@ -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);
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index db5915447d39..1ca4ce9dc3d8 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -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 {
@@ -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;
});
}
@@ -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);
});
}
}