summaryrefslogtreecommitdiff
path: root/core/java/android/view/SurfaceView.java
diff options
context:
space:
mode:
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);
}
/**