diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 2b96a14b04d48..7bdf5cf879f32 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -30,6 +30,7 @@ import android.graphics.BLASTBufferQueue; import android.graphics.BlendMode; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.HardwareRenderer; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PixelFormat; @@ -221,8 +222,35 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall private int mPendingReportDraws; - private SurfaceControl.Transaction mRtTransaction = new SurfaceControl.Transaction(); - private SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction(); + /** + * Transaction that should be used from the render thread. This transaction is only thread safe + * with other calls directly from the render thread. + */ + private final SurfaceControl.Transaction mRtTransaction = new SurfaceControl.Transaction(); + + /** + * Transaction that should be used whe + * {@link HardwareRenderer.FrameDrawingCallback#onFrameDraw} is invoked. All + * frame callbacks can use the same transaction since they will be thread safe + */ + private final SurfaceControl.Transaction mFrameCallbackTransaction = + new SurfaceControl.Transaction(); + + /** + * Transaction that should be used for + * {@link RenderNode.PositionUpdateListener#positionChanged(long, int, int, int, int)} + * The callback is invoked from a thread pool so it's not thread safe with other render thread + * transactions. Keep the transactions for position changed callbacks on its own transaction. + */ + private final SurfaceControl.Transaction mPositionChangedTransaction = + new SurfaceControl.Transaction(); + + /** + * A temporary transaction holder that should only be used when applying right away. There + * should be no assumption about thread safety for this transaction. + */ + private final SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction(); + private int mParentSurfaceSequenceId; private RemoteAccessibilityController mRemoteAccessibilityController = @@ -432,7 +460,6 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall * This gets called on a RenderThread worker thread, so members accessed here must * be protected by a lock. */ - final boolean useBLAST = useBLASTSync(viewRoot); viewRoot.registerRtFrameCallback(frame -> { try { synchronized (mSurfaceControlLock) { @@ -456,8 +483,9 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall Log.d(TAG, System.identityHashCode(this) + " updateSurfaceAlpha RT: set alpha=" + alpha); } - mRtTransaction.setAlpha(mSurfaceControl, alpha); - applyRtTransaction(frame); + + mFrameCallbackTransaction.setAlpha(mSurfaceControl, alpha); + applyOrMergeTransaction(mFrameCallbackTransaction, frame); } // It's possible that mSurfaceControl is released in the UI thread before // the transaction completes. If that happens, an exception is thrown, which @@ -806,7 +834,6 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall * This gets called on a RenderThread worker thread, so members accessed here must * be protected by a lock. */ - final boolean useBLAST = useBLASTSync(viewRoot); viewRoot.registerRtFrameCallback(frame -> { try { synchronized (mSurfaceControlLock) { @@ -814,8 +841,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall return; } - updateRelativeZ(mRtTransaction); - applyRtTransaction(frame); + updateRelativeZ(mFrameCallbackTransaction); + applyOrMergeTransaction(mFrameCallbackTransaction, frame); } // It's possible that mSurfaceControl is released in the UI thread before // the transaction completes. If that happens, an exception is thrown, which @@ -1380,22 +1407,21 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall return mRTLastReportedPosition; } - private void setParentSpaceRectangle(Rect position, long frameNumber) { + private void setParentSpaceRectangle(Rect position, long frameNumber, Transaction t) { final ViewRootImpl viewRoot = getViewRootImpl(); - applySurfaceTransforms(mSurfaceControl, mRtTransaction, position); - applyChildSurfaceTransaction_renderWorker(mRtTransaction, viewRoot.mSurface, frameNumber); - applyRtTransaction(frameNumber); + applySurfaceTransforms(mSurfaceControl, t, position); + applyChildSurfaceTransaction_renderWorker(t, viewRoot.mSurface, frameNumber); + applyOrMergeTransaction(t, frameNumber); } - private void applyRtTransaction(long frameNumber) { + private void applyOrMergeTransaction(Transaction t, long frameNumber) { final ViewRootImpl viewRoot = getViewRootImpl(); boolean useBLAST = viewRoot != null && useBLASTSync(viewRoot); if (useBLAST) { // If we are using BLAST, merge the transaction with the viewroot buffer transaction. - viewRoot.mergeWithNextTransaction(mRtTransaction, frameNumber); - return; + viewRoot.mergeWithNextTransaction(t, frameNumber); } else { - mRtTransaction.apply(); + t.apply(); } } @@ -1436,7 +1462,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall left, top, right, bottom)); } mRTLastReportedPosition.set(left, top, right, bottom); - setParentSpaceRectangle(mRTLastReportedPosition, frameNumber); + setParentSpaceRectangle(mRTLastReportedPosition, frameNumber, + mPositionChangedTransaction); // Now overwrite mRTLastReportedPosition with our values } catch (Exception ex) { Log.e(TAG, "Exception from repositionChild", ex); @@ -1448,7 +1475,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall float bottom, float vecX, float vecY, float maxStretch) { mRtTransaction.setStretchEffect(mSurfaceControl, left, top, right, bottom, vecX, vecY, maxStretch); - applyRtTransaction(frameNumber); + applyOrMergeTransaction(mRtTransaction, frameNumber); } @Override @@ -1468,14 +1495,12 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall * need to hold the lock here. */ synchronized (mSurfaceControlLock) { - final ViewRootImpl viewRoot = getViewRootImpl(); - mRtTransaction.hide(mSurfaceControl); if (mRtReleaseSurfaces) { mRtReleaseSurfaces = false; releaseSurfaces(mRtTransaction); } - applyRtTransaction(frameNumber); + applyOrMergeTransaction(mRtTransaction, frameNumber); mRtHandlingPositionUpdates = false; } }