探索Surface同步机制

0.前言

之前遇到了因Surface同步迟迟未完成导致发生无焦点窗口类型anr的情况,现在抽空对android13中的Surface同步机制进行梳理与总结。

1.简介

Surface同步机制为android13新增,相关核心代码为SurfaceSyncer.java,主要作用为提供ViewRootImpl与SurfaceView(假如窗口存在SurfaceView的情况下)同步服务,实现在主Surface与SurfaceView均完成绘制时再去上报至WMS进行窗口状态的切换,避免主Surface绘制完成上报至WMS后、同时SurfaceView迟迟没有绘制完成使得startingWindow过早移除从而产生黑屏的现象。Android14上保留了Surface同步机制,但是相关代码位置发生变化,不再有SurfaceSyncer.java,而是移动至SurfaceSyncGroup.java。相关核心方法为createSyncIfNeeded、checkIfSyncIsComplete等。

2.Surface同步流程

2.1 ViewRootImpl发起同步

ViewRootImpl中会在绘制流程中发起sync流程,依次完成callback注册、seqId返回、添加syncTarget、通知SurfaceView发起merge等流程。

/frameworks/base/core/java/android/view/ViewRootImpl.java

2685      private void performTraversals() {
...
>>回调各个listener的onPreDraw方法,同时通知SurfaceView发起sync流程
3491          boolean cancelAndRedraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw();
3492          if (!cancelAndRedraw) {
>>ViewRootImpl发起sync流程
3493              createSyncIfNeeded();
3494          }
...
3529          if (!cancelAndRedraw) {
3530              mReportNextDraw = false;
3531              mSyncBufferCallback = null;
>>置mSyncBuffer=false
3532              mSyncBuffer = false;
3533              if (isInLocalSync()) {
3534                  mSurfaceSyncer.markSyncReady(mSyncId);
>>重置mSyncId为UNSET_SYNC_ID
3535                  mSyncId = UNSET_SYNC_ID;
3536              }
3537          }
4201      /**
4202       * This VRI is currently in the middle of a sync request, but specifically one initiated from
4203       * within VRI.
4204       */
>>VRI发起sync后会把mSyncId重置为UNSET_SYNC_ID
>>如果返回true,说明VRI正处于sync中,尚未完成sync流程
4205      public boolean isInLocalSync() {
4206          return mSyncId != UNSET_SYNC_ID;
4207      }
3540      private void createSyncIfNeeded() {
3541          // Started a sync already or there's nothing needing to sync
>>假如VRI正在Sync,或者mReportNextDraw为false,那么立即return
3542          if (isInLocalSync() || !mReportNextDraw) {
3543              return;
3544          }
3545  
>>这里的mSyncSeqId为relayoutWindow后由WMS返回的id,赋值给seqId是为了后面执行>>reportDrawFinished流程时再回传至WMS
3546          final int seqId = mSyncSeqId;
>>正式发起sync流程,返回syncId
>>传入的callback会在完成同步后被回调
3547          mSyncId = mSurfaceSyncer.setupSync(transaction -> {
3548              // Callback will be invoked on executor thread so post to main thread.
3549              mHandler.postAtFrontOfQueue(() -> {
3550                  mSurfaceChangedTransaction.merge(transaction);
3551                  reportDrawFinished(seqId);
3552              });
3553          });
3554          if (DEBUG_BLAST) {
3555              Log.d(mTag, "Setup new sync id=" + mSyncId);
3556          }
>>将VRI对应的syncTarget添加至SurfaceSyncer
3557          mSurfaceSyncer.addToSync(mSyncId, mSyncTarget);
>>通知SurfaceView发起merge流程
3558          notifySurfaceSyncStarted();
3559      }

2.2 SurfaceView发起同步

SurfaceView会在ViewRootImpl回调OnPreDrawListener.onPreDraw方法时执行updateSurface方法,原因是SurfaceView实现了OnPreDrawListener并进行了注册。然后SurfaceView会在handleSyncNoBuffer方法发起sync流程,也会依次完成callback注册、seqId返回、添加syncTarget等操作。

frameworks/base/core/java/android/view/SurfaceView.java

>>SurfaceView实现OnPreDrawListener,回调onPreDraw时会执行updateSurface方法
157      private final ViewTreeObserver.OnPreDrawListener mDrawListener = () -> {
158          // reposition ourselves where the surface is
159          mHaveFrame = getWidth() > 0 && getHeight() > 0;
160          updateSurface();
161          return true;
162      };
284      protected void onAttachedToWindow() {
285          super.onAttachedToWindow();
...
295          if (!mGlobalListenersAdded) {
296              ViewTreeObserver observer = getViewTreeObserver();
297              observer.addOnScrollChangedListener(mScrollChangedListener);
>>在attachedToWindow时注册OnPreDrawListener
298              observer.addOnPreDrawListener(mDrawListener);
299              mGlobalListenersAdded = true;
300          }
875      protected void updateSurface() {
...
1023                              if (shouldSyncBuffer) {
1024                                  handleSyncBufferCallback(callbacks, syncBufferTransactionCallback);
1025                              } else {
>>当onPreDraw被回调时,如果shouldSyncBuffer=false,将执行handleSyncNoBuffer方法
1026                                  handleSyncNoBuffer(callbacks);
1027                              }
1071      private void handleSyncNoBuffer(SurfaceHolder.Callback[] callbacks) {
>>SurfaceView发起sync流程
1072          final int syncId = mSurfaceSyncer.setupSync(this::onDrawFinished);
1073  
>>SurfaceView添加对应的syncTarget
1074          mSurfaceSyncer.addToSync(syncId, syncBufferCallback -> redrawNeededAsync(callbacks,
1075                  () -> {
1076                      syncBufferCallback.onBufferReady(null);
1077                      synchronized (mSyncIds) {
1078                          mSyncIds.remove(syncId);
1079                      }
1080                  }));
1081  
>>回调markSyncReady方法,会将对应SurfaceSyncer中的mSyncReady置为true
1082          mSurfaceSyncer.markSyncReady(syncId);
1083          synchronized (mSyncIds) {
1084              mSyncIds.add(syncId);
1085          }
1086      }

2.3 合并同步

sync流程中的merge操作由VRI发起,发起的时机是由VRI决定的,时机为VRI添加syncTarget后会调用notifySurfaceSyncStarted方法,该方法会通知到SurfaceView中。merge操作的本质就是,将VRI与SurfaceView各自对应的syncSet给merge到一起。

/frameworks/base/core/java/android/view/ViewRootImpl.java

3540      private void createSyncIfNeeded() {
...
>>VRI向SurfaceSyncer中添加syncTarget
3557          mSurfaceSyncer.addToSync(mSyncId, mSyncTarget);
>>回调callback通知SurfaceView
3558          notifySurfaceSyncStarted();
2085      private void notifySurfaceSyncStarted() {
2086          for (int i = 0; i < mSurfaceChangedCallbacks.size(); i++) {
>>回调surfaceSyncStarted方法
2087              mSurfaceChangedCallbacks.get(i).surfaceSyncStarted();
2088          }
2089      }
2054      public void addSurfaceChangedCallback(SurfaceChangedCallback c) {
>>通过addSurfaceChangedCallback方法将callback添加到mSurfaceChangedCallbacks
2055          mSurfaceChangedCallbacks.add(c);
2056      }

/frameworks/base/core/java/android/view/SurfaceView.java

284      protected void onAttachedToWindow() {
285          super.onAttachedToWindow();
...
286  
>>SurfaceView调用VRI的接口去添加callback,用于接收surface变化通知
287          getViewRootImpl().addSurfaceChangedCallback(this);
288          mWindowStopped = false;
1098      public void surfaceSyncStarted() {
1099          ViewRootImpl viewRoot = getViewRootImpl();
1100          if (viewRoot != null) {
1101              synchronized (mSyncIds) {
1102                  for (int syncId : mSyncIds) {
>>接到VRI通知后,SurfaceView发起merge操作
>>将SurafaceView对应的syncId以及SurfaceSyncer传入VRI
1103                      viewRoot.mergeSync(syncId, mSurfaceSyncer);
1104                  }
1105              }
1106          }
1107      }
frameworks/base/core/java/android/view/ViewRootImpl.java
10977      void mergeSync(int syncId, SurfaceSyncer otherSyncer) {
10978          if (!isInLocalSync()) {
10979              return;
10980          }
>>最终由VRI对应的SurfaceSyncer发起merge操作
>>mSyncId为VRI发起sync的序列号
10981          mSurfaceSyncer.merge(mSyncId, syncId, otherSyncer);
10982      }

frameworks/base/core/java/android/window/SurfaceSyncer.java

160      public void merge(int syncId, int otherSyncId, SurfaceSyncer otherSurfaceSyncer) {
161          SyncSet syncSet;
162          synchronized (mSyncSetLock) {
>>获取VRI对应的syncSet
163              syncSet = mSyncSets.get(syncId);
164          }
165  
>>获取SurfaceView对应的syncSet
166          SyncSet otherSyncSet = otherSurfaceSyncer.getAndValidateSyncSet(otherSyncId);
167          if (otherSyncSet == null) {
168              return;
169          }
170  
>>打印merge相关log
171          if (DEBUG) {
172              Log.d(TAG,
173                      "merge id=" + otherSyncId + " from=" + otherSurfaceSyncer + " into id=" + syncId
174                              + " from" + this);
175          }
>>最终最终把VRI和SurfaceView各自的syncSet给merge
176          syncSet.merge(otherSyncSet);
177      }
427          public void merge(SyncSet otherSyncSet) {
428              synchronized (mLock) {
>>把SurfaceView对应的syncSet添加到VRI对应syncSet中的一个列表中
429                  mMergedSyncSets.add(otherSyncSet);
430              }
>>同时更新callback
>>注意这里更新的是SurfaceView对应SurfaceSyncer中的callback
>>即该callback调用时机由SurfaceView控制,但callback中的操作是针对VRI所对应的syncSet
431              otherSyncSet.updateCallback(transaction -> {
432                  synchronized (mLock) {
>>callback回调时会将VRI对应syncSet中的列表中元素移除
433                      mMergedSyncSets.remove(otherSyncSet);
434                      mTransaction.merge(transaction);
>>同时检查VRI对应sync流程是否完成
435                      checkIfSyncIsComplete();
436                  }
437              });
438          }

2.4 检查同步完成情况

checkIfSyncIsComplete方法是检查sync流程是否完成的核心逻辑所在,VRI与SurfaceView均是通过此方法来判断各自的sync流程是否完成。其中,SurfaceView判断自己的sync流程是否完成不受VRI的影响,而VRI判断自己的sync流程是否完成则会受到SurfaceView(前提是SurfaceView发起了sync流程)影响,原因是SurfaceView对应的syncSet会merge到VRI对应的syncSet中,因此VRI完成sync流程前需要SurfaceView先完成sync流程。

在checkIfSyncIsComplete方法中,判断完成sync流程需要同时满足三个条件,而调用此方法检查是否完成sync流程的时机就是其中每个条件在得到满足时,即第一个条件满足时回去调用checkIfSyncIsComplete方法去检查,第二个条件满足时又会调用此方法去检查sync流程完成情况,依次类推。

frameworks/base/core/java/android/window/SurfaceSyncer.java

364          private void checkIfSyncIsComplete() {
>>判断完成sync流程需要同时满足:1.mSyncReady=true;2.mPendingSyncs.size()=0;
>>3.mMergedSyncSets.size()=0.只要有一个条件没有满足,便会拦截、判断为当前sync流程未完成。
>>其中,前面两个条件均在特定时机才满足,而mMergedSyncSets条件对于SurfaceView始终是满足的,
>>因为不会有其他Surface的syncSet会merge到SurfaceView对应的syncSet中。
365              if (!mSyncReady || !mPendingSyncs.isEmpty() || !mMergedSyncSets.isEmpty()) {
366                  if (DEBUG) {
367                      Log.d(TAG, "Syncable is not complete. mSyncReady=" + mSyncReady
368                              + " mPendingSyncs=" + mPendingSyncs.size() + " mergedSyncs="
369                              + mMergedSyncSets.size());
370                  }
371                  return;
372              }
373  
>>执行到这里,说明当前SurfaceSyncer完成了sync流程
374              if (DEBUG) {
375                  Log.d(TAG, "Successfully finished sync id=" + mSyncId);
376              }
377  
>>执行对应syncTarget的onSyncComplete方法
378              for (SyncTarget syncTarget : mSyncTargets) {
379                  syncTarget.onSyncComplete();
380              }
381              mSyncTargets.clear();
>>执行前面设置的callback:mSYncRequestCompleteCallback
382              mSyncRequestCompleteCallback.accept(mTransaction);
>>置mFinished为true
383              mFinished = true;
384          }

2.4.1 设置mSyncReady为true

调用markSyncReady会把mSyncReady置为true,同时调用checkIfSyncIsComplete方法检查当前sync流程是否完成。

frameworks/base/core/java/android/window/SurfaceSyncer.java

142      public void markSyncReady(int syncId) {
143          SyncSet syncSet;
144          synchronized (mSyncSetLock) {
145              syncSet = mSyncSets.get(syncId);
146          }
147          if (syncSet == null) {
148              Log.e(TAG, "Failed to find syncSet for syncId=" + syncId);
149              return;
150          }
151          syncSet.markSyncReady();
152      }

2.4.2 移除mPendingSyncs中元素

mPendingSyncs中的元素是发起sync流程初期通过addToSync方法向mPendingSyncs中添加的,在完成sync流程前需要把mPendingSyncs中的元素给移除掉。

>>向SurfaceSyncer中通过syncId添加syncTraget
223      public boolean addToSync(int syncId, @NonNull SyncTarget syncTarget) {
224          SyncSet syncSet = getAndValidateSyncSet(syncId);
225          if (syncSet == null) {
226              return false;
227          }
228          if (DEBUG) {
229              Log.d(TAG, "addToSync id=" + syncId);
230          }
>>调用对应的syncSet的addSyncableSurface方法
231          return syncSet.addSyncableSurface(syncTarget);
232      }
329          boolean addSyncableSurface(SyncTarget syncTarget) {
>>实现syncBufferCallback
330              SyncBufferCallback syncBufferCallback = new SyncBufferCallback() {
331                  @Override
332                  public void onBufferReady(Transaction t) {
333                      synchronized (mLock) {
334                          if (t != null) {
335                              mTransaction.merge(t);
336                          }
>>回调callback时会将mPendingSyncs中的元素移除
337                          mPendingSyncs.remove(hashCode());
338                          checkIfSyncIsComplete();
339                      }
340                  }
341              };
342  
343              synchronized (mLock) {
344                  if (mSyncReady) {
345                      Log.e(TAG, "Sync " + mSyncId + " was already marked as ready. No more "
346                              + "SyncTargets can be added.");
347                      return false;
348                  }
>>向pendingSyncs中添加syncBufferCallback
349                  mPendingSyncs.add(syncBufferCallback.hashCode());
350                  mSyncTargets.add(syncTarget);
351              }
>>将syncBufferCallback添加到syncTaret中,说明callback触发时机由syncTarget决定
352              syncTarget.onReadyToSync(syncBufferCallback);
353              return true;
354          }

2.4.3 移除mMergedSyncSets中元素

mMergedSyncSets中的元素是SurfaceView发起merge流程、将自己对应的syncSet给添加到了mMergedSyncSets中的。在完成sync流程前需要将mMergedSyncSets中的元素给移除掉。

>>由SurfaceView发起调用,传入参数分别为VRI对应的syncId、SurafceView对应的syncId、
>>以及SurafceView对应的SurfaceSyncer
160      public void merge(int syncId, int otherSyncId, SurfaceSyncer otherSurfaceSyncer) {
161          SyncSet syncSet;
162          synchronized (mSyncSetLock) {
>>通过syncId获取VRI对应的syncSet
163              syncSet = mSyncSets.get(syncId);
164          }
165  
>>通过syncId获取SurfaceView对应的syncSet
166          SyncSet otherSyncSet = otherSurfaceSyncer.getAndValidateSyncSet(otherSyncId);
167          if (otherSyncSet == null) {
168              return;
169          }
170  
171          if (DEBUG) {
172              Log.d(TAG,
173                      "merge id=" + otherSyncId + " from=" + otherSurfaceSyncer + " into id=" + syncId
174                              + " from" + this);
175          }
>>将SurfaceView对应的syncSet合并到VRI对应的syncSet中
176          syncSet.merge(otherSyncSet);
177      }
427          public void merge(SyncSet otherSyncSet) {
428              synchronized (mLock) {
>>向mMergedSyncSets中添加元素,元素类型为SyncSet。
429                  mMergedSyncSets.add(otherSyncSet);
430              }
431              otherSyncSet.updateCallback(transaction -> {
432                  synchronized (mLock) {
>>当callback回调时会将元素从mMergedSyncSets中移除
>>移除的时机则由otherSyncSet决定
433                      mMergedSyncSets.remove(otherSyncSet);
434                      mTransaction.merge(transaction);
435                      checkIfSyncIsComplete();
436                  }
437              });
438          }

2.5 同步完成并报告

一般流程为SurfaceView先完成sync流程、然后VRI完成sync流程,最后VRI向WMS报告当前窗口绘制完毕。

2.5.1 SurfaceView同步完成

SurfaceView中的sync流程相对VRI要简单一些,其不需要检查merge条件(准确的说是因为其对应SurfaceSyncer中的mMergedSyncSets一直为空,始终是满足条件的),当SurfaceView绘制完成时基本就算是完成sync流程了,此时对应的三个条件均已满足。

frameworks/base/core/java/android/view/SurfaceView.java
1071      private void handleSyncNoBuffer(SurfaceHolder.Callback[] callbacks) {
1072          final int syncId = mSurfaceSyncer.setupSync(this::onDrawFinished);
1073  
>>向SurfaceSyncer中添加syncTarget
>>其中第二个参数为syncTarget,重写了SyncTarget的onReadyToSync方法
>>在重写的onReadyToSync方法中,会执行redrawNeededAsync方法,而syncBufferCallback的
>>执行时机则由redrawNeededAsync方法决定,一般认为是SurfaceView绘制完成后执行
1074          mSurfaceSyncer.addToSync(syncId, syncBufferCallback -> redrawNeededAsync(callbacks,
1075                  () -> {
1076                      syncBufferCallback.onBufferReady(null);
1077                      synchronized (mSyncIds) {
1078                          mSyncIds.remove(syncId);
1079                      }
1080                  }));
1081  
>>在向SurfaceSyncer中添加完syncTarget后,就会立马调用markSyncReady方法将mSyncRead置为true
1082          mSurfaceSyncer.markSyncReady(syncId);
1083          synchronized (mSyncIds) {
1084              mSyncIds.add(syncId);
1085          }
1086      }

2.5.2 ViewRootImpl同步完成

VRI在绘制完成后、底层回调FrameCallBack时,会执行syncBufferCallback.onBufferReady方法,移除对应SurfaceSyncer中的mPendingSyncs中的元素。这里syncBufferCallback是VRI向SurfaceSyncer添加syncTarget时由SurafaceSyncer传入。

2.5.2.1 VRI设置mSyncReady为true

VRI会在performTraversal流程结束时将对应SurfaceSyncer中的mSyncReady置为true,应该是三个条件中最先满足的一个。

2685      private void performTraversals() {
...
3529          if (!cancelAndRedraw) {
3530              mReportNextDraw = false;
3531              mSyncBufferCallback = null;
3532              mSyncBuffer = false;
3533              if (isInLocalSync()) {
>>VRI调用markSyncReady方法将mSyncReady置为true
3534                  mSurfaceSyncer.markSyncReady(mSyncId);
3535                  mSyncId = UNSET_SYNC_ID;
3536              }
3537          }
2.5.2.2 VRI移除mPendingSyncs中元素

VRI在绘制完成后、底层回调FrameCommitCallback时,会执行syncBufferCallback.onBufferReady 方法,移除对应SurfaceSyncer中对应mPendingSyncs中的元素。这里的syncBufferCallback是VRI向SurfaceSyncer添加syncTarget时从SurfaceSyncer传入。

10938      public final SurfaceSyncer.SyncTarget mSyncTarget = new SurfaceSyncer.SyncTarget() {
10939          @Override
10940          public void onReadyToSync(SurfaceSyncer.SyncBufferCallback syncBufferCallback) {
>>SurfaceSyncer侧回调syncTarget的onReadyToSync方法时,会执行VRI的readyToSync方法
10941              readyToSync(syncBufferCallback);
10942          }   

10954      private void readyToSync(SurfaceSyncer.SyncBufferCallback syncBufferCallback) {
...
10968          if (DEBUG_BLAST) {
10969              Log.d(mTag, "Setting syncFrameCallback");
10970          }
>>将由SurfaceSyncer传入的syncBufferCallback赋值给mSyncBufferCallback
10971          mSyncBufferCallback = syncBufferCallback;
4263      private boolean performDraw() {
...
4276          addFrameCommitCallbackIfNeeded();
4277  
4278          boolean usingAsyncReport = isHardwareEnabled() && mSyncBufferCallback != null;
4279          if (usingAsyncReport) {
>>注册calback时将mSyncBufferCallback传入
4280              registerCallbacksForSync(mSyncBuffer, mSyncBufferCallback);
4281          } else if (mHasPendingTransactions) {
10864      private void registerCallbacksForSync(boolean syncBuffer,
10865              final SurfaceSyncer.SyncBufferCallback syncBufferCallback) {
...
10870          if (DEBUG_BLAST) {
10871              Log.d(mTag, "registerCallbacksForSync syncBuffer=" + syncBuffer);
10872          }
10873          mAttachInfo.mThreadedRenderer.registerRtFrameCallback(new FrameDrawingCallback() {
10874              @Override
10875              public void onFrameDraw(long frame) {
10876              }
10877  
10878              @Override
10879              public HardwareRenderer.FrameCommitCallback onFrameDraw(int syncResult, long frame) {
10880                  if (DEBUG_BLAST) {
10881                      Log.d(mTag,
10882                              "Received frameDrawingCallback syncResult=" + syncResult + " frameNum="
10883                                      + frame + ".");
10884                  }
...
>>如果syncBuffer=true,会向BlastBufferQueue中传入一个callback
>>该callback会在底层绘制完成后回调,并将包含buffer的transaction作为参数传入callback
10901                  if (syncBuffer) {
10902                      mBlastBufferQueue.syncNextTransaction(syncBufferCallback::onBufferReady);
10903                  }
10904  
>>返回FrameCommitCallback类型的callback
10905                  return didProduceBuffer -> {
10906                      if (DEBUG_BLAST) {
10907                          Log.d(mTag, "Received frameCommittedCallback"
10908                                  + " lastAttemptedDrawFrameNum=" + frame
10909                                  + " didProduceBuffer=" + didProduceBuffer);
10910                      }
...
10927                      // If we didn't request to sync a buffer, then we won't get the
10928                      // syncNextTransaction callback. Instead, just report back to the Syncer so it
10929                      // knows that this sync request is complete.
10930                      if (!syncBuffer) {
>>当绘制完成时,底层回调FrameCommitCallback时会执行syncBufferCallback,将VRI对应的
>>SurfaceSyncer中的mPendingSyncs中元素移除掉
10931                          syncBufferCallback.onBufferReady(null);
10932                      }
    
2.5.2.3 VRI移除mMergedSyncSets中元素

如前面所述,当SurfaceView通知VRI发起merge流程后,会执行SurfaceView对应syncSet的updateCallback流程,去更新SurfaceView中的callback。当这个callback被回调时会将VRI对应SurfaceSyncer中mMergedSyncSets中的元素移除,从而使得VRI完成sync流程所需的三个条件之一得到满足。一般情况下,这个条件是VRI完成sync流程的最后一个条件。

427          public void merge(SyncSet otherSyncSet) {
428              synchronized (mLock) {
>>VRI发起merge时会将SurfaceView对应的syncSets添加到自身的mMergedSyncSets中
429                  mMergedSyncSets.add(otherSyncSet);
430              }
>>更新SurfaceView对应syncSet的callback,实际上updateCallback中的参数为一个consumer
431              otherSyncSet.updateCallback(transaction -> {
432                  synchronized (mLock) {
>>该callback被SurfaceView回调时会把VRI对应mMergedSyncSets中的元素移除
433                      mMergedSyncSets.remove(otherSyncSet);
434                      mTransaction.merge(transaction);
435                      checkIfSyncIsComplete();
436                  }
437              });
438          }

可以看的,实际上updateCallback方法传入的是一个consumer类型的参数,该consumer放在了mSyncRequestCompleteCallback中,即该consumer的执行时机取决于mSyncRequestCompleteCallback的执行时机。

396          public void updateCallback(Consumer<Transaction> transactionConsumer) {
397              synchronized (mLock) {
398                  if (mFinished) {
399                      Log.e(TAG, "Attempting to merge SyncSet " + mSyncId + " when sync is"
400                              + " already complete");
401                      transactionConsumer.accept(new Transaction());
402                  }
403  
404                  final Consumer<Transaction> oldCallback = mSyncRequestCompleteCallback;
405                  mSyncRequestCompleteCallback = transaction -> {
406                      oldCallback.accept(new Transaction());
>>执行传入的consumer,执行的时机为mSyncRequestCompleteCallback的执行时机
407                      transactionConsumer.accept(transaction);
408                  };
409              }
410          }

mSyncRequestCompleteCallback的执行时机为完成sync流程时,具体来说就是当checkIfSyncIsComplete方法检查SurfaceView对应SurfaceSyncer的三项条件都通过时会执行mSyncRequestCompleteCallback,从而执行callback中的consumer去把VRI对应的SurfaceSyncer中的mMergedSyncSets中的元素移除,从而使得VRI满足完成sync的条件。

364          private void checkIfSyncIsComplete() {
365              if (!mSyncReady || !mPendingSyncs.isEmpty() || !mMergedSyncSets.isEmpty()) {
366                  if (DEBUG) {
367                      Log.d(TAG, "Syncable is not complete. mSyncReady=" + mSyncReady
368                              + " mPendingSyncs=" + mPendingSyncs.size() + " mergedSyncs="
369                              + mMergedSyncSets.size());
370                  }
371                  return;
372              }
...
374              if (DEBUG) {
375                  Log.d(TAG, "Successfully finished sync id=" + mSyncId);
376              }
...
>>sync完成后,执行 mSyncRequestCompleteCallback 
382              mSyncRequestCompleteCallback.accept(mTransaction);
383              mFinished = true;

2.5.3 报告WMS

在VRI发起ync流程时,会向SurfaceSyncer中传入一个consumer,而reportDrawFinished方法就是在此consumer中调用执行。

3540      private void createSyncIfNeeded() {
...
3546          final int seqId = mSyncSeqId;
3547          mSyncId = mSurfaceSyncer.setupSync(transaction -> {
3548              // Callback will be invoked on executor thread so post to main thread.
3549              mHandler.postAtFrontOfQueue(() -> {
3550                  mSurfaceChangedTransaction.merge(transaction);
>>setupSync方法中的参数为consumer类型
>>reportDrawFinished方法的执行时机就是该consumer的执行时机
3551                  reportDrawFinished(seqId);
3552              });
3553          });

从VRI传过来的consumer会继续传入对应的yncSet中,即该consumer的执行时机由syncSet决定。

118      public int setupSync(@NonNull Consumer<Transaction> syncRequestComplete) {
119          synchronized (mSyncSetLock) {
120              final int syncId = mIdCounter++;
121              if (DEBUG) {
122                  Log.d(TAG, "setupSync " + syncId);
123              }
124              SyncSet syncSet = new SyncSet(syncId, transaction -> {
125                  synchronized (mSyncSetLock) {
126                      mSyncSets.remove(syncId);
127                  }
>>consumer传入syncSet中
128                  syncRequestComplete.accept(transaction);
129              });

对应consumer传入syncSet中时,会赋值给mSyncRequestCompleteCallback。因此,该callback的执行时机就是consumer的执行时机,也就是reportDrawFinished方法的执行时机。

324          private SyncSet(int syncId, Consumer<Transaction> syncRequestComplete) {
325              mSyncId = syncId;
326              mSyncRequestCompleteCallback = syncRequestComplete;
327          }

根据前面2.5.2.3得知,mSyncRequestCompleteCallback的执行时机为VRI完成sync流程之时。因此,reporDrawFinished方法的执行时机也正是VRI完成sync流程的时候。该方法调用后,WMS得知应用绘制完成,开始更新对应窗口状态。

2.6 整体流程

整体流程如下:

VRI发起performTraversal -> SurfaceView发起sync -> VRI发起sync -> SurfaceView通知VRI发起merge ->SurfaceView绘制完成 -> SurfaceView完成sync -> VRI完成sync -> VRI发起reportDrawFinished流程

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值