赞
踩
本文参考http://gityuan.com/2017/01/08/windowmanger/ 结合Android12.0的源码进行分析
Android图形系统的大概组成:
Android最常见的界面就是和用户交互的Activity了,上面也承载着图形,Activity的图形结构图如下:
这里以一个Activity的启动来看,大致流程就是调用startActivity时会让AMS启动一个Activity,如果Activity所在的进程没有启动,那么会向Zygote请求fork一个进程。当进程创建后会执行ActivityThread.main(通过反射执行的)接着会调用attach和AMS取得联系,AMS得到ActivityThread后就会去启动应用进程的Activity,应用进程启动Activity的函数从下面开始:
/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 }
我们先看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 }
当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 }
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 }
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 }
这里的IPC通信addToDisplayAsUser主要是将当前的window和wms建立联系用来接受WMS的消息
Activity中各元素的对应关系:
可以看到,Activity的顶级View是DecorView,那么我们的View在哪里显示的呢?下面看一下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 }
这里的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 }
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 }
如果上面layoutResource的布局文件是R.layout.screen_simple的话那么布局应该是下面这样:
当Activity的decorview和content创建完成后就到了将我们的view添加到decorview中调用的是mLayoutInflater.inflate去解析我们的布局文件并将view设置到mContentParent的子view中
当DecorView加载完毕后回到2.2节,在ViewRootImpl的setView流程中会调用requestLayout来绘制View,
/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(); }
可以看到View的绘制会经过5个阶段:
预测量阶段 (measureHierarchy) 预测量阶段会对View树进行第一次测量,在此阶段会计算出View显示出内容的所需要的尺寸,即期望的窗口尺寸
窗口布局阶段 (relayoutWindow) 根据预测量的结果向WMS请求调整窗口的尺寸,这将引发WMS对窗口进行重新布局并将结果返回给Viewrootimpl
测量阶段(performMeasure) 根据上面WMS返回的布局结果对view进行最终测量
布局阶段(performLayout) 测量完成后对view树进行布局
绘制阶段(performDraw) 确定view的尺寸和位置后进行绘制工作
/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 }
/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 }
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 }
因为之前传进来的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 }
流程图如下:
Measure的总结:
MeasureSpec是由specMode和specSize组成的
DecorView其MeasureSpec由窗口尺寸和自身的LayoutParams决定
普通View其MeasureSpec由父容器的MeasureSpec和自身的LayoutParams决定
View的measure方法是final的无法重载,自定义View只能重载其onMeasure来实现测量
View测量后的大小是通过setMeasuredDimension保存下来的,之后再通过getMeasuredWidth和getMeasuredHeight获取到的
当所有的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 }
主要看一下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 }
布局的操作是在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 }
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 }
主要是调用了父类的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 }
Layout小结:Layout主要时ViewGroup确定子view的位置,一般View不需要重载,View设置为Gone后不会调用onLayout,必须在View布局完之后调用getWidth和getHeight才能得到正确的宽高。主要流程如下:
绘制过程就是将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
activity 的view在ViewRootImpl发起的performTraversals后开始绘制流程 测量 布局 绘制
绘制是通过图形处理引擎来绘制的
2D:Canvas 封装了skia的实现
3D:OpenGl ES 将窗口flag的WindowManager.LayoutParams.MEMORY_TYPE_GPU位置为1即可使用OpenGL ES引擎绘制
每一个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进行合成
SurfaceFlinger是一个单独的进程,接受所有的Surface作为输入,创建Layer(其主要组件是一个BufferQueue)与Surface一一对应,接着根据Zorder,透明度,大小位置等参数,计算出Layer在最终合成图像中的位置,接着交给HWComposer或者OpenGL生成最终的栅格化数据,放到Layer的FrameBuffer中
Layer是SurfaceFlinger合成的基本操作单元,其主要组件是一个BufferQueue。Layer在应用请求创建Surface时创建,因此Layer和surface时一一对应的,Layer中有一个FrameBuffer,用来放HWComposer或者OpenGL生成的栅格化数据,每一个FrameBuffer都有两个GraphicBuffer一个FrontBuffer和一个BackBuffer。
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技术。
显示数据的产生、传送合成的过程如下:
显示屏上的内容是从硬件缓冲区中读取出来的,大致的读取过程时从buffer的起始地址从上到下,从左到右扫描整个buffer将内容映射到显示屏上。硬件缓冲器一般是双缓冲结构,一个FrontBuffer用来给屏幕显示,一个BackBuffer用于后台合成下一帧的图形。
如下图所示:
假设前一帧内容显示完毕,并且后一帧的内容准备好了,那么就将前后缓冲区进行角色互换。
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进行合成,最终送到屏幕显示。
基本概念:
屏幕刷新率(HZ):代表屏幕在一秒内刷新屏幕的次数 即一秒钟内显示多少帧
系统帧速率(FPS):代表系统在一秒钟内合成的帧数,由系统算法和硬件决定
屏幕刷新率代表了屏幕消费显示内容的速度,系统帧速率决定了生产显示内容的速度,是一个典型的生产消费的模型,非常需要做好同步。
Android从4.1开始引入了三个核心元素来优化同步问题:Vsync,Tripple Buffer和Choreographer;
垂直同步(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又引入了三重缓冲区
这样一来虽然在第一帧仍然会卡顿一次,但是后面的就流畅了。Buffer也不是越多越好,因为buffer多了CPU合成的数据会有延迟才能被显示。
单Buffer:图形撕裂
双buffer:解决图形撕裂,但是卡顿明显且CPU利用率低
三Buffer:优化卡顿,提供高CPU、GPU利用率,但是引入了延迟问题
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开始下一帧的绘制,当然在绘制前会移除阻塞器。
在2.2小节中我们知道了当Activtiy的显示最终会走到ViewRootImpl的setView,在ViewRootImpl的setView函数中主要有两步和显示息息相关
1.调用requestLayout来绘制View,实际上requestLayout只是向Choreographer注册了回调接口还未真正地进行绘制。
2.调用mWindowSession.addToDisplayAsUser这个操作其实是在View绘制之前。
首先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 }
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 }
ComposerService是一个单例模式,用来获取SurfaceFlinger的代理对象并保存在成员变量mComposerService中,接着SurfaceComposerClient通过ComposerService的代理接口调用createConnection和SurfaceFlinger建立联系
这里主要的逻辑关系是这样的,ComposerService作为一个Client和SurfaceFlinger作为Server进行Binder IPC通信,而SurfaceComposerClient则是作为一个Client和ComposerService作为Server进行Binder IPC进行通信,他们的关系如下图:
简单来说ComposerService是作为一个桥梁连接了SurfaceComposerClient和SurfaceFlinger。
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 }
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 ...
其中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); ... }
在创建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 }
接着通过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 }
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 }
创建好SurfaceControler对象后就进入第二阶段从SurfaceControl中的对象copy到mSurface
/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 }
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 }
所以获取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 }
接着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 }
其中BBQSurface是一个继承于Surface的类,返回给app的Surface包含了mProducer和SurfaceFlinger的代理对象
这个mProducer则是提供GraphicBuffer给APP用来绘制UI的,继承于BufferQueueProducer,其中提供给APP的GraphicBuffer则是从mSlots中获取的,最多可以提供64个BufferSlot 。
Android12 将整个BufferQueue的生产消费机制全部放在了应用进程中去实现,只有在最后将APP的绘制的数据交给SF时才涉及到跨进程,另外申请GraphicBuffer时在构造函数中调用initHandle来进行内存映射
关于一些ConsumeListener的机制,在创建Consumer时,会去new 一个BufferQuqueConsumer,接着将mConsumer作为参数新建一个
我们知道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.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 }
createBufferQueue主要就是创建了BufferQueueCore并以这个core为参数创建了BBQBufferQueueProducer和BufferQueueConsumer
BufferQueueCore是BufferQueue的核心,生产者和消费者都需要通过BufferQueueCore来管理buffer,其中会创建一个64个BufferSlot的mSlots数组,而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 }
由于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 }
到这里为止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 };
重点是几个和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 }
这里以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); ...
在上面mBufferItemConsumer将当前的BLASTBufferQueue设置为了mFrameAvailableListener,所以最后BufferQueueCore的consumerlistener的回调全部都在BLASTBufferQueue中处理。
我们知道上层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 }
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 }
上面代码中的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 }
dequeueBuffer返回的是一个mSlots的index,后面还要根据这个index从mSlots中取出对应的buffer调用的是requestBuffer,在dequeueBuffer中会判断当前的
mGraphicBuffer是否需要申请,如果需要申请那么会新建一个GraphicBuffer去,并在构造函数中完成内存映射。接着通知消费者那些buffer出队,BLASTBufferQueue接收到通知后主要是记录了出队的时间。
当上层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 }
可以看到最终也是通过调用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 }
从上面代码可以看出来主要就是先确定当前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 }
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 }
主要是调用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 }
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 }
SurfaceFlinger运行在一个单独的进程中,主要负责接受所有的Surface作为输入,创建Layer与Surface一一对应,接着根据Zorder,透明度,大小位置等参数,计算出Layer在最终合成图像中的位置,接着交给HWComposer或者OpenGL生成最终的栅格化数据,放到Layer的FrameBuffer中
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
启动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 }
从上面代码可以看到SF进程在启动时主要做了以下几件事:
1.启动内存分配服务,主要是为BufferQueue中的GraphicBuffer申请共享内存
2.设置SF的binder线程,并开启线程池
3.初始化SurfaceFlinger加入servicemanager的管理
4.启动DisplayService
5.调用 flinger->run()使得SurfaceFlinger开始工作
在调用createSurfaceFlinger会新建一个SurfaceFlinger对象,对象新建后会调用到onFirstRef
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
491 void SurfaceFlinger::onFirstRef() {
492 mEventQueue->init(this);
493 }
在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 }
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 }
可以看到是一个死循环不断查询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 }
主要功能就是将任务发送给mEventQueue中使其得到调度执行。
在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 }
可以看到最终调用到了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 }
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 }
图层合成就是把多个图层按既定的显示区域,展现到显示屏上。
比如Android手机launcher的主界面图层合成如下:
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 }
主要还是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
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 }
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.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 }
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 }
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 }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。