当前位置:   article > 正文

Android12 图形系统_bbq-wrapper

bbq-wrapper

Android S 图形系统

本文参考http://gityuan.com/2017/01/08/windowmanger/ 结合Android12.0的源码进行分析

一、概述

Android图形系统的大概组成:

  • Surface:代表画布 (在ViewRootImpl初始化时创建的)
  • WMS(Window Manager Service): 添加window的过程主要功能是添加Surface,管理所有的Surface布局,以及Z轴排序问题;
  • SurfaceFinger: 将Surface按次序混合并显示到物理屏幕上;

Android最常见的界面就是和用户交互的Activity了,上面也承载着图形,Activity的图形结构图如下:
在这里插入图片描述

二、Window的加载过程

这里以一个Activity的启动来看,大致流程就是调用startActivity时会让AMS启动一个Activity,如果Activity所在的进程没有启动,那么会向Zygote请求fork一个进程。当进程创建后会执行ActivityThread.main(通过反射执行的)接着会调用attach和AMS取得联系,AMS得到ActivityThread后就会去启动应用进程的Activity,应用进程启动Activity的函数从下面开始:

2.1Window的创建

/frameworks/base/core/java/android/app/ActivityThread.java
3513      private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
             ...
3531          //1.利用反射创建Activity的对象
3532          ContextImpl appContext = createBaseContextForActivity(r);
3533          Activity activity = null;
3534          try {
3535              java.lang.ClassLoader cl = appContext.getClassLoader();
3536              activity = mInstrumentation.newActivity(
3537                      cl, component.getClassName(), r.intent);
3538              StrictMode.incrementExpectedActivityCount(activity.getClass());
3539              r.intent.setExtrasClassLoader(cl);
3540              r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
3541                      appContext.getAttributionSource());
3542              if (r.state != null) {
3543                  r.state.setClassLoader(cl);
3544              }
3545          } catch (Exception e) {
3546              if (!mInstrumentation.onException(activity, e)) {
3547                  throw new RuntimeException(
3548                      "Unable to instantiate activity " + component
3549                      + ": " + e.toString(), e);
3550              }
3551          }
3552  
                      ... 
                      //2.调用Attach来初始化一些对象
3586                  activity.attach(appContext, this, getInstrumentation(), r.token,
3587                          r.ident, app, r.intent, r.activityInfo, title, r.parent,
3588                          r.embeddedID, r.lastNonConfigurationInstances, config,
3589                          r.referrer, r.voiceInteractor, window, r.configCallback,
3590                          r.assistToken, r.shareableActivityToken);
3591  
                      //3.回调我们Activity中的onCreate函数
3609                  if (r.isPersistable()) {
3610                      mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
3611                  } else {
3612                      mInstrumentation.callActivityOnCreate(activity, r.state);
3613                  }
            
3643          return activity;
3644      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

我们先看Activity的attach做了什么初始化:

/frameworks/base/core/java/android/app/Activity.java
7931      @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
7932      final void attach(Context context, ActivityThread aThread,
7933              Instrumentation instr, IBinder token, int ident,
7934              Application application, Intent intent, ActivityInfo info,
7935              CharSequence title, Activity parent, String id,
7936              NonConfigurationInstances lastNonConfigurationInstances,
7937              Configuration config, String referrer, IVoiceInteractor voiceInteractor,
7938              Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken,
7939              IBinder shareableActivityToken) {
7940          attachBaseContext(context);
7941  
7942          mFragments.attachHost(null /*parent*/);
7943          // 1.新建了PhoneWindow
7944          mWindow = new PhoneWindow(this, window, activityConfigCallback);
7945          mWindow.setWindowControllerCallback(mWindowControllerCallback);
7946          mWindow.setCallback(this);
7947          mWindow.setOnWindowDismissedCallback(this);
7948          mWindow.getLayoutInflater().setPrivateFactory(this);
7949          if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
7950              mWindow.setSoftInputMode(info.softInputMode);
7951          }
7952          if (info.uiOptions != 0) {
7953              mWindow.setUiOptions(info.uiOptions);
7954          }
7955          mUiThread = Thread.currentThread();
7956          //2.设置ActivityThread为Activity的主线程
7957          mMainThread = aThread;
			  ...
              //3.获取到WMS的代理并设置给PhoneWindow mToken对应了activity和window的关系
7981          mWindow.setWindowManager(
7982                  (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
7983                  mToken, mComponent.flattenToString(),
7984                  (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
7985          if (mParent != null) {
7986              mWindow.setContainer(mParent.getWindow());
7987          }
              //这里获取到的mWindowManager其实是WindowManagerImpl 也是WMS的代理的实现类
      		  mWindowManager = mWindow.getWindowManager();
7997      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

2.2 window加载View

当Actvity启动后AMS会接着回调Activity的onResumed在此之前,先到ActivityThread的handleResumeActivity

/frameworks/base/core/java/android/app/ActivityThread.java
4785      public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
4786              boolean isForward, String reason) {
4787          // If we are getting ready to gc after going to the background, well
4788          // we are back active so skip it.
4789          unscheduleGcIdler();
4790          mSomeActivitiesChanged = true;
4791  
4792          // TODO Push resumeArgs into the activity for consideration
4793          // skip below steps for double-resume and r.mFinish = true case.
              //1. performResumeActivity会回调到我们的Activity中的onResumed
4794          if (!performResumeActivity(r, finalStateRequest, reason)) {
4795              return;
4796          }
              ...
4823          if (r.window == null && !a.mFinished && willBeVisible) {
4824              r.window = r.activity.getWindow();
4825              View decor = r.window.getDecorView();
4826              decor.setVisibility(View.INVISIBLE);
                  //2.获取activity的WMS的代理引用
4827              ViewManager wm = a.getWindowManager();
                  ...
4856                         
4844              if (a.mVisibleFromClient) {
4845                  if (!a.mWindowAdded) {
4846                      a.mWindowAdded = true;
                          //3.关键函数 第一次显示 走这边 addview
4847                      wm.addView(decor, l);
              ... 
4868          // The window is now visible if it has been added, we are not
4869          // simply finishing, and we are not starting another activity.
4870          if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
4871              if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward);
4872              ViewRootImpl impl = r.window.getDecorView().getViewRootImpl();
4873              WindowManager.LayoutParams l = impl != null
4874                      ? impl.mWindowAttributes : r.window.getAttributes();
4875              if ((l.softInputMode
4876                      & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
4877                      != forwardBit) {
4878                  l.softInputMode = (l.softInputMode
4879                          & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
4880                          | forwardBit;
4881                  if (r.activity.mVisibleFromClient) {
4882                      ViewManager wm = a.getWindowManager();
4883                      View decor = r.window.getDecorView();
                          //更新窗口的布局
4884                      wm.updateViewLayout(decor, l);
4885                  }
4886              }
4887  
4888              r.activity.mVisibleFromServer = true;
4889              mNumVisibleActivities++;
4890              if (r.activity.mVisibleFromClient) {
                      //activity显示出来
4891                  r.activity.makeVisible();
4892              }
4893          }
4899      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

addView会调用到WindowManagerImpl的addview最终调用到WindowManagerGlobal的addView如下:这里的addView是把DecorView加入进去

/frameworks/base/core/java/android/view/WindowManagerGlobal.java
321      public void addView(View view, ViewGroup.LayoutParams params,
322              Display display, Window parentWindow, int userId) {
                 ...
                 //1.创建一个ViewRootImpl对象,在ViewRootImpl对象初始化时,就会初始化绘制所需要的surface
389              root = new ViewRootImpl(view.getContext(), display);
390  
391              view.setLayoutParams(wparams);
392              //2.将view和ViewRootImpl都加入到WindowManagerGlobal的内部list中
393              mViews.add(view);
394              mRoots.add(root);
395              mParams.add(wparams);
396  
397              // do this last because it fires off messages to start doing things
398              try {
                     //3.调用ViewRootImpl的setView完成View的绘制并添加到Window上
399                  root.setView(view, wparams, panelParentView, userId);
400              } catch (RuntimeException e) {
401                  // BadTokenException or InvalidDisplayException, clean up.
402                  if (index >= 0) {
403                      removeViewLocked(index, true);
404                  }
405                  throw e;
406              }
407          }
408      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

WindowManagerGlobal是一个单例对象,一个进程只有一个,并且拥有整个进程所有的DecorView和ViewImpl

/frameworks/base/core/java/android/view/ViewRootImpl.java
1000      public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
1001              int userId) {
                      ...
                      //1.View的绘制
1096                  requestLayout();
                      //2.新建inputChannel对象用来IMS和app进程的通信
1097                  InputChannel inputChannel = null;
1098                  if ((mWindowAttributes.inputFeatures
1099                          & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
1100                      inputChannel = new InputChannel();
1101                  }
                      ...
1112  
1113                  try {
1114                      mOrigWindowType = mWindowAttributes.type;
1115                      mAttachInfo.mRecomputeGlobalAttributes = true;
1116                      collectViewAttributes();
1117                      adjustLayoutParamsForCompatibility(mWindowAttributes);
1118                      controlInsetsForCompatibility(mWindowAttributes);
                          //3.添加DisplayId mWindow是一个Iwindow的实现类,用来接受WMS向APP进程发送的消息 
1119                      res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
1120                              getHostVisibility(), mDisplay.getDisplayId(), userId,
1121                              mInsetsController.getRequestedVisibility(), inputChannel, mTempInsets,
1122                              mTempControls);
1123                      if (mTranslator != null) {
1124                          mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
1125                          mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls);
1126                      }
1127                  } catch (RemoteException e) {
1128                      mAdded = false;
1129                      mView = null;
1130                      mAttachInfo.mRootView = null;
1131                      mFallbackEventHandler.setView(null);
1132                      unscheduleTraversals();
1133                      setAccessibilityFocus(null, null);
1134                      throw new RuntimeException("Adding window failed", e);
1135                  } finally {
1136                      if (restore) {
1137                          attrs.restore();
1138                      }
1139                  }
1140  
                         //4.接受IMS发送过来的消息
1214                      mInputEventReceiver = new WindowInputEventReceiver(inputChannel,
1215                              Looper.myLooper());
1216  
                       ...
1253              }
1254          }
1255      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

这里的IPC通信addToDisplayAsUser主要是将当前的window和wms建立联系用来接受WMS的消息

Activity中各元素的对应关系:

在这里插入图片描述

可以看到,Activity的顶级View是DecorView,那么我们的View在哪里显示的呢?下面看一下DecorView的加载流程。

三、DecorView的加载流程

我们写过APP的都知道,在写一个Activity时会在onCreate回调中调用一个setContentView,并将我们Activity的布局文件传进去。我们就从这边开始分析:

/frameworks/base/core/java/android/app/Activity.java
3539      public void setContentView(View view) {
3540          getWindow().setContentView(view);
3541          initWindowDecorActionBar(); //初始化ActionBar
3542      }
  • 1
  • 2
  • 3
  • 4
  • 5

这里的getWindow返回的时mWindow,指的是PhoneWindow实例

445      @Override
446      public void setContentView(int layoutResID) {
447          // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
448          // decor, when theme attributes and the like are crystalized. Do not check the feature
449          // before this happens.
450          if (mContentParent == null) {
                 //1.当Activity初始化时,mContentParent为null 创建decorview和mContentParent
451              installDecor();
452          } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
453              mContentParent.removeAllViews();
454          }
455  
456          if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
457              final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
458                      getContext());
459              transitionTo(newScene);
460          } else {
                 //将我们定义的布局文件加载到Decorview中
461              mLayoutInflater.inflate(layoutResID, mContentParent);
462          }
             //3.让DecorView延伸到systemUI下面防止在扩展时被覆盖达到全屏,沉浸等不同效果
463          mContentParent.requestApplyInsets();
464          final Callback cb = getCallback();
465          if (cb != null && !isDestroyed()) {
466              cb.onContentChanged();
467          }
468          mContentParentExplicitlySet = true;
469      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

3.1 installDecor

installDecor主要是在Activity首次被初始化的时候才会被调用,用来新建顶级viewDecorView和mContentParent,

/frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java
2714      private void installDecor() {
2715          mForceDecorInstall = false;
2716          if (mDecor == null) {
                  //1.初始化DecorView	
2717              mDecor = generateDecor(-1);
2718              mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
2719              mDecor.setIsRootNamespace(true);
2720              if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
2721                  mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
2722              }
2723          } else {
2724              mDecor.setWindow(this);
2725          }
2726          if (mContentParent == null) {
                  //2.初始化mContentParent
2727              mContentParent = generateLayout(mDecor);
				  ...
2848      }
2357      protected DecorView generateDecor(int featureId) {
2358          // System process doesn't have application context and in that case we need to directly use
2359          // the context we have. Otherwise we want the application context, so we don't cling to the
2360          // activity.
              ...
2375          return new DecorView(context, featureId, this, getAttributes());
2376      }

2377  
2378      protected ViewGroup generateLayout(DecorView decor) {
2379          // Apply data from current theme.
2380          //1.获取Activity配置的一些属性如style等等
2381          TypedArray a = getWindowStyle();
2382  
              ...
2602  
2603          // Inflate the window decor.
2604          //2.获取窗口features,根据features设置window 主题对应的布局文件
2605          int layoutResource;
2606          int features = getLocalFeatures();
2607          // System.out.println("Features: 0x" + Integer.toHexString(features));
              ...
2663          mDecor.startChanging();
              //3.将上面选定的布局文件inflate为view树添加到decorview中
2664          mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
2665          //4.将窗口修饰布局文件中的@android:id/content的viewgroup赋值给mContentParent
2666          ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
2667          if (contentParent == null) {
2668              throw new RuntimeException("Window couldn't find content container view");
2669          }
2670  
              ...
2704          mDecor.finishChanging();
2705  
2706          return contentParent;
2707      }    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

如果上面layoutResource的布局文件是R.layout.screen_simple的话那么布局应该是下面这样:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ho4WHAlD-1642062245360)(D:\文档\image\image-20211103114231173.png)]

3.2 mLayoutInflater.inflate

当Activity的decorview和content创建完成后就到了将我们的view添加到decorview中调用的是mLayoutInflater.inflate去解析我们的布局文件并将view设置到mContentParent的子view中

当DecorView加载完毕后回到2.2节,在ViewRootImpl的setView流程中会调用requestLayout来绘制View,

3.3 DecorView的绘制

 /frameworks/base/core/java/android/view/ViewRootImpl.java
2510      private void performTraversals() {
		...
            //1.预测量
2711          if (mApplyInsetsRequested && !(mWillMove || mWillResize)) {
2712              dispatchApplyInsets(host);
2713              if (mLayoutRequested) {
2714                  // Short-circuit catching a new layout request here, so
2715                  // we don't need to go through two layout passes when things
2716                  // change due to fitting system windows, which can happen a lot.
                      //1.预测量阶段
2717                  windowSizeMayChange |= measureHierarchy(host, lp,
2718                          mView.getContext().getResources(),
2719                          desiredWindowWidth, desiredWindowHeight);
2720              }
2721          }
     	...
            		  //2.窗口布局阶段
2823                  relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
3066              if (!mStopped || wasReportNextDraw) {
3067                  boolean focusChangedDueToTouchMode = ensureTouchModeLocally(
3068                          (relayoutResult&WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE) != 0);
3069                  if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth()
3070                          || mHeight != host.getMeasuredHeight() || dispatchApplyInsets ||
3071                          updatedConfiguration) {
3072                      int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
3073                      int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
3074  
3075                      if (DEBUG_LAYOUT) Log.v(mTag, "Ooops, something changed!  mWidth="
3076                              + mWidth + " measuredWidth=" + host.getMeasuredWidth()
3077                              + " mHeight=" + mHeight
3078                              + " measuredHeight=" + host.getMeasuredHeight()
3079                              + " dispatchApplyInsets=" + dispatchApplyInsets);
3080  
3081                       // Ask host how big it wants to be
                          //3.测量阶段
3082                      performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
    	...
            
3136          final boolean didLayout = layoutRequested && (!mStopped || wasReportNextDraw);
3137          boolean triggerGlobalLayoutListener = didLayout
3138                  || mAttachInfo.mRecomputeGlobalAttributes;
3139          if (didLayout) {
                  //4.布局阶段
3140              performLayout(lp, mWidth, mHeight);
3141  
    	...
3297          boolean cancelDraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || !isViewVisible;
3298  
3299          if (!cancelDraw) {
3300              if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
3301                  for (int i = 0; i < mPendingTransitions.size(); ++i) {
3302                      mPendingTransitions.get(i).startChangingAnimations();
3303                  }
3304                  mPendingTransitions.clear();
3305              }
                  //5.绘制阶段
3306              performDraw();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

可以看到View的绘制会经过5个阶段:

  • 预测量阶段 (measureHierarchy) 预测量阶段会对View树进行第一次测量,在此阶段会计算出View显示出内容的所需要的尺寸,即期望的窗口尺寸

  • 窗口布局阶段 (relayoutWindow) 根据预测量的结果向WMS请求调整窗口的尺寸,这将引发WMS对窗口进行重新布局并将结果返回给Viewrootimpl

  • 测量阶段(performMeasure) 根据上面WMS返回的布局结果对view进行最终测量

  • 布局阶段(performLayout) 测量完成后对view树进行布局

  • 绘制阶段(performDraw) 确定view的尺寸和位置后进行绘制工作

3.3.1 预测量阶段(measureHierarchy)

/frameworks/base/core/java/android/view/ViewRootImpl.java
2353      private boolean measureHierarchy(final View host, final WindowManager.LayoutParams lp,
2354              final Resources res, final int desiredWindowWidth, final int desiredWindowHeight) {
2355          int childWidthMeasureSpec;
2356          int childHeightMeasureSpec;
2357          boolean windowSizeMayChange = false;
2358  
2359          if (DEBUG_ORIENTATION || DEBUG_LAYOUT) Log.v(mTag,
2360                  "Measuring " + host + " in display " + desiredWindowWidth
2361                  + "x" + desiredWindowHeight + "...");
2362  
2363          boolean goodMeasure = false;
              //只有View的width是WRAP_CONTENT时才需要进行协商
2364          if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
2365              // On large screens, we don't want to allow dialogs to just
2366              // stretch to fill the entire width of the screen to display
2367              // one line of text.  First try doing the layout at a smaller
2368              // size to see if it will fit.
2369              final DisplayMetrics packageMetrics = res.getDisplayMetrics();
2370              res.getValue(com.android.internal.R.dimen.config_prefDialogWidth, mTmpValue, true);
2371              int baseSize = 0;
2372              if (mTmpValue.type == TypedValue.TYPE_DIMENSION) {
2373                  baseSize = (int)mTmpValue.getDimension(packageMetrics);
2374              }
2375              if (DEBUG_DIALOG) Log.v(mTag, "Window " + mView + ": baseSize=" + baseSize
2376                      + ", desiredWindowWidth=" + desiredWindowWidth);
2377              if (baseSize != 0 && desiredWindowWidth > baseSize) {
2378                  childWidthMeasureSpec = getRootMeasureSpec(baseSize, lp.width);
2379                  childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height);
                      //第一次协商在 以 config_prefDialogWidth为限制来测量 最终调用到View的onMeasure 
2380                  performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
2381                  if (DEBUG_DIALOG) Log.v(mTag, "Window " + mView + ": measured ("
2382                          + host.getMeasuredWidth() + "," + host.getMeasuredHeight()
2383                          + ") from width spec: " + MeasureSpec.toString(childWidthMeasureSpec)
2384                          + " and height spec: " + MeasureSpec.toString(childHeightMeasureSpec));
2385                  if ((host.getMeasuredWidthAndState()&View.MEASURED_STATE_TOO_SMALL) == 0) {
                          //测量结果满意
2386                      goodMeasure = true;
2387                  } else {
2388                      // Didn't fit in that size... try expanding a bit.
                          //第二次协商将宽度的限制放宽,区期望的宽度和定义的限制宽度的中间值作为宽度
2389                      baseSize = (baseSize+desiredWindowWidth)/2;
2390                      if (DEBUG_DIALOG) Log.v(mTag, "Window " + mView + ": next baseSize="
2391                              + baseSize);
2392                      childWidthMeasureSpec = getRootMeasureSpec(baseSize, lp.width);
2393                      performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
2394                      if (DEBUG_DIALOG) Log.v(mTag, "Window " + mView + ": measured ("
2395                              + host.getMeasuredWidth() + "," + host.getMeasuredHeight() + ")");
2396                      if ((host.getMeasuredWidthAndState()&View.MEASURED_STATE_TOO_SMALL) == 0) {
2397                          if (DEBUG_DIALOG) Log.v(mTag, "Good!");
2398                          goodMeasure = true;
2399                      }
2400                  }
2401              }
2402          }
2403  
2404          if (!goodMeasure) {
                  //第三次协商,不添加限制了,不在检查view树是否满意,请求WMS重新调整窗口的尺寸
2405              childWidthMeasureSpec = getRootMeasureSpec(desiredWindowWidth, lp.width);
2406              childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height);
2407              performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
2408              if (mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight()) {
2409                  windowSizeMayChange = true;
2410              }
2411          }
2412  
2413          if (DBG) {
2414              System.out.println("======================================");
2415              System.out.println("performTraversals -- after measure");
2416              host.debug();
2417          }
2418  
2419          return windowSizeMayChange;
2420      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74

3.3.2 窗口布局阶段(relayoutWindow)

 /frameworks/base/core/java/android/view/ViewRootImpl.java
7748      private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
7749              boolean insetsPending) throws RemoteException {
7750  
              ...
7776          //向WMS请求改变窗口尺寸 activity的宽高放在了mTmpFrames中
7777          int relayoutResult = mWindowSession.relayout(mWindow, params,
7778                  (int) (mView.getMeasuredWidth() * appScale + 0.5f),
7779                  (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
7780                  insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
7781                  mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
7782                  mTempControls, mSurfaceSize);
              ...
7813  
7814          if (mTranslator != null) {
7815              mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame);
7816              mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
7817              mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls);
7818          }
     		  //将WMS计算的窗口的尺寸保存在 mWinFrame中
7819          setFrame(mTmpFrames.frame);
              ...
7824          return relayoutResult;
7825      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

3.3.3 测量阶段(performMeasure)

performeasure是View的测量过程,确定各个view的尺寸的过程,对于View只需要完成自身的测量即可,对于viewgroup除了测量自身还需要调用各个子view的measure进行递归

/frameworks/base/core/java/android/view/ViewRootImpl.java
3602      private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
3603          if (mView == null) {
3604              return;
3605          }
3606          Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");
3607          try {
3608              mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
3609          } finally {
3610              Trace.traceEnd(Trace.TRACE_TAG_VIEW);
3611          }
3612      }
/frameworks/base/core/java/android/view/View.java
25736      public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
    
               ...
25745  
25746          // Suppress sign extension for the low bytes
               //把widthMeasureSpec和heightMeasureSpec拼接起来作为缓存的key
25747          long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
25748          if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2);
25749  
25750          final boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
25751  
25752          // Optimize layout by avoiding an extra EXACTLY pass when the view is
25753          // already measured as the correct size. In API 23 and below, this
25754          // extra pass is required to make LinearLayout re-distribute weight.
25755          final boolean specChanged = widthMeasureSpec != mOldWidthMeasureSpec
25756                  || heightMeasureSpec != mOldHeightMeasureSpec;
25757          final boolean isSpecExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY
25758                  && MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY;
25759          final boolean matchesSpecSize = getMeasuredWidth() == MeasureSpec.getSize(widthMeasureSpec)
25760                  && getMeasuredHeight() == MeasureSpec.getSize(heightMeasureSpec);
25761          final boolean needsLayout = specChanged
25762                  && (sAlwaysRemeasureExactly || !isSpecExactly || !matchesSpecSize);
25763          //forceLayout是mPrivateFlags中存在PFLAG_FORCE_LAYOUT标志
25764          if (forceLayout || needsLayout) {
25765              // first clears the measured dimension flag
25766              mPrivateFlags &= ~PFLAG_MEASURED_DIMENSION_SET;
25767  
25768              resolveRtlPropertiesIfNeeded();
25769              // 尝试从缓存中取出测量值
25770              int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key);
25771              if (cacheIndex < 0 || sIgnoreMeasureCache) {
25772                  // measure ourselves, this should set the measured dimension flag back
                       //触发view的onMersure
25773                  onMeasure(widthMeasureSpec, heightMeasureSpec);
25774                  mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
25775              } else {
25776                  long value = mMeasureCache.valueAt(cacheIndex);
25777                  // Casting a long to int drops the high 32 bits, no mask needed
25778                  setMeasuredDimensionRaw((int) (value >> 32), (int) value);
25779                  mPrivateFlags3 |= PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
25780              }
25781  
25782              // flag not set, setMeasuredDimension() was not invoked, we raise
25783              // an exception to warn the developer
25784              if ((mPrivateFlags & PFLAG_MEASURED_DIMENSION_SET) != PFLAG_MEASURED_DIMENSION_SET) {
25785                  throw new IllegalStateException("View with id " + getId() + ": "
25786                          + getClass().getName() + "#onMeasure() did not set the"
25787                          + " measured dimension by calling"
25788                          + " setMeasuredDimension()");
25789              }
25790  
25791              mPrivateFlags |= PFLAG_LAYOUT_REQUIRED;
25792          }
25793  
25794          mOldWidthMeasureSpec = widthMeasureSpec;
25795          mOldHeightMeasureSpec = heightMeasureSpec;
25796  
25797          mMeasureCache.put(key, ((long) mMeasuredWidth) << 32 |
25798                  (long) mMeasuredHeight & 0xffffffffL); // suppress sign extension
25799      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

因为之前传进来的mView指的是DecorView,所以onMeasure执行到DecorView的onMeasure ViewGroup没有实现onMearsure的方法,所以都是其子类实现的,例如FrameLayout,LinearLayout等等,在这些子类的onMearsure实现中会对其子View进行调用measure方法:

/frameworks/base/core/java/com/android/internal/policy/DecorView.java
698      @Override
699      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
             //计算DecorView的宽高
760          ...
             //调用父类的onMeasure 来递归调用其子view的measure方法
761          super.onMeasure(widthMeasureSpec, heightMeasureSpec);
762  
             //计算宽高
788  
789          // TODO: Support height?
790  
791          if (measure) {
792              super.onMeasure(widthMeasureSpec, heightMeasureSpec);
793          }
794      }

/frameworks/base/core/java/android/widget/FrameLayout.java
178      @Override
179      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
             //1.获取子view的个数
180          int count = getChildCount();
190  
191          for (int i = 0; i < count; i++) {
192              final View child = getChildAt(i);
193              if (mMeasureAllChildren || child.getVisibility() != GONE) {
                     //2.测量调用子view的measure方法
194                  measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
195                  final LayoutParams lp = (LayoutParams) child.getLayoutParams();
196                  maxWidth = Math.max(maxWidth,
197                          child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
198                  maxHeight = Math.max(maxHeight,
199                          child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
200                  childState = combineMeasuredStates(childState, child.getMeasuredState());
201                  if (measureMatchParentChildren) {
202                      if (lp.width == LayoutParams.MATCH_PARENT ||
203                              lp.height == LayoutParams.MATCH_PARENT) {
204                          mMatchParentChildren.add(child);
205                      }
206                  }
207              }
208          }
209          //3.设置FrameLayout本身的宽高
225          setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
226                  resolveSizeAndState(maxHeight, heightMeasureSpec,
227                          childState << MEASURED_HEIGHT_STATE_SHIFT));
228  
229          count = mMatchParentChildren.size();
230          if (count > 1) {
231              for (int i = 0; i < count; i++) {
                      ...
262                  //4.计算match_parent的子view的宽高
263                  child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
264              }
265          }
266      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

流程图如下:

在这里插入图片描述

Measure的总结:

MeasureSpec是由specMode和specSize组成的

DecorView其MeasureSpec由窗口尺寸和自身的LayoutParams决定

普通View其MeasureSpec由父容器的MeasureSpec和自身的LayoutParams决定

View的measure方法是final的无法重载,自定义View只能重载其onMeasure来实现测量

View测量后的大小是通过setMeasuredDimension保存下来的,之后再通过getMeasuredWidth和getMeasuredHeight获取到的

3.3.4 布局过程(performLayout)

当所有的View自身的大小测量完毕后就要开始确定他们在窗口中的位置就是布局过程主要是ViewGroup确定子View和子Viewgroup的位置

padding:是控件的内容相对控件的边缘的边距.

margin :是控件边缘相对父空间的边距

/frameworks/base/core/java/android/view/ViewRootImpl.java
3665      private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
3666              int desiredWindowHeight) {
              //1. desiredWindowWidth 和 desiredWindowHeight这边传过来的是当前Window的宽高(mWidth,mHeight)
3667          mScrollMayChange = true;
3668          mInLayout = true;
3669  
3670          final View host = mView;
3671          if (host == null) {
3672              return;
3673          }
3674          if (DEBUG_ORIENTATION || DEBUG_LAYOUT) {
3675              Log.v(mTag, "Laying out " + host + " to (" +
3676                      host.getMeasuredWidth() + ", " + host.getMeasuredHeight() + ")");
3677          }
3678  
3679          Trace.traceBegin(Trace.TRACE_TAG_VIEW, "layout");
3680          try {
                  //2.调用DecorView的layout 传入的参数分别是左 上 右 下 mInLayout layout标记
3681              host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
3682              
3683              mInLayout = false;
                  //处理一些View调用requestLayout的请求
3684              int numViewsRequestingLayout = mLayoutRequesters.size();
3685              if (numViewsRequestingLayout > 0) {
3686                  // requestLayout() was called during layout.
3687                  // If no layout-request flags are set on the requesting views, there is no problem.
3688                  // If some requests are still pending, then we need to clear those flags and do
3689                  // a full request/measure/layout pass to handle this situation.
3690                  ArrayList<View> validLayoutRequesters = getValidLayoutRequesters(mLayoutRequesters,
3691                          false);
3692                  if (validLayoutRequesters != null) {
                          ...
                          //重新对View进行测量和布局
3706                      measureHierarchy(host, lp, mView.getContext().getResources(),
3707                              desiredWindowWidth, desiredWindowHeight);
3708                      mInLayout = true;
3709                      host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
3710  
3711                      mHandlingLayoutInLayoutRequest = false;
3712                      //如果还有其他的请求放到下次执行
3713                      // Check the valid requests again, this time without checking/clearing the
3714                      // layout flags, since requests happening during the second pass get noop'd
3715                      validLayoutRequesters = getValidLayoutRequesters(mLayoutRequesters, true);
3716                      if (validLayoutRequesters != null) {
3717                          final ArrayList<View> finalRequesters = validLayoutRequesters;
3718                          // Post second-pass requests to the next frame
3719                          getRunQueue().post(new Runnable() {
3720                              @Override
3721                              public void run() {
3722                                  int numValidRequests = finalRequesters.size();
3723                                  for (int i = 0; i < numValidRequests; ++i) {
3724                                      final View view = finalRequesters.get(i);
3725                                      Log.w("View", "requestLayout() improperly called by " + view +
3726                                              " during second layout pass: posting in next frame");
3727                                      view.requestLayout();
3728                                  }
3729                              }
3730                          });
3731                      }
3732                  }
3733  
3734              }
3735          } finally {
3736              Trace.traceEnd(Trace.TRACE_TAG_VIEW);
3737          }
3738          mInLayout = false;
3739      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

主要看一下DecorView的layout做了什么,在DecorView.java中没有找到layout函数,所以他的父类的layout函数最后一路找到了View.java的layout

/frameworks/base/core/java/android/view/View.java
23128      public void layout(int l, int t, int r, int b) {
               //1.判断是否需要重新测量
23129          if ((mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) != 0) {
23130              onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec);
23131              mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
23132          }
23133          //2.保存当前的View的位置
23134          int oldL = mLeft;
23135          int oldT = mTop;
23136          int oldB = mBottom;
23137          int oldR = mRight;
23138          //3.设置当前视图的左 顶 右 底的位置,并判断布局是否改变
23139          boolean changed = isLayoutModeOptical(mParent) ?
23140                  setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b);
23141          //4.如果布局改变了,或者mPrivateFlags的PFLAG_LAYOUT_REQUIRED被标记了
23142          if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
                   //回调到DecorView的onLayout
23143              onLayout(changed, l, t, r, b);
23144  
23145              if (shouldDrawRoundScrollbar()) {
23146                  if(mRoundScrollbarRenderer == null) {
23147                      mRoundScrollbarRenderer = new RoundScrollbarRenderer(this);
23148                  }
23149              } else {
23150                  mRoundScrollbarRenderer = null;
23151              }
23152              //清楚标记
23153              mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED;
23154  
23155              ListenerInfo li = mListenerInfo;
23156              if (li != null && li.mOnLayoutChangeListeners != null) {
23157                  ArrayList<OnLayoutChangeListener> listenersCopy =
23158                          (ArrayList<OnLayoutChangeListener>)li.mOnLayoutChangeListeners.clone();
23159                  int numListeners = listenersCopy.size();
23160                  for (int i = 0; i < numListeners; ++i) {
23161                      listenersCopy.get(i).onLayoutChange(this, l, t, r, b, oldL, oldT, oldR, oldB);
23162                  }
23163              }
23164          }
23165  
23166          final boolean wasLayoutValid = isLayoutValid();
23167  
23168          mPrivateFlags &= ~PFLAG_FORCE_LAYOUT;
23169          mPrivateFlags3 |= PFLAG3_IS_LAID_OUT;
               ...
23206      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

布局的操作是在setFrame里setOpticalFrame最后也是将四个位置的值改变后调用的setFrame;

/frameworks/base/core/java/android/view/View.java
23250      protected boolean setFrame(int left, int top, int right, int bottom) {
23251          boolean changed = false;
23252  
23253          if (DBG) {
23254              Log.d(VIEW_LOG_TAG, this + " View.setFrame(" + left + "," + top + ","
23255                      + right + "," + bottom + ")");
23256          }
23257          //1.判断当前的顶点是否需要改变
23258          if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) {
23259              changed = true;
23260              
23261              // Remember our drawn bit
23262              int drawn = mPrivateFlags & PFLAG_DRAWN;
23263             
23264              int oldWidth = mRight - mLeft;
23265              int oldHeight = mBottom - mTop;
23266              int newWidth = right - left;
23267              int newHeight = bottom - top;
                   //判断View的大小是否改变
23268              boolean sizeChanged = (newWidth != oldWidth) || (newHeight != oldHeight);
23269  
23270              // Invalidate our old position
                   //重新绘制
23271              invalidate(sizeChanged);
23272              //设置四个顶点的位置
23273              mLeft = left;
23274              mTop = top;
23275              mRight = right;
23276              mBottom = bottom;
23277              mRenderNode.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
23278              //设置标志
23279              mPrivateFlags |= PFLAG_HAS_BOUNDS;
23280  
23281              
23282              if (sizeChanged) {
                       //最后会回调到View的onSizeChange函数
23283                  sizeChange(newWidth, newHeight, oldWidth, oldHeight);
23284              }
23285  
23286              if ((mViewFlags & VISIBILITY_MASK) == VISIBLE || mGhostView != null) {
23287                  // If we are visible, force the DRAWN bit to on so that
23288                  // this invalidate will go through (at least to our parent).
23289                  // This is because someone may have invalidated this view
23290                  // before this call to setFrame came in, thereby clearing
23291                  // the DRAWN bit.
23292                  mPrivateFlags |= PFLAG_DRAWN;
23293                  invalidate(sizeChanged);
23294                  // parent display list may need to be recreated based on a change in the bounds
23295                  // of any child
23296                  invalidateParentCaches();
23297              }
23298  
23299              // Reset drawn bit to original value (invalidate turns it off)
23300              mPrivateFlags |= drawn;
23301  
23302              mBackgroundSizeChanged = true;
23303              mDefaultFocusHighlightSizeChanged = true;
23304              if (mForegroundInfo != null) {
23305                  mForegroundInfo.mBoundsChanged = true;
23306              }
23307  
23308              notifySubtreeAccessibilityStateChangedIfNeeded();
23309          }
23310          return changed;
23311      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

setFrame中可以看到四个顶点的值被写入到View的成员变量mLeft,mRight,mTop和mRight中接着回到onLayout

onLayout在View中是一个空函数,可实现可不实现,而在ViewGroup中是一个抽象函数,其子类必须实现。接着看Decorview的onLayout:

/frameworks/base/core/java/com/android/internal/policy/DecorView.java
796      @Override
797      protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
798          super.onLayout(changed, left, top, right, bottom);
             ...
816      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

主要是调用了父类的onLayout也就是FrameLayout:

/frameworks/base/core/java/android/widget/FrameLayout.java
268      @Override
269      protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
270          layoutChildren(left, top, right, bottom, false /* no force left gravity */);
271      }
273      void layoutChildren(int left, int top, int right, int bottom, boolean forceLeftGravity) {
274          final int count = getChildCount();
275  
276          final int parentLeft = getPaddingLeftWithForeground();
277          final int parentRight = right - left - getPaddingRightWithForeground();
278  
279          final int parentTop = getPaddingTopWithForeground();
280          final int parentBottom = bottom - top - getPaddingBottomWithForeground();
281  
282          for (int i = 0; i < count; i++) {
283              final View child = getChildAt(i);
284              if (child.getVisibility() != GONE) {
                     //只有child可见时才会布局
285                  final LayoutParams lp = (LayoutParams) child.getLayoutParams();
286  
287                  final int width = child.getMeasuredWidth();
288                  final int height = child.getMeasuredHeight();
289  
290                  int childLeft;
291                  int childTop;
292  
                     //计算子view的left和top,剩下的根据width和height计算即可
                     ...
331  
332                  child.layout(childLeft, childTop, childLeft + width, childTop + height);
333              }
334          }
335      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

Layout小结:Layout主要时ViewGroup确定子view的位置,一般View不需要重载,View设置为Gone后不会调用onLayout,必须在View布局完之后调用getWidth和getHeight才能得到正确的宽高。主要流程如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MbHbMVeW-1642062245360)(D:\文档\image\layout执行流程.webp)]

3.3.5 绘制过程(performDraw)

绘制过程就是将View绘制到界面上看一下时如何绘制的

/frameworks/base/core/java/android/view/ViewRootImpl.java
4128      private void performDraw() {
4129          if (mAttachInfo.mDisplayState == Display.STATE_OFF && !mReportNextDraw) {
4130              return;
4131          } else if (mView == null) {
4132              return;
4133          }
4134  
4135          final boolean fullRedrawNeeded =
4136                  mFullRedrawNeeded || mReportNextDraw || mNextDrawUseBlastSync;
4137          mFullRedrawNeeded = false;
4138          //1.标志绘制开始
4139          mIsDrawing = true;
4140          Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");
4141  
4142          boolean usingAsyncReport = addFrameCompleteCallbackIfNeeded();
4143          addFrameCallbackIfNeeded();
4144          //2.调用draw开始绘制
4145          try {
4146              boolean canUseAsync = draw(fullRedrawNeeded);
4147              if (usingAsyncReport && !canUseAsync) {
4148                  mAttachInfo.mThreadedRenderer.setFrameCompleteCallback(null);
4149                  usingAsyncReport = false;
4150              }
4151          } finally {
                  //3.标志绘制结束
4152              mIsDrawing = false;
4153              Trace.traceEnd(Trace.TRACE_TAG_VIEW);
4154          }
4155  
             ...
4202      }

4281      private boolean draw(boolean fullRedrawNeeded) {
4282          Surface surface = mSurface;
                    ...
4445  
4446                  if (!drawSoftware(surface, mAttachInfo, xOffset, yOffset,
4447                          scalingRequired, dirty, surfaceInsets)) {
4448                      return false;
4449                  }
4450              }
4451          }
4452  
4453          if (animating) {
4454              mFullRedrawNeeded = true;
4455              scheduleTraversals();
4456          }
4457          return useAsyncReport;
4458      }

4460      /**
4461       * @return true if drawing was successful, false if an error occurred
4462       */
4463      private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,
4464              boolean scalingRequired, Rect dirty, Rect surfaceInsets) {
4465           
4466          // Draw with software renderer.
4467          final Canvas canvas;
				  ...
4484              //1.从surface中锁定一块画布
4485              canvas = mSurface.lockCanvas(dirty);
                  //2.调用View的draw在画布上绘制图像
4538              mView.draw(canvas);
4539  
4540              drawAccessibilityFocusedDrawableIfNeeded(canvas);
4541          } finally {
4542              try {
                      //3.解锁画布并发送数据
4543                  surface.unlockCanvasAndPost(canvas);
4544              } catch (IllegalArgumentException e) {
4545                  Log.e(mTag, "Could not unlock surface", e);
4546                  mLayoutRequested = true;    // ask wm for a new surface next time.
4547                  //noinspection ReturnInsideFinallyBlock
4548                  return false;
4549              }
4550  
4551              if (LOCAL_LOGV) {
4552                  Log.v(mTag, "Surface " + surface + " unlockCanvasAndPost");
4553              }
4554          }
4555          return true;
4556      }
4557  

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

3.4 Activity创建流程总结

在这里插入图片描述

四、Surface图形系统概览

4.1 app绘制流程

​ activity 的view在ViewRootImpl发起的performTraversals后开始绘制流程 测量 布局 绘制

绘制是通过图形处理引擎来绘制的

2D:Canvas 封装了skia的实现

3D:OpenGl ES 将窗口flag的WindowManager.LayoutParams.MEMORY_TYPE_GPU位置为1即可使用OpenGL ES引擎绘制

4.2 一些重要的类

4.2.1Surface

​ 每一个Window对应一个Surface,View需要画在Surface的Canvas上,在3.3.5节的绘制过程中可以知道绘制的时候会首先从surface中lock一块画布用来绘制

绘制调用的Canvas的api 底层是skia的封装,绘制完成后数据存在了Canvas中最后通过Surface传递给底层去消费。图形数据的传输是通过Buffer来传递的,Surface是对Buffer的封装,surface内部有多个Buffer,管理Buffer的流程如下:

在这里插入图片描述

1.消费者本地对象注册一个帧可用的监听

2.上层app通过surface请求buffer来绘制view (Surface.LockCanvas)

3.BufferQueue出列一个Buffer给app去绘制View

4.上层app拿到这个Buffer后进行绘制并将数据保存在Buffer后通过Surface将Buffer入队到BufferQueue (surface.unlockCanvasAndPost)

5.当Buffer入队时,会触发监听,这时SurfaceFlinger就知道有一个Buffer准备完成了,他就会调用acquireBuffer去消费Buffer中的数据进行合成,当消费完成后,Buffer会被重新release到BufferQueue中等待下一才的调用。

在上面这个流程中,Buffer的状态有以下几种:

​ 1.Free 可被上层使用

​ 2.Dequeued:出列正在被上层使用

​ 3.Queued:入列,等待surfaceFlinger合成

​ 4.Acquired:被获取,SurfaceFlinger持有该Buffer进行合成

4.2.2 SurfaceFlinger

SurfaceFlinger是一个单独的进程,接受所有的Surface作为输入,创建Layer(其主要组件是一个BufferQueue)与Surface一一对应,接着根据Zorder,透明度,大小位置等参数,计算出Layer在最终合成图像中的位置,接着交给HWComposer或者OpenGL生成最终的栅格化数据,放到Layer的FrameBuffer中

4.2.3 Layer

Layer是SurfaceFlinger合成的基本操作单元,其主要组件是一个BufferQueue。Layer在应用请求创建Surface时创建,因此Layer和surface时一一对应的,Layer中有一个FrameBuffer,用来放HWComposer或者OpenGL生成的栅格化数据,每一个FrameBuffer都有两个GraphicBuffer一个FrontBuffer和一个BackBuffer。

4.2.4 Hardware Composer

Hardware Composer HAL(HWC) 时Android3.0引入的,它的主要功能是通过可用硬件确定组合缓冲区的最有效方式。

1)SurfaceFlinger为HWC提供完整的layers的列表并且和HWC进行通信

2)HWComposer根据硬件的性能来决定是使用硬件图层合成器还是GPU合成分别将每个layer打上标记(overlay或者GLES composition)来响应。

3)SurfaceFlinger处理需要GPU合成的layer,接着将结果交给HWComposer来显示,需要硬件图层合成的就直接将layer交给HWComposer去合成并显示

4)合成layer时优先使用HWComposer来合成,如果HWComposer无法解决,SurfaceFlinger调用OpenGL标准接口去合成。

在上面的流程中SurfaceFlinger合成Layer叫做离线合成,因为需要surfaceflinger需要先将所有图层绘制到一个最终的framebuffer上,再将FrameBuffer送给LCD曲线是,这个合成和送显一般时异步的。而HWComposer则是在线合成,在LCD需要某一行数据时,HWComposer直接将所有与该行相关的图层的数据取出合成一行像素数据送给LCD显示,当只有一个图层数据时,又叫overlay技术。

显示数据的产生、传送合成的过程如下:

在这里插入图片描述

4.3 Screen显示

显示屏上的内容是从硬件缓冲区中读取出来的,大致的读取过程时从buffer的起始地址从上到下,从左到右扫描整个buffer将内容映射到显示屏上。硬件缓冲器一般是双缓冲结构,一个FrontBuffer用来给屏幕显示,一个BackBuffer用于后台合成下一帧的图形。

如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zbcdLB1n-1642062245361)(D:\文档\image\硬件帧缓冲区.webp)]

假设前一帧内容显示完毕,并且后一帧的内容准备好了,那么就将前后缓冲区进行角色互换。

4.4 总结

在这里插入图片描述

Window加载View时会新建一个ViewRootImpl,ViewRootImpl会新建一个Surface,接着调用ViewRootImpl的setView首先绘制图形,测量确定view的大小,布局确定View的位置,绘制时会向surface请求一个buffer,接着调用Canvas(skia引擎)在Buffer中绘制图形并将图形数据保存在buffer中接着通过surface将图形数据发送给SurfaceFlinger,SurfaceFlinger接收到Buffer中的数据后将数据合成栅格化后设置到Surface创建时内部创建的和surface一一对应的layer的framebuffer中,接着将layers自己调用OpenGL接口合成或者交给HWComposer进行合成,最终送到屏幕显示。

4.5 CPU/GPU合成速率和Display刷新率同步问题

基本概念:

屏幕刷新率(HZ):代表屏幕在一秒内刷新屏幕的次数 即一秒钟内显示多少帧

系统帧速率(FPS):代表系统在一秒钟内合成的帧数,由系统算法和硬件决定

屏幕刷新率代表了屏幕消费显示内容的速度,系统帧速率决定了生产显示内容的速度,是一个典型的生产消费的模型,非常需要做好同步。

Android从4.1开始引入了三个核心元素来优化同步问题:Vsync,Tripple Buffer和Choreographer;

4.5.1 Vsync(垂直同步)

垂直同步(Vsync):当屏幕从帧缓冲区扫描完一帧到屏幕后,在扫描下一帧的内容前发出一个同步信号,这个信号用来切换前缓冲区和后缓冲区。很明显这个信号是以屏幕刷新率为基准的,原因是系统和成帧的速率是可以调整的,但是屏幕显示的帧速率是固定的。

CPU和GPU的分工:

CPU:Measure Layout,纹理和多边形的生成,发送纹理和多边形到GPU

GPU:将CPU生成的纹理和多边形进行格栅化和合成

1)没有Vsync的例子:
在这里插入图片描述

没有Vsync会出现两种情况

1.屏幕卡顿:这种情况是当屏幕刷新率比系统合成帧速率快出现的一种情况,也就是上图的情况,此时前缓冲区的内容已经显示到屏幕上,但是系统尚未准备好后缓冲区的内容,屏幕只好接着显示上一帧的内容,造成一帧内容显示多次。

2.屏幕撕裂:这种情况是当系统合成帧速率比屏幕刷新率快时出现的一种情况,此时屏幕还未完全把前缓冲区的内容完全显示到屏幕上,而系统已经准备好下一帧,并要求读取下一帧到屏幕上,导致屏幕上半部分是上一帧的图形,下半部分是下一帧的图形,造成屏幕上显示多帧。

所以为了解决屏幕撕裂,Google 引入了Vsync垂直同步信号,用来控制系统合成帧速率和屏幕刷新率的同步。

2)引入Vsync后:

在这里插入图片描述

可以看到当CPU收到Vsync信号后才会开始绘制下一帧的内容。Vsync只能解决屏幕撕裂,如果CPU/GPU的合成速率高于屏幕刷新率,那么CPU和GPU就出现了空闲状态。但是如果CPU/GPU的合成速率低于屏幕刷新率就会出现下面这个情况:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kux1o2Zi-1642062245362)(D:\文档\image\屏幕卡顿.webp)]

上面这个情况是在第一个16ms处GPU使用一个buffer,屏幕使用一个Buffer,CPU没有buffer可用导致了CPU的空闲,但是GPU的速率又太慢导致屏幕在显示完A帧后B帧还未准备好,所以系统只能继续显示A帧。造成了卡顿,如果这时有第三个buffer给CPU使用,那么在第一个16ms处CPU就可以使用第三个buffer来合成数据。不至于导致后面的每一帧都卡顿。所以Google又引入了三重缓冲区

4.5.2 Tripple Buffer

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bJ81QsK8-1642062245362)(D:\文档\image\引入三重缓冲区.webp)]

这样一来虽然在第一帧仍然会卡顿一次,但是后面的就流畅了。Buffer也不是越多越好,因为buffer多了CPU合成的数据会有延迟才能被显示。

单Buffer:图形撕裂

双buffer:解决图形撕裂,但是卡顿明显且CPU利用率低

三Buffer:优化卡顿,提供高CPU、GPU利用率,但是引入了延迟问题

4.5.3 Choreographer

Vsync信号光是切换前后缓冲区的,没有控制上层的绘制节奏,也就是说上层的生产节奏和屏幕的显示节奏是脱离的,那么显示内容的合成还是无法同步。

所以Google在4.1引入了Choreographer如下:

在这里插入图片描述

Choreographer是Google为上层设计的一个类作为上层Vsync信号的接收者,类图如下:

在这里插入图片描述

Choreographer需要想SurfaceFlinger中注册一个Vsync接收器DiaplayEventReceiver,同时在内部维护了一个CallbackQueues 用来保存上层关心Vsync信号的组件比如ViewRootImpl,TextView,ValueAnimator等等.

Vsync信号控制上层绘制的流程图如下:

在这里插入图片描述

上层绘制UI基本都是调用requestLayout或者invalidate触发更新视图的请求

大致流程如下:

requestLayout或者invalidate触发更新视图的请求,请求被传递到ViewRootimpl中,ViewRootImpl向主线程中加入一个阻塞器,该阻塞器会拦截所有的同步请求,也就是说此时我们向主线程中发送的所有的同步消息都不会得到执行。接着ViewRootImpl向Choreographer注册一个callback,当Choreographer收到底层上传的Vsync信号后向主线程MessageQueue发送一个异步消息,之前加入的阻塞器只能拦截同步消息,无法拦截异步消息所以Choreographer发送给主线程的消息可以得到执行,执行者是ViewRootImpl开始下一帧的绘制,当然在绘制前会移除阻塞器。

五、APP和SurfaceFlinger的通信

在2.2小节中我们知道了当Activtiy的显示最终会走到ViewRootImpl的setView,在ViewRootImpl的setView函数中主要有两步和显示息息相关

1.调用requestLayout来绘制View,实际上requestLayout只是向Choreographer注册了回调接口还未真正地进行绘制。

2.调用mWindowSession.addToDisplayAsUser这个操作其实是在View绘制之前。

5.1 app和SurfaceFlinger建立连接

首先mWindowSession是WindowManagerGlobal.getWindowSession,由于WindowManagerGlobal是一个单例,所以mWindowSeesion也是一个进程只有一个对象负责和WMS进行通信所以addToDisplayAsUser最终执行者是WMS的addWindow

/frameworks/base/services/core/java/com/android/server/wm/Session.java
200      public int addToDisplayAsUser(IWindow window, WindowManager.LayoutParams attrs,
201              int viewVisibility, int displayId, int userId, InsetsState requestedVisibility,
202              InputChannel outInputChannel, InsetsState outInsetsState,
203              InsetsSourceControl[] outActiveControls) {
    			//mService是WindowManagerService
204          return mService.addWindow(this, window, attrs, viewVisibility, displayId, userId,
205                  requestedVisibility, outInputChannel, outInsetsState, outActiveControls);
206      }
		 //后面会用到
638      void windowAddedLocked() {
639           ...
648          if (mSurfaceSession == null) {
649              if (DEBUG) {
650                  Slog.v(TAG_WM, "First window added to " + this + ", creating SurfaceSession");
651              }
                 //新建SurfaceSession和SurfaceFlinger建立联系
652              mSurfaceSession = new SurfaceSession();
653              ProtoLog.i(WM_SHOW_TRANSACTIONS, "  NEW SURFACE SESSION %s", mSurfaceSession);
                 //将当前的Session加入到WMS的mSessions中
654              mService.mSessions.add(this);
655              if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
656                  mService.dispatchNewAnimatorScaleLocked(this);
657              }
658          }
659          mNumWindow++;
660      }

/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
1457      public int addWindow(Session session, IWindow client, LayoutParams attrs, int viewVisibility,
1458              int displayId, int requestUserId, InsetsState requestedVisibility,
1459              InputChannel outInputChannel, InsetsState outInsetsState,
1460              InsetsSourceControl[] outActiveControls) {
    		....
                  //WindowState是系统层对Window管理的封装类,和Window是一一对应的关系
1662              final WindowState win = new WindowState(this, session, client, token, parentWindow,
1663                      appOp[0], attrs, viewVisibility, session.mUid, userId,
1664                      session.mCanAddInternalSystemWindow);
			....
                  win.attach();
    
}
/frameworks/base/services/core/java/com/android/server/wm/WindowState.java
1171      void attach() {
1172          if (DEBUG) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
1173          mSession.windowAddedLocked();//mSession是系统这边的Session
1174      }    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

windowAddedLocked会创建SurfaceSession并将当前的Session添加到WMS的mSessions中主要看一下SurfaceSession的创建过程他和app与surfaceFlinger的建立有关系。

SurfaceSession初始化对象时会通过JNI调用NativeCreate创建一个SurfaceComposerClient,当SurfaceComposerClient调用incStrong进行引用计数加一时, SurfaceComposerClient的ononFirstRef就会执行

/frameworks/native/libs/gui/SurfaceComposerClient.cpp
1792  void SurfaceComposerClient::onFirstRef() {
1793      sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1794      if (sf != nullptr && mStatus == NO_INIT) {
1795          sp<ISurfaceComposerClient> conn;
1796          conn = sf->createConnection();//conn获得了SurfaceFlinger对象
1797          if (conn != nullptr) {
1798              mClient = conn;
1799              mStatus = NO_ERROR;
1800          }
1801      }
1802  }

92  /*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
93      ComposerService& instance = ComposerService::getInstance();
94      Mutex::Autolock _l(instance.mLock);
95      if (instance.mComposerService == nullptr) {
96          if (ComposerService::getInstance().connectLocked()) {
97              ALOGD("ComposerService reconnected");
98          }
99      }
100      return instance.mComposerService;
101  }
68  bool ComposerService::connectLocked() {
69      const String16 name("SurfaceFlinger");
70      mComposerService = waitForService<ISurfaceComposer>(name);
71      if (mComposerService == nullptr) {
72          return false; // fatal error or permission problem
73      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

ComposerService是一个单例模式,用来获取SurfaceFlinger的代理对象并保存在成员变量mComposerService中,接着SurfaceComposerClient通过ComposerService的代理接口调用createConnection和SurfaceFlinger建立联系

这里主要的逻辑关系是这样的,ComposerService作为一个Client和SurfaceFlinger作为Server进行Binder IPC通信,而SurfaceComposerClient则是作为一个Client和ComposerService作为Server进行Binder IPC进行通信,他们的关系如下图:

在这里插入图片描述

简单来说ComposerService是作为一个桥梁连接了SurfaceComposerClient和SurfaceFlinger。

5.2 app请求SurfaceFlinger创建Surface

Surface的创建是发生在View的绘制流程中,也就是ViewRootImpl在接收到Choreographer发送的Vsync信号异步消息后才会执行View的绘制即3.3小节的内容,View的绘制总共有5个阶段,创建Surface主要是在第二阶段窗口布局阶段,RelayoutWindow。

/frameworks/base/core/java/android/view/ViewRootImpl.java
6518      private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
6519              boolean insetsPending) throws RemoteException {
6520  
              ...
              //1.创建一个mSurfaceControl对象
7777          int relayoutResult = mWindowSession.relayout(mWindow, params,
7778                  (int) (mView.getMeasuredWidth() * appScale + 0.5f),
7779                  (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
7780                  insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
7781                  mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
7782                  mTempControls, mSurfaceSize);
7783          mPendingBackDropFrame.set(mTmpFrames.backdropFrame);
7784          if (mSurfaceControl.isValid()) {
7785              if (!useBLAST()) {
                      //2.将mSurfaceControl中的surface拷贝给当前的mSurface
7786                  mSurface.copyFrom(mSurfaceControl);
7787              } else {
7788                  final Surface blastSurface = getOrCreateBLASTSurface();
7789                  // If blastSurface == null that means it hasn't changed since the last time we
7790                  // called. In this situation, avoid calling transferFrom as we would then
7791                  // inc the generation ID and cause EGL resources to be recreated.
7792                  if (blastSurface != null) {
7793                      mSurface.transferFrom(blastSurface);
7794                  }
7795              }
7796              if (mAttachInfo.mThreadedRenderer != null) {
7797                  if (HardwareRenderer.isWebViewOverlaysEnabled()) {
7798                      addPrepareSurfaceControlForWebviewCallback();
7799                      addASurfaceTransactionCallback();
7800                  }
7801                  mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl);
7802              }
7803          } else {
7804              destroySurface();
7805          }
              ...
6569          return relayoutResult;
6570      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

5.2.1 RelayoutWindow

relayout最终通过Session调用到WMS的relayoutWindow

/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
1864      public int relayoutWindow(Session session, IWindow client, int seq, LayoutParams attrs,
1865              int requestedWidth, int requestedHeight, int viewVisibility, int flags,
1866              long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
1867              Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame,
1868              DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration,
1869              Surface outSurface) {
    	  ....
2370              if (shouldRelayout) {
2371                  try {
2372                      result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
2373                  } catch (Exception e) {
2374                      displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/);
2375  
2376                      ProtoLog.w(WM_ERROR,
2377                              "Exception thrown when creating surface for client %s (%s). %s",
2378                              client, win.mAttrs.getTitle(), e);
2379                      Binder.restoreCallingIdentity(origId);
2380                      return 0;
2381                  }
2382              }
2383  
    	  ...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

其中createSurfaceControl是创建surface的主要函数

/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
2597      private int createSurfaceControl(SurfaceControl outSurfaceControl, int result,
2598              WindowState win, WindowStateAnimator winAnimator) {
2599          if (!win.mHasSurface) {
2600              result |= RELAYOUT_RES_SURFACE_CHANGED;
2601          }
2602  
2603          WindowSurfaceController surfaceController;
2604          try {
2605              Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl");
2606              surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type);
2607          } finally {
2608              Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
2609          }
2610          if (surfaceController != null) {
2611              surfaceController.getSurfaceControl(outSurfaceControl);
2612              ProtoLog.i(WM_SHOW_TRANSACTIONS, "OUT SURFACE %s: copied", outSurfaceControl);
2613  
2614          } else {
2615              // For some reason there isn't a surface.  Clear the
2616              // caller's object so they see the same state.
2617              ProtoLog.w(WM_ERROR, "Failed to create surface control for %s", win);
2618              outSurfaceControl.release();
2619          }
2620  
2621          return result;
2622      }
/frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java
304      WindowSurfaceController createSurfaceLocked(int windowType) {
    	 ...
311              w.setHasSurface(false);
         ...
352              mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), width,
353                      height, format, flags, this, windowType);
354              mSurfaceController.setColorSpaceAgnostic((attrs.privateFlags
355                      & WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0);
356  
357              mSurfaceFormat = format;
358              
359              w.setHasSurface(true);
    	 ...
}

    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

在创建WindowSurfaceController时会通过Builder模式创建一个SurfaceControl而SurfaceControl在创建的过程中会创建一个Native层的对象

1408      private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
1409              SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView,
1410              String callsite)
1411                      throws OutOfResourcesException, IllegalArgumentException {
1412          if (name == null) {
1413              throw new IllegalArgumentException("name must not be null");
1414          }
1415  
1416          mName = name;
1417          mWidth = w;
1418          mHeight = h;
1419          mLocalOwnerView = localOwnerView;
1420          Parcel metaParcel = Parcel.obtain();
1421          try {
1422              if (metadata != null && metadata.size() > 0) {
1423                  metaParcel.writeInt(metadata.size());
1424                  for (int i = 0; i < metadata.size(); ++i) {
1425                      metaParcel.writeInt(metadata.keyAt(i));
1426                      metaParcel.writeByteArray(
1427                              ByteBuffer.allocate(4).order(ByteOrder.nativeOrder())
1428                                      .putInt(metadata.valueAt(i)).array());
1429                  }
1430                  metaParcel.setDataPosition(0);
1431              }
                  //native层的Surface对象
1432              mNativeObject = nativeCreate(session, name, w, h, format, flags,
1433                      parent != null ? parent.mNativeObject : 0, metaParcel);
1434          } finally {
1435              metaParcel.recycle();
1436          }
1437          if (mNativeObject == 0) {
1438              throw new OutOfResourcesException(
1439                      "Couldn't allocate SurfaceControl native object");
1440          }
1441          mNativeHandle = nativeGetHandle(mNativeObject);
1442          mCloseGuard.openWithCallSite("release", callsite);
1443      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

接着通过JNI调用到SurfaceComposerClient.cpp的createSurfaceChecked中创建一个native层的surface并将引用计数加一

/frameworks/native/libs/gui/SurfaceComposerClient.cpp
1874  status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
1875                                                       PixelFormat format,
1876                                                       sp<SurfaceControl>* outSurface, uint32_t flags,
1877                                                       const sp<IBinder>& parentHandle,
1878                                                       LayerMetadata metadata,
1879                                                       uint32_t* outTransformHint) {
1880      sp<SurfaceControl> sur;
1881      status_t err = mStatus;
1882  
1883      if (mStatus == NO_ERROR) {
1884          sp<IBinder> handle;
1885          sp<IGraphicBufferProducer> gbp;
1886  
1887          uint32_t transformHint = 0;
1888          int32_t id = -1;
1889          err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
1890                                       &handle, &gbp, &id, &transformHint);
1891  
1892          if (outTransformHint) {
1893              *outTransformHint = transformHint;
1894          }
1895          ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
1896          if (err == NO_ERROR) {
1897              *outSurface =
1898                      new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
1899          }
1900      }
1901      return err;
1902  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

mClient是SurfaceFlinger的代理端,所以最终调用到了SurfaceFlinger的createSurface

/frameworks/native/services/surfaceflinger/Client.cpp
79  status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
80                                 uint32_t flags, const sp<IBinder>& parentHandle,
81                                 LayerMetadata metadata, sp<IBinder>* handle,
82                                 sp<IGraphicBufferProducer>* gbp, int32_t* outLayerId,
83                                 uint32_t* outTransformHint) {
84      // We rely on createLayer to check permissions.
85      return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
86                                   parentHandle, outLayerId, nullptr, outTransformHint);
87  }
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
4289  status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w,
4290                                       uint32_t h, PixelFormat format, uint32_t flags,
4291                                       LayerMetadata metadata, sp<IBinder>* handle,
4292                                       sp<IGraphicBufferProducer>* gbp,
4293                                       const sp<IBinder>& parentHandle, int32_t* outLayerId,
4294                                       const sp<Layer>& parentLayer, uint32_t* outTransformHint) {
         //handle和gbp是需要返回给app端的重要数据
4295      if (int32_t(w|h) < 0) {
4296          ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
4297                  int(w), int(h));
4298          return BAD_VALUE;
4299      }
4300  
4301      ALOG_ASSERT(parentLayer == nullptr || parentHandle == nullptr,
4302              "Expected only one of parentLayer or parentHandle to be non-null. "
4303              "Programmer error?");
4304  
4305      status_t result = NO_ERROR;
4306  
4307      sp<Layer> layer;
4308  
4309      std::string uniqueName = getUniqueLayerName(name.string());
4310  
4311      switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
4312          case ISurfaceComposerClient::eFXSurfaceBufferQueue:
4313          case ISurfaceComposerClient::eFXSurfaceBufferState: {
4314              result = createBufferStateLayer(client, std::move(uniqueName), w, h, flags,
4315                                              std::move(metadata), handle, &layer);
4316              std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter();
4317              if (pendingBufferCounter) {
4318                  std::string counterName = layer->getPendingBufferCounterName();
4319                  mBufferCountTracker.add((*handle)->localBinder(), counterName,
4320                                          pendingBufferCounter);
4321              }
4322          } break;
4323          case ISurfaceComposerClient::eFXSurfaceEffect:
4324              // check if buffer size is set for color layer.
4325              if (w > 0 || h > 0) {
4326                  ALOGE("createLayer() failed, w or h cannot be set for color layer (w=%d, h=%d)",
4327                        int(w), int(h));
4328                  return BAD_VALUE;
4329              }
4330  
4331              result = createEffectLayer(client, std::move(uniqueName), w, h, flags,
4332                                         std::move(metadata), handle, &layer);
4333              break;
4334          case ISurfaceComposerClient::eFXSurfaceContainer:
4335              // check if buffer size is set for container layer.
4336              if (w > 0 || h > 0) {
4337                  ALOGE("createLayer() failed, w or h cannot be set for container layer (w=%d, h=%d)",
4338                        int(w), int(h));
4339                  return BAD_VALUE;
4340              }
4341              result = createContainerLayer(client, std::move(uniqueName), w, h, flags,
4342                                            std::move(metadata), handle, &layer);
4343              break;
4344          default:
4345              result = BAD_VALUE;
4346              break;
4347      }
4348  
4349      if (result != NO_ERROR) {
4350          return result;
4351      }
4352  
4353      bool addToRoot = callingThreadHasUnscopedSurfaceFlingerAccess();
          //此时handle已经创建,但是gbp还没有创建 这个handle就是surfaceflinger的binder代理对象
4354      result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer, addToRoot,
4355                              outTransformHint);
4356      if (result != NO_ERROR) {
4357          return result;
4358      }
4359      mInterceptor->saveSurfaceCreation(layer);
4360  
4361      setTransactionFlags(eTransactionNeeded);
4362      *outLayerId = layer->sequence;
4363      return result;
4364  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89

创建好SurfaceControler对象后就进入第二阶段从SurfaceControl中的对象copy到mSurface

5.2.2 Surface.copyFrom

/frameworks/base/core/java/android/view/Surface.java
594      public void copyFrom(SurfaceControl other) {
595          if (other == null) {
596              throw new IllegalArgumentException("other must not be null");
597          }
598          //1.获取传进来的SurfaceControler的native对象的指针
599          long surfaceControlPtr = other.mNativeObject;
600          if (surfaceControlPtr == 0) {
601              throw new NullPointerException(
602                      "null SurfaceControl native object. Are you using a released SurfaceControl?");
603          }
             //2.获取surfaceControler中的surface对象并传给mNativeObject
604          long newNativeObject = nativeGetFromSurfaceControl(mNativeObject, surfaceControlPtr);
605          updateNativeObject(newNativeObject);
606      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

nativeGetFromSurfaceControl则通过JNI调用到SurfaceControl.cpp的getSurface

/frameworks/native/libs/gui/SurfaceControl.cpp
135  sp<Surface> SurfaceControl::generateSurfaceLocked()
136  {
137      uint32_t ignore;
138      auto flags = mCreateFlags & (ISurfaceComposerClient::eCursorWindow |
139                                   ISurfaceComposerClient::eOpaque);
         //这边会调用SurfaceFlinger去创建一个bbq-wrapper的SurfaceControler
    140      mBbqChild = mClient->createSurface(String8("bbq-wrapper"), 0, 0, mFormat,
141                                         flags, mHandle, {}, &ignore);
         //将name为bbq-wrapper的surface创建为一个name为“bbq-adapter”的BLASTBufferQueue
142      mBbq = sp<BLASTBufferQueue>::make("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);
143  
144      // This surface is always consumed by SurfaceFlinger, so the
145      // producerControlledByApp value doesn't matter; using false.
146      mSurfaceData = mBbq->getSurface(true);
147  
148      return mSurfaceData;
149  }
150  
151  sp<Surface> SurfaceControl::getSurface()
152  {
153      Mutex::Autolock _l(mLock);
154      if (mSurfaceData == nullptr) {
155          return generateSurfaceLocked();
156      }
157      return mSurfaceData;
158  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

所以获取Surface对象时,先创建一个name为bbq-wrapper的SurfaceControler中,接着将SurfaceControlerb包装成一个bbq-adapter的BLASTBufferQueue,最终从BLASTBufferQueue获取一个带SurfaceControler的handle的Surface对象。先看BLASTBufferQueue时如何创建的:

/frameworks/native/libs/gui/BLASTBufferQueue.cpp
133  BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface,
134                                     int width, int height, int32_t format)
135        : mSurfaceControl(surface),
136          mSize(width, height),
137          mRequestedSize(mSize),
138          mFormat(format),
139          mNextTransaction(nullptr) {
         //创建BufferQueue并将生产者和消费之赋给mProducer和mConsumer具体流程见5.3.1
140      createBufferQueue(&mProducer, &mConsumer);
141      // since the adapter is in the client process, set dequeue timeout
142      // explicitly so that dequeueBuffer will block
143      mProducer->setDequeueTimeout(std::numeric_limits<int64_t>::max());
144  
145      // safe default, most producers are expected to override this
146      mProducer->setMaxDequeuedBufferCount(2);
147      mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer,
148                                                        GraphicBuffer::USAGE_HW_COMPOSER |
149                                                                GraphicBuffer::USAGE_HW_TEXTURE,
150                                                        1, false);
151      static int32_t id = 0;
152      mName = name + "#" + std::to_string(id);
153      auto consumerName = mName + "(BLAST Consumer)" + std::to_string(id);
154      mQueuedBufferTrace = "QueuedBuffer - " + mName + "BLAST#" + std::to_string(id);
155      id++;
156      mBufferItemConsumer->setName(String8(consumerName.c_str()));
157      mBufferItemConsumer->setFrameAvailableListener(this);
158      mBufferItemConsumer->setBufferFreedListener(this);
159      mBufferItemConsumer->setDefaultBufferSize(mSize.width, mSize.height);
160      mBufferItemConsumer->setDefaultBufferFormat(convertBufferFormat(format));
161      mBufferItemConsumer->setBlastBufferQueue(this);
162  
163      ComposerService::getComposerService()->getMaxAcquiredBufferCount(&mMaxAcquiredBuffers);
164      mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBuffers);
165  
166      mTransformHint = mSurfaceControl->getTransformHint();
167      mBufferItemConsumer->setTransformHint(mTransformHint);
168      SurfaceComposerClient::Transaction()
169              .setFlags(surface, layer_state_t::eEnableBackpressure,
170                        layer_state_t::eEnableBackpressure)
171              .setApplyToken(mApplyToken)
172              .apply();
173      mNumAcquired = 0;
174      mNumFrameAvailable = 0;
175      BQA_LOGV("BLASTBufferQueue created width=%d height=%d format=%d mTransformHint=%d", width,
176               height, format, mTransformHint);
177  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

接着getSurface就会将mProducer放到Surface总返回给app

/frameworks/native/libs/gui/BLASTBufferQueue.cpp
688  sp<Surface> BLASTBufferQueue::getSurface(bool includeSurfaceControlHandle) {
    	 //includeSurfaceControlHandle = true
689      std::unique_lock _lock{mMutex};
690      sp<IBinder> scHandle = nullptr;
691      if (includeSurfaceControlHandle && mSurfaceControl) {
692          scHandle = mSurfaceControl->getHandle();
693      }
694      return new BBQSurface(mProducer, true, scHandle, this);
695  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

其中BBQSurface是一个继承于Surface的类,返回给app的Surface包含了mProducer和SurfaceFlinger的代理对象

这个mProducer则是提供GraphicBuffer给APP用来绘制UI的,继承于BufferQueueProducer,其中提供给APP的GraphicBuffer则是从mSlots中获取的,最多可以提供64个BufferSlot 。

5.2.3 小结

Android12 将整个BufferQueue的生产消费机制全部放在了应用进程中去实现,只有在最后将APP的绘制的数据交给SF时才涉及到跨进程,另外申请GraphicBuffer时在构造函数中调用initHandle来进行内存映射

关于一些ConsumeListener的机制,在创建Consumer时,会去new 一个BufferQuqueConsumer,接着将mConsumer作为参数新建一个

5.3 BufferQueue的生产消费机制

我们知道Android系统绘制的大概流程是

1.消费者本地对象注册一个帧可用的监听

2.上层app通过surface请求buffer来绘制view (Surface.LockCanvas)

3.BufferQueue出列一个Buffer给app去绘制View

4.上层app拿到这个Buffer后进行绘制并将数据保存在Buffer后通过Surface将Buffer入队到BufferQueue (surface.unlockCanvasAndPost)

5.当Buffer入队时,会触发监听,这时SurfaceFlinger就知道有一个Buffer准备完成了,他就会调用acquireBuffer去消费Buffer中的数据进行合成,当消费完成后,Buffer会被重新release到BufferQueue中等待下一才的调用。(这一步在Android12中略有不同)

5.3.1 BufferQueue的创建

从5.2.2可以知道BufferQueue的创建是在创建BLASTBufferQueue时的createBufferQueue中完成的

797  void BLASTBufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
798                                           sp<IGraphicBufferConsumer>* outConsumer) {
799      LOG_ALWAYS_FATAL_IF(outProducer == nullptr, "BLASTBufferQueue: outProducer must not be NULL");
800      LOG_ALWAYS_FATAL_IF(outConsumer == nullptr, "BLASTBufferQueue: outConsumer must not be NULL");
801  
802      sp<BufferQueueCore> core(new BufferQueueCore());
803      LOG_ALWAYS_FATAL_IF(core == nullptr, "BLASTBufferQueue: failed to create BufferQueueCore");
804  
805      sp<IGraphicBufferProducer> producer(new BBQBufferQueueProducer(core));
806      LOG_ALWAYS_FATAL_IF(producer == nullptr,
807                          "BLASTBufferQueue: failed to create BBQBufferQueueProducer");
808  
809      sp<BufferQueueConsumer> consumer(new BufferQueueConsumer(core));
810      consumer->setAllowExtraAcquire(true);
811      LOG_ALWAYS_FATAL_IF(consumer == nullptr,
812                          "BLASTBufferQueue: failed to create BufferQueueConsumer");
813  
814      *outProducer = producer;
815      *outConsumer = consumer;
816  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

createBufferQueue主要就是创建了BufferQueueCore并以这个core为参数创建了BBQBufferQueueProducer和BufferQueueConsumer
BufferQueueCore是BufferQueue的核心,生产者和消费者都需要通过BufferQueueCore来管理buffer,其中会创建一个64个BufferSlotmSlots数组,而BufferSlot中有一个mGraphicBuffer成员用来存储Buffer的数据,BufferState 用来记录buffer的状态。
接着回到BLASTBufferQueue的构造函数中,将BufferQueueConsumer为参数创建了mBufferItemConsumer。

BufferItemConsumer继承于ConsumerBase并且在初始化的时候会调用ConsumerBase的构造函数,在ConsumerBase的构造函数中可以看到如下代码:

/frameworks/native/libs/gui/ConsumerBase.cpp
58  ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) :
59          mAbandoned(false),
60          mConsumer(bufferQueue),
61          mPrevFinalReleaseFence(Fence::NO_FENCE) {
62      // Choose a name using the PID and a process-unique ID.
63      mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
64      //此处的bufferQueue就是创建BufferItemConsumer时传进来的BufferQueueConsumer
65      // Note that we can't create an sp<...>(this) in a ctor that will not keep a
66      // reference once the ctor ends, as that would cause the refcount of 'this'
67      // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
68      // that's what we create.
69      wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
70      sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
71  
72      status_t err = mConsumer->consumerConnect(proxy, controlledByApp);
73      if (err != NO_ERROR) {
74          CB_LOGE("ConsumerBase: error connecting to BufferQueue: %s (%d)",
75                  strerror(-err), err);
76      } else {
77          mConsumer->setConsumerName(mName);
78      }
79  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

由于ConsumerBase继承了ConsumerListener,所以相当于将ConsumerBase作为ConsumerListener传给了BufferQueueConsumer的consumerConnect

在BufferQueueConsumer的头文件中有consumerConnect的实现:

/frameworks/native/libs/gui/include/gui/BufferQueueConsumer.h
165      virtual status_t consumerConnect(const sp<IConsumerListener>& consumer,
166              bool controlledByApp) {
167          return connect(consumer, controlledByApp);
168      }
/frameworks/native/libs/gui/BufferQueueConsumer.cpp
510  status_t BufferQueueConsumer::connect(
511          const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
512      ATRACE_CALL();
         ...
529      mCore->mConsumerListener = consumerListener;
530      mCore->mConsumerControlledByApp = controlledByApp;
532      return NO_ERROR;
533  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

到这里为止BufferQueueCore中的mConsumerListener最终调用到ConsumerBase中。我们可以先看一下ConsumerListener有那些需要实现的:

/frameworks/native/libs/gui/include/gui/IConsumerListener.h
38  class ConsumerListener : public virtual RefBase {
39  public:
40      ConsumerListener() {}
41      virtual ~ConsumerListener();
42  
43      // onDisconnect is called when a producer disconnects from the BufferQueue.
44      virtual void onDisconnect() {} /* Asynchronous */
45  
46      // onFrameDequeued is called when a call to the BufferQueueProducer::dequeueBuffer successfully
47      // returns a slot from the BufferQueue.
48      virtual void onFrameDequeued(const uint64_t) {}
49  
50      // onFrameCancelled is called when the client calls cancelBuffer, thereby releasing the slot
51      // back to the BufferQueue.
52      virtual void onFrameCancelled(const uint64_t) {}
53  
54      // onFrameDetached is called after a successful detachBuffer() call while in asynchronous mode.
55      virtual void onFrameDetached(const uint64_t) {}
56  
57      // onFrameAvailable is called from queueBuffer each time an additional frame becomes available
58      // for consumption. This means that frames that are queued while in asynchronous mode only
59      // trigger the callback if no previous frames are pending. Frames queued while in synchronous
60      // mode always trigger the callback. The item passed to the callback will contain all of the
61      // information about the queued frame except for its GraphicBuffer pointer, which will always be
62      // null (except if the consumer is SurfaceFlinger).
63      //
64      // This is called without any lock held and can be called concurrently by multiple threads.
65      virtual void onFrameAvailable(const BufferItem& item) = 0; /* Asynchronous */
66  
67      // onFrameReplaced is called from queueBuffer if the frame being queued is replacing an existing
68      // slot in the queue. Any call to queueBuffer that doesn't call onFrameAvailable will call this
69      // callback instead. The item passed to the callback will contain all of the information about
70      // the queued frame except for its GraphicBuffer pointer, which will always be null.
71      //
72      // This is called without any lock held and can be called concurrently by multiple threads.
73      virtual void onFrameReplaced(const BufferItem& /* item */) {} /* Asynchronous */
74  
75      // onBuffersReleased is called to notify the buffer consumer that the BufferQueue has released
76      // its references to one or more GraphicBuffers contained in its slots. The buffer consumer
77      // should then call BufferQueue::getReleasedBuffers to retrieve the list of buffers.
78      //
79      // This is called without any lock held and can be called concurrently by multiple threads.
80      virtual void onBuffersReleased() = 0; /* Asynchronous */
81  
82      // onSidebandStreamChanged is called to notify the buffer consumer that the BufferQueue's
83      // sideband buffer stream has changed. This is called when a stream is first attached and when
84      // it is either detached or replaced by a different stream.
85      virtual void onSidebandStreamChanged() = 0; /* Asynchronous */
86  
87      // Notifies the consumer of any new producer-side timestamps and returns the combined frame
88      // history that hasn't already been retrieved.
89      //
90      // WARNING: This method can only be called when the BufferQueue is in the consumer's process.
91      virtual void addAndGetFrameTimestamps(const NewFrameEventsEntry* /*newTimestamps*/,
92                                            FrameEventHistoryDelta* /*outDelta*/) {}
93  };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

重点是几个和frame相关的回调,分别是onFrameDequeued,onFrameAvailable,onFrameReplaced,onFrameDetached,onFrameCancelled这几个回调,看一下ConsumerBase是如何实现这几个回调的。

/frameworks/native/libs/gui/ConsumerBase.cpp
104  void ConsumerBase::onFrameDequeued(const uint64_t bufferId) {
105      CB_LOGV("onFrameDequeued");
106  
107      sp<FrameAvailableListener> listener;
108      {
109          Mutex::Autolock lock(mFrameAvailableMutex);
110          listener = mFrameAvailableListener.promote();
111      }
112  
113      if (listener != nullptr) {
114          listener->onFrameDequeued(bufferId);
115      }
116  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这里以onFrameDequeued为例,可以看出全部又委托给mFrameAvailableListener去做了,那么这个mFrameAvailableListener是在哪里初始化的呢?

回到BLASTBufferQueued额构造函数中有这样一句代码

/frameworks/native/libs/gui/BLASTBufferQueue.cpp
133  BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface,
134                                     int width, int height, int32_t format)
135        : mSurfaceControl(surface),
136          mSize(width, height),
137          mRequestedSize(mSize),
138          mFormat(format),
139          mNextTransaction(nullptr) {
140      createBufferQueue(&mProducer, &mConsumer);
147      mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer,
148                                                        GraphicBuffer::USAGE_HW_COMPOSER |
149                                                                GraphicBuffer::USAGE_HW_TEXTURE,
150                                                        1, false);
151      static int32_t id = 0;
152      mName = name + "#" + std::to_string(id);
153      auto consumerName = mName + "(BLAST Consumer)" + std::to_string(id);
154      mQueuedBufferTrace = "QueuedBuffer - " + mName + "BLAST#" + std::to_string(id);
155      id++;
156      mBufferItemConsumer->setName(String8(consumerName.c_str()));
157      mBufferItemConsumer->setFrameAvailableListener(this);
158      mBufferItemConsumer->setBufferFreedListener(this);
159      mBufferItemConsumer->setDefaultBufferSize(mSize.width, mSize.height);
160      mBufferItemConsumer->setDefaultBufferFormat(convertBufferFormat(format));
161      mBufferItemConsumer->setBlastBufferQueue(this);
         ...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

在上面mBufferItemConsumer将当前的BLASTBufferQueue设置为了mFrameAvailableListener,所以最后BufferQueueCore的consumerlistener的回调全部都在BLASTBufferQueue中处理。

5.3.2 上层app请求Buffer

我们知道上层app的UI绘制会首先调用Surface.LockCanvasl来请求一块buffer来绘制UI,

/frameworks/base/core/java/android/view/Surface.java
428      public Canvas lockCanvas(Rect inOutDirty)
429              throws Surface.OutOfResourcesException, IllegalArgumentException {
430          synchronized (mLock) {
431              checkNotReleasedLocked();
432              if (mLockedObject != 0) {
433                  // Ideally, nativeLockCanvas() would throw in this situation and prevent the
434                  // double-lock, but that won't happen if mNativeObject was updated.  We can't
435                  // abandon the old mLockedObject because it might still be in use, so instead
436                  // we just refuse to re-lock the Surface.
437                  throw new IllegalArgumentException("Surface was already locked");
438              }
439              mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
440              return mCanvas;
441          }
442      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

java层的lockCanvas通过JNI函数nativeLockCanvas调用到native层的surface.cpp的lock函数,申请的是一块 ANativeWindow_Buffer的buffer

/frameworks/native/libs/gui/Surface.cpp
2395  status_t Surface::lock(
2396          ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
2397  {
2398      if (mLockedBuffer != nullptr) {
2399          ALOGE("Surface::lock failed, already locked");
2400          return INVALID_OPERATION;
2401      }
2402  
          ...
2411  
2412      ANativeWindowBuffer* out;
2413      int fenceFd = -1;
          //申请buffer
2414      status_t err = dequeueBuffer(&out, &fenceFd);
2415      ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
2416      if (err == NO_ERROR) {
2417          sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
2418          const Rect bounds(backBuffer->width, backBuffer->height);    
              ...
2475  
2476          if (res != 0) {
2477              err = INVALID_OPERATION;
2478          } else {
2479              mLockedBuffer = backBuffer;
2480              outBuffer->width  = backBuffer->width;
2481              outBuffer->height = backBuffer->height;
2482              outBuffer->stride = backBuffer->stride;
2483              outBuffer->format = backBuffer->format;
2484              outBuffer->bits   = vaddr;
2485          }
2486      }
2487      return err;
2488  }

631  int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
632      ATRACE_CALL();
633      ALOGV("Surface::dequeueBuffer");
634  
635      IGraphicBufferProducer::DequeueBufferInput dqInput;
636      {
            
641  
642          getDequeueBufferInputLocked(&dqInput);
643          //1.如果之前已经申请过Buffer,那么直接返回
644          if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot !=
645                  BufferItem::INVALID_BUFFER_SLOT) {
646              sp<GraphicBuffer>& gbuf(mSlots[mSharedBufferSlot].buffer);
647              if (gbuf != nullptr) {
648                  *buffer = gbuf.get();
649                  *fenceFd = -1;
650                  return OK;
651              }
652          }
653      } // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer
654  
655      int buf = -1;
656      sp<Fence> fence;
657      nsecs_t startTime = systemTime();
658  
659      FrameEventHistoryDelta frameTimestamps;
         //2.确定mSlots中的index
660      status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, dqInput.width,
661                                                              dqInput.height, dqInput.format,
662                                                              dqInput.usage, &mBufferAge,
663                                                              dqInput.getTimestamps ?
664                                                                      &frameTimestamps : nullptr);
665      mLastDequeueDuration = systemTime() - startTime;
666  
         ....
702  
703      if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == nullptr) {
704          if (mReportRemovedBuffers && (gbuf != nullptr)) {
705              mRemovedBuffers.push_back(gbuf);
706          }
             //3.根据index确定具体的buffer
707          result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
708          if (result != NO_ERROR) {
709              ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
710              mGraphicBufferProducer->cancelBuffer(buf, fence);
711              return result;
712          }
713      }
714  
715      if (fence->isValid()) {
716          *fenceFd = fence->dup();
717          if (*fenceFd == -1) {
718              ALOGE("dequeueBuffer: error duping fence: %d", errno);
719              // dup() should never fail; something is badly wrong. Soldier on
720              // and hope for the best; the worst that should happen is some
721              // visible corruption that lasts until the next frame.
722          }
723      } else {
724          *fenceFd = -1;
725      }
726      //4.返回buffer给app
727      *buffer = gbuf.get();
728  
729      if (mSharedBufferMode && mAutoRefresh) {
             //更新mSharedBufferSlot
730          mSharedBufferSlot = buf;
731          mSharedBufferHasBeenQueued = false;
732      } else if (mSharedBufferSlot == buf) {
733          mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
734          mSharedBufferHasBeenQueued = false;
735      }
736  
737      mDequeuedSlots.insert(buf);
738  
739      return OK;
740  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111

上面代码中的dequeueBuffer最终调用到了mGraphicBufferProducer的dequeueBuffer函数中,那么mGraphicBufferProducer是在哪里赋值的呢?我们在5.2.2小节知道我们的Surface是一个继承于Surface的BBQSurface,在创建BBQSurface时传入了一个mProducer,所以最后调用到了mProducer的dequeueBuffer,而mProducer则是一个继承于BufferQueueProducer的BBQBufferQueueProducer。而在BBQBufferQueueProducer并未重写dequeueBuffer,所以最后调用到了下面这个函数:

/frameworks/native/libs/gui/BufferQueueProducer.cpp
379  status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* outFence,
380                                              uint32_t width, uint32_t height, PixelFormat format,
381                                              uint64_t usage, uint64_t* outBufferAge,
382                                              FrameEventHistoryDelta* outTimestamps) {
            ...
439  
440          int found = BufferItem::INVALID_BUFFER_SLOT;
441          while (found == BufferItem::INVALID_BUFFER_SLOT) {
                 //1.先在mSlot数组中查找FREE状态的slot,如果找到了就返回这个slot中的index。
442              status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue, lock, &found);
443              if (status != NO_ERROR) {
444                  return status;
445              }
446  
447              // This should not happen
448              if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
449                  BQ_LOGE("dequeueBuffer: no available buffer slots");
450                  return -EBUSY;
451              }
452  			 //2.然后将返回index的slot的Graphicbuffer赋给buffer变量
473          const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
474          if (mCore->mSharedBufferSlot == found &&
475                  buffer->needsReallocation(width, height, format, BQ_LAYER_COUNT, usage)) {
476              BQ_LOGE("dequeueBuffer: cannot re-allocate a shared"
477                      "buffer");
478  
479              return BAD_VALUE;
480          }
481  
482          if (mCore->mSharedBufferSlot != found) {
483              mCore->mActiveBuffers.insert(found);
484          }
485          *outSlot = found;
486          ATRACE_BUFFER_INDEX(found);
487  
488          attachedByConsumer = mSlots[found].mNeedsReallocation;
489          mSlots[found].mNeedsReallocation = false;
490  
491          mSlots[found].mBufferState.dequeue();
492  
493          if ((buffer == nullptr) ||
494                  buffer->needsReallocation(width, height, format, BQ_LAYER_COUNT, usage))
495          {
496              mSlots[found].mAcquireCalled = false;
497              mSlots[found].mGraphicBuffer = nullptr;
498              mSlots[found].mRequestBufferCalled = false;
499              mSlots[found].mEglDisplay = EGL_NO_DISPLAY;
500              mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
501              mSlots[found].mFence = Fence::NO_FENCE;
502              mCore->mBufferAge = 0;
503              mCore->mIsAllocating = true;
504  
505              returnFlags |= BUFFER_NEEDS_REALLOCATION;
506          } else {
507              // We add 1 because that will be the frame number when this buffer
508              // is queued
509              mCore->mBufferAge = mCore->mFrameCounter + 1 - mSlots[found].mFrameNumber;
510          }
511  
512          BQ_LOGV("dequeueBuffer: setting buffer age to %" PRIu64,
513                  mCore->mBufferAge);
514  
515          if (CC_UNLIKELY(mSlots[found].mFence == nullptr)) {
516              BQ_LOGE("dequeueBuffer: about to return a NULL fence - "
517                      "slot=%d w=%d h=%d format=%u",
518                      found, buffer->width, buffer->height, buffer->format);
519          }
520  
521          eglDisplay = mSlots[found].mEglDisplay;
522          eglFence = mSlots[found].mEglFence;
523          // Don't return a fence in shared buffer mode, except for the first
524          // frame.
525          *outFence = (mCore->mSharedBufferMode &&
526                  mCore->mSharedBufferSlot == found) ?
527                  Fence::NO_FENCE : mSlots[found].mFence;
528          mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
529          mSlots[found].mFence = Fence::NO_FENCE;
530  
531          // If shared buffer mode has just been enabled, cache the slot of the
532          // first buffer that is dequeued and mark it as the shared buffer.
533          if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot ==
534                  BufferQueueCore::INVALID_BUFFER_SLOT) {
535              mCore->mSharedBufferSlot = found;
536              mSlots[found].mBufferState.mShared = true;
537          }
538  
539          if (!(returnFlags & BUFFER_NEEDS_REALLOCATION)) {
540              if (mCore->mConsumerListener != nullptr) {
541                  mCore->mConsumerListener->onFrameDequeued(mSlots[*outSlot].mGraphicBuffer->getId());
542              }
543          }
544      } // Autolock scope
545      //3.判断是否需要申请buffer,如果需要新建一个GraphicBuffer,在GraphicBuffer的构造函数中完成内存映射
546      if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
547          BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
548          sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
549                  width, height, format, BQ_LAYER_COUNT, usage,
550                  {mConsumerName.string(), mConsumerName.size()});
551  
552          status_t error = graphicBuffer->initCheck();
553  
554          { // Autolock scope
555              std::lock_guard<std::mutex> lock(mCore->mMutex);
556  
557              if (error == NO_ERROR && !mCore->mIsAbandoned) {
558                  graphicBuffer->setGenerationNumber(mCore->mGenerationNumber);
559                  mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
560                  if (mCore->mConsumerListener != nullptr) {
                         //4.通知消费者哪个GraphicBuffer出队
561                      mCore->mConsumerListener->onFrameDequeued(
562                              mSlots[*outSlot].mGraphicBuffer->getId());
563                  }
564              }
565  
566              mCore->mIsAllocating = false;
567              mCore->mIsAllocatingCondition.notify_all();
568  
569              if (error != NO_ERROR) {
570                  mCore->mFreeSlots.insert(*outSlot);
571                  mCore->clearBufferSlotLocked(*outSlot);
572                  BQ_LOGE("dequeueBuffer: createGraphicBuffer failed");
573                  return error;
574              }
575  
576              if (mCore->mIsAbandoned) {
577                  mCore->mFreeSlots.insert(*outSlot);
578                  mCore->clearBufferSlotLocked(*outSlot);
579                  BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
580                  return NO_INIT;
581              }
582  
583              VALIDATE_CONSISTENCY();
584          } // Autolock scope
585      }
586  
         ...
615  
616      return returnFlags;
617  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140

dequeueBuffer返回的是一个mSlots的index,后面还要根据这个index从mSlots中取出对应的buffer调用的是requestBuffer,在dequeueBuffer中会判断当前的

mGraphicBuffer是否需要申请,如果需要申请那么会新建一个GraphicBuffer去,并在构造函数中完成内存映射。接着通知消费者那些buffer出队,BLASTBufferQueue接收到通知后主要是记录了出队的时间。

5.3.3 上层app将UI数据写入后将Buffer入队

当上层app使用请求到的Buffer进行UI绘制后会调用Surface.unlockCanvasAndPost将Buffer入队,这一节我们看一下这个流程:

/frameworks/base/core/java/android/view/Surface.java
450      public void unlockCanvasAndPost(Canvas canvas) {
451          synchronized (mLock) {
452              checkNotReleasedLocked();
453  
454              if (mHwuiContext != null) {
455                  mHwuiContext.unlockAndPost(canvas);
456              } else {
457                  unlockSwCanvasAndPost(canvas);
458              }
459          }
460      }
462      private void unlockSwCanvasAndPost(Canvas canvas) {
463          if (canvas != mCanvas) {
464              throw new IllegalArgumentException("canvas object must be the same instance that "
465                      + "was previously returned by lockCanvas");
466          }
467          if (mNativeObject != mLockedObject) {
468              Log.w(TAG, "WARNING: Surface's mNativeObject (0x" +
469                      Long.toHexString(mNativeObject) + ") != mLockedObject (0x" +
470                      Long.toHexString(mLockedObject) +")");
471          }
472          if (mLockedObject == 0) {
473              throw new IllegalStateException("Surface was not locked");
474          }
475          try {
476              nativeUnlockCanvasAndPost(mLockedObject, canvas);
477          } finally {
478              nativeRelease(mLockedObject);
479              mLockedObject = 0;
480          }
481      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

可以看到最终也是通过调用JNI走到native层的surface.cpp

/frameworks/native/libs/gui/Surface.cpp
2490  status_t Surface::unlockAndPost()
2491  {
2492      if (mLockedBuffer == nullptr) {
2493          ALOGE("Surface::unlockAndPost failed, no locked buffer");
2494          return INVALID_OPERATION;
2495      }
2496  
2497      int fd = -1;
          //1.解锁buffer
2498      status_t err = mLockedBuffer->unlockAsync(&fd);
2499      ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
2500      //2.将buffer入队
2501      err = queueBuffer(mLockedBuffer.get(), fd);
2502      ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
2503              mLockedBuffer->handle, strerror(-err));
2504  
2505      mPostedBuffer = mLockedBuffer;
2506      mLockedBuffer = nullptr;
2507      return err;
2508  }
1147  int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
1148      ATRACE_CALL();
1149      ALOGV("Surface::queueBuffer");
1150      Mutex::Autolock lock(mMutex);
1151      //1.定位buffer所在mSlots中的index
1152      int i = getSlotFromBufferLocked(buffer);
1153      if (i < 0) {
1154          if (fenceFd >= 0) {
1155              close(fenceFd);
1156          }
1157          return i;
1158      }
1159      if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) {
1160          if (fenceFd >= 0) {
1161              close(fenceFd);
1162          }
1163          return OK;
1164      }
1165  
1166      IGraphicBufferProducer::QueueBufferOutput output;
1167      IGraphicBufferProducer::QueueBufferInput input;
    	  //将buffer包装成QueueBufferInput
1168      getQueueBufferInputLocked(buffer, fenceFd, mTimestamp, &input);
1169      sp<Fence> fence = input.fence;
1170  
1171      nsecs_t now = systemTime();
          //2.调用mGraphicBufferProducer的queueBuffer
1172      status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
1173      mLastQueueDuration = systemTime() - now;
1174      if (err != OK)  {
1175          ALOGE("queueBuffer: error queuing buffer, %d", err);
1176      }
1177  
1178      onBufferQueuedLocked(i, fence, output);
1179      return err;
1180  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

从上面代码可以看出来主要就是先确定当前buffer在mSlots中的index,接着调用mGraphicBufferProducer的queueBuffer和5.3.1节一样调用到BufferQueueProducer中的queueBuffer

/frameworks/native/libs/gui/BufferQueueProducer.cpp
804  status_t BufferQueueProducer::queueBuffer(int slot,
805          const QueueBufferInput &input, QueueBufferOutput *output) {
806      ATRACE_CALL();
807      ATRACE_BUFFER_INDEX(slot);
808  
809      int64_t requestedPresentTimestamp;
810      bool isAutoTimestamp;
811      android_dataspace dataSpace;
812      Rect crop(Rect::EMPTY_RECT);
813      int scalingMode;
814      uint32_t transform;
815      uint32_t stickyTransform;
816      sp<Fence> acquireFence;
817      bool getFrameTimestamps = false;
         //1.从QueueBufferInput中取出各种参数
818      input.deflate(&requestedPresentTimestamp, &isAutoTimestamp, &dataSpace,
819              &crop, &scalingMode, &transform, &acquireFence, &stickyTransform,
820              &getFrameTimestamps);
821      const Region& surfaceDamage = input.getSurfaceDamage();
822      const HdrMetadata& hdrMetadata = input.getHdrMetadata();
823  
            ...
841  
842      sp<IConsumerListener> frameAvailableListener;
843      sp<IConsumerListener> frameReplacedListener;
            ...
881  
882          BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d"
883                  " validHdrMetadataTypes=0x%x crop=[%d,%d,%d,%d] transform=%#x scale=%s",
884                  slot, mCore->mFrameCounter + 1, requestedPresentTimestamp, dataSpace,
885                  hdrMetadata.validTypes, crop.left, crop.top, crop.right, crop.bottom,
886                  transform,
887                  BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode)));
888          
889          const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
890          Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
891          Rect croppedRect(Rect::EMPTY_RECT);
892          crop.intersect(bufferRect, &croppedRect);
893          if (croppedRect != crop) {
894              BQ_LOGE("queueBuffer: crop rect is not contained within the "
895                      "buffer in slot %d", slot);
896              return BAD_VALUE;
897          }
898  
899          // Override UNKNOWN dataspace with consumer default
900          if (dataSpace == HAL_DATASPACE_UNKNOWN) {
901              dataSpace = mCore->mDefaultBufferDataSpace;
902          }
903  
904          mSlots[slot].mFence = acquireFence;
905          mSlots[slot].mBufferState.queue();
906  
907          // Increment the frame counter and store a local version of it
908          // for use outside the lock on mCore->mMutex.
909          ++mCore->mFrameCounter;
910          currentFrameNumber = mCore->mFrameCounter;
911          mSlots[slot].mFrameNumber = currentFrameNumber;
912          //2.将buffer包装成BufferItem
913          item.mAcquireCalled = mSlots[slot].mAcquireCalled;
914          item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
915          item.mCrop = crop;
916          item.mTransform = transform &
917                  ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
918          item.mTransformToDisplayInverse =
919                  (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
920          item.mScalingMode = static_cast<uint32_t>(scalingMode);
921          item.mTimestamp = requestedPresentTimestamp;
922          item.mIsAutoTimestamp = isAutoTimestamp;
923          item.mDataSpace = dataSpace;
924          item.mHdrMetadata = hdrMetadata;
925          item.mFrameNumber = currentFrameNumber;
926          item.mSlot = slot;
927          item.mFence = acquireFence;
928          item.mFenceTime = acquireFenceTime;
929          item.mIsDroppable = mCore->mAsyncMode ||
930                  (mConsumerIsSurfaceFlinger && mCore->mQueueBufferCanDrop) ||
931                  (mCore->mLegacyBufferDrop && mCore->mQueueBufferCanDrop) ||
932                  (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == slot);
933          item.mSurfaceDamage = surfaceDamage;
934          item.mQueuedBuffer = true;
935          item.mAutoRefresh = mCore->mSharedBufferMode && mCore->mAutoRefresh;
936          item.mApi = mCore->mConnectedApi;
937  
938          mStickyTransform = stickyTransform;
939  
940          // Cache the shared buffer data so that the BufferItem can be recreated.
941          if (mCore->mSharedBufferMode) {
942              mCore->mSharedBufferCache.crop = crop;
943              mCore->mSharedBufferCache.transform = transform;
944              mCore->mSharedBufferCache.scalingMode = static_cast<uint32_t>(
945                      scalingMode);
946              mCore->mSharedBufferCache.dataspace = dataSpace;
947          }
948  
949          output->bufferReplaced = false;
             //3.将bufferItem入队
950          if (mCore->mQueue.empty()) {
951              // When the queue is empty, we can ignore mDequeueBufferCannotBlock
952              // and simply queue this buffer
953              mCore->mQueue.push_back(item);
954              frameAvailableListener = mCore->mConsumerListener;
955          } else {
956              // When the queue is not empty, we need to look at the last buffer
957              // in the queue to see if we need to replace it
958              const BufferItem& last = mCore->mQueue.itemAt(
959                      mCore->mQueue.size() - 1);
960              if (last.mIsDroppable) {
961  
962                  if (!last.mIsStale) {
963                      mSlots[last.mSlot].mBufferState.freeQueued();
964  
965                      // After leaving shared buffer mode, the shared buffer will
966                      // still be around. Mark it as no longer shared if this
967                      // operation causes it to be free.
968                      if (!mCore->mSharedBufferMode &&
969                              mSlots[last.mSlot].mBufferState.isFree()) {
970                          mSlots[last.mSlot].mBufferState.mShared = false;
971                      }
972                      // Don't put the shared buffer on the free list.
973                      if (!mSlots[last.mSlot].mBufferState.isShared()) {
974                          mCore->mActiveBuffers.erase(last.mSlot);
975                          mCore->mFreeBuffers.push_back(last.mSlot);
976                          output->bufferReplaced = true;
977                      }
978                  }
979  
980                  // Make sure to merge the damage rect from the frame we're about
981                  // to drop into the new frame's damage rect.
982                  if (last.mSurfaceDamage.bounds() == Rect::INVALID_RECT ||
983                      item.mSurfaceDamage.bounds() == Rect::INVALID_RECT) {
984                      item.mSurfaceDamage = Region::INVALID_REGION;
985                  } else {
986                      item.mSurfaceDamage |= last.mSurfaceDamage;
987                  }
988  
989                  // Overwrite the droppable buffer with the incoming one
990                  mCore->mQueue.editItemAt(mCore->mQueue.size() - 1) = item;
991                  frameReplacedListener = mCore->mConsumerListener;
992              } else {
993                  mCore->mQueue.push_back(item);
994                  frameAvailableListener = mCore->mConsumerListener;
995              }
996          }
997  
998          mCore->mBufferHasBeenQueued = true;
999          mCore->mDequeueCondition.notify_all();
1000          mCore->mLastQueuedSlot = slot;
1001  
1002          output->width = mCore->mDefaultWidth;
1003          output->height = mCore->mDefaultHeight;
1004          output->transformHint = mCore->mTransformHintInUse = mCore->mTransformHint;
1005          output->numPendingBuffers = static_cast<uint32_t>(mCore->mQueue.size());
1006          output->nextFrameNumber = mCore->mFrameCounter + 1;
1007  
          ...
1036  
1037      // Call back without the main BufferQueue lock held, but with the callback
1038      // lock held so we can ensure that callbacks occur in order
1039  
1040      int connectedApi;
1041      sp<Fence> lastQueuedFence;
1042  
1043      { // scope for the lock
1044          std::unique_lock<std::mutex> lock(mCallbackMutex);
1045          while (callbackTicket != mCurrentCallbackTicket) {
1046              mCallbackCondition.wait(lock);
1047          }
1048          //通知消费者数据已经完成
1049          if (frameAvailableListener != nullptr) {
1050              frameAvailableListener->onFrameAvailable(item);
1051          } else if (frameReplacedListener != nullptr) {
1052              frameReplacedListener->onFrameReplaced(item);
1053          }
1054  
1055          connectedApi = mCore->mConnectedApi;
1056          lastQueuedFence = std::move(mLastQueueBufferFence);
1057  
1058          mLastQueueBufferFence = std::move(acquireFence);
1059          mLastQueuedCrop = item.mCrop;
1060          mLastQueuedTransform = item.mTransform;
1061  
1062          ++mCurrentCallbackTicket;
1063          mCallbackCondition.notify_all();
1064      }
1065  
1066      // Wait without lock held
1067      if (connectedApi == NATIVE_WINDOW_API_EGL) {
1068          // Waiting here allows for two full buffers to be queued but not a
1069          // third. In the event that frames take varying time, this makes a
1070          // small trade-off in favor of latency rather than throughput.
1071          lastQueuedFence->waitForever("Throttling EGL Production");
1072      }
1073  
1074      return NO_ERROR;
1075  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196

buffer入队主要是将buffer包装成BufferItem后push到BufferQueueCore的mQueue中并通知消费者数据已经准备完成,由5.3.1小节我们知道这个消息是在BLASTBufferQueue的onFrameAvailable中处理的。

 /frameworks/native/libs/gui/BLASTBufferQueue.cpp
546  void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) {
547      ATRACE_CALL();
548      std::unique_lock _lock{mMutex};
549  
550      const bool nextTransactionSet = mNextTransaction != nullptr;
551      if (nextTransactionSet) {
552          while (mNumFrameAvailable > 0 || maxBuffersAcquired(false /* includeExtraAcquire */)) {
553              BQA_LOGV("waiting in onFrameAvailable...");
554              mCallbackCV.wait(_lock);
555          }
556      }
557      // add to shadow queue
558      mNumFrameAvailable++;
559      ATRACE_INT(mQueuedBufferTrace.c_str(),
560                 mNumFrameAvailable + mNumAcquired - mPendingRelease.size());
561  
562      BQA_LOGV("onFrameAvailable framenumber=%" PRIu64 " nextTransactionSet=%s", item.mFrameNumber,
563               toString(nextTransactionSet));
564      processNextBufferLocked(nextTransactionSet /* useNextTransaction */);
565  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

5.3.4 SurfaceFlinger消费BufferItem

主要是调用processNextBufferLocked来处理准备好的BufferItem。

/frameworks/native/libs/gui/BLASTBufferQueue.cpp
389  void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) {
390      ATRACE_CALL();
391      // If the next transaction is set, we want to guarantee the our acquire will not fail, so don't
392      // include the extra buffer when checking if we can acquire the next buffer.
393      const bool includeExtraAcquire = !useNextTransaction;
394      if (mNumFrameAvailable == 0 || maxBuffersAcquired(includeExtraAcquire)) {
395          mCallbackCV.notify_all();
396          return;
397      }
398  
399      if (mSurfaceControl == nullptr) {
400          BQA_LOGE("ERROR : surface control is null");
401          return;
402      }
403      //1.构建Transaction进行进程间通讯
404      SurfaceComposerClient::Transaction localTransaction;
405      bool applyTransaction = true;
406      SurfaceComposerClient::Transaction* t = &localTransaction;
407      if (mNextTransaction != nullptr && useNextTransaction) {
408          t = mNextTransaction;
409          mNextTransaction = nullptr;
410          applyTransaction = false;
411      }
412  
413      BufferItem bufferItem;
414      //2.调用mBufferItemConsumer的acquireBuffer取出已经准备好的bufferItem
415      status_t status =
416              mBufferItemConsumer->acquireBuffer(&bufferItem, 0 /* expectedPresent */, false);
417      if (status == BufferQueue::NO_BUFFER_AVAILABLE) {
418          BQA_LOGV("Failed to acquire a buffer, err=NO_BUFFER_AVAILABLE");
419          return;
420      } else if (status != OK) {
421          BQA_LOGE("Failed to acquire a buffer, err=%s", statusToString(status).c_str());
422          return;
423      }
         //3.取出存放UI数据的mGraphicBuffer
424      auto buffer = bufferItem.mGraphicBuffer;
425      mNumFrameAvailable--;
426  
         ...
442  
443      mNumAcquired++;
444      mLastAcquiredFrameNumber = bufferItem.mFrameNumber;
445      ReleaseCallbackId releaseCallbackId(buffer->getId(), mLastAcquiredFrameNumber);
446      mSubmitted[releaseCallbackId] = bufferItem;
447  
448      bool needsDisconnect = false;
449      mBufferItemConsumer->getConnectionEvents(bufferItem.mFrameNumber, &needsDisconnect);
450  
451      // if producer disconnected before, notify SurfaceFlinger
452      if (needsDisconnect) {
453          t->notifyProducerDisconnect(mSurfaceControl);
454      }
455  
456      // Ensure BLASTBufferQueue stays alive until we receive the transaction complete callback.
457      incStrong((void*)transactionCallbackThunk);
458  
459      Rect crop = computeCrop(bufferItem);
460      const bool updateDestinationFrame =
461              bufferItem.mScalingMode == NATIVE_WINDOW_SCALING_MODE_FREEZE ||
462              !mLastBufferInfo.hasBuffer;
         //4.更新最后的Buffer信息
463      mLastBufferInfo.update(true /* hasBuffer */, bufferItem.mGraphicBuffer->getWidth(),
464                             bufferItem.mGraphicBuffer->getHeight(), bufferItem.mTransform,
465                             bufferItem.mScalingMode, crop);
466  
467      auto releaseBufferCallback =
468              std::bind(releaseBufferCallbackThunk, wp<BLASTBufferQueue>(this) /* callbackContext */,
469                        std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
470                        std::placeholders::_4);
         //5.Transaction设置对应layer的属性
         //这里我们将buffer给了ComposerState的state的buffer,相当于我们的UI数据存放在了mComposerStates数组中
471      t->setBuffer(mSurfaceControl, buffer, releaseCallbackId, releaseBufferCallback);
472      t->setDataspace(mSurfaceControl, static_cast<ui::Dataspace>(bufferItem.mDataSpace));
473      t->setHdrMetadata(mSurfaceControl, bufferItem.mHdrMetadata);
474      t->setSurfaceDamageRegion(mSurfaceControl, bufferItem.mSurfaceDamage);
475      t->setAcquireFence(mSurfaceControl,
476                         bufferItem.mFence ? new Fence(bufferItem.mFence->dup()) : Fence::NO_FENCE);
477      t->addTransactionCompletedCallback(transactionCallbackThunk, static_cast<void*>(this));
478      mSurfaceControlsWithPendingCallback.push(mSurfaceControl);
479  
480      if (updateDestinationFrame) {
481          t->setDestinationFrame(mSurfaceControl, Rect(0, 0, mSize.getWidth(), mSize.getHeight()));
482      }
483      t->setBufferCrop(mSurfaceControl, crop);
484      t->setTransform(mSurfaceControl, bufferItem.mTransform);
485      t->setTransformToDisplayInverse(mSurfaceControl, bufferItem.mTransformToDisplayInverse);
486      if (!bufferItem.mIsAutoTimestamp) {
487          t->setDesiredPresentTime(bufferItem.mTimestamp);
488      }
489      t->setFrameNumber(mSurfaceControl, bufferItem.mFrameNumber);
490  
491      if (!mNextFrameTimelineInfoQueue.empty()) {
492          t->setFrameTimelineInfo(mNextFrameTimelineInfoQueue.front());
493          mNextFrameTimelineInfoQueue.pop();
494      }
495  
496      if (mAutoRefresh != bufferItem.mAutoRefresh) {
497          t->setAutoRefresh(mSurfaceControl, bufferItem.mAutoRefresh);
498          mAutoRefresh = bufferItem.mAutoRefresh;
499      }
500      {
501          std::unique_lock _lock{mTimestampMutex};
502          auto dequeueTime = mDequeueTimestamps.find(buffer->getId());
503          if (dequeueTime != mDequeueTimestamps.end()) {
504              Parcel p;
505              p.writeInt64(dequeueTime->second);
506              t->setMetadata(mSurfaceControl, METADATA_DEQUEUE_TIME, p);
507              mDequeueTimestamps.erase(dequeueTime);
508          }
509      }
510  
511      auto mergeTransaction =
512              [&t, currentFrameNumber = bufferItem.mFrameNumber](
513                      std::tuple<uint64_t, SurfaceComposerClient::Transaction> pendingTransaction) {
514                  auto& [targetFrameNumber, transaction] = pendingTransaction;
515                  if (currentFrameNumber < targetFrameNumber) {
516                      return false;
517                  }
518                  t->merge(std::move(transaction));
519                  return true;
520              };
521  
522      mPendingTransactions.erase(std::remove_if(mPendingTransactions.begin(),
523                                                mPendingTransactions.end(), mergeTransaction),
524                                 mPendingTransactions.end());
525  
526      if (applyTransaction) {
             //6.apply使得上面的设置开始生效
527          t->setApplyToken(mApplyToken).apply();
528      }
529  
530      BQA_LOGV("processNextBufferLocked size=%dx%d mFrameNumber=%" PRIu64
531               " applyTransaction=%s mTimestamp=%" PRId64 "%s mPendingTransactions.size=%d"
532               " graphicBufferId=%" PRIu64 "%s transform=%d",
533               mSize.width, mSize.height, bufferItem.mFrameNumber, toString(applyTransaction),
534               bufferItem.mTimestamp, bufferItem.mIsAutoTimestamp ? "(auto)" : "",
535               static_cast<uint32_t>(mPendingTransactions.size()), bufferItem.mGraphicBuffer->getId(),
536               bufferItem.mAutoRefresh ? " mAutoRefresh" : "", bufferItem.mTransform);
537  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141

processNextBufferLockedz主要就是将BufferItem中的各种数据取出填充到SurfaceComposerClient中的Transaction,最终调用Transaction的apply将数据传给SurfaceFlinger去设置layer;

/frameworks/native/libs/gui/SurfaceComposerClient.cpp
820  status_t SurfaceComposerClient::Transaction::apply(bool synchronous) {
821      if (mStatus != NO_ERROR) {
822          return mStatus;
823      }
824      //1.获取SurfaceFlinger的代理
825      sp<ISurfaceComposer> sf(ComposerService::getComposerService());
826      //2.向SF设置一些回调
827      bool hasListenerCallbacks = !mListenerCallbacks.empty();
828      std::vector<ListenerCallbacks> listenerCallbacks;
829      // For every listener with registered callbacks
830      for (const auto& [listener, callbackInfo] : mListenerCallbacks) {
831          auto& [callbackIds, surfaceControls] = callbackInfo;
832          if (callbackIds.empty()) {
833              continue;
834          }
835  
836          if (surfaceControls.empty()) {
837              listenerCallbacks.emplace_back(IInterface::asBinder(listener), std::move(callbackIds));
838          } else {
839              // If the listener has any SurfaceControls set on this Transaction update the surface
840              // state
841              for (const auto& surfaceControl : surfaceControls) {
842                  layer_state_t* s = getLayerState(surfaceControl);
843                  if (!s) {
844                      ALOGE("failed to get layer state");
845                      continue;
846                  }
847                  std::vector<CallbackId> callbacks(callbackIds.begin(), callbackIds.end());
848                  s->what |= layer_state_t::eHasListenerCallbacksChanged;
849                  s->listeners.emplace_back(IInterface::asBinder(listener), callbacks);
850              }
851          }
852      }
853  
854      cacheBuffers();
855  
856      Vector<ComposerState> composerStates;
857      Vector<DisplayState> displayStates;
858      uint32_t flags = 0;
859  
860      mForceSynchronous |= synchronous;
861      //3.将app绘制的UI数据存放到了composerStates中
862      for (auto const& kv : mComposerStates){
863          composerStates.add(kv.second);
864      }
865  
866      displayStates = std::move(mDisplayStates);
867  
868      if (mForceSynchronous) {
869          flags |= ISurfaceComposer::eSynchronous;
870      }
871      if (mAnimation) {
872          flags |= ISurfaceComposer::eAnimation;
873      }
874  
875      // If both mEarlyWakeupStart and mEarlyWakeupEnd are set
876      // it is equivalent for none
877      if (mEarlyWakeupStart && !mEarlyWakeupEnd) {
878          flags |= ISurfaceComposer::eEarlyWakeupStart;
879      }
880      if (mEarlyWakeupEnd && !mEarlyWakeupStart) {
881          flags |= ISurfaceComposer::eEarlyWakeupEnd;
882      }
883  
884      sp<IBinder> applyToken = mApplyToken
885              ? mApplyToken
886              : IInterface::asBinder(TransactionCompletedListener::getIInstance());
887      //4.将UI数据和layer的状态都发送给了SurfaceFlinger使其生效
888      sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,
889                              mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,
890                              {} /*uncacheBuffer - only set in doUncacheBufferTransaction*/,
891                              hasListenerCallbacks, listenerCallbacks, mId);
892      mId = generateId();
893  
894      // Clear the current states and flags
895      clear();
896  
897      mStatus = NO_ERROR;
898      return NO_ERROR;
899  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

六、SurfaceFlinger

SurfaceFlinger运行在一个单独的进程中,主要负责接受所有的Surface作为输入,创建Layer与Surface一一对应,接着根据Zorder,透明度,大小位置等参数,计算出Layer在最终合成图像中的位置,接着交给HWComposer或者OpenGL生成最终的栅格化数据,放到Layer的FrameBuffer中

6.1 SurfaceFlinger的启动流程

SurfaceFlinger(以下简称SF)是由init进程解析surfaceflinger.rc启动的。

/frameworks/native/services/surfaceflinger/surfaceflinger.rc
1 service surfaceflinger /system/bin/surfaceflinger
2     class core animation
3     user system
4     group graphics drmrpc readproc
5     capabilities SYS_NICE
6     onrestart restart zygote
7     task_profiles HighPerformance
8     socket pdx/system/vr/display/client     stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
9     socket pdx/system/vr/display/manager    stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
10     socket pdx/system/vr/display/vsync      stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

启动SF进程时会先执行main_surfaceflinger.cpp中的main函数:

/frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
80  int main(int, char**) {
81      signal(SIGPIPE, SIG_IGN);
82  
83      hardware::configureRpcThreadpool(1 /* maxThreads */,
84              false /* callerWillJoin */);
85      //1.启动内存分配服务
86      startGraphicsAllocatorService();
87  
88      // When SF is launched in its own process, limit the number of
89      // binder threads to 4.
        //2.设置SF的binder线程数为4
90      ProcessState::self()->setThreadPoolMaxThreadCount(4);
        ....  
118      // start the thread pool
         //3.开启SF的binder线程池
119      sp<ProcessState> ps(ProcessState::self());
120      ps->startThreadPool();
         ...
         //4.初始化SurfaceFlinger
129      // instantiate surfaceflinger
130      sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
131  
132      // Set the minimum policy of surfaceflinger node to be SCHED_FIFO.
133      // So any thread with policy/priority lower than {SCHED_FIFO, 1}, will run
134      // at least with SCHED_FIFO policy and priority 1.
135      if (errorInPriorityModification == 0) {
136          flinger->setMinSchedulerPolicy(SCHED_FIFO, newPriority);
137      }
138  
139      setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
140  
141      set_sched_policy(0, SP_FOREGROUND);
142  
143      // Put most SurfaceFlinger threads in the system-background cpuset
144      // Keeps us from unnecessarily using big cores
145      // Do this after the binder thread pool init
146      if (cpusets_enabled()) set_cpuset_policy(0, SP_SYSTEM);
147    
148      // initialize before clients can connect
149      flinger->init();
150      //5.将SF加入servicemanager的管理
151      // publish surface flinger
152      sp<IServiceManager> sm(defaultServiceManager());
153      sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
154                     IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
155      //6.启动DisplayService
156      startDisplayService(); // dependency on SF getting registered above
157  
158      if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) {
159          ALOGW("Couldn't set to SCHED_FIFO: %s", strerror(errno));
160      }
161      //7.在SF进程主线程中启动SurfaceFlinger的run方法
162      // run surface flinger in this thread
163      flinger->run();
164  
165      return 0;
166  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

从上面代码可以看到SF进程在启动时主要做了以下几件事:

1.启动内存分配服务,主要是为BufferQueue中的GraphicBuffer申请共享内存

2.设置SF的binder线程,并开启线程池

3.初始化SurfaceFlinger加入servicemanager的管理

4.启动DisplayService

5.调用 flinger->run()使得SurfaceFlinger开始工作

6.2 SurfaceFlinger的初始化

在调用createSurfaceFlinger会新建一个SurfaceFlinger对象,对象新建后会调用到onFirstRef

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
491  void SurfaceFlinger::onFirstRef() {
492      mEventQueue->init(this);
493  }
  • 1
  • 2
  • 3
  • 4

在onFirstRef中会初始化一个事件队列,mEventQueue是一个MessageQueue主要用来进行图层的合成。接着调用了flinger->init()进行SurfaceFlinger的初始化操作:

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
774  void SurfaceFlinger::init() {
775      ALOGI(  "SurfaceFlinger's main thread ready to run. "
776              "Initializing graphics H/W...");
777      Mutex::Autolock _l(mStateLock);
778      //1.创建渲染引擎并设置给SurfaceFlinger
779      // Get a RenderEngine for the given display / config (can't fail)
780      // TODO(b/77156734): We need to stop casting and use HAL types when possible.
781      // Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.
782      mCompositionEngine->setRenderEngine(renderengine::RenderEngine::create(
783              renderengine::RenderEngineCreationArgs::Builder()
784                      .setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
785                      .setImageCacheSize(maxFrameBufferAcquiredBuffers)
786                      .setUseColorManagerment(useColorManagement)
787                      .setEnableProtectedContext(enable_protected_contents(false))
788                      .setPrecacheToneMapperShaderOnly(false)
789                      .setSupportsBackgroundBlur(mSupportsBlur)
790                      .setContextPriority(
791                              useContextPriority
792                                      ? renderengine::RenderEngine::ContextPriority::REALTIME
793                                      : renderengine::RenderEngine::ContextPriority::MEDIUM)
794                      .build()));
795  
796      // Set SF main policy after initializing RenderEngine which has its own policy.
797      if (!SetTaskProfiles(0, {"SFMainPolicy"})) {
798          ALOGW("Failed to set main task profile");
799      }
800  
801      mCompositionEngine->setTimeStats(mTimeStats);
802      mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName));
803      mCompositionEngine->getHwComposer().setCallback(this);
804      ClientCache::getInstance().setRenderEngine(&getRenderEngine());
805  
806      if (base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false)) {
807          enableHalVirtualDisplays(true);
808      }
809       //2.初始化Vsync信号机制
810      // Process any initial hotplug and resulting display changes.
811      processDisplayHotplugEventsLocked();
812      const auto display = getDefaultDisplayDeviceLocked();
813      LOG_ALWAYS_FATAL_IF(!display, "Missing internal display after registering composer callback.");
814      const auto displayId = display->getPhysicalId();
815      LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(displayId),
816                          "Internal display is disconnected.");
817  
818      // initialize our drawing state
819      mDrawingState = mCurrentState;
820      //3.初始化显示设备
821      // set initial conditions (e.g. unblank default device)
822      initializeDisplays();
823      //4.初始化电量监控
824      mPowerAdvisor.init();
825  
826      char primeShaderCache[PROPERTY_VALUE_MAX];
827      property_get("service.sf.prime_shader_cache", primeShaderCache, "1");
828      if (atoi(primeShaderCache)) {
829          if (setSchedFifo(false) != NO_ERROR) {
830              ALOGW("Can't set SCHED_OTHER for primeCache");
831          }
832  
833          mRenderEnginePrimeCacheFuture = getRenderEngine().primeCache();
834  
835          if (setSchedFifo(true) != NO_ERROR) {
836              ALOGW("Can't set SCHED_OTHER for primeCache");
837          }
838      }
839  
840      getRenderEngine().onPrimaryDisplaySizeChanged(display->getSize());
841  
842      // Inform native graphics APIs whether the present timestamp is supported:
843     //5.创建并启动PropertySetThread
844      const bool presentFenceReliable =
845              !getHwComposer().hasCapability(hal::Capability::PRESENT_FENCE_IS_NOT_RELIABLE);
846      mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);
847  
848      if (mStartPropertySetThread->Start() != NO_ERROR) {
849          ALOGE("Run StartPropertySetThread failed!");
850      }
851  
852      ALOGV("Done initializing");
853  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

SurfaceFlinger的初始化主要做了5件事:

1.最重要的事情就是创建初始化了渲染引擎

2.获取默认的显示设备并初始化

3.初始化电量监控

4.创建并启动PropertySetThread

然后调用flinger->run()开始进行图层的合成:

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
509  void SurfaceFlinger::run() {
510      while (true) {
511          mEventQueue->waitMessage();
512      }
513  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

可以看到是一个死循环不断查询mEventQueue的message

SurfaceFlinger中有一个模板函数:

515  template <typename F, typename T>
516  inline std::future<T> SurfaceFlinger::schedule(F&& f) {
517      auto [task, future] = makeTask(std::move(f));
518      mEventQueue->postMessage(std::move(task));
519      return std::move(future);
520  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

主要功能就是将任务发送给mEventQueue中使其得到调度执行。

6.3 Vsync的初始化

在SurfaceFlinger的init函数中调用过processDisplayHotplugEventsLocked,在其中创建Display时会调用initScheduler如下:

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
2571  void SurfaceFlinger::processDisplayHotplugEventsLocked() {
2572      for (const auto& event : mPendingHotplugEvents) {
2573          std::optional<DisplayIdentificationInfo> info =
2574                  getHwComposer().onHotplug(event.hwcDisplayId, event.connection);
2575  
2576          if (!info) {
2577              continue;
2578          }
2579  
2580          const auto displayId = info->id;
2581          const auto it = mPhysicalDisplayTokens.find(displayId);
2582  
2583          if (event.connection == hal::Connection::CONNECTED) {
2584              DisplayModes supportedModes;
2585              DisplayModePtr activeMode;
2586              loadDisplayModes(displayId, supportedModes, activeMode);
2587  
2588              if (it == mPhysicalDisplayTokens.end()) {
2589                  ALOGV("Creating display %s", to_string(displayId).c_str());
2590  
2591                  DisplayDeviceState state;
2592                  state.physical = {.id = displayId,
2593                                    .type = getHwComposer().getDisplayConnectionType(displayId),
2594                                    .hwcDisplayId = event.hwcDisplayId,
2595                                    .deviceProductInfo = std::move(info->deviceProductInfo),
2596                                    .supportedModes = std::move(supportedModes),
2597                                    .activeMode = activeMode};
2598                  state.isSecure = true; // All physical displays are currently considered secure.
2599                  state.displayName = std::move(info->name);
2600  
2601                  sp<IBinder> token = new BBinder();
2602                  mCurrentState.displays.add(token, state);
2603                  mPhysicalDisplayTokens.emplace(displayId, std::move(token));
2604  
2605                  if (event.hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) {
                          //vsync初始化的入口
2606                      initScheduler(state);
2607                  }
2608  
2609                  mInterceptor->saveDisplayCreation(state);
2610              } else {
2611                  ...
2622          } else {
2623              ...
2635      }
2636  
2637      mPendingHotplugEvents.clear();
2638  }    
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
3151  void SurfaceFlinger::initScheduler(const DisplayDeviceState& displayState) {
3152      if (mScheduler) {
3153          // In practice it's not allowed to hotplug in/out the primary display once it's been
3154          // connected during startup, but some tests do it, so just warn and return.
3155          ALOGW("Can't re-init scheduler");
3156          return;
3157      }
          ...
3174  
3175      // start the EventThread用来分发Vsync信号
3176      mScheduler = getFactory().createScheduler(*mRefreshRateConfigs, *this);
3177      const auto configs = mVsyncConfiguration->getCurrentConfigs();
3178      const nsecs_t vsyncPeriod = currRefreshRate.getPeriodNsecs();
3179      mAppConnectionHandle =
3180              mScheduler->createConnection("app", mFrameTimeline->getTokenManager(),
3181                                           /*workDuration=*/configs.late.appWorkDuration,
3182                                           /*readyDuration=*/configs.late.sfWorkDuration,
3183                                           impl::EventThread::InterceptVSyncsCallback());
3184      mSfConnectionHandle =
3185              mScheduler->createConnection("appSf", mFrameTimeline->getTokenManager(),
3186                                           /*workDuration=*/std::chrono::nanoseconds(vsyncPeriod),
3187                                           /*readyDuration=*/configs.late.sfWorkDuration,
3188                                           [this](nsecs_t timestamp) {
3189                                               mInterceptor->saveVSyncEvent(timestamp);
3190                                           });
3191      //调用mEventQueue的initVsync来初始化Vsync机制
3192      mEventQueue->initVsync(mScheduler->getVsyncDispatch(), *mFrameTimeline->getTokenManager(),
3193                             configs.late.sfWorkDuration);
3194  
         ...
3213  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

可以看到最终调用到了mEventQueue的initVsync来初始化Vsync机制;

/frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
120  void MessageQueue::initVsync(scheduler::VSyncDispatch& dispatch,
121                               frametimeline::TokenManager& tokenManager,
122                               std::chrono::nanoseconds workDuration) {
123      setDuration(workDuration);
124      mVsync.tokenManager = &tokenManager;
125      mVsync.registration = std::make_unique<
126              scheduler::VSyncCallbackRegistration>(dispatch,
127                                                    std::bind(&MessageQueue::vsyncCallback, this,
128                                                              std::placeholders::_1,
129                                                              std::placeholders::_2,
130                                                              std::placeholders::_3),
131                                                    "sf");
132  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

mEventQueue的initVsync就是将vsyncCallback注册给了EventThread,当有Vsync信号产生时就会调用到vsyncCallback:

/frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
105  void MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime) {
106      ATRACE_CALL();
107      // Trace VSYNC-sf
108      mVsync.value = (mVsync.value + 1) % 2;
109  
110      {
111          std::lock_guard lock(mVsync.mutex);
112          mVsync.lastCallbackTime = std::chrono::nanoseconds(vsyncTime);
113          mVsync.scheduled = false;
114      }
115      mHandler->dispatchInvalidate(mVsync.tokenManager->generateTokenForPredictions(
116                                           {targetWakeupTime, readyTime, vsyncTime}),
117                                   vsyncTime);
118  }
40  void MessageQueue::Handler::dispatchInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTimestamp) {
41      if ((mEventMask.fetch_or() & eventMaskInvalidate) == 0) {
42          mVsyncId = vsyncId;
43          mExpectedVSyncTime = expectedVSyncTimestamp;
44          mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
45      }
46  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

6.4 SurfaceFlinger图层合成过程

6.4.1 图层合成

图层合成就是把多个图层按既定的显示区域,展现到显示屏上。

比如Android手机launcher的主界面图层合成如下:
在这里插入图片描述

6.4.2 Surface合成消息

SurfaceFlinger合成图层依赖于Android的异步消息处理机制,也就是mEventQueue的调度。

mEventQueue是在SurfaceFlinger在创建时在onFirstRef中初始化的。

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
491  void SurfaceFlinger::onFirstRef() {
492      mEventQueue->init(this);
493  }
/frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
68  void MessageQueue::init(const sp<SurfaceFlinger>& flinger) {
69      mFlinger = flinger;
70      mLooper = new Looper(true);
71      mHandler = new Handler(*this);
72  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

主要还是handler的异步机制:调用MessageQueue::Handler::handleMessage来处理INVALIDATE和 REFRESH的消息,最终交给SurfaceFlinger去处理:

frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
53  void MessageQueue::Handler::handleMessage(const Message& message) {
54      switch (message.what) {
55          case INVALIDATE:
56              mEventMask.fetch_and(~eventMaskInvalidate);
57              mQueue.mFlinger->onMessageReceived(message.what, mVsyncId, mExpectedVSyncTime);
58              break;
59          case REFRESH:
60              mEventMask.fetch_and(~eventMaskRefresh);
61              mQueue.mFlinger->onMessageReceived(message.what, mVsyncId, mExpectedVSyncTime);
62              break;
63      }
64  }
65  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

SurfaceFlinger处理INVALIDATE和 REFRESH消息的函数是onMessageReceived:

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
1862  void SurfaceFlinger::onMessageReceived(int32_t what, int64_t vsyncId, nsecs_t expectedVSyncTime) {
1863      switch (what) {
1864          case MessageQueue::INVALIDATE: {
1865              onMessageInvalidate(vsyncId, expectedVSyncTime);
1866              break;
1867          }
1868          case MessageQueue::REFRESH: {
1869              onMessageRefresh();
1870              break;
1871          }
1872      }
1873  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

SurfaceFlinger处理的消息分为两种:

INVALIDATE消息:用于处理layer或者display属性的变化以及layer对应的buffer的更新

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
1875  void SurfaceFlinger::onMessageInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTime) {
         ....
1973      bool refreshNeeded;
1974      {
1975          mTracePostComposition = mTracing.flagIsSet(SurfaceTracing::TRACE_COMPOSITION) ||
1976                  mTracing.flagIsSet(SurfaceTracing::TRACE_SYNC) ||
1977                  mTracing.flagIsSet(SurfaceTracing::TRACE_BUFFERS);
1978          const bool tracePreComposition = mTracingEnabled && !mTracePostComposition;
1979          ConditionalLockGuard<std::mutex> lock(mTracingLock, tracePreComposition);
1980  
1981          mFrameTimeline->setSfWakeUp(vsyncId, frameStart, Fps::fromPeriodNsecs(stats.vsyncPeriod));
1982          //1.layer或者display的属性发生改变调用handleMessageTransaction来处理
1983          refreshNeeded = handleMessageTransaction();
              //2.layer的buffer发生更新调用handleMessageInvalidate来处理
1984          refreshNeeded |= handleMessageInvalidate();
1985          if (tracePreComposition) {
1986              if (mVisibleRegionsDirty) {
1987                  mTracing.notifyLocked("visibleRegionsDirty");
1988              }
1989          }
1990      }
1991  
1992      // Layers need to get updated (in the previous line) before we can use them for
1993      // choosing the refresh rate.
1994      // Hold mStateLock as chooseRefreshRateForContent promotes wp<Layer> to sp<Layer>
1995      // and may eventually call to ~Layer() if it holds the last reference
1996      {
1997          Mutex::Autolock _l(mStateLock);
1998          mScheduler->chooseRefreshRateForContent();
1999      }
2000  
2001      ON_MAIN_THREAD(performSetActiveMode());
2002  
2003      updateCursorAsync();
2004      updateInputFlinger();
2005  
2006      refreshNeeded |= mRepaintEverything;
2007      if (refreshNeeded && CC_LIKELY(mBootStage != BootStage::BOOTLOADER)) {
2008          // Signal a refresh if a transaction modified the window state,
2009          // a new buffer was latched, or if HWC has requested a full
2010          // repaint
2011          if (mFrameStartTime <= 0) {
2012              // We should only use the time of the first invalidate
2013              // message that signals a refresh as the beginning of the
2014              // frame. Otherwise the real frame time will be
2015              // underestimated.
2016              mFrameStartTime = frameStart;
2017          }
2018  
2019          // Run the refresh immediately after invalidate as there is no point going thru the message
2020          // queue again, and to ensure that we actually refresh the screen instead of handling
2021          // other messages that were queued us already in the MessageQueue.
2022          mRefreshPending = true;
              //3.重新渲染
2023          onMessageRefresh();
2024      }
2025      notifyRegionSamplingThread();
2026  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

1.Layer或者Display属性的更新通过调用handleMessageTransaction来处理

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
2028  bool SurfaceFlinger::handleMessageTransaction() {
2029      ATRACE_CALL();
2030  
2031      if (getTransactionFlags(eTransactionFlushNeeded)) {
2032          flushTransactionQueues();
2033      }
2034      uint32_t transactionFlags = peekTransactionFlags();
2035      bool runHandleTransaction =
2036              ((transactionFlags & (~eTransactionFlushNeeded)) != 0) || mForceTraversal;
2037  
2038      if (runHandleTransaction) {
2039          handleTransaction(eTransactionMask);
2040      }
2041  
2042      if (transactionFlushNeeded()) {
2043          setTransactionFlags(eTransactionFlushNeeded);
2044      }
2045  
2046      return runHandleTransaction;
2047  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

handleMessageTransaction主要是通过调用flushTransactionQueues来使app层设置的layer的属性或者display的属性改动生效

2.layer的buffer的更新通过调用handleMessageInvalidate处理

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
2158  bool SurfaceFlinger::handleMessageInvalidate() {
2159      ATRACE_CALL();
2160      bool refreshNeeded = handlePageFlip();
2161  
2162      // Send on commit callbacks
2163      mTransactionCallbackInvoker.sendCallbacks();
2164  
2165      if (mVisibleRegionsDirty) {
2166          computeLayerBounds();
2167      }
2168  
2169      for (auto& layer : mLayersPendingRefresh) {
2170          Region visibleReg;
2171          visibleReg.set(layer->getScreenBounds());
2172          invalidateLayerStack(layer, visibleReg);
2173      }
2174      mLayersPendingRefresh.clear();
2175      return refreshNeeded;
2176  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

handleMessageInvalidate主要是先调用handlePageFlip将需要更新的layer放入mLayersPendingRefresh中,接着对每个需要更新的layer计算脏区域

REFRESH消息:表示SurfaceFlinger需要进行一次合成,通过onMessageRefresh实现,在收到INVALIDATE消息后如果layer或者display的属性发生改变,layer的buffer发生改变,HWC请求一次Repaint,那么会触发一次刷新,调用onMessageRefresh

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
2049  void SurfaceFlinger::onMessageRefresh() {
2050      ATRACE_CALL();
2051  
2052      mRefreshPending = false;
2053      //1.构建刷新参数
2054      compositionengine::CompositionRefreshArgs refreshArgs;
2055      const auto& displays = ON_MAIN_THREAD(mDisplays);
2056      refreshArgs.outputs.reserve(displays.size());
2057      for (const auto& [_, display] : displays) {
2058          refreshArgs.outputs.push_back(display->getCompositionDisplay());
2059      }
2060      mDrawingState.traverseInZOrder([&refreshArgs](Layer* layer) {
2061          if (auto layerFE = layer->getCompositionEngineLayerFE())
2062              refreshArgs.layers.push_back(layerFE);
2063      });
2064      refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size());
2065      for (auto layer : mLayersWithQueuedFrames) {
2066          if (auto layerFE = layer->getCompositionEngineLayerFE())
2067              refreshArgs.layersWithQueuedFrames.push_back(layerFE);
2068      }
2069  
2070      refreshArgs.repaintEverything = mRepaintEverything.exchange(false);
2071      refreshArgs.outputColorSetting = useColorManagement
2072              ? mDisplayColorSetting
2073              : compositionengine::OutputColorSetting::kUnmanaged;
2074      refreshArgs.colorSpaceAgnosticDataspace = mColorSpaceAgnosticDataspace;
2075      refreshArgs.forceOutputColorMode = mForceColorMode;
2076  
2077      refreshArgs.updatingOutputGeometryThisFrame = mVisibleRegionsDirty;
2078      refreshArgs.updatingGeometryThisFrame = mGeometryInvalid || mVisibleRegionsDirty;
2079      refreshArgs.blursAreExpensive = mBlursAreExpensive;
2080      refreshArgs.internalDisplayRotationFlags = DisplayDevice::getPrimaryDisplayRotationFlags();
2081  
2082      if (CC_UNLIKELY(mDrawingState.colorMatrixChanged)) {
2083          refreshArgs.colorTransformMatrix = mDrawingState.colorMatrix;
2084          mDrawingState.colorMatrixChanged = false;
2085      }
2086  
2087      refreshArgs.devOptForceClientComposition = mDebugDisableHWC || mDebugRegion;
2088  
2089      if (mDebugRegion != 0) {
2090          refreshArgs.devOptFlashDirtyRegionsDelay =
2091                  std::chrono::milliseconds(mDebugRegion > 1 ? mDebugRegion : 0);
2092      }
2093  
2094      const auto prevVsyncTime = mScheduler->getPreviousVsyncFrom(mExpectedPresentTime);
2095      const auto hwcMinWorkDuration = mVsyncConfiguration->getCurrentConfigs().hwcMinWorkDuration;
2096      refreshArgs.earliestPresentTime = prevVsyncTime - hwcMinWorkDuration;
2097      refreshArgs.previousPresentFence = mPreviousPresentFences[0].fenceTime;
2098      refreshArgs.nextInvalidateTime = mEventQueue->nextExpectedInvalidate();
2099  
2100      mGeometryInvalid = false;
2101  
2102      // Store the present time just before calling to the composition engine so we could notify
2103      // the scheduler.
2104      const auto presentTime = systemTime();
2105      //2.调用合成引擎的present来进行合成
2106      mCompositionEngine->present(refreshArgs);
2107      mTimeStats->recordFrameDuration(mFrameStartTime, systemTime());
2108      // Reset the frame start time now that we've recorded this frame.
2109      mFrameStartTime = 0;
2110  
2111      mScheduler->onDisplayRefreshed(presentTime);
2112  
2113      postFrame();
          //3.合成刷新的后期处理将图像传递到物理屏幕。
2114      postComposition();
2115  
2116      const bool prevFrameHadClientComposition = mHadClientComposition;
2117  
2118      mHadClientComposition = std::any_of(displays.cbegin(), displays.cend(), [](const auto& pair) {
2119          const auto& state = pair.second->getCompositionDisplay()->getState();
2120          return state.usesClientComposition && !state.reusedClientComposition;
2121      });
2122      mHadDeviceComposition = std::any_of(displays.cbegin(), displays.cend(), [](const auto& pair) {
2123          const auto& state = pair.second->getCompositionDisplay()->getState();
2124          return state.usesDeviceComposition;
2125      });
2126      mReusedClientComposition =
2127              std::any_of(displays.cbegin(), displays.cend(), [](const auto& pair) {
2128                  const auto& state = pair.second->getCompositionDisplay()->getState();
2129                  return state.reusedClientComposition;
2130              });
2131      // Only report a strategy change if we move in and out of client composition
2132      if (prevFrameHadClientComposition != mHadClientComposition) {
2133          mTimeStats->incrementCompositionStrategyChanges();
2134      }
2135  
2136      // TODO: b/160583065 Enable skip validation when SF caches all client composition layers
2137      const bool usedGpuComposition = mHadClientComposition || mReusedClientComposition;
2138      modulateVsync(&VsyncModulator::onDisplayRefresh, usedGpuComposition);
2139  
2140      mLayersWithQueuedFrames.clear();
2141      if (mTracingEnabled && mTracePostComposition) {
2142          // This may block if SurfaceTracing is running in sync mode.
2143          if (mVisibleRegionsDirty) {
2144              mTracing.notify("visibleRegionsDirty");
2145          } else if (mTracing.flagIsSet(SurfaceTracing::TRACE_BUFFERS)) {
2146              mTracing.notify("bufferLatched");
2147          }
2148      }
2149  
2150      mVisibleRegionsWereDirtyThisFrame = mVisibleRegionsDirty; // Cache value for use in post-comp
2151      mVisibleRegionsDirty = false;
2152  
2153      if (mCompositionEngine->needsAnotherUpdate()) {
2154          signalLayerUpdate();
2155      }
2156  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110

七 总结

  1. SurfaceFlinger 是在init.rc解析的时候被创建的,执行其main方法,实例化了Surfaceflinger,并向ServiceManager注册,SurfaceFlinger运行在单独进程中。
  2. 在 Activity 创建过程中执行 scheduleLaunchActivity() 之后便调用到了 handleLaunchActivity() 方法。首先通过Instrumentation创建Activity,然后执行Activity的attach()方法,创建 PhoneWindow,且与activity建立回调关联。获取WindowManager,层层代理最终干活的是WindowManagerGlobal。
  3. setContentView过程,创建DecorView,并把xml的View树解析出来,加到DecorView上的contentParent部分。
  4. Activity 调用makeVisible ,实际上是WindowManagerGlobal执行addView操作,然后调用ViewRootImpl setView操作。
  5. ViewRootImpl setView 做了两件事: 1) requestLayout触发绘制流程 2)mWindowSession.addToDisplay 通过IPC 执行WMS.addWindow
  6. requestLayout :中的relayoutWindow过程中app请求SurfaceFlinger创建Surface
  7. mWindowSession.addToDisplay:最终执行WMS.addWindow方法,该方法流程最终建立了app与SurfaceFlinger服务连接。
  8. Android应用程序与SurfaceFlinger服务是运行在不同的进程中的,用Binder进行通信,用匿名共享内存进行UI数据传递。
  9. requestLayout draw的流程中:Surface通过dequeueBuffer获取一块GraphicBuffer, 然后onDraw中通过传入的Java层Canvas 调用底层Skia引擎中的SKCanvas(画家)、SKBitmap(画布)进行具体绘制操作,绘制完成之后把图形数据放入GraphicBuffer,最后Surface执行queueBuffer,把这块带有图形数据的buffer送回BufferQueue,并通过onFrameAvailable通知Layer更新。
  10. SurfaceFlinger合成图层依赖于Android的异步消息处理机制,每16ms接收一次vsync信号来执行图层合成操作,最终通过onMessageRefresh一系列方法的处理,其中包括把GraphicBuffer数据映射为OpenGL的texture ,收集所有Layer计算显示区域,然后通过openG 或 HWC进行合成以及栅格化处理,最后送显。
    参考:Android图形系统篇
    WMS—启动过程
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/288632
推荐阅读
  

闽ICP备14008679号