Merge "SurfaceView: Clean up synchronized changes with applyTransactionOnVriDraw"

This commit is contained in:
TreeHugger Robot
2022-02-12 02:53:19 +00:00
committed by Android (Google) Code Review

View File

@@ -23,7 +23,6 @@ import static android.view.WindowManagerPolicyConstants.APPLICATION_PANEL_SUBLAY
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.CompatibilityInfo.Translator;
import android.graphics.BLASTBufferQueue;
@@ -42,7 +41,6 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceControl.Transaction;
@@ -135,7 +133,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
private boolean mDisableBackgroundLayer = false;
/**
* We use this lock to protect access to mSurfaceControl and
* We use this lock to protect access to mSurfaceControl and
* SurfaceViewPositionUpdateListener#mPositionChangedTransaction. Both are accessed on the UI
* thread and the render thread.
*/
@@ -376,11 +374,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
private void updateSurfaceAlpha() {
if (!mUseAlpha) {
if (DEBUG) {
Log.d(TAG, System.identityHashCode(this)
+ " updateSurfaceAlpha: setUseAlpha() is not called, ignored.");
}
if (!mUseAlpha || !mHaveFrame || mSurfaceControl == null) {
return;
}
final float viewAlpha = getAlpha();
@@ -389,88 +383,16 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
+ " updateSurfaceAlpha:"
+ " translucent color is not supported for a surface placed z-below.");
}
if (!mHaveFrame) {
if (DEBUG) {
Log.d(TAG, System.identityHashCode(this)
+ " updateSurfaceAlpha: has no surface.");
}
return;
}
final ViewRootImpl viewRoot = getViewRootImpl();
if (viewRoot == null) {
if (DEBUG) {
Log.d(TAG, System.identityHashCode(this)
+ " updateSurfaceAlpha: ViewRootImpl not available.");
}
return;
}
if (mSurfaceControl == null) {
if (DEBUG) {
Log.d(TAG, System.identityHashCode(this)
+ "updateSurfaceAlpha:"
+ " surface is not yet created, or already released.");
}
return;
}
final Surface parent = viewRoot.mSurface;
if (parent == null || !parent.isValid()) {
if (DEBUG) {
Log.d(TAG, System.identityHashCode(this)
+ " updateSurfaceAlpha: ViewRootImpl has no valid surface");
}
return;
}
final float alpha = getFixedAlpha();
if (alpha != mSurfaceAlpha) {
if (isHardwareAccelerated()) {
/*
* Schedule a callback that reflects an alpha value onto the underlying surfaces.
* This gets called on a RenderThread worker thread, so members accessed here must
* be protected by a lock.
*/
viewRoot.registerRtFrameCallback(frame -> {
try {
synchronized (mSurfaceControlLock) {
if (!parent.isValid()) {
if (DEBUG) {
Log.d(TAG, System.identityHashCode(this)
+ " updateSurfaceAlpha RT:"
+ " ViewRootImpl has no valid surface");
}
return;
}
if (mSurfaceControl == null) {
if (DEBUG) {
Log.d(TAG, System.identityHashCode(this)
+ "updateSurfaceAlpha RT:"
+ " mSurfaceControl has already released");
}
return;
}
if (DEBUG) {
Log.d(TAG, System.identityHashCode(this)
+ " updateSurfaceAlpha RT: set alpha=" + alpha);
}
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
// must be caught immediately.
} catch (Exception e) {
Log.e(TAG, System.identityHashCode(this)
+ "updateSurfaceAlpha RT: Exception during surface transaction", e);
}
});
damageInParent();
} else {
if (DEBUG) {
Log.d(TAG, System.identityHashCode(this)
+ " updateSurfaceAlpha: set alpha=" + alpha);
}
mTmpTransaction.setAlpha(mSurfaceControl, alpha).apply();
}
final Transaction transaction = new Transaction();
transaction.setAlpha(mSurfaceControl, alpha);
viewRoot.applyTransactionOnDraw(transaction);
damageInParent();
mSurfaceAlpha = alpha;
}
}
@@ -527,12 +449,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mRequestedVisible = false;
updateSurface();
// We don't release this as part of releaseSurfaces as
// that is also called on transient visibility changes. We can't
// recreate this Surface, so only release it when we are fully
// detached.
tryReleaseSurfaces(true /* releaseSurfacePackage*/);
releaseSurfaces(true /* releaseSurfacePackage*/);
mHaveFrame = false;
super.onDetachedFromWindow();
@@ -625,7 +542,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
public void setClipBounds(Rect clipBounds) {
super.setClipBounds(clipBounds);
if (!mClipSurfaceToBounds) {
if (!mClipSurfaceToBounds || mSurfaceControl == null) {
return;
}
@@ -635,18 +552,15 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
invalidate();
}
if (mSurfaceControl != null) {
if (mClipBounds != null) {
mTmpRect.set(mClipBounds);
} else {
mTmpRect.set(0, 0, mSurfaceWidth, mSurfaceHeight);
}
SyncRtSurfaceTransactionApplier applier = new SyncRtSurfaceTransactionApplier(this);
applier.scheduleApply(
new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(mSurfaceControl)
.withWindowCrop(mTmpRect)
.build());
if (mClipBounds != null) {
mTmpRect.set(mClipBounds);
} else {
mTmpRect.set(0, 0, mSurfaceWidth, mSurfaceHeight);
}
final Transaction transaction = new Transaction();
transaction.setWindowCrop(mSurfaceControl, mTmpRect);
applyTransactionOnVriDraw(transaction);
invalidate();
}
private void clearSurfaceViewPort(Canvas canvas) {
@@ -782,37 +696,10 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
if (viewRoot == null) {
return true;
}
final Surface parent = viewRoot.mSurface;
if (parent == null || !parent.isValid()) {
return true;
}
/*
* Schedule a callback that reflects an alpha value onto the underlying surfaces.
* This gets called on a RenderThread worker thread, so members accessed here must
* be protected by a lock.
*/
viewRoot.registerRtFrameCallback(frame -> {
try {
synchronized (mSurfaceControlLock) {
if (!parent.isValid() || mSurfaceControl == null) {
return;
}
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
// must be caught immediately.
} catch (Exception e) {
Log.e(TAG, System.identityHashCode(this)
+ "setZOrderOnTop RT: Exception during surface transaction", e);
}
});
final Transaction transaction = new SurfaceControl.Transaction();
updateRelativeZ(transaction);
viewRoot.applyTransactionOnDraw(transaction);
invalidate();
return true;
}
@@ -863,7 +750,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
return t;
}
private void tryReleaseSurfaces(boolean releaseSurfacePackage) {
private void releaseSurfaces(boolean releaseSurfacePackage) {
mSurfaceAlpha = 1f;
synchronized (mSurfaceControlLock) {
@@ -892,12 +779,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mSurfacePackage = null;
}
ViewRootImpl viewRoot = getViewRootImpl();
if (viewRoot != null) {
viewRoot.applyTransactionOnDraw(transaction);
} else {
transaction.apply();
}
applyTransactionOnVriDraw(transaction);
}
}
@@ -1041,7 +923,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
if (viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) {
notifySurfaceDestroyed();
tryReleaseSurfaces(false /* releaseSurfacePackage*/);
releaseSurfaces(false /* releaseSurfacePackage*/);
return;
}
@@ -1182,7 +1064,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
} finally {
mIsCreating = false;
if (mSurfaceControl != null && !mSurfaceCreated) {
tryReleaseSurfaces(false /* releaseSurfacePackage*/);
releaseSurfaces(false /* releaseSurfacePackage*/);
}
}
} catch (Exception ex) {
@@ -1316,17 +1198,6 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
runOnUiThread(() -> performDrawFinished(t));
}
/**
* A place to over-ride for applying child-surface transactions.
* These can be synchronized with the viewroot surface using deferTransaction.
*
* Called from RenderWorker while UI thread is paused.
* @hide
*/
protected void applyChildSurfaceTransaction_renderWorker(SurfaceControl.Transaction t,
Surface viewRootSurface, long nextViewRootFrameNumber) {
}
/**
* Sets the surface position and scale. Can be called on
* the UI thread as well as on the renderer thread.
@@ -1435,11 +1306,6 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
if (mViewVisibility) {
mPositionChangedTransaction.show(mSurfaceControl);
}
final ViewRootImpl viewRoot = getViewRootImpl();
if (viewRoot != null) {
applyChildSurfaceTransaction_renderWorker(mPositionChangedTransaction,
viewRoot.mSurface, frameNumber);
}
applyOrMergeTransaction(mPositionChangedTransaction, frameNumber);
mPendingTransaction = false;
} catch (Exception ex) {
@@ -1837,12 +1703,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mSurfacePackage.release();
}
reparentSurfacePackage(transaction, p);
final ViewRootImpl viewRoot = getViewRootImpl();
if (viewRoot != null) {
viewRoot.applyTransactionOnDraw(transaction);
} else {
transaction.apply();
}
applyTransactionOnVriDraw(transaction);
}
mSurfacePackage = p;
invalidate();
@@ -1948,4 +1809,13 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
}
private void applyTransactionOnVriDraw(Transaction t) {
final ViewRootImpl viewRoot = getViewRootImpl();
if (viewRoot != null) {
// If we are using BLAST, merge the transaction with the viewroot buffer transaction.
viewRoot.applyTransactionOnDraw(t);
} else {
t.apply();
}
}
}