Merge "ViewRootImpl: Add P2P sync primitive"

This commit is contained in:
TreeHugger Robot
2021-11-09 23:33:58 +00:00
committed by Android (Google) Code Review

View File

@@ -211,6 +211,7 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.function.Consumer;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -742,6 +743,8 @@ 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;
@@ -3259,6 +3262,9 @@ public final class ViewRootImpl implements ViewParent,
}
boolean cancelDraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || !isViewVisible;
if (mBLASTDrawConsumer != null) {
useBlastSync = true;
}
if (!cancelDraw) {
if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
@@ -3977,6 +3983,9 @@ public final class ViewRootImpl implements ViewParent,
Log.d(mTag, "Creating frameCompleteCallback");
}
final Consumer<SurfaceControl.Transaction> blastSyncConsumer = mBLASTDrawConsumer;
mBLASTDrawConsumer = null;
mAttachInfo.mThreadedRenderer.setFrameCompleteCallback(() -> {
long frameNr = mBlastBufferQueue.getLastAcquiredFrameNum();
if (DEBUG_BLAST) {
@@ -4002,6 +4011,9 @@ public final class ViewRootImpl implements ViewParent,
mHandler.postAtFrontOfQueue(() -> {
if (useBlastSync) {
mSurfaceChangedTransaction.merge(tmpTransaction);
if (blastSyncConsumer != null) {
blastSyncConsumer.accept(mSurfaceChangedTransaction);
}
}
if (reportNextDraw) {
@@ -10457,4 +10469,35 @@ public final class ViewRootImpl implements ViewParent,
listener.onBufferTransformHintChanged(hint);
}
}
/**
* 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;
}
}