summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vishnu Nair <vishnun@google.com> 2024-10-14 23:33:10 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-10-14 23:33:10 +0000
commit34daf84e313ed11259dfc341fa6c94b7bd1f1d34 (patch)
tree0fb387b5e912ea8b64dc9d9f6b1bb0d658d61ad2
parentff50c08826dffbb8223ea72e549d95cb6a91dc64 (diff)
parent89f28270932c1c42c42706285e99bb30e28ae4b6 (diff)
Merge "Fix ViewRootImpl traversal issue after SurfaceSyncGroup timeout" into main
-rw-r--r--core/java/android/view/ViewRootImpl.java41
-rw-r--r--core/java/android/window/SurfaceSyncGroup.java10
2 files changed, 43 insertions, 8 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index b921213cc26c..3be9a821a463 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -6971,9 +6971,7 @@ public final class ViewRootImpl implements ViewParent,
handleScrollCaptureRequest((IScrollCaptureResponseListener) msg.obj);
break;
case MSG_PAUSED_FOR_SYNC_TIMEOUT:
- Log.e(mTag, "Timedout waiting to unpause for sync");
- mNumPausedForSync = 0;
- scheduleTraversals();
+ resumeAfterSyncTimeout();
break;
case MSG_CHECK_INVALIDATION_IDLE: {
long delta;
@@ -12777,6 +12775,15 @@ public final class ViewRootImpl implements ViewParent,
activeSurfaceSyncGroup.addTransaction(t);
}
+ /**
+ * Resume rendering after being paused for sync due to a timeout.
+ */
+ private void resumeAfterSyncTimeout() {
+ Log.e(mTag, "Timedout waiting to unpause for sync mNumPausedForSync=" + mNumPausedForSync);
+ mNumPausedForSync = 0;
+ scheduleTraversals();
+ }
+
@Override
public SurfaceSyncGroup getOrCreateSurfaceSyncGroup() {
boolean newSyncGroup = false;
@@ -12804,6 +12811,16 @@ public final class ViewRootImpl implements ViewParent,
}
});
newSyncGroup = true;
+
+ // If the sync group is marked ready by a timeout, check if rendering is paused and
+ // if it is, resume rendering and trigger a traversal.
+ mActiveSurfaceSyncGroup.addSyncCompleteCallback(mExecutor, () -> {
+ if (mActiveSurfaceSyncGroup != null
+ && mActiveSurfaceSyncGroup.isComplete() && mNumPausedForSync > 0) {
+ mHandler.removeMessages(MSG_PAUSED_FOR_SYNC_TIMEOUT);
+ resumeAfterSyncTimeout();
+ }
+ });
}
Trace.instant(Trace.TRACE_TAG_VIEW,
@@ -12818,12 +12835,20 @@ public final class ViewRootImpl implements ViewParent,
}
}
- mNumPausedForSync++;
- mHandler.removeMessages(MSG_PAUSED_FOR_SYNC_TIMEOUT);
- mHandler.sendEmptyMessageDelayed(MSG_PAUSED_FOR_SYNC_TIMEOUT,
- 1000 * Build.HW_TIMEOUT_MULTIPLIER);
+ // The sync group can be marked ready by a timeout. This makes incrementing
+ // mNumPausedForSync racy. Here we check if the sync group is complete and
+ // if it is then we don't pause for syncing.
+ if (!mActiveSurfaceSyncGroup.isComplete()) {
+ mNumPausedForSync++;
+ mHandler.removeMessages(MSG_PAUSED_FOR_SYNC_TIMEOUT);
+ mHandler.sendEmptyMessageDelayed(MSG_PAUSED_FOR_SYNC_TIMEOUT,
+ 1000 * Build.HW_TIMEOUT_MULTIPLIER);
+ } else {
+ Log.d(mTag, "Active sync group is already completed "
+ + mActiveSurfaceSyncGroup.getName());
+ }
return mActiveSurfaceSyncGroup;
- };
+ }
private final Executor mSimpleExecutor = Runnable::run;
diff --git a/core/java/android/window/SurfaceSyncGroup.java b/core/java/android/window/SurfaceSyncGroup.java
index 5d14698c82b3..a68bdc05e20e 100644
--- a/core/java/android/window/SurfaceSyncGroup.java
+++ b/core/java/android/window/SurfaceSyncGroup.java
@@ -839,6 +839,16 @@ public final class SurfaceSyncGroup {
}
/**
+ * Returns true if the SurfaceSyncGroup has completed its sync.
+ * @hide
+ */
+ public boolean isComplete() {
+ synchronized (mLock) {
+ return mFinished;
+ }
+ }
+
+ /**
* A frame callback that is used to synchronize SurfaceViews. The owner of the SurfaceView must
* implement onFrameStarted when trying to sync the SurfaceView. This is to ensure the sync
* knows when the frame is ready to add to the sync.