Clean up buffer sync logic in SurfaceView.

The current code is a bit confuisng to read so cleaned up the code that
handles syncing a buffer when a VRI relayout request creates a sync.

Test: YT, Camera, Chrome
Bug: 200284684
Change-Id: I243ee5ebcb59c478c48461544813cab43a2678d4
This commit is contained in:
chaviw
2022-03-24 16:15:38 -05:00
parent 4c07041a1b
commit 481ccbaedf

View File

@@ -966,13 +966,16 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
final boolean redrawNeeded = sizeChanged || creating || hintChanged
|| (mVisible && !mDrawFinished);
final TransactionCallback transactionCallback =
redrawNeeded ? new TransactionCallback() : null;
if (redrawNeeded && viewRoot.wasRelayoutRequested() && viewRoot.isInSync()) {
boolean shouldSyncBuffer =
redrawNeeded && viewRoot.wasRelayoutRequested() && viewRoot.isInSync();
SyncBufferTransactionCallback syncBufferTransactionCallback = null;
if (shouldSyncBuffer) {
syncBufferTransactionCallback = new SyncBufferTransactionCallback();
mBlastBufferQueue.syncNextTransaction(
false /* acquireSingleBuffer */,
transactionCallback::onTransactionReady);
syncBufferTransactionCallback::onTransactionReady);
}
final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
translator, creating, sizeChanged, hintChanged, surfaceUpdateTransaction);
@@ -1011,7 +1014,18 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
}
if (redrawNeeded) {
redrawNeeded(callbacks, transactionCallback);
if (DEBUG) {
Log.i(TAG, System.identityHashCode(this) + " surfaceRedrawNeeded");
}
if (callbacks == null) {
callbacks = getSurfaceCallbacks();
}
if (shouldSyncBuffer) {
handleSyncBufferCallback(callbacks, syncBufferTransactionCallback);
} else {
redrawNeededAsync(callbacks, this::onDrawFinished);
}
}
}
} finally {
@@ -1030,38 +1044,30 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
}
private void redrawNeeded(SurfaceHolder.Callback[] callbacks,
@Nullable TransactionCallback transactionCallback) {
if (DEBUG) {
Log.i(TAG, System.identityHashCode(this) + " surfaceRedrawNeeded");
}
final SurfaceHolder.Callback[] capturedCallbacks =
callbacks == null ? getSurfaceCallbacks() : callbacks;
/**
* If SV is trying to be part of the VRI sync, we need to add SV to the VRI sync before
* invoking the redrawNeeded call to the owner. This is to ensure we can set up the SV in
* the sync before the SV owner knows it needs to draw a new frame.
* Once the redrawNeeded callback is invoked, we can stop the continuous sync transaction
* call which will invoke the syncTransaction callback that contains the buffer. The
* code waits until we can retrieve the transaction that contains the buffer before
* notifying the syncer that the buffer is ready.
*/
private void handleSyncBufferCallback(SurfaceHolder.Callback[] callbacks,
SyncBufferTransactionCallback syncBufferTransactionCallback) {
ViewRootImpl viewRoot = getViewRootImpl();
boolean isVriSync = viewRoot.addToSync(syncBufferCallback ->
redrawNeededAsync(capturedCallbacks, () -> {
getViewRootImpl().addToSync(syncBufferCallback ->
redrawNeededAsync(callbacks, () -> {
Transaction t = null;
if (mBlastBufferQueue != null) {
mBlastBufferQueue.stopContinuousSyncTransaction();
t = syncBufferTransactionCallback.waitForTransaction();
}
Transaction t = null;
if (transactionCallback != null && mBlastBufferQueue != null) {
t = transactionCallback.waitForTransaction();
}
// If relayout was requested, then a callback from BBQ will
// be invoked with the sync transaction. onDrawFinished will be
// called in there
syncBufferCallback.onBufferReady(t);
onDrawFinished();
}));
// If isVriSync, then everything was setup in the addToSync.
if (isVriSync) {
return;
}
redrawNeededAsync(capturedCallbacks, this::onDrawFinished);
}
private void redrawNeededAsync(SurfaceHolder.Callback[] callbacks,
@@ -1070,7 +1076,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
}
private static class TransactionCallback {
private static class SyncBufferTransactionCallback {
private final CountDownLatch mCountDownLatch = new CountDownLatch(1);
private Transaction mTransaction;