Port SurfaceView deferTransaction usage to BLAST
When the SurfaceView is invalidated (e.g. geometry has changed) we ask the ViewRootImpl to render the next buffer in to a BLAST transaction which the SurfaceView will also use from it's RT callbacks in place of deferTransactionUntil Test: Flip USE_BLAST_BUFFERQUEUE flag. Run SurfaceViewSyncTests. Bug: 146598493 Change-Id: I43d301f25101afae32ad1c43a3a3210c5aeadd0f
This commit is contained in:
@@ -379,9 +379,11 @@ 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 = ViewRootImpl.USE_BLAST_BUFFERQUEUE;
|
||||
viewRoot.registerRtFrameCallback(frame -> {
|
||||
try {
|
||||
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
|
||||
final SurfaceControl.Transaction t = useBLAST ?
|
||||
viewRoot.getBLASTSyncTransaction() : new SurfaceControl.Transaction();
|
||||
synchronized (mSurfaceControlLock) {
|
||||
if (!parent.isValid()) {
|
||||
if (DEBUG) {
|
||||
@@ -404,7 +406,9 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
+ " updateSurfaceAlpha RT: set alpha=" + alpha);
|
||||
}
|
||||
t.setAlpha(mSurfaceControl, alpha);
|
||||
t.deferTransactionUntilSurface(mSurfaceControl, parent, frame);
|
||||
if (!useBLAST) {
|
||||
t.deferTransactionUntilSurface(mSurfaceControl, parent, frame);
|
||||
}
|
||||
}
|
||||
// It's possible that mSurfaceControl is released in the UI thread before
|
||||
// the transaction completes. If that happens, an exception is thrown, which
|
||||
@@ -1101,33 +1105,39 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
Surface viewRootSurface, long nextViewRootFrameNumber) {
|
||||
}
|
||||
|
||||
private void applySurfaceTransforms(SurfaceControl surface, Rect position, long frameNumber) {
|
||||
if (frameNumber > 0) {
|
||||
private void applySurfaceTransforms(SurfaceControl surface, SurfaceControl.Transaction t,
|
||||
Rect position, long frameNumber) {
|
||||
if (frameNumber > 0 && ViewRootImpl.USE_BLAST_BUFFERQUEUE == false) {
|
||||
final ViewRootImpl viewRoot = getViewRootImpl();
|
||||
|
||||
mRtTransaction.deferTransactionUntilSurface(surface, viewRoot.mSurface,
|
||||
t.deferTransactionUntilSurface(surface, viewRoot.mSurface,
|
||||
frameNumber);
|
||||
}
|
||||
|
||||
mRtTransaction.setPosition(surface, position.left, position.top);
|
||||
mRtTransaction.setMatrix(surface,
|
||||
t.setPosition(surface, position.left, position.top);
|
||||
t.setMatrix(surface,
|
||||
position.width() / (float) mSurfaceWidth,
|
||||
0.0f, 0.0f,
|
||||
position.height() / (float) mSurfaceHeight);
|
||||
if (mViewVisibility) {
|
||||
mRtTransaction.show(surface);
|
||||
t.show(surface);
|
||||
}
|
||||
}
|
||||
|
||||
private void setParentSpaceRectangle(Rect position, long frameNumber) {
|
||||
final boolean useBLAST = ViewRootImpl.USE_BLAST_BUFFERQUEUE;
|
||||
final ViewRootImpl viewRoot = getViewRootImpl();
|
||||
final SurfaceControl.Transaction t = useBLAST ? viewRoot.getBLASTSyncTransaction() :
|
||||
mRtTransaction;
|
||||
|
||||
applySurfaceTransforms(mSurfaceControl, position, frameNumber);
|
||||
applySurfaceTransforms(mSurfaceControl, t, position, frameNumber);
|
||||
|
||||
applyChildSurfaceTransaction_renderWorker(mRtTransaction, viewRoot.mSurface,
|
||||
applyChildSurfaceTransaction_renderWorker(t, viewRoot.mSurface,
|
||||
frameNumber);
|
||||
|
||||
mRtTransaction.apply();
|
||||
if (!useBLAST) {
|
||||
t.apply();
|
||||
}
|
||||
}
|
||||
|
||||
private Rect mRTLastReportedPosition = new Rect();
|
||||
@@ -1176,6 +1186,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
|
||||
@Override
|
||||
public void positionLost(long frameNumber) {
|
||||
boolean useBLAST = ViewRootImpl.USE_BLAST_BUFFERQUEUE;
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, String.format("%d windowPositionLost, frameNr = %d",
|
||||
System.identityHashCode(this), frameNumber));
|
||||
@@ -1187,13 +1198,18 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
}
|
||||
|
||||
final ViewRootImpl viewRoot = getViewRootImpl();
|
||||
if (frameNumber > 0 && viewRoot != null) {
|
||||
|
||||
final SurfaceControl.Transaction t = useBLAST ?
|
||||
(viewRoot != null ? viewRoot.getBLASTSyncTransaction() : mRtTransaction) :
|
||||
mRtTransaction;
|
||||
|
||||
if (frameNumber > 0 && viewRoot != null && !useBLAST) {
|
||||
if (viewRoot.mSurface.isValid()) {
|
||||
mRtTransaction.deferTransactionUntilSurface(mSurfaceControl, viewRoot.mSurface,
|
||||
frameNumber);
|
||||
}
|
||||
}
|
||||
mRtTransaction.hide(mSurfaceControl);
|
||||
t.hide(mSurfaceControl);
|
||||
|
||||
synchronized (mSurfaceControlLock) {
|
||||
if (mRtReleaseSurfaces) {
|
||||
@@ -1206,7 +1222,11 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
mRtHandlingPositionUpdates = false;
|
||||
}
|
||||
|
||||
mRtTransaction.apply();
|
||||
// If we aren't using BLAST, we apply the transaction locally, otherise we let the ViewRoot apply it for us.
|
||||
// If the ViewRoot is null, we behave as if we aren't using BLAST so we need to apply the transaction.
|
||||
if (!useBLAST || viewRoot == null) {
|
||||
mRtTransaction.apply();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1496,4 +1516,19 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
||||
t.setRelativeLayer(mBackgroundControl, viewRoot, Integer.MIN_VALUE);
|
||||
t.setRelativeLayer(mSurfaceControl, viewRoot, mSubLayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Note: Base class method is @UnsupportedAppUsage
|
||||
*/
|
||||
@Override
|
||||
public void invalidate(boolean invalidateCache) {
|
||||
super.invalidate(invalidateCache);
|
||||
if (ViewRootImpl.USE_BLAST_BUFFERQUEUE == false) {
|
||||
return;
|
||||
}
|
||||
final ViewRootImpl viewRoot = getViewRootImpl();
|
||||
if (viewRoot == null) return;
|
||||
viewRoot.setUseBLASTSyncTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +191,10 @@ public final class ViewRootImpl implements ViewParent,
|
||||
*/
|
||||
private static final boolean MT_RENDERER_AVAILABLE = true;
|
||||
|
||||
private static final boolean USE_BLAST_BUFFERQUEUE = false;
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static final boolean USE_BLAST_BUFFERQUEUE = false;
|
||||
|
||||
/**
|
||||
* If set to 2, the view system will switch from using rectangles retrieved from window to
|
||||
@@ -632,6 +635,12 @@ public final class ViewRootImpl implements ViewParent,
|
||||
int localChanges;
|
||||
}
|
||||
|
||||
private boolean mNextDrawUseBLASTSyncTransaction;
|
||||
// Be very careful with the threading here. This is used from the render thread while
|
||||
// the UI thread is paused and then applied and cleared from the UI thread right after
|
||||
// draw returns.
|
||||
private SurfaceControl.Transaction mRtBLASTSyncTransaction = new SurfaceControl.Transaction();
|
||||
|
||||
private String mTag = TAG;
|
||||
public ViewRootImpl(Context context, Display display) {
|
||||
this(context, display, WindowManagerGlobal.getWindowSession());
|
||||
@@ -3604,6 +3613,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
final Handler handler = mAttachInfo.mHandler;
|
||||
mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) ->
|
||||
handler.postAtFrontOfQueue(() -> {
|
||||
finishBLASTSync();
|
||||
// TODO: Use the frame number
|
||||
pendingDrawFinished();
|
||||
if (commitCallbacks != null) {
|
||||
@@ -3616,6 +3626,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
final Handler handler = mAttachInfo.mHandler;
|
||||
mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) ->
|
||||
handler.postAtFrontOfQueue(() -> {
|
||||
finishBLASTSync();
|
||||
for (int i = 0; i < commitCallbacks.size(); i++) {
|
||||
commitCallbacks.get(i).run();
|
||||
}
|
||||
@@ -3624,10 +3635,14 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
|
||||
try {
|
||||
if (mNextDrawUseBLASTSyncTransaction) {
|
||||
mBlastBufferQueue.setNextTransaction(mRtBLASTSyncTransaction);
|
||||
}
|
||||
boolean canUseAsync = draw(fullRedrawNeeded);
|
||||
if (usingAsyncReport && !canUseAsync) {
|
||||
mAttachInfo.mThreadedRenderer.setFrameCompleteCallback(null);
|
||||
usingAsyncReport = false;
|
||||
finishBLASTSync();
|
||||
}
|
||||
} finally {
|
||||
mIsDrawing = false;
|
||||
@@ -9421,4 +9436,19 @@ public final class ViewRootImpl implements ViewParent,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void setUseBLASTSyncTransaction() {
|
||||
mNextDrawUseBLASTSyncTransaction = true;
|
||||
}
|
||||
|
||||
private void finishBLASTSync() {
|
||||
if (mNextDrawUseBLASTSyncTransaction) {
|
||||
mNextDrawUseBLASTSyncTransaction = false;
|
||||
mRtBLASTSyncTransaction.apply();
|
||||
}
|
||||
}
|
||||
|
||||
SurfaceControl.Transaction getBLASTSyncTransaction() {
|
||||
return mRtBLASTSyncTransaction;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user