Merge "Clean up buffer sync logic in SurfaceView." into tm-dev

This commit is contained in:
Chavi Weingarten
2022-04-01 18:17:25 +00:00
committed by Android (Google) Code Review

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;