[automerge] Force draw during a blast sync and disable rt animations 2p: 7b7dabc218

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17390711

Bug: 200284684
Change-Id: Iafaeb33579f46ec47bdf40f550f09cb71c17b982
This commit is contained in:
chaviw
2022-03-28 23:58:25 +00:00
committed by Presubmit Automerger Backend
3 changed files with 54 additions and 18 deletions

View File

@@ -817,12 +817,7 @@ public final class ViewRootImpl implements ViewParent,
private final SurfaceSyncer mSurfaceSyncer = new SurfaceSyncer(); private final SurfaceSyncer mSurfaceSyncer = new SurfaceSyncer();
private int mLastSyncId = -1; private int mLastSyncId = -1;
private SurfaceSyncer.SyncBufferCallback mSyncBufferCallback; private SurfaceSyncer.SyncBufferCallback mSyncBufferCallback;
private int mNumSyncsInProgress = 0;
/**
* Keeps track of the last frame number that was attempted to draw. Should only be accessed on
* the RenderThread.
*/
private long mRtLastAttemptedDrawFrameNum = 0;
private HashSet<ScrollCaptureCallback> mRootScrollCaptureCallbacks; private HashSet<ScrollCaptureCallback> mRootScrollCaptureCallbacks;
@@ -4250,7 +4245,7 @@ public final class ViewRootImpl implements ViewParent,
mHasPendingTransactions = false; mHasPendingTransactions = false;
try { try {
boolean canUseAsync = draw(fullRedrawNeeded); boolean canUseAsync = draw(fullRedrawNeeded, usingAsyncReport && mSyncBuffer);
if (usingAsyncReport && !canUseAsync) { if (usingAsyncReport && !canUseAsync) {
mAttachInfo.mThreadedRenderer.setFrameCallback(null); mAttachInfo.mThreadedRenderer.setFrameCallback(null);
usingAsyncReport = false; usingAsyncReport = false;
@@ -4410,7 +4405,7 @@ public final class ViewRootImpl implements ViewParent,
} }
} }
private boolean draw(boolean fullRedrawNeeded) { private boolean draw(boolean fullRedrawNeeded, boolean forceDraw) {
Surface surface = mSurface; Surface surface = mSurface;
if (!surface.isValid()) { if (!surface.isValid()) {
return false; return false;
@@ -4547,6 +4542,9 @@ public final class ViewRootImpl implements ViewParent,
useAsyncReport = true; useAsyncReport = true;
if (forceDraw) {
mAttachInfo.mThreadedRenderer.forceDrawNextFrame();
}
mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this); mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);
} else { } else {
// If we get here with a disabled & requested hardware renderer, something went // If we get here with a disabled & requested hardware renderer, something went
@@ -10870,9 +10868,28 @@ public final class ViewRootImpl implements ViewParent,
}); });
} }
public final SurfaceSyncer.SyncTarget mSyncTarget = this::readyToSync; public final SurfaceSyncer.SyncTarget mSyncTarget = new SurfaceSyncer.SyncTarget() {
@Override
public void onReadyToSync(SurfaceSyncer.SyncBufferCallback syncBufferCallback) {
readyToSync(syncBufferCallback);
}
@Override
public void onSyncComplete() {
mHandler.postAtFrontOfQueue(() -> {
if (--mNumSyncsInProgress == 0 && mAttachInfo.mThreadedRenderer != null) {
HardwareRenderer.setRtAnimationsEnabled(true);
}
});
}
};
private void readyToSync(SurfaceSyncer.SyncBufferCallback syncBufferCallback) { private void readyToSync(SurfaceSyncer.SyncBufferCallback syncBufferCallback) {
mNumSyncsInProgress++;
if (mAttachInfo.mThreadedRenderer != null) {
HardwareRenderer.setRtAnimationsEnabled(false);
}
if (mSyncBufferCallback != null) { if (mSyncBufferCallback != null) {
Log.d(mTag, "Already set sync for the next draw."); Log.d(mTag, "Already set sync for the next draw.");
mSyncBufferCallback.onBufferReady(null); mSyncBufferCallback.onBufferReady(null);

View File

@@ -21,15 +21,16 @@ import android.annotation.Nullable;
import android.annotation.UiThread; import android.annotation.UiThread;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.ArraySet;
import android.util.Log; import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.SurfaceControl.Transaction; import android.view.SurfaceControl.Transaction;
import android.view.SurfaceView; import android.view.SurfaceView;
import android.view.View; import android.view.View;
import android.view.ViewRootImpl;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
@@ -99,7 +100,9 @@ public class SurfaceSyncer {
Handler handler = new Handler(Looper.myLooper()); Handler handler = new Handler(Looper.myLooper());
return setupSync(transaction -> { return setupSync(transaction -> {
transaction.apply(); transaction.apply();
handler.post(onComplete); if (onComplete != null) {
handler.post(onComplete);
}
}); });
} }
@@ -171,7 +174,11 @@ public class SurfaceSyncer {
*/ */
@UiThread @UiThread
public boolean addToSync(int syncId, @NonNull View view) { public boolean addToSync(int syncId, @NonNull View view) {
return addToSync(syncId, view.getViewRootImpl().mSyncTarget); ViewRootImpl viewRoot = view.getViewRootImpl();
if (viewRoot == null) {
return false;
}
return addToSync(syncId, viewRoot.mSyncTarget);
} }
/** /**
@@ -232,9 +239,17 @@ public class SurfaceSyncer {
* and {@link SyncBufferCallback#onBufferReady(Transaction)} in order for this Syncable * and {@link SyncBufferCallback#onBufferReady(Transaction)} in order for this Syncable
* to be marked as complete. * to be marked as complete.
* *
* Always invoked on the thread that initiated the call to
* {@link #addToSync(int, SyncTarget)}
*
* @param syncBufferCallback A SyncBufferCallback that the caller must invoke onBufferReady * @param syncBufferCallback A SyncBufferCallback that the caller must invoke onBufferReady
*/ */
void onReadyToSync(SyncBufferCallback syncBufferCallback); void onReadyToSync(SyncBufferCallback syncBufferCallback);
/**
* There's no guarantee about the thread this callback is invoked on.
*/
default void onSyncComplete() {}
} }
/** /**
@@ -260,11 +275,13 @@ public class SurfaceSyncer {
private final Object mLock = new Object(); private final Object mLock = new Object();
@GuardedBy("mLock") @GuardedBy("mLock")
private final Set<Integer> mPendingSyncs = new HashSet<>(); private final Set<Integer> mPendingSyncs = new ArraySet<>();
@GuardedBy("mLock") @GuardedBy("mLock")
private final Transaction mTransaction = sTransactionFactory.get(); private final Transaction mTransaction = sTransactionFactory.get();
@GuardedBy("mLock") @GuardedBy("mLock")
private boolean mSyncReady; private boolean mSyncReady;
@GuardedBy("mLock")
private final Set<SyncTarget> mSyncTargets = new ArraySet<>();
private final int mSyncId; private final int mSyncId;
private final Consumer<Transaction> mSyncRequestCompleteCallback; private final Consumer<Transaction> mSyncRequestCompleteCallback;
@@ -290,6 +307,7 @@ public class SurfaceSyncer {
synchronized (mLock) { synchronized (mLock) {
mPendingSyncs.add(syncBufferCallback.hashCode()); mPendingSyncs.add(syncBufferCallback.hashCode());
mSyncTargets.add(syncTarget);
} }
syncTarget.onReadyToSync(syncBufferCallback); syncTarget.onReadyToSync(syncBufferCallback);
} }
@@ -314,6 +332,11 @@ public class SurfaceSyncer {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "Successfully finished sync id=" + mSyncId); Log.d(TAG, "Successfully finished sync id=" + mSyncId);
} }
for (SyncTarget syncTarget : mSyncTargets) {
syncTarget.onSyncComplete();
}
mSyncTargets.clear();
mSyncRequestCompleteCallback.accept(mTransaction); mSyncRequestCompleteCallback.accept(mTransaction);
} }

View File

@@ -1,14 +1,11 @@
package com.android.systemui.animation package com.android.systemui.animation
import android.app.ActivityManager
import android.view.View import android.view.View
import android.window.SurfaceSyncer import android.window.SurfaceSyncer
/** A util class to synchronize 2 view roots. */ /** A util class to synchronize 2 view roots. */
// TODO(b/200284684): Remove this class. // TODO(b/200284684): Remove this class.
object ViewRootSync { object ViewRootSync {
// TODO(b/217621394): Remove special handling for low-RAM devices after animation sync is fixed
private val forceDisableSynchronization = ActivityManager.isLowRamDeviceStatic()
private var surfaceSyncer: SurfaceSyncer? = null private var surfaceSyncer: SurfaceSyncer? = null
/** /**
@@ -23,8 +20,7 @@ object ViewRootSync {
otherView: View, otherView: View,
then: () -> Unit then: () -> Unit
) { ) {
if (forceDisableSynchronization || if (!view.isAttachedToWindow || view.viewRootImpl == null ||
!view.isAttachedToWindow || view.viewRootImpl == null ||
!otherView.isAttachedToWindow || otherView.viewRootImpl == null || !otherView.isAttachedToWindow || otherView.viewRootImpl == null ||
view.viewRootImpl == otherView.viewRootImpl) { view.viewRootImpl == otherView.viewRootImpl) {
// No need to synchronize if either the touch surface or dialog view is not attached // No need to synchronize if either the touch surface or dialog view is not attached