summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorchaviw <chaviw@google.com>2021-11-01 18:29:29 -0500
committerChavi Weingarten <chaviw@google.com>2021-12-01 17:17:55 +0000
commit1602deb6741aeaac37ba4fba5c6efe5949580782 (patch)
tree901906d5a5f55f19b726face7678a872d4ae06a1 /core/java
parenta1749585d37a50ddd49443d0a39d3b3bb08509d3 (diff)
Synchronize SV buffers with main window when config changes
When the main window gets a configuration change, the new buffer for the SV will get applied in the same transaction as the main window. This will allow apps to implement seamless rotation without a frame or more of black where the SV was resized, but the buffer was not yet updated. This also includes an optimization where if only SV change occurs, but there was no request from WMS to report drawing, VRI can apply the transaction immediately without reporting to WMS. Test: SV with seamless rotation enabled Bug: 200284684 Change-Id: I5569d815eef92acf3bf9d7f753bd5ab94a332cfe
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/view/SurfaceView.java25
-rw-r--r--core/java/android/view/ViewRootImpl.java44
2 files changed, 59 insertions, 10 deletions
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 1ddb043153ab..ba436e16288e 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -228,6 +228,11 @@ 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
@@ -496,7 +501,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
}
- private void performDrawFinished() {
+ private void performDrawFinished(Transaction t) {
+ mSyncTransaction.merge(t);
if (mDeferredDestroySurfaceControl != null) {
synchronized (mSurfaceControlLock) {
mTmpTransaction.remove(mDeferredDestroySurfaceControl).apply();
@@ -521,7 +527,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
void notifyDrawFinished() {
ViewRootImpl viewRoot = getViewRootImpl();
if (viewRoot != null) {
- viewRoot.pendingDrawFinished();
+ viewRoot.pendingDrawFinished(mSyncTransaction);
}
mPendingReportDraws--;
}
@@ -1202,10 +1208,17 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
callbacks = getSurfaceCallbacks();
}
+ final Transaction t = new Transaction();
+ if (viewRoot.wasRelayoutRequested()) {
+ mBlastBufferQueue.setSyncTransaction(t,
+ false /* acquireSingleBuffer */);
+ }
mPendingReportDraws++;
viewRoot.drawPending();
- SurfaceCallbackHelper sch =
- new SurfaceCallbackHelper(this::onDrawFinished);
+ SurfaceCallbackHelper sch = new SurfaceCallbackHelper(() -> {
+ mBlastBufferQueue.setSyncTransaction(null);
+ onDrawFinished(t);
+ });
sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
}
}
@@ -1367,13 +1380,13 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mSurfaceHeight, mFormat);
}
- private void onDrawFinished() {
+ private void onDrawFinished(Transaction t) {
if (DEBUG) {
Log.i(TAG, System.identityHashCode(this) + " "
+ "finishedDrawing");
}
- runOnUiThread(this::performDrawFinished);
+ runOnUiThread(() -> performDrawFinished(t));
}
/**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 0c30cbb3e149..3fc7ee380055 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -532,6 +532,11 @@ public final class ViewRootImpl implements ViewParent,
boolean mPerformContentCapture;
boolean mReportNextDraw;
+ /**
+ * Set if the reportDraw was requested from WM. If just a local report draw was invoked, there's
+ * no need to report back to system server and can just apply immediately on the client.
+ */
+ boolean mReportDrawToWm;
boolean mFullRedrawNeeded;
boolean mNewSurfaceNeeded;
boolean mForceNextWindowRelayout;
@@ -754,6 +759,8 @@ public final class ViewRootImpl implements ViewParent,
*/
private int mSurfaceSequenceId = 0;
+ private boolean mRelayoutRequested;
+
private String mTag = TAG;
public ViewRootImpl(Context context, Display display) {
@@ -3311,6 +3318,7 @@ public final class ViewRootImpl implements ViewParent,
}
mIsInTraversal = false;
+ mRelayoutRequested = false;
}
private void notifyContentCatpureEvents() {
@@ -3941,10 +3949,18 @@ public final class ViewRootImpl implements ViewParent,
mDrawsNeededToReport++;
}
- void pendingDrawFinished() {
+ void pendingDrawFinished(Transaction t) {
if (mDrawsNeededToReport == 0) {
throw new RuntimeException("Unbalanced drawPending/pendingDrawFinished calls");
}
+
+ if (t != null) {
+ if (DEBUG_BLAST) {
+ Log.d(mTag, "Merging transaction into main window transaction");
+ }
+ mSurfaceChangedTransaction.merge(t);
+ }
+
mDrawsNeededToReport--;
if (mDrawsNeededToReport == 0) {
reportDrawFinished();
@@ -3954,17 +3970,31 @@ public final class ViewRootImpl implements ViewParent,
}
}
+ void pendingDrawFinished() {
+ pendingDrawFinished(null);
+ }
+
private void postDrawFinished() {
mHandler.sendEmptyMessage(MSG_DRAW_FINISHED);
}
private void reportDrawFinished() {
- try {
+ if (DEBUG_BLAST) {
+ Log.d(mTag, "reportDrawFinished");
+ }
+ mDrawsNeededToReport = 0;
+
+ if (!mReportDrawToWm) {
if (DEBUG_BLAST) {
- Log.d(mTag, "reportDrawFinished");
+ Log.d(mTag, "No need to report finishDrawing. Apply immediately");
}
- mDrawsNeededToReport = 0;
+ mSurfaceChangedTransaction.apply();
+ return;
+ }
+
+ try {
mWindowSession.finishDrawing(mWindow, mSurfaceChangedTransaction);
+ mReportDrawToWm = false;
} catch (RemoteException e) {
Log.e(mTag, "Unable to report draw finished", e);
mSurfaceChangedTransaction.apply();
@@ -7756,6 +7786,7 @@ public final class ViewRootImpl implements ViewParent,
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
+ mRelayoutRequested = true;
float appScale = mAttachInfo.mApplicationScale;
boolean restore = false;
if (params != null && mTranslator != null) {
@@ -9573,6 +9604,7 @@ public final class ViewRootImpl implements ViewParent,
if (mReportNextDraw == false) {
drawPending();
}
+ mReportDrawToWm = true;
mReportNextDraw = true;
}
@@ -10501,4 +10533,8 @@ public final class ViewRootImpl implements ViewParent,
mBLASTDrawConsumer = consume;
return true;
}
+
+ boolean wasRelayoutRequested() {
+ return mRelayoutRequested;
+ }
}