diff options
| -rw-r--r-- | core/java/android/view/SurfaceView.java | 203 | ||||
| -rw-r--r-- | core/java/android/widget/inline/InlineContentView.java | 5 |
2 files changed, 119 insertions, 89 deletions
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 91d5b208c237..9aa243b241f7 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -133,8 +133,9 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall private boolean mDisableBackgroundLayer = false; /** - * We use this lock to protect access to mSurfaceControl. Both are accessed on the UI - * thread and the render thread via RenderNode.PositionUpdateListener#positionLost. + * We use this lock to protect access to mSurfaceControl and + * SurfaceViewPositionUpdateListener#mPositionChangedTransaction. Both are accessed on the UI + * thread and the render thread. */ final Object mSurfaceControlLock = new Object(); final Rect mTmpRect = new Rect(); @@ -223,6 +224,12 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall private final SurfaceControl.Transaction mFrameCallbackTransaction = 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 = @@ -753,7 +760,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall mBlastBufferQueue = null; } - final Transaction transaction = new Transaction(); + Transaction transaction = new Transaction(); if (mSurfaceControl != null) { transaction.remove(mSurfaceControl); mSurfaceControl = null; @@ -783,18 +790,22 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall // synchronously otherwise we may see flickers. // When the listener is updated, we will get at least a single position update call so we can // guarantee any changes we post will be applied. - private void replacePositionUpdateListener(int surfaceWidth, int surfaceHeight) { + private void replacePositionUpdateListener(int surfaceWidth, int surfaceHeight, + Transaction geometryTransaction) { if (mPositionListener != null) { mRenderNode.removePositionUpdateListener(mPositionListener); + synchronized (mSurfaceControlLock) { + geometryTransaction = mPositionListener.getTransaction().merge(geometryTransaction); + } } mPositionListener = new SurfaceViewPositionUpdateListener(surfaceWidth, surfaceHeight, - mSurfaceControl); + geometryTransaction); mRenderNode.addPositionUpdateListener(mPositionListener); } private boolean performSurfaceTransaction(ViewRootImpl viewRoot, Translator translator, boolean creating, boolean sizeChanged, boolean hintChanged, - Transaction surfaceUpdateTransaction) { + Transaction geometryTransaction) { boolean realSizeChanged = false; mSurfaceLock.lock(); @@ -809,60 +820,59 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall // SurfaceChangedCallback to update the relative z. This is needed so that // we do not change the relative z before the server is ready to swap the // parent surface. - if (creating) { - updateRelativeZ(surfaceUpdateTransaction); - if (mSurfacePackage != null) { - reparentSurfacePackage(surfaceUpdateTransaction, mSurfacePackage); - } + if (creating || (mParentSurfaceSequenceId == viewRoot.getSurfaceSequenceId())) { + updateRelativeZ(mTmpTransaction); } mParentSurfaceSequenceId = viewRoot.getSurfaceSequenceId(); if (mViewVisibility) { - surfaceUpdateTransaction.show(mSurfaceControl); + geometryTransaction.show(mSurfaceControl); } else { - surfaceUpdateTransaction.hide(mSurfaceControl); + geometryTransaction.hide(mSurfaceControl); } + if (mSurfacePackage != null) { + reparentSurfacePackage(mTmpTransaction, mSurfacePackage); + } - - updateBackgroundVisibility(surfaceUpdateTransaction); - updateBackgroundColor(surfaceUpdateTransaction); + updateBackgroundVisibility(mTmpTransaction); + updateBackgroundColor(mTmpTransaction); if (mUseAlpha) { float alpha = getFixedAlpha(); - surfaceUpdateTransaction.setAlpha(mSurfaceControl, alpha); + mTmpTransaction.setAlpha(mSurfaceControl, alpha); mSurfaceAlpha = alpha; } - surfaceUpdateTransaction.setCornerRadius(mSurfaceControl, mCornerRadius); + geometryTransaction.setCornerRadius(mSurfaceControl, mCornerRadius); if ((sizeChanged || hintChanged) && !creating) { - setBufferSize(surfaceUpdateTransaction); + setBufferSize(geometryTransaction); } if (sizeChanged || creating || !isHardwareAccelerated()) { + onSetSurfacePositionAndScaleRT(geometryTransaction, mSurfaceControl, + mScreenRect.left, /*positionLeft*/ + mScreenRect.top /*positionTop*/ , + mScreenRect.width() / (float) mSurfaceWidth /*postScaleX*/, + mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/); // Set a window crop when creating the surface or changing its size to // crop the buffer to the surface size since the buffer producer may // use SCALING_MODE_SCALE and submit a larger size than the surface // size. if (mClipSurfaceToBounds && mClipBounds != null) { - surfaceUpdateTransaction.setWindowCrop(mSurfaceControl, mClipBounds); + geometryTransaction.setWindowCrop(mSurfaceControl, mClipBounds); } else { - surfaceUpdateTransaction.setWindowCrop(mSurfaceControl, mSurfaceWidth, + geometryTransaction.setWindowCrop(mSurfaceControl, mSurfaceWidth, mSurfaceHeight); } - surfaceUpdateTransaction.setDesintationFrame(mBlastSurfaceControl, mSurfaceWidth, + geometryTransaction.setDesintationFrame(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight); if (isHardwareAccelerated()) { // This will consume the passed in transaction and the transaction will be // applied on a render worker thread. - replacePositionUpdateListener(mSurfaceWidth, mSurfaceHeight); - } else { - onSetSurfacePositionAndScale(surfaceUpdateTransaction, mSurfaceControl, - mScreenRect.left /*positionLeft*/, - mScreenRect.top /*positionTop*/, - mScreenRect.width() / (float) mSurfaceWidth /*postScaleX*/, - mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/); + replacePositionUpdateListener(mSurfaceWidth, mSurfaceHeight, + geometryTransaction); } if (DEBUG_POSITION) { Log.d(TAG, String.format( @@ -874,7 +884,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall mScreenRect.bottom, mSurfaceWidth, mSurfaceHeight)); } } - applyTransactionOnVriDraw(surfaceUpdateTransaction); + mTmpTransaction.merge(geometryTransaction); + mTmpTransaction.apply(); updateEmbeddedAccessibilityMatrix(); mSurfaceFrame.left = 0; @@ -982,17 +993,17 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall mScreenRect.offset(surfaceInsets.left, surfaceInsets.top); // Collect all geometry changes and apply these changes on the RenderThread worker // via the RenderNode.PositionUpdateListener. - final Transaction surfaceUpdateTransaction = new Transaction(); + final Transaction geometryTransaction = new Transaction(); if (creating) { updateOpaqueFlag(); final String name = "SurfaceView[" + viewRoot.getTitle().toString() + "]"; - createBlastSurfaceControls(viewRoot, name, surfaceUpdateTransaction); + createBlastSurfaceControls(viewRoot, name, geometryTransaction); } else if (mSurfaceControl == null) { return; } final boolean realSizeChanged = performSurfaceTransaction(viewRoot, - translator, creating, sizeChanged, hintChanged, surfaceUpdateTransaction); + translator, creating, sizeChanged, hintChanged, geometryTransaction); final boolean redrawNeeded = sizeChanged || creating || hintChanged || (mVisible && !mDrawFinished); @@ -1128,7 +1139,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall * */ private void createBlastSurfaceControls(ViewRootImpl viewRoot, String name, - Transaction surfaceUpdateTransaction) { + Transaction geometryTransaction) { if (mSurfaceControl == null) { mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession) .setName(name) @@ -1151,10 +1162,11 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall .build(); } else { // update blast layer - surfaceUpdateTransaction + mTmpTransaction .setOpaque(mBlastSurfaceControl, (mSurfaceFlags & SurfaceControl.OPAQUE) != 0) .setSecure(mBlastSurfaceControl, (mSurfaceFlags & SurfaceControl.SECURE) != 0) - .show(mBlastSurfaceControl); + .show(mBlastSurfaceControl) + .apply(); } if (mBackgroundControl == null) { @@ -1201,7 +1213,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall * * @hide */ - protected void onSetSurfacePositionAndScale(@NonNull Transaction transaction, + protected void onSetSurfacePositionAndScaleRT(@NonNull Transaction transaction, @NonNull SurfaceControl surface, int positionLeft, int positionTop, float postScaleX, float postScaleY) { transaction.setPosition(surface, positionLeft, positionTop); @@ -1214,14 +1226,12 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall if (mSurfaceControl == null) { return; } - final Transaction transaction = new Transaction(); - onSetSurfacePositionAndScale(transaction, mSurfaceControl, + onSetSurfacePositionAndScaleRT(mTmpTransaction, mSurfaceControl, mScreenRect.left, /*positionLeft*/ mScreenRect.top/*positionTop*/ , mScreenRect.width() / (float) mSurfaceWidth /*postScaleX*/, mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/); - applyTransactionOnVriDraw(transaction); - invalidate(); + mTmpTransaction.apply(); } /** @@ -1243,57 +1253,66 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } } - private final Rect mRTLastReportedPosition = new Rect(); - private final Point mRTLastReportedSurfaceSize = new Point(); + private Rect mRTLastReportedPosition = new Rect(); + private Point mRTLastReportedSurfaceSize = new Point(); private class SurfaceViewPositionUpdateListener implements RenderNode.PositionUpdateListener { - private final int mRtSurfaceWidth; - private final int mRtSurfaceHeight; + int mRtSurfaceWidth = -1; + int mRtSurfaceHeight = -1; private final SurfaceControl.Transaction mPositionChangedTransaction = new SurfaceControl.Transaction(); - private final SurfaceControl mRtSurfaceControl = new SurfaceControl(); + boolean mPendingTransaction = false; SurfaceViewPositionUpdateListener(int surfaceWidth, int surfaceHeight, - SurfaceControl surfaceControl) { + @Nullable Transaction t) { mRtSurfaceWidth = surfaceWidth; mRtSurfaceHeight = surfaceHeight; - mRtSurfaceControl.copyFrom(surfaceControl, "SurfaceViewPositionUpdateListener"); + if (t != null) { + mPositionChangedTransaction.merge(t); + mPendingTransaction = true; + } } @Override public void positionChanged(long frameNumber, int left, int top, int right, int bottom) { - if (mRTLastReportedPosition.left == left - && mRTLastReportedPosition.top == top - && mRTLastReportedPosition.right == right - && mRTLastReportedPosition.bottom == bottom - && mRTLastReportedSurfaceSize.x == mRtSurfaceWidth - && mRTLastReportedSurfaceSize.y == mRtSurfaceHeight) { - return; - } - try { - if (DEBUG_POSITION) { - Log.d(TAG, String.format( - "%d updateSurfacePosition RenderWorker, frameNr = %d, " - + "position = [%d, %d, %d, %d] surfaceSize = %dx%d", - System.identityHashCode(SurfaceView.this), frameNumber, - left, top, right, bottom, mRtSurfaceWidth, mRtSurfaceHeight)); + synchronized(mSurfaceControlLock) { + if (mSurfaceControl == null) { + return; } - mRTLastReportedPosition.set(left, top, right, bottom); - mRTLastReportedSurfaceSize.set(mRtSurfaceWidth, mRtSurfaceHeight); - onSetSurfacePositionAndScale(mPositionChangedTransaction, mRtSurfaceControl, - mRTLastReportedPosition.left /*positionLeft*/, - mRTLastReportedPosition.top /*positionTop*/, - mRTLastReportedPosition.width() - / (float) mRtSurfaceWidth /*postScaleX*/, - mRTLastReportedPosition.height() - / (float) mRtSurfaceHeight /*postScaleY*/); - if (mViewVisibility) { - // b/131239825 - mPositionChangedTransaction.show(mRtSurfaceControl); + if (mRTLastReportedPosition.left == left + && mRTLastReportedPosition.top == top + && mRTLastReportedPosition.right == right + && mRTLastReportedPosition.bottom == bottom + && mRTLastReportedSurfaceSize.x == mRtSurfaceWidth + && mRTLastReportedSurfaceSize.y == mRtSurfaceHeight + && !mPendingTransaction) { + return; + } + try { + if (DEBUG_POSITION) { + Log.d(TAG, String.format( + "%d updateSurfacePosition RenderWorker, frameNr = %d, " + + "position = [%d, %d, %d, %d] surfaceSize = %dx%d", + System.identityHashCode(SurfaceView.this), frameNumber, + left, top, right, bottom, mRtSurfaceWidth, mRtSurfaceHeight)); + } + mRTLastReportedPosition.set(left, top, right, bottom); + mRTLastReportedSurfaceSize.set(mRtSurfaceWidth, mRtSurfaceHeight); + onSetSurfacePositionAndScaleRT(mPositionChangedTransaction, mSurfaceControl, + mRTLastReportedPosition.left /*positionLeft*/, + mRTLastReportedPosition.top /*positionTop*/, + mRTLastReportedPosition.width() + / (float) mRtSurfaceWidth /*postScaleX*/, + mRTLastReportedPosition.height() + / (float) mRtSurfaceHeight /*postScaleY*/); + if (mViewVisibility) { + mPositionChangedTransaction.show(mSurfaceControl); + } + applyOrMergeTransaction(mPositionChangedTransaction, frameNumber); + mPendingTransaction = false; + } catch (Exception ex) { + Log.e(TAG, "Exception from repositionChild", ex); } - applyOrMergeTransaction(mPositionChangedTransaction, frameNumber); - } catch (Exception ex) { - Log.e(TAG, "Exception from repositionChild", ex); } } @@ -1302,7 +1321,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall float vecX, float vecY, float maxStretchX, float maxStretchY, float childRelativeLeft, float childRelativeTop, float childRelativeRight, float childRelativeBottom) { - mRtTransaction.setStretchEffect(mRtSurfaceControl, width, height, vecX, vecY, + mRtTransaction.setStretchEffect(mSurfaceControl, width, height, vecX, vecY, maxStretchX, maxStretchY, childRelativeLeft, childRelativeTop, childRelativeRight, childRelativeBottom); applyOrMergeTransaction(mRtTransaction, frameNumber); @@ -1317,14 +1336,28 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall mRTLastReportedPosition.setEmpty(); mRTLastReportedSurfaceSize.set(-1, -1); - // positionLost can be called while UI thread is un-paused. + /** + * positionLost can be called while UI thread is un-paused so we + * need to hold the lock here. + */ synchronized (mSurfaceControlLock) { - if (mSurfaceControl == null) return; - // b/131239825 + if (mPendingTransaction) { + Log.w(TAG, System.identityHashCode(SurfaceView.this) + + "Pending transaction cleared."); + mPositionChangedTransaction.clear(); + mPendingTransaction = false; + } + if (mSurfaceControl == null) { + return; + } mRtTransaction.hide(mSurfaceControl); applyOrMergeTransaction(mRtTransaction, frameNumber); } } + + public Transaction getTransaction() { + return mPositionChangedTransaction; + } } private SurfaceViewPositionUpdateListener mPositionListener = null; @@ -1371,10 +1404,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall * @hide */ public void setResizeBackgroundColor(int bgColor) { - final SurfaceControl.Transaction transaction = new SurfaceControl.Transaction(); - setResizeBackgroundColor(transaction, bgColor); - applyTransactionOnVriDraw(transaction); - invalidate(); + setResizeBackgroundColor(mTmpTransaction, bgColor); + mTmpTransaction.apply(); } /** diff --git a/core/java/android/widget/inline/InlineContentView.java b/core/java/android/widget/inline/InlineContentView.java index e4f483a29343..9712311aab7c 100644 --- a/core/java/android/widget/inline/InlineContentView.java +++ b/core/java/android/widget/inline/InlineContentView.java @@ -230,9 +230,8 @@ public class InlineContentView extends ViewGroup { int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); mSurfaceView = new SurfaceView(context, attrs, defStyleAttr, defStyleRes) { - // b/219807628 @Override - protected void onSetSurfacePositionAndScale( + protected void onSetSurfacePositionAndScaleRT( @NonNull SurfaceControl.Transaction transaction, @NonNull SurfaceControl surface, int positionLeft, int positionTop, float postScaleX, float postScaleY) { @@ -249,7 +248,7 @@ public class InlineContentView extends ViewGroup { postScaleX = InlineContentView.this.getScaleX(); postScaleY = InlineContentView.this.getScaleY(); - super.onSetSurfacePositionAndScale(transaction, surface, positionLeft, + super.onSetSurfacePositionAndScaleRT(transaction, surface, positionLeft, positionTop, postScaleX, postScaleY); } }; |