Merge "Remove consumeNextDraw and replace with SurfaceSyncer" into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
381743d2ee
@@ -228,7 +228,6 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* The top of a view hierarchy, implementing the needed protocol between View
|
||||
@@ -827,8 +826,6 @@ public final class ViewRootImpl implements ViewParent,
|
||||
*/
|
||||
private long mRtLastAttemptedDrawFrameNum = 0;
|
||||
|
||||
private Consumer<SurfaceControl.Transaction> mBLASTDrawConsumer;
|
||||
|
||||
private HashSet<ScrollCaptureCallback> mRootScrollCaptureCallbacks;
|
||||
|
||||
private long mScrollCaptureRequestTimeout = SCROLL_CAPTURE_REQUEST_TIMEOUT_MILLIS;
|
||||
@@ -3492,35 +3489,23 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
|
||||
private void createSyncIfNeeded() {
|
||||
// Started a sync already.
|
||||
if (mLastSyncId != -1) {
|
||||
// Started a sync already or there's nothing needing to sync
|
||||
if (mLastSyncId != -1 || !mReportNextDraw) {
|
||||
return;
|
||||
}
|
||||
|
||||
Consumer<Transaction> syncConsumer = null;
|
||||
final int seqId = mSyncSeqId;
|
||||
|
||||
if (mBLASTDrawConsumer != null) {
|
||||
syncConsumer = mBLASTDrawConsumer;
|
||||
mBLASTDrawConsumer = null;
|
||||
} else if (mReportNextDraw) {
|
||||
syncConsumer = transaction -> {
|
||||
mLastSyncId = mSurfaceSyncer.setupSync(transaction -> {
|
||||
// Callback will be invoked on executor thread so post to main thread.
|
||||
mHandler.postAtFrontOfQueue(() -> {
|
||||
mSurfaceChangedTransaction.merge(transaction);
|
||||
reportDrawFinished(seqId);
|
||||
};
|
||||
}
|
||||
|
||||
if (syncConsumer != null) {
|
||||
final Consumer<Transaction> capturedSyncConsumer = syncConsumer;
|
||||
mLastSyncId = mSurfaceSyncer.setupSync(transaction -> {
|
||||
// Callback will be invoked on executor thread so post to main thread.
|
||||
mHandler.postAtFrontOfQueue(() -> capturedSyncConsumer.accept(transaction));
|
||||
});
|
||||
if (DEBUG_BLAST) {
|
||||
Log.d(mTag, "Setup new sync id=" + mLastSyncId);
|
||||
}
|
||||
mSurfaceSyncer.addToSync(mLastSyncId, mSyncTarget);
|
||||
});
|
||||
if (DEBUG_BLAST) {
|
||||
Log.d(mTag, "Setup new sync id=" + mLastSyncId);
|
||||
}
|
||||
mSurfaceSyncer.addToSync(mLastSyncId, mSyncTarget);
|
||||
}
|
||||
|
||||
private void notifyContentCatpureEvents() {
|
||||
@@ -10774,37 +10759,6 @@ public final class ViewRootImpl implements ViewParent,
|
||||
showControl, transformationApplied, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect the next draw of this ViewRoot (from the UI thread perspective)
|
||||
* to the passed in consumer. This can be used to create P2P synchronization
|
||||
* between ViewRoot's however it comes with many caveats.
|
||||
*
|
||||
* 1. You MUST consume the transaction, by either applying it immediately or
|
||||
* merging it in to another transaction. The threading model doesn't
|
||||
* allow you to hold in the passed transaction.
|
||||
* 2. If you merge it in to another transaction, this ViewRootImpl will be
|
||||
* paused until you finally apply that transaction and it receives
|
||||
* the callback from SF. If you lose track of the transaction you will
|
||||
* ANR the app.
|
||||
* 3. Only one person can consume the transaction at a time, if you already
|
||||
* have a pending consumer for this frame, the function will return false
|
||||
* 4. Someone else may have requested to consume the next frame, in which case
|
||||
* this function will return false and you will not receive a callback.
|
||||
* 5. This function does not trigger drawing so even if it returns true you
|
||||
* may not receive a callback unless there is some other UI thread work
|
||||
* to trigger drawing. If it returns true, and a draw occurs, the callback
|
||||
* will be called (Though again watch out for the null transaction case!)
|
||||
* 6. This function must be called on the UI thread. The consumer will likewise
|
||||
* be called on the UI thread.
|
||||
*/
|
||||
public boolean consumeNextDraw(Consumer<SurfaceControl.Transaction> consume) {
|
||||
if (mBLASTDrawConsumer != null) {
|
||||
return false;
|
||||
}
|
||||
mBLASTDrawConsumer = consume;
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean wasRelayoutRequested() {
|
||||
return mRelayoutRequested;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package com.android.systemui.animation
|
||||
|
||||
import android.app.ActivityManager
|
||||
import android.view.SurfaceControl
|
||||
import android.view.View
|
||||
import android.view.ViewRootImpl
|
||||
import android.window.SurfaceSyncer
|
||||
|
||||
/** A util class to synchronize 2 view roots. */
|
||||
// TODO(b/200284684): Remove this class.
|
||||
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
|
||||
|
||||
/**
|
||||
* Synchronize the next draw between the view roots of [view] and [otherView], then run [then].
|
||||
@@ -33,35 +33,11 @@ object ViewRootSync {
|
||||
return
|
||||
}
|
||||
|
||||
// Consume the next frames of both view roots to make sure the ghost view is drawn at
|
||||
// exactly the same time as when the touch surface is made invisible.
|
||||
var remainingTransactions = 0
|
||||
val mergedTransactions = SurfaceControl.Transaction()
|
||||
|
||||
fun onTransaction(transaction: SurfaceControl.Transaction?) {
|
||||
remainingTransactions--
|
||||
transaction?.let { mergedTransactions.merge(it) }
|
||||
|
||||
if (remainingTransactions == 0) {
|
||||
mergedTransactions.apply()
|
||||
then()
|
||||
}
|
||||
}
|
||||
|
||||
fun consumeNextDraw(viewRootImpl: ViewRootImpl) {
|
||||
if (viewRootImpl.consumeNextDraw(::onTransaction)) {
|
||||
remainingTransactions++
|
||||
|
||||
// Make sure we trigger a traversal.
|
||||
viewRootImpl.view.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
consumeNextDraw(view.viewRootImpl)
|
||||
consumeNextDraw(otherView.viewRootImpl)
|
||||
|
||||
if (remainingTransactions == 0) {
|
||||
then()
|
||||
surfaceSyncer = SurfaceSyncer().apply {
|
||||
val syncId = setupSync(Runnable { then() })
|
||||
addToSync(syncId, view)
|
||||
addToSync(syncId, otherView)
|
||||
markSyncReady(syncId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user