// ....... publicSurfaceSyncGroup(String name, Consumer<Transaction> transactionReadyConsumer) { // sCounter is a way to give the SurfaceSyncGroup a unique name even if the name passed in // is not. // Avoid letting the count get too big so just reset to 0. It's unlikely that we'll have // more than MAX_COUNT active syncs that have overlapping names // 默认counter的最高限制为 100 次 if (sCounter.get() >= MAX_COUNT) { sCounter.set(0); }
// 调用transactionReadyConsumer transactionReadyConsumer.accept(transaction); synchronized (mLock) { // If there's a registered listener with WMS, that means we aren't actually complete // until WMS notifies us that the parent has completed. // 逐一调用 SyncCompleteCallback // mSyncCompleteCallbacks通过 SurfaceSyncGroup.addSyncCompleteCallback添加。 if (mSurfaceSyncGroupCompletedListener == null) { invokeSyncCompleteCallbacks(); } } };
// 创建 Callback public ITransactionReadyCallback createTransactionReadyCallback(boolean parentSyncGroupMerge) { // ...... // 创建ITransactionReadyCallback ITransactionReadyCallbacktransactionReadyCallback= newITransactionReadyCallback.Stub() { @Override publicvoidonTransactionReady(Transaction t) { synchronized (mLock) { if (t != null) { t.sanitize(Binder.getCallingPid(), Binder.getCallingUid()); // When an older parent sync group is added due to a child syncGroup // getting added to multiple groups, we need to maintain merge order // so the older parentSyncGroup transactions are overwritten by // anything in the newer parentSyncGroup. if (parentSyncGroupMerge) { t.merge(mTransaction); } mTransaction.merge(t); } mPendingSyncs.remove(this); // ...... checkIfSyncIsComplete(); } } };
if (syncBuffer) { // 调用 syncNextTransaction 同步下一帧 Transaction。 booleanresult= mBlastBufferQueue.syncNextTransaction(transaction -> { RunnabletimeoutRunnable= () -> Log.e(mTag, "Failed to submit the sync transaction after 4s. Likely to ANR " + "soon"); mHandler.postDelayed(timeoutRunnable, 4000L * Build.HW_TIMEOUT_MULTIPLIER); transaction.addTransactionCommittedListener(mSimpleExecutor, () -> mHandler.removeCallbacks(timeoutRunnable)); surfaceSyncGroup.addTransaction(transaction); surfaceSyncGroup.markSyncReady(); }); if (!result) { // syncNextTransaction can only return false if something is already trying // to sync the same frame in the same BBQ. That shouldn't be possible, but // if it did happen, invoke markSyncReady so the active SSG doesn't get // stuck. // ...... surfaceSyncGroup.markSyncReady(); } }
// View measure操作 performMeasure(...); // View layout操作 performLayout(...); // 判断是否需要拦截绘制逻辑 booleancancelDueToPreDrawListener= mAttachInfo.mTreeObserver.dispatchOnPreDraw(); booleancancelAndRedraw= cancelDueToPreDrawListener || (cancelDraw && mDrewOnceForSync); // 绘制前:开启 Sync if (!cancelAndRedraw) { // A sync was already requested before the WMS requested sync. This means we need to // sync the buffer, regardless if WMS wants to sync the buffer. if (mActiveSurfaceSyncGroup != null) { mSyncBuffer = true; }
// If the active SSG is also requesting to sync a buffer, the following needs to happen // 1. Ensure we keep track of the number of active syncs to know when to disable RT // RT animations that conflict with syncing a buffer. // 2. Add a safeguard SSG to prevent multiple SSG that sync buffers from being submitted // out of order. if (mActiveSurfaceSyncGroup != null && mSyncBuffer) { updateSyncInProgressCount(mActiveSurfaceSyncGroup); safeguardOverlappingSyncs(mActiveSurfaceSyncGroup); } } // View draw 操作 performDraw(...); // 绘制后:关闭 Sync if (!cancelAndRedraw) { mReportNextDraw = false; mLastReportNextDrawReason = null; mActiveSurfaceSyncGroup = null; mHasPendingTransactions = false; mSyncBuffer = false; if (isInWMSRequestedSync()) { mWmsRequestSyncGroup.markSyncReady(); mWmsRequestSyncGroup = null; mWmsRequestSyncGroupState = WMS_SYNC_NONE; } }
// 用于创建 privatevoidcreateSyncIfNeeded() { // WMS requested sync already started or there's nothing needing to sync // 如果已经创建了 WMS or mReportNextDraw为 false 直接返回 // Note:此处可以发现若 pre0 前置条件没有被触发mReportNextDraw为 false,那么 CreateSync 会失败。 if (isInWMSRequestedSync() || !mReportNextDraw) { return; }
finalintseqId= mSyncSeqId; mWmsRequestSyncGroupState = WMS_SYNC_PENDING; mWmsRequestSyncGroup = newSurfaceSyncGroup("wmsSync-" + mTag, t -> { mWmsRequestSyncGroupState = WMS_SYNC_MERGED; // See b/286355097. If the current process is not system, then invoking finishDraw on // any thread is fine since once it calls into system process, finishDrawing will run // on a different thread. However, when the current process is system, the finishDraw in // system server will be run on the current thread, which could result in a deadlock. if (mWindowSession instanceof Binder) { // The transaction should be copied to a local reference when posting onto a new // thread because up until now the SSG is holding a lock on the transaction. Once // the call jumps onto a new thread, the lock is no longer held and the transaction // send back may be modified or used again. TransactiontransactionCopy=newTransaction(); transactionCopy.merge(t); mHandler.postAtFrontOfQueue(() -> reportDrawFinished(transactionCopy, seqId)); } else { reportDrawFinished(t, seqId); } }); if (DEBUG_BLAST) { Log.d(mTag, "Setup new sync=" + mWmsRequestSyncGroup.getName()); } // 添加 ViewRootImpl 中 mWmsRequestSyncGroup.add(this, null/* runnable */); }
if (syncBuffer) { // 调用 syncNextTransaction 同步下一帧 Transaction。 booleanresult= mBlastBufferQueue.syncNextTransaction(transaction -> { RunnabletimeoutRunnable= () -> Log.e(mTag, "Failed to submit the sync transaction after 4s. Likely to ANR " + "soon"); mHandler.postDelayed(timeoutRunnable, 4000L * Build.HW_TIMEOUT_MULTIPLIER); transaction.addTransactionCommittedListener(mSimpleExecutor, () -> mHandler.removeCallbacks(timeoutRunnable)); surfaceSyncGroup.addTransaction(transaction); surfaceSyncGroup.markSyncReady(); }); if (!result) { // syncNextTransaction can only return false if something is already trying // to sync the same frame in the same BBQ. That shouldn't be possible, but // if it did happen, invoke markSyncReady so the active SSG doesn't get // stuck. // ...... surfaceSyncGroup.markSyncReady(); } }
// SurfaceView.java publicbooleanapplyTransactionOnDraw(@NonNull SurfaceControl.Transaction t) { if (mRemoved || !isHardwareEnabled()) { logAndTrace("applyTransactionOnDraw applyImmediately"); t.apply(); } else { Trace.instant(Trace.TRACE_TAG_VIEW, "applyTransactionOnDraw-" + mTag); // Copy and clear the passed in transaction for thread safety. The new transaction is // accessed on the render thread. mPendingTransaction.merge(t); mHasPendingTransactions = true; } returntrue; }