diff options
Diffstat (limited to 'core/java/android/view/ViewRootImpl.java')
| -rw-r--r-- | core/java/android/view/ViewRootImpl.java | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 844403298cc9..66b109df5d74 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -195,6 +195,7 @@ import android.view.contentcapture.MainContentCaptureSession; import android.view.inputmethod.InputMethodManager; import android.widget.Scroller; import android.window.ClientWindowFrames; +import android.window.SurfaceSyncer; import android.window.WindowOnBackInvokedDispatcher; import com.android.internal.R; @@ -10880,4 +10881,71 @@ public final class ViewRootImpl implements ViewParent, IWindowSession getWindowSession() { return mWindowSession; } + + private void registerCallbacksForSync( + final SurfaceSyncer.SyncBufferCallback syncBufferCallback) { + if (!isHardwareEnabled()) { + // TODO: correctly handle when hardware disabled + syncBufferCallback.onBufferReady(null); + return; + } + + mAttachInfo.mThreadedRenderer.registerRtFrameCallback(new FrameDrawingCallback() { + @Override + public void onFrameDraw(long frame) { + } + + @Override + public HardwareRenderer.FrameCommitCallback onFrameDraw(int syncResult, long frame) { + if (DEBUG_BLAST) { + Log.d(mTag, + "Received frameDrawingCallback syncResult=" + syncResult + " frameNum=" + + frame + "."); + } + + final Transaction t = new Transaction(); + + // If the syncResults are SYNC_LOST_SURFACE_REWARD_IF_FOUND or + // SYNC_CONTEXT_IS_STOPPED it means nothing will draw. There's no need to set up + // any blast sync or commit callback, and the code should directly call + // pendingDrawFinished. + if ((syncResult + & (SYNC_LOST_SURFACE_REWARD_IF_FOUND | SYNC_CONTEXT_IS_STOPPED)) != 0) { + t.merge(mBlastBufferQueue.gatherPendingTransactions(frame)); + syncBufferCallback.onBufferReady(t); + return null; + } + + mBlastBufferQueue.setSyncTransaction(t); + if (DEBUG_BLAST) { + Log.d(mTag, "Setting up sync and frameCommitCallback"); + } + + return didProduceBuffer -> { + if (DEBUG_BLAST) { + Log.d(mTag, "Received frameCommittedCallback" + + " lastAttemptedDrawFrameNum=" + frame + + " didProduceBuffer=" + didProduceBuffer); + } + + // If frame wasn't drawn, clear out the next transaction so it doesn't affect + // the next draw attempt. The next transaction and transaction complete callback + // were only set for the current draw attempt. + if (!didProduceBuffer) { + mBlastBufferQueue.setSyncTransaction(null); + // Gather the transactions that were sent to mergeWithNextTransaction + // since the frame didn't draw on this vsync. It's possible the frame will + // draw later, but it's better to not be sync than to block on a frame that + // may never come. + t.merge(mBlastBufferQueue.gatherPendingTransactions(frame)); + } + + syncBufferCallback.onBufferReady(t); + }; + } + }); + } + + public final SurfaceSyncer.SyncTarget mSyncTarget = + syncBufferCallback -> registerCallbacksForSync(syncBufferCallback); } |
