summaryrefslogtreecommitdiff
path: root/core/java/android/view/SurfaceView.java
diff options
context:
space:
mode:
authorchaviw <chaviw@google.com>2022-02-01 10:41:25 -0600
committerRobert Carr <racarr@google.com>2022-03-23 15:25:20 -0700
commit48cda45ffa7d57830f95fed3c8268ef17d2d96bc (patch)
tree6a2991f3017de27e62997f6741c328f7931d15a4 /core/java/android/view/SurfaceView.java
parent5c687a5145f01b2568199e065f8df97ea4045980 (diff)
Replace VRI and SV sync logic with SurfaceSyncer
Instead of using the count to keep track of sync information in VRI, use the SurfaceSyncer to handle this. This also means changing SV since SV would also increment the VRI counter. This cleans up the logic since code that's used for the SurfaceSyncer can be re-used in VRI. Test: seamless rotation, launching apps Bug: 200284684 Fixes: 225776224 Change-Id: Idb505b35eef9f99b2f76e9d1f1b26f5c50ed9a90
Diffstat (limited to 'core/java/android/view/SurfaceView.java')
-rw-r--r--core/java/android/view/SurfaceView.java145
1 files changed, 77 insertions, 68 deletions
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 413855639d09..c04b0964a7a4 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -50,6 +50,7 @@ import android.view.accessibility.IAccessibilityEmbeddedConnection;
import com.android.internal.view.SurfaceCallbackHelper;
import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
@@ -203,8 +204,6 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
private int mSurfaceFlags = SurfaceControl.HIDDEN;
- private int mPendingReportDraws;
-
/**
* Transaction that should be used from the render thread. This transaction is only thread safe
* with other calls directly from the render thread.
@@ -212,11 +211,6 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
private final SurfaceControl.Transaction mRtTransaction = new SurfaceControl.Transaction();
/**
- * Used on the main thread to set the transaction that will be synced with the main window.
- */
- private final Transaction mSyncTransaction = new Transaction();
-
- /**
* Transaction that should be used whe
* {@link HardwareRenderer.FrameDrawingCallback#onFrameDraw} is invoked. All
* frame callbacks can use the same transaction since they will be thread safe
@@ -391,31 +385,12 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
}
- private void performDrawFinished(@Nullable Transaction t) {
- if (t != null) {
- mSyncTransaction.merge(t);
- }
-
- if (mPendingReportDraws > 0) {
- mDrawFinished = true;
- if (mAttachedToWindow) {
- mParent.requestTransparentRegion(SurfaceView.this);
- notifyDrawFinished();
- invalidate();
- }
- } else {
- Log.e(TAG, System.identityHashCode(this) + "finished drawing"
- + " but no pending report draw (extra call"
- + " to draw completion runnable?)");
- }
- }
-
- void notifyDrawFinished() {
- ViewRootImpl viewRoot = getViewRootImpl();
- if (viewRoot != null) {
- viewRoot.pendingDrawFinished(mSyncTransaction);
+ private void performDrawFinished() {
+ mDrawFinished = true;
+ if (mAttachedToWindow) {
+ mParent.requestTransparentRegion(SurfaceView.this);
+ invalidate();
}
- mPendingReportDraws--;
}
@Override
@@ -438,10 +413,6 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mGlobalListenersAdded = false;
}
- while (mPendingReportDraws > 0) {
- notifyDrawFinished();
- }
-
mRequestedVisible = false;
updateSurface();
@@ -993,10 +964,17 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
return;
}
- final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
- translator, creating, sizeChanged, hintChanged, surfaceUpdateTransaction);
final boolean redrawNeeded = sizeChanged || creating || hintChanged
|| (mVisible && !mDrawFinished);
+ final TransactionCallback transactionCallback =
+ redrawNeeded ? new TransactionCallback() : null;
+ if (redrawNeeded && viewRoot.wasRelayoutRequested() && viewRoot.isInSync()) {
+ mBlastBufferQueue.syncNextTransaction(
+ false /* acquireSingleBuffer */,
+ transactionCallback::onTransactionReady);
+ }
+ final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
+ translator, creating, sizeChanged, hintChanged, surfaceUpdateTransaction);
try {
SurfaceHolder.Callback[] callbacks = null;
@@ -1015,9 +993,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mIsCreating = true;
if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
+ "visibleChanged -- surfaceCreated");
- if (callbacks == null) {
- callbacks = getSurfaceCallbacks();
- }
+ callbacks = getSurfaceCallbacks();
for (SurfaceHolder.Callback c : callbacks) {
c.surfaceCreated(mSurfaceHolder);
}
@@ -1035,32 +1011,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
}
if (redrawNeeded) {
- if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
- + "surfaceRedrawNeeded");
- if (callbacks == null) {
- callbacks = getSurfaceCallbacks();
- }
-
- final boolean wasRelayoutRequested = viewRoot.wasRelayoutRequested();
- if (wasRelayoutRequested && (mBlastBufferQueue != null)) {
- mBlastBufferQueue.syncNextTransaction(
- false /* acquireSingleBuffer */,
- this::onDrawFinished);
- }
- mPendingReportDraws++;
- viewRoot.drawPending();
- SurfaceCallbackHelper sch = new SurfaceCallbackHelper(() -> {
- if (mBlastBufferQueue != null) {
- mBlastBufferQueue.stopContinuousSyncTransaction();
- }
- // If relayout was requested, then a callback from BBQ will
- // be invoked with the sync transaction. onDrawFinished will be
- // called in there
- if (!wasRelayoutRequested) {
- onDrawFinished(null);
- }
- });
- sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
+ redrawNeeded(callbacks, transactionCallback);
}
}
} finally {
@@ -1079,6 +1030,64 @@ 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;
+
+ ViewRootImpl viewRoot = getViewRootImpl();
+ boolean isVriSync = viewRoot.addToSync(syncBufferCallback ->
+ redrawNeededAsync(capturedCallbacks, () -> {
+ if (mBlastBufferQueue != null) {
+ mBlastBufferQueue.stopContinuousSyncTransaction();
+ }
+
+ 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,
+ Runnable callbacksCollected) {
+ SurfaceCallbackHelper sch = new SurfaceCallbackHelper(callbacksCollected);
+ sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
+ }
+
+ private static class TransactionCallback {
+ private final CountDownLatch mCountDownLatch = new CountDownLatch(1);
+ private Transaction mTransaction;
+
+ Transaction waitForTransaction() {
+ try {
+ mCountDownLatch.await();
+ } catch (InterruptedException e) {
+ }
+ return mTransaction;
+ }
+
+ void onTransactionReady(Transaction t) {
+ mTransaction = t;
+ mCountDownLatch.countDown();
+ }
+ }
+
/**
* Copy the Surface from the SurfaceControl or the blast adapter.
*
@@ -1189,13 +1198,13 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat);
}
- private void onDrawFinished(@Nullable Transaction t) {
+ private void onDrawFinished() {
if (DEBUG) {
Log.i(TAG, System.identityHashCode(this) + " "
+ "finishedDrawing");
}
- runOnUiThread(() -> performDrawFinished(t));
+ runOnUiThread(this::performDrawFinished);
}
/**