注:文章都是通过阅读各位前辈总结的资料 Android 9.0 && Linux(Kernel 3.18)Qualcomm平台源码、加上自己的思考分析总结出来的,其中难免有理解不对的地方,欢迎大家批评指正。文章为个人学习、研究、欣赏之用,图文内容整理自互联网,如有侵权,请联系删除(◕‿◕),转载请注明出处(©Qualcomm ©Android @Linux 版权所有),谢谢。 (==文章基于 Kernel-3.18 ==)&&(==文章基于 Android 9.0 ==)
【开发板 Intrinsyc Open-Q™ 820 µSOM Development Kit】 【开发板 Android 9.0 && Linux(Kernel 3.18)源码链接】
正是由于前人的分析和总结,帮助我节约了大量的时间和精力,特别感谢!!!
(1)【Android Display System】
==源码(部分)==:packages/apps/testViewportGreen && testViewportBlue && testViewportRed/ frameworks/base/core/java/android/app/ frameworks/base/services/core/java/com/android/server/wm/ frameworks/base/services/core/java/com/android/server/am/ frameworks/base/services/core/java/com/android/server/policy/ frameworks/native/services/surfaceflinger/ frameworks/native/libs/gui/ frameworks/native/libs/ui/
(一)、Window添加过程 接着上一篇文章开始分析,performLaunchActivity()方法完成了两件事:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 G:\android9.0 \frameworks\base\core\java\android\app\ActivityThread.java private Activity performLaunchActivity (ActivityClientRecord r, Intent customIntent) { if (localLOGV) Slog.i(TAG, "performLaunchActivity" ,new RuntimeException("here" ).fillInStackTrace());; ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null ) { r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE); } ComponentName component = r.intent.getComponent(); if (component == null ) { component = r.intent.resolveActivity( mInitialApplication.getPackageManager()); r.intent.setComponent(component); } if (r.activityInfo.targetActivity != null ) { component = new ComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity); } ContextImpl appContext = createBaseContextForActivity(r); Activity activity = null ; try { java.lang.ClassLoader cl = appContext.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); r.intent.prepareToEnterProcess(); if (r.state != null ) { r.state.setClassLoader(cl); } } catch (Exception e) { if (!mInstrumentation.onException(activity, e)) { throw new RuntimeException( "Unable to instantiate activity " + component + ": " + e.toString(), e); } } try { Application app = r.packageInfo.makeApplication(false , mInstrumentation); if (localLOGV) Slog.v(TAG, "Performing launch of " + r); if (localLOGV) Slog.v( TAG, r + ": app=" + app + ", appName=" + app.getPackageName() + ", pkg=" + r.packageInfo.getPackageName() + ", comp=" + r.intent.getComponent().toShortString() + ", dir=" + r.packageInfo.getAppDir()); if (activity != null ) { CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); Configuration config = new Configuration(mCompatConfiguration); if (r.overrideConfig != null ) { config.updateFrom(r.overrideConfig); } if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " + r.activityInfo.name + " with config " + config); Window window = null ; if (r.mPendingRemoveWindow != null && r.mPreserveWindow) { window = r.mPendingRemoveWindow; r.mPendingRemoveWindow = null ; r.mPendingRemoveWindowManager = null ; } appContext.setOuterContext(activity); activity.attach(appContext, this , getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor, window, r.configCallback, r.assistToken); if (customIntent != null ) { activity.mIntent = customIntent; } r.lastNonConfigurationInstances = null ; checkAndBlockForNetworkAccess(); activity.mStartedActivity = false ; int theme = r.activityInfo.getThemeResource(); if (theme != 0 ) { activity.setTheme(theme); } activity.mCalled = false ; if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } if (!activity.mCalled) { throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onCreate()" ); } r.activity = activity; } r.setState(ON_CREATE); synchronized (mResourcesManager) { mActivities.put(r.token, r); } } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { if (!mInstrumentation.onException(activity, e)) { throw new RuntimeException( "Unable to start activity " + component + ": " + e.toString(), e); } } return activity; }
Activity窗口对象PhoneWindow的创建,通过attach函数来完成;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 G:\android9.0 \frameworks\base\core\java\android\app\Activity.java final void attach (Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances, Configuration config, String referrer, IVoiceInteractor voiceInteractor, Window window, ActivityConfigCallback activityConfigCallback) { attachBaseContext(context); mFragments.attachHost(null ); mWindow = new PhoneWindow(this , window, activityConfigCallback); mWindow.setWindowControllerCallback(this ); mWindow.setCallback(this ); mWindow.setOnWindowDismissedCallback(this ); mWindow.getLayoutInflater().setPrivateFactory(this ); if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) { mWindow.setSoftInputMode(info.softInputMode); } if (info.uiOptions != 0 ) { mWindow.setUiOptions(info.uiOptions); } mUiThread = Thread.currentThread(); mMainThread = aThread; mInstrumentation = instr; mToken = token; mIdent = ident; mApplication = application; mIntent = intent; mReferrer = referrer; mComponent = intent.getComponent(); mActivityInfo = info; mTitle = title; mParent = parent; mEmbeddedID = id; mLastNonConfigurationInstances = lastNonConfigurationInstances; if (voiceInteractor != null ) { if (lastNonConfigurationInstances != null ) { mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor; } else { mVoiceInteractor = new VoiceInteractor(voiceInteractor, this , this , Looper.myLooper()); } } mWindow.setWindowManager( (WindowManager)context.getSystemService(Context.WINDOW_SERVICE), mToken, mComponent.flattenToString(), (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0 ); if (mParent != null ) { mWindow.setContainer(mParent.getWindow()); } mWindowManager = mWindow.getWindowManager(); mCurrentConfig = config; mWindow.setColorMode(info.colorMode); setAutofillCompatibilityEnabled(application.isAutofillCompatibilityEnabled()); enableAutofillCompatibilityIfNeeded(); }
Activity视图对象的创建,通过callActivityOnCreate >>> setContentView函数来完成;
(2)、Activity.setContentView() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 G:\android9.0 \frameworks\base\core\java\android\app\Activity.java final void performCreate (Bundle icicle, PersistableBundle persistentState) { mCanEnterPictureInPicture = true ; restoreHasCurrentPermissionRequest(icicle); if (persistentState != null ) { onCreate(icicle, persistentState); } else { onCreate(icicle); } writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate" ); mActivityTransitionState.readState(icicle); mVisibleFromClient = !mWindow.getWindowStyle().getBoolean( com.android.internal.R.styleable.Window_windowNoDisplay, false ); mFragments.dispatchActivityCreated(); mActivityTransitionState.setEnterActivityOptions(this , getActivityOptions()); }
1 2 3 4 5 6 G:\android9.0 \frameworks\base\core\java\android\app\Activity.java public void setContentView (@LayoutRes int layoutResID) { getWindow().setContentView(layoutResID); initWindowDecorActionBar(); }
getWindow()函数得到前面创建的窗口对象PhoneWindow,通过PhoneWindow来设置Activity的视图。 [->PhoneWindow.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 G:\android9.0 \frameworks\base\core\java\com\android\internal\policy\PhoneWindow.java @Override public void setContentView (int layoutResID) { if (mContentParent == null ) { installDecor(); } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) { mContentParent.removeAllViews(); } if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) { final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID, getContext()); transitionTo(newScene); } else { mLayoutInflater.inflate(layoutResID, mContentParent); } mContentParent.requestApplyInsets(); final Callback cb = getCallback(); if (cb != null && !isDestroyed()) { cb.onContentChanged(); } mContentParentExplicitlySet = true ; }
Activity.onCreate()会调用setContentView(),整个过程主要是Activity的布局文件或View添加至窗口里, 详细过程不再赘述,详细加载过程请参考: Android应用setContentView与LayoutInflater加载解析机制源码分析 重点概括为:
1 2 3 4 ● 创建一个DecorView的对象mDecor,该mDecor对象将作为整个应用窗口的根视图。 ● 依据Feature等style theme创建不同的窗口修饰布局文件,并且通过findViewById获取Activity布局文件该存放的地方(窗口修饰布局文件中id为content的FrameLayout)。 ● 将Activity的布局文件添加至id为content的FrameLayout内。 ● 当setContentView设置显示OK以后会回调Activity的onContentChanged方法。Activity的各种View的findViewById()方法等都可以放到该方法中,系统会帮忙回调。
#####(3)、ActivityThread.handleResumeActivity() 在调用完performLaunchActivity()方法之后,其有掉用了handleResumeActivity()法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 G:\android9.0 \frameworks\base\core\java\android\app\ActivityThread.java @Override public void handleResumeActivity (IBinder token, boolean finalStateRequest, boolean isForward, String reason) { unscheduleGcIdler(); mSomeActivitiesChanged = true ; final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason); ...... final Activity a = r.activity; if (localLOGV) { Slog.v(TAG, "Resume " + r + " started activity: " + a.mStartedActivity + ", hideForNow: " + r.hideForNow + ", finished: " + a.mFinished); } final int forwardBit = isForward ? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0 ; ...... if (r.window == null && !a.mFinished && willBeVisible) { r.window = r.activity.getWindow(); View decor = r.window.getDecorView(); decor.setVisibility(View.INVISIBLE); ViewManager wm = a.getWindowManager(); WindowManager.LayoutParams l = r.window.getAttributes(); a.mDecor = decor; l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; l.softInputMode |= forwardBit; ...... if (a.mVisibleFromClient) { if (!a.mWindowAdded) { a.mWindowAdded = true ; wm.addView(decor, l); } else { a.onWindowAttributesChanged(l); } } } else if (!willBeVisible) { r.hideForNow = true ; } cleanUpPendingRemoveWindows(r, false ); if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) { if (r.newConfig != null ) { performConfigurationChangedForActivity(r, r.newConfig); r.newConfig = null ; } if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward); WindowManager.LayoutParams l = r.window.getAttributes(); if ((l.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != forwardBit) { l.softInputMode = (l.softInputMode & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) | forwardBit; if (r.activity.mVisibleFromClient) { ViewManager wm = a.getWindowManager(); View decor = r.window.getDecorView(); wm.updateViewLayout(decor, l); } } r.activity.mVisibleFromServer = true ; mNumVisibleActivities++; if (r.activity.mVisibleFromClient) { r.activity.makeVisible(); } } r.nextIdle = mNewActivities; mNewActivities = r; if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r); Looper.myQueue().addIdleHandler(new Idler()); }
我们知道,在前面的performLaunchActivity函数中完成Activity的创建后,会将当前当前创建的Activity在应用程序进程端的描述符ActivityClientRecord以键值对的形式保存到ActivityThread的成员变量mActivities中:mActivities.put(r.token, r);,r.token就是Activity的身份证,即是IApplicationToken.Proxy代理对象,也用于与AMS通信。上面的函数首先通过performResumeActivity从mActivities变量中取出Activity的应用程序端描述符ActivityClientRecord,然后取出前面为Activity创建的视图对象DecorView和窗口管理器WindowManager,最后将视图对象添加到窗口管理器中。
#####(4)、ViewManager.addView()
ViewManager.addView()真正实现的的地方在WindowManagerImpl.java中
1 2 3 4 5 6 7 8 G:\android9.0 \frameworks\base\core\java\android\view\ViewManager.java public interface ViewManager {public void addView (View view, ViewGroup.LayoutParams params) ;public void updateViewLayout (View view, ViewGroup.LayoutParams params) ;public void removeView (View view) ;}
[->WindowManagerImpl.java]
1 2 3 4 5 6 7 G:\android9.0 \frameworks\base\core\java\android\view\WindowManagerImpl.java Override public void addView (@NonNull View view, @NonNull ViewGroup.LayoutParams params) { ...... mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow); }
[->WindowManagerGlobal.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 G:\android9.0 \frameworks\base\core\java\android\view\WindowManagerGlobal.java public void addView (View view, ViewGroup.LayoutParams params, Display display, Window parentWindow) { final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params; if (parentWindow != null ) { parentWindow.adjustLayoutParamsForSubWindow(wparams); } else { final Context context = view.getContext(); if (context != null && (context.getApplicationInfo().flags & ApplicationInfo.FLAG_HARDWARE_ACCELERATED) != 0 ) { wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; } } ...... ViewRootImpl root; View panelParentView = null ; synchronized (mLock) { ...... root = new ViewRootImpl(view.getContext(), display); view.setLayoutParams(wparams); mViews.add(view); mRoots.add(root); mParams.add(wparams); } try { root.setView(view, wparams, panelParentView); } ...... }
#####(5)、ViewRootImpl.setView()
5.1、ViewRootImpl()构造过程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 G:\android9.0 \frameworks\base\core\java\android\view\ViewRootImpl.java final W mWindow; final Surface mSurface = new Surface(); final ViewRootHandler mHandler = new ViewRootHandler(); ...... public ViewRootImpl (Context context, Display display) { mContext = context; mWindowSession = WindowManagerGlobal.getWindowSession(); mDisplay = display; mBasePackageName = context.getBasePackageName(); mThread = Thread.currentThread(); mLocation = new WindowLeaked(null ); mLocation.fillInStackTrace(); mWidth = -1 ; mHeight = -1 ; mDirty = new Rect(); mTempRect = new Rect(); mVisRect = new Rect(); mWinFrame = new Rect(); mWindow = new W(this ); mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion; mViewVisibility = View.GONE; mTransparentRegion = new Region(); mPreviousTransparentRegion = new Region(); mFirst = true ; mAdded = false ; mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this , mHandler, this , context); mAccessibilityManager = AccessibilityManager.getInstance(context); mAccessibilityManager.addAccessibilityStateChangeListener( mAccessibilityInteractionConnectionManager, mHandler); mHighContrastTextManager = new HighContrastTextManager(); mAccessibilityManager.addHighTextContrastStateChangeListener( mHighContrastTextManager, mHandler); mViewConfiguration = ViewConfiguration.get(context); mDensity = context.getResources().getDisplayMetrics().densityDpi; mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi; mFallbackEventHandler = new PhoneFallbackEventHandler(context); mChoreographer = Choreographer.getInstance(); mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); loadSystemProperties(); mPerf = new BoostFramework(context); }
在ViewRootImpl的构造函数中初始化了一些成员变量,ViewRootImpl创建了以下几个主要对象:
(1) 通过WindowManagerGlobal.getWindowSession()得到IWindowSession的代理对象,该对象用于和WMS通信。
(2) 创建了一个W本地Binder对象,用于WMS与APP进程通信。
(3) 采用单例模式创建了一个Choreographer对象,用于统一调度窗口绘图。
(4) 创建ViewRootHandler对象,用于处理当前视图消息。
(5) 构造一个AttachInfo对象;
(6) 创建Surface对象,用于绘制当前视图,当然该Surface对象的真正创建是由WMS来完成的,只不过是WMS传递给应用程序进程的。
5.1.1、IWindowSession代理获取过程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 G:\android9.0 \frameworks\base\core\java\android\view\WindowManagerGlobal.java public static IWindowSession getWindowSession () { synchronized (WindowManagerGlobal.class) { if (sWindowSession == null ) { try { InputMethodManager imm = InputMethodManager.getInstance(); IWindowManager windowManager = getWindowManagerService(); sWindowSession = windowManager.openSession( new IWindowSessionCallback.Stub() { @Override public void onAnimatorScaleChanged (float scale) { ValueAnimator.setDurationScale(scale); } }, imm.getClient(), imm.getInputContext()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return sWindowSession; } }
5.1.1.1、WindowManagerService.openSession() 通过Binder通信WindowManagerService.openSession() 通过WMS的openSession函数创建应用程序与WMS之间的连接通道,即获取IWindowSession代理对象,并将该代理对象保存到ViewRootImpl的静态成员变量sWindowSession中,因此在应用程序进程中有且只有一个IWindowSession代理对象。
1 2 3 4 5 6 7 8 9 10 11 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java @Override public IWindowSession openSession (IWindowSessionCallback callback, IInputMethodClient client, IInputContext inputContext) { if (client == null ) throw new IllegalArgumentException("null client" ); if (inputContext == null ) throw new IllegalArgumentException("null inputContext" ); Session session = new Session(this , callback, client, inputContext); return session; }
5.1.1.2、new Session() 在WMS服务端构造了一个Session实例对象。ViewRootImpl 是一很重要的类,类似 ActivityThread 负责跟AmS通信一样,ViewRootImpl 的一个重要职责就是跟 WmS 通信,它通静态变量 sWindowSession(IWindowSession实例)与 WmS 进行通信。每个应用进程,仅有一个 sWindowSession 对象,它对应了 WmS 中的 Session 子类,WmS 为每一个应用进程分配一个 Session 对象。WindowState 类有一个 IWindow mClient 参数,是在构造方法中赋值的,是由 Session 调用 addWindow 传递过来了,对应了 ViewRootImpl 中的 W 类的实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\Session.java class Session extends IWindowSession .Stub implements IBinder .DeathRecipient { final WindowManagerService mService; final IWindowSessionCallback mCallback; final IInputMethodClient mClient; final int mUid; final int mPid; private final String mStringName; SurfaceSession mSurfaceSession; private int mNumWindow = 0 ; private final Set<WindowSurfaceController> mAppOverlaySurfaces = new HashSet<>(); private final Set<WindowSurfaceController> mAlertWindowSurfaces = new HashSet<>(); private final DragDropController mDragDropController; final boolean mCanAddInternalSystemWindow; final boolean mCanHideNonSystemOverlayWindows; final boolean mCanAcquireSleepToken; private AlertWindowNotification mAlertWindowNotification; private boolean mShowingAlertWindowNotificationAllowed; private boolean mClientDead = false ; private float mLastReportedAnimatorScale; private String mPackageName; private String mRelayoutTag; public Session (WindowManagerService service, IWindowSessionCallback callback, IInputMethodClient client, IInputContext inputContext) { mService = service; mCallback = callback; mClient = client; ...... mDragDropController = mService.mDragDropController; ...... synchronized (mService.mWindowMap) { if (mService.mInputMethodManager == null && mService.mHaveInputMethods) { IBinder b = ServiceManager.getService( Context.INPUT_METHOD_SERVICE); mService.mInputMethodManager = IInputMethodManager.Stub.asInterface(b); } } long ident = Binder.clearCallingIdentity(); try { if (mService.mInputMethodManager != null ) { mService.mInputMethodManager.addClient(client, inputContext, mUid, mPid); } else { client.setUsingInputMethod(false ); } client.asBinder().linkToDeath(this , 0 ); } catch (RemoteException e) { ...... } finally { Binder.restoreCallingIdentity(ident); } }
5.1.2、创建W本地Binder对象 1 2 3 4 5 6 7 8 9 10 11 12 G:\android9.0 \frameworks\base\core\java\android\view\ViewRootImpl.java static class W extends IWindow .Stub { private final WeakReference<ViewRootImpl> mViewAncestor; private final IWindowSession mWindowSession; W(ViewRootImpl viewAncestor) { mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor); mWindowSession = viewAncestor.mWindowSession; } ...... }
5.1.3、Choreographer创建 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 G:\android9.0 \frameworks\base\core\java\android\view\Choreographer.java private Choreographer (Looper looper, int vsyncSource) { mLooper = looper; mHandler = new FrameHandler(looper); mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper, vsyncSource) : null ; mLastFrameTimeNanos = Long.MIN_VALUE; mFrameIntervalNanos = (long )(1000000000 / getRefreshRate()); mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1 ]; for (int i = 0 ; i <= CALLBACK_LAST; i++) { mCallbackQueues[i] = new CallbackQueue(); } setFPSDivisor(SystemProperties.getInt(ThreadedRenderer.DEBUG_FPS_DIVISOR, 1 )); } G:\android9.0 \frameworks\base\core\java\android\view\Choreographer.java private final class FrameDisplayEventReceiver extends DisplayEventReceiver implements Runnable { ...... public FrameDisplayEventReceiver (Looper looper, int vsyncSource) { super (looper, vsyncSource); } ...... }
FrameDisplayEventReceiver 继承 DisplayEventReceiver
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 G:\android9.0 \frameworks\base\core\java\android\view\DisplayEventReceiver.java public DisplayEventReceiver (Looper looper, int vsyncSource) { ...... mMessageQueue = looper.getQueue(); mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this ), mMessageQueue, vsyncSource); mCloseGuard.open("dispose" ); } >>>>>>JNI G:\android9.0 \frameworks\base\core\jni\android_view_DisplayEventReceiver.cpp static jlong nativeInit (JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj, jint vsyncSource) { sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); if (messageQueue == NULL) { jniThrowRuntimeException(env, "MessageQueue is not initialized." ); return 0 ; } sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env, receiverWeak, messageQueue, vsyncSource); status_t status = receiver->initialize(); if (status) { String8 message; message.appendFormat("Failed to initialize display event receiver. status=%d" , status); jniThrowRuntimeException(env, message.string()); return 0 ; } receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); return reinterpret_cast<jlong>(receiver.get()); } NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource) : DisplayEventDispatcher(messageQueue->getLooper(), static_cast<ISurfaceComposer::VsyncSource>(vsyncSource)), mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)), mMessageQueue(messageQueue) { ALOGV("receiver %p ~ Initializing display event receiver." , this ); }
NativeDisplayEventReceiver 继承与DisplayEventDispatcher,所以DisplayEventDispatcher会执行初始化操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 G:\android9.0 \frameworks\base\libs\androidfw\DisplayEventDispatcher.cpp DisplayEventDispatcher::DisplayEventDispatcher(const sp<Looper>& looper, ISurfaceComposer::VsyncSource vsyncSource) : mLooper(looper), mReceiver(vsyncSource), mWaitingForVsync(false ) { ALOGV("dispatcher %p ~ Initializing display event dispatcher." , this ); } status_t DisplayEventDispatcher::initialize () { status_t result = mReceiver.initCheck(); if (result) { ALOGW("Failed to initialize display event receiver, status=%d" , result); return result; } int rc = mLooper->addFd(mReceiver.getFd(), 0 , Looper::EVENT_INPUT, this , NULL ); if (rc < 0 ) { return UNKNOWN_ERROR; } return OK; }
监听mReceiver的所获取的文件句柄,一旦有数据到来,则回调this(此处NativeDisplayEventReceiver)中所复写LooperCallback对象的 handleEvent。
5.1.3.1、Native DisplayEventReceiver初始化 mReceiver为DisplayEventReceiver实例
1 2 3 4 5 6 7 8 9 10 11 12 G:\android9.0 \frameworks\native\libs\gui\DisplayEventReceiver.cpp DisplayEventReceiver::DisplayEventReceiver(ISurfaceComposer::VsyncSource vsyncSource) { sp<ISurfaceComposer> sf (ComposerService::getComposerService()) ; if (sf != NULL ) { mEventConnection = sf->createDisplayEventConnection(vsyncSource); if (mEventConnection != NULL ) { mDataChannel = std ::make_unique<gui::BitTube>(); mEventConnection->stealReceiveChannel(mDataChannel.get()); } } }
此处通过binder通信与SurfaceFlinger建立连接,直接看SurfaceFlinger服务端的实现
5.1.3.2、createDisplayEventConnection 1 2 3 4 5 6 7 8 9 10 11 G:\android9.0 \frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection ( ISurfaceComposer::VsyncSource vsyncSource) { if (vsyncSource == eVsyncSourceSurfaceFlinger) { return mSFEventThread->createEventConnection(); } else { return mEventThread->createEventConnection(); } }
我们这里不是eVsyncSourceSurfaceFlinger,所以会走mEventThread->createEventConnection() 分支,为app进程创建一个Connection,会首先调用Connection::onFirstRef(),然后加入到mDisplayEventConnections中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 G:\android9.0 \frameworks\native\services\surfaceflinger\EventThread.cpp sp<BnDisplayEventConnection> EventThread::createEventConnection () const { return new Connection(const_cast <EventThread*>(this )); } EventThread::Connection::Connection(EventThread* eventThread) : count(-1 ), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize) {} void EventThread::Connection::onFirstRef() { mEventThread->registerDisplayEventConnection(this ); } status_t EventThread::registerDisplayEventConnection ( const sp<EventThread::Connection>& connection) { std ::lock_guard<std ::mutex> lock (mMutex) ; mDisplayEventConnections.add(connection); mCondition.notify_all(); return NO_ERROR; }
5.1.3.3、mEventConnection->stealReceiveChannel(mDataChannel.get()) Binder通信直接看服务端实现,将从客户端传来的BitTube设置到接收VSync信号的FD
1 2 3 4 5 6 7 8 9 10 11 12 G:\android9.0 \frameworks\native\services\surfaceflinger\EventThread.cpp status_t EventThread::Connection::stealReceiveChannel(gui::BitTube* outChannel) { outChannel->setReceiveFd(mChannel.moveReceiveFd()); return NO_ERROR; } G:\android9.0 \frameworks\native\libs\gui\BitTube.cpp void BitTube::setReceiveFd (base::unique_fd&& receiveFd) { mReceiveFd = std ::move(receiveFd); }
5.1.4、构造AttachInfo对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 G:\android9.0 \frameworks\base\core\java\android\view\View.java final static class AttachInfo { ...... final IWindowSession mSession; final IWindow mWindow; final IBinder mWindowToken; Display mDisplay; final Callbacks mRootCallbacks; IWindowId mIWindowId; WindowId mWindowId; View mRootView; ...... final ViewTreeObserver mTreeObserver; Canvas mCanvas; final ViewRootImpl mViewRootImpl; final Handler mHandler; ...... AttachInfo(IWindowSession session, IWindow window, Display display, ViewRootImpl viewRootImpl, Handler handler, Callbacks effectPlayer, Context context) { mSession = session; mWindow = window; mWindowToken = window.asBinder(); mDisplay = display; mViewRootImpl = viewRootImpl; mHandler = handler; mRootCallbacks = effectPlayer; mTreeObserver = new ViewTreeObserver(context); }
5.2、视图View添加过程 窗口管理器WindowManagerImpl为当前添加的窗口创建好各种对象后,调用ViewRootImpl的setView函数向WMS服务添加一个窗口对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 G:\android9.0 \frameworks\base\core\java\android\view\ViewRootImpl.java public void setView (View view, WindowManager.LayoutParams attrs, View panelParentView) { synchronized (this ) { if (mView == null ) { mView = view; mAttachInfo.mDisplayState = mDisplay.getState(); mDisplayManager.registerDisplayListener(mDisplayListener, mHandler); mViewLayoutDirectionInitial = mView.getRawLayoutDirection(); mFallbackEventHandler.setView(view); mWindowAttributes.copyFrom(attrs); ...... attrs = mWindowAttributes; setTag(); ...... mClientWindowLayoutFlags = attrs.flags; setAccessibilityFocus(null , null ); ...... CompatibilityInfo compatibilityInfo = mDisplay.getDisplayAdjustments().getCompatibilityInfo(); mTranslator = compatibilityInfo.getTranslator(); ...... if (DEBUG_LAYOUT) Log.d(mTag, "WindowLayout in setView:" + attrs); --------------------------------------------------- 对应Log: Line 2310 : 04 -16 13 :08 :36.961 D/ViewRootImpl[TestActivity]( 2602 ): WindowLayout in setView:{(0 ,0 )(fillxfill) sim={forwardNavigation} ty=BASE_APPLICATION fmt=TRANSPARENT wanim=0x1030000 Line 2311 : 04 -16 13 :08 :36.961 D/ViewRootImpl[TestActivity]( 2602 ): fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED} --------------------------------------------------- if (!compatibilityInfo.supportsScreen()) { attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; mLastInCompatMode = true ; } mSoftInputMode = attrs.softInputMode; mWindowAttributesChanged = true ; mWindowAttributesChangesFlag = WindowManager.LayoutParams.EVERYTHING_CHANGED; mAttachInfo.mRootView = view; mAttachInfo.mScalingRequired = mTranslator != null ; mAttachInfo.mApplicationScale = mTranslator == null ? 1.0f : mTranslator.applicationScale; if (panelParentView != null ) { mAttachInfo.mPanelParentWindowToken = panelParentView.getApplicationWindowToken(); } mAdded = true ; int res; 1 )在添加窗口前进行UI布局 requestLayout(); if ((mWindowAttributes.inputFeatures & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0 ) { mInputChannel = new InputChannel(); } mForceDecorViewVisibility = (mWindowAttributes.privateFlags & PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0 ; try { mOrigWindowType = mWindowAttributes.type; mAttachInfo.mRecomputeGlobalAttributes = true ; collectViewAttributes(); res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, getHostVisibility(), mDisplay.getDisplayId(), mWinFrame, mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel); } catch (RemoteException e) { mAdded = false ; mView = null ; mAttachInfo.mRootView = null ; mInputChannel = null ; mFallbackEventHandler.setView(null ); unscheduleTraversals(); setAccessibilityFocus(null , null ); throw new RuntimeException("Adding window failed" , e); } finally { if (restore) { attrs.restore(); } } ...... ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :36.968 V/ViewRootImpl[TestActivity]( 2602 ): Added window android.view.ViewRootImpl$W@ad597e9 ---------------------------------------------------------------- if (DEBUG_LAYOUT) Log.v(mTag, "Added window " + mWindow); ...... if (mInputChannel != null ) { if (mInputQueueCallback != null ) { mInputQueue = new InputQueue(); mInputQueueCallback.onInputQueueCreated(mInputQueue); } mInputEventReceiver = new WindowInputEventReceiver(mInputChannel, Looper.myLooper()); } view.assignParent(this ); mAddedTouchMode = (res & WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE) != 0 ; mAppVisible = (res & WindowManagerGlobal.ADD_FLAG_APP_VISIBLE) != 0 ; if (mAccessibilityManager.isEnabled()) { mAccessibilityInteractionConnectionManager.ensureConnection(); } if (view.getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) { view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); } CharSequence counterSuffix = attrs.getTitle(); mSyntheticInputStage = new SyntheticInputStage(); InputStage viewPostImeStage = new ViewPostImeInputStage(mSyntheticInputStage); InputStage nativePostImeStage = new NativePostImeInputStage(viewPostImeStage, "aq:native-post-ime:" + counterSuffix); InputStage earlyPostImeStage = new EarlyPostImeInputStage(nativePostImeStage); InputStage imeStage = new ImeInputStage(earlyPostImeStage, "aq:ime:" + counterSuffix); InputStage viewPreImeStage = new ViewPreImeInputStage(imeStage); InputStage nativePreImeStage = new NativePreImeInputStage(viewPreImeStage, "aq:native-pre-ime:" + counterSuffix); mFirstInputStage = nativePreImeStage; mFirstPostImeInputStage = earlyPostImeStage; mPendingInputEventQueueLengthCounterName = "aq:pending:" + counterSuffix; } } }
通过前面的分析可以知道,用户自定义的UI作为一个子View被添加到DecorView中,然后将顶级视图DecorView添加到应用程序进程的窗口管理器中,窗口管理器首先为当前添加的View创建一个ViewRootImpl对象、一个布局参数对象ViewGroup.LayoutParams,然后将这三个对象分别保存到当前应用程序进程的窗口管理器WindowManagerImpl中,最后通过ViewRootImpl对象将当前视图对象注册到WMS服务中。
ViewRootImpl的setView函数向WMS服务添加一个窗口对象过程:
(1) requestLayout()在应用程序进程中进行窗口UI布局;
(2) WindowSession.addToDisplay()向WMS服务注册一个窗口对象;
(3) 注册应用程序进程端的消息接收通道;
5.2.1、窗口UI布局过程 ViewRootImpl.requestLayout() requestLayout函数调用里面使用了Hanlder的一个小手段,那就是利用postSyncBarrier添加了一个Barrier(挡板),这个挡板的作用是阻塞普通的同步消息的执行,在挡板被撤销之前,只会执行异步消息,而requestLayout先添加了一个挡板Barrier,之后自己插入了一个异步任务mTraversalRunnable,其主要作用就是保证mTraversalRunnable在所有同步Message之前被执行,保证View绘制的最高优先级。具体实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 G:\android9.0 \frameworks\base\core\java\android\view\ViewRootImpl.java Override public void requestLayout () { if (!mHandlingLayoutInLayoutRequest) { checkThread(); mLayoutRequested = true ; scheduleTraversals(); } } final class TraversalRunnable implements Runnable { @Override public void run () { doTraversal(); } } final TraversalRunnable mTraversalRunnable = new TraversalRunnable();void scheduleTraversals () { if (!mTraversalScheduled) { mTraversalScheduled = true ; mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier(); mChoreographer.postCallback( Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null ); if (!mUnbufferedInputDispatch) { scheduleConsumeBatchedInput(); } notifyRendererOfFramePending(); pokeDrawLockIfNeeded(); } }
5.2.2、添加回调过程 mChoreographer.postCallback() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 G:\android9.0 \frameworks\base\core\java\android\view\Choreographer.java public void postCallback (int callbackType, Runnable action, Object token) { postCallbackDelayed(callbackType, action, token, 0 ); } public void postCallbackDelayed (int callbackType, Runnable action, Object token, long delayMillis) { ...... postCallbackDelayedInternal(callbackType, action, token, delayMillis); } private void postCallbackDelayedInternal (int callbackType, Object action, Object token, long delayMillis) { if (DEBUG_FRAMES) { Log.d(TAG, "PostCallback: type=" + callbackType + ", action=" + action + ", token=" + token + ", delayMillis=" + delayMillis); } synchronized (mLock) { final long now = SystemClock.uptimeMillis(); final long dueTime = now + delayMillis; mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token); if (dueTime <= now) { scheduleFrameLocked(now); } else { Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action); msg.arg1 = callbackType; msg.setAsynchronous(true ); mHandler.sendMessageAtTime(msg, dueTime); } } } scheduleFrameLocked(long now) { if (!mFrameScheduled) { mFrameScheduled = true ; ...... if (USE_VSYNC) { if (DEBUG_FRAMES) { Log.d(TAG, "Scheduling next frame on vsync." ); } if (isRunningOnLooperThreadLocked()) { scheduleVsyncLocked(); } else { Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC); msg.setAsynchronous(true ); mHandler.sendMessageAtFrontOfQueue(msg); } } else { final long nextFrameTime = Math.max( mLastFrameTimeNanos / TimeUtils.NANOS_PER_MS + sFrameDelay, now); if (DEBUG_FRAMES) { Log.d(TAG, "Scheduling next frame in " + (nextFrameTime - now) + " ms." ); } Message msg = mHandler.obtainMessage(MSG_DO_FRAME); msg.setAsynchronous(true ); mHandler.sendMessageAtTime(msg, nextFrameTime); } } }
消息处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 G:\android9.0 \frameworks\base\core\java\android\view\Choreographer.java private final class FrameHandler extends Handler { public FrameHandler (Looper looper) { super (looper); } @Override public void handleMessage (Message msg) { switch (msg.what) { case MSG_DO_FRAME: doFrame(System.nanoTime(), 0 ); break ; case MSG_DO_SCHEDULE_VSYNC: doScheduleVsync(); break ; case MSG_DO_SCHEDULE_CALLBACK: doScheduleCallback(msg.arg1); break ; } } } void doScheduleVsync () { synchronized (mLock) { if (mFrameScheduled) { scheduleVsyncLocked(); } } } private void scheduleVsyncLocked () { mDisplayEventReceiver.scheduleVsync(); }
在该函数中考虑了两种情况,一种是系统没有使用Vsync机制,在这种情况下,首先根据屏幕刷新频率计算下一次刷新时间,通过异步消息方式延时执行doFrame()函数实现屏幕刷新。如果系统使用了Vsync机制,并且当前线程具备消息循环,则直接请求Vsync信号,否则就通过主线程来请求Vsync信号。
5.2.3、Vsync请求过程 mDisplayEventReceiver.scheduleVsync() 我们知道在Choreographer构造函数中,构造了一个FrameDisplayEventReceiver对象,用于请求并接收Vsync信号,Vsync信号请求过程如下:
1 2 3 4 5 6 7 8 9 10 G:\android9.0 \frameworks\base\core\java\android\view\DisplayEventReceiver.java public void scheduleVsync () { if (mReceiverPtr == 0 ) { Log.w(TAG, "Attempted to schedule a vertical sync pulse but the display event " + "receiver has already been disposed." ); } else { nativeScheduleVsync(mReceiverPtr); } }
1 2 3 4 5 6 7 8 9 10 11 G:\android9.0 \frameworks\base\core\jni\android_view_DisplayEventReceiver.cpp static void nativeScheduleVsync (JNIEnv* env, jclass clazz, jlong receiverPtr) { sp<NativeDisplayEventReceiver> receiver = reinterpret_cast <NativeDisplayEventReceiver*>(receiverPtr); status_t status = receiver->scheduleVsync(); if (status) { String8 message; message.appendFormat("Failed to schedule next vertical sync pulse. status=%d" , status); jniThrowRuntimeException(env, message.string ()); } }
VSync请求过程又转交给了DisplayEventDispatcher: [->DisplayEventDispatcher.cpp]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 G:\android9.0 \frameworks\base\libs\androidfw\DisplayEventDispatcher.cpp status_t DisplayEventDispatcher::scheduleVsync () { if (!mWaitingForVsync) { ALOGV("dispatcher %p ~ Scheduling vsync." , this ); nsecs_t vsyncTimestamp; int32_t vsyncDisplayId; uint32_t vsyncCount; if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) { ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "" , this , ns2ms(static_cast <nsecs_t >(vsyncTimestamp))); } status_t status = mReceiver.requestNextVsync(); if (status) { ALOGW("Failed to request next vsync, status=%d" , status); return status; } mWaitingForVsync = true ; } return OK; }
VSync请求过程又转交给了DisplayEventReceiver: [->DisplayEventReceiver.cpp]
1 2 3 4 5 6 7 8 G:\android9.0 \frameworks\native\libs\gui\DisplayEventReceiver.cpp status_t DisplayEventReceiver::requestNextVsync () { if (mEventConnection != NULL ) { mEventConnection->requestNextVsync(); return NO_ERROR; } return NO_INIT; }
看服务端的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 G:\android9.0 \frameworks\native\services\surfaceflinger\EventThread.cpp void EventThread::requestNextVsync (const sp<EventThread::Connection>& connection) { std ::lock_guard<std ::mutex> lock (mMutex) ; if (mResyncWithRateLimitCallback) { mResyncWithRateLimitCallback(); } if (connection->count < 0 ) { connection->count = 0 ; mCondition.notify_all(); } } void EventThread::threadMain () NO_THREAD_SAFETY_ANALYSIS { std ::unique_lock<std ::mutex> lock (mMutex) ; while (mKeepRunning) { DisplayEventReceiver::Event event; Vector<sp<EventThread::Connection> > signalConnections; signalConnections = waitForEventLocked(&lock, &event); const size_t count = signalConnections.size(); for (size_t i = 0 ; i < count; i++) { const sp<Connection>& conn (signalConnections[i]) ; status_t err = conn->postEvent(event); if (err == -EAGAIN || err == -EWOULDBLOCK) { ALOGW("EventThread: dropping event (%08x) for connection %p" , event.header.type, conn.get()); } else if (err < 0 ) { removeDisplayEventConnectionLocked(signalConnections[i]); } } } }
waitForEventLocked()函数中等待下一个VSYNC的trigger.。
需要说明的是
/** Vsync start****** / /** Vsync end****** / 之间的代码此时其实还未执行,call requestNextVsync()来告诉系统我要在下一个VSYNC需要被trigger.
继续ViewRootImpl的setView函数中的WindowSession.addToDisplay()。
5.3、mWindowSession.addToDisplay()向WMS服务注册一个窗口对象 1 2 3 4 5 6 7 8 9 10 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\Session.java Override public int addToDisplay (IWindow window, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) { return mService.addWindow(this , window, seq, attrs, viewVisibility, displayId, outFrame, outContentInsets, outStableInsets, outOutsets, outDisplayCutout, outInputChannel); }
看看WindowManagerService.java的addWindow()实现
5.3.1、WindowManagerService.addWindow() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java public int addWindow (Session session, IWindow client, int seq, LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) { int [] appOp = new int [1 ]; ...... boolean reportNewConfig = false ; WindowState parentWindow = null ; long origId; final int callingUid = Binder.getCallingUid(); final int type = attrs.type; mFocusingActivity = attrs.getTitle().toString(); synchronized (mWindowMap) { ....... final DisplayContent displayContent = getDisplayContentOrCreate(displayId); ...... AppWindowToken atoken = null ; final boolean hasParent = parentWindow != null ; WindowToken token = displayContent.getWindowToken( hasParent ? parentWindow.mAttrs.token : attrs.token); final int rootType = hasParent ? parentWindow.mAttrs.type : type; boolean addToastWindowRequiresToken = false ; if (token == null ) { ....... final IBinder binder = attrs.token != null ? attrs.token : client.asBinder(); final boolean isRoundedCornerOverlay = (attrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0 ; token = new WindowToken(this , binder, type, false , displayContent, session.mCanAddInternalSystemWindow, isRoundedCornerOverlay); } ...... } else if (token.asAppWindowToken() != null ) { Slog.w(TAG_WM, "Non-null appWindowToken for system window of rootType=" + rootType); attrs.token = null ; token = new WindowToken(this , client.asBinder(), type, false , displayContent, session.mCanAddInternalSystemWindow); } final WindowState win = new WindowState(this , session, client, token, parentWindow, appOp[0 ], seq, attrs, viewVisibility, session.mUid, session.mCanAddInternalSystemWindow); ...... final boolean hasStatusBarServicePermission = mContext.checkCallingOrSelfPermission(permission.STATUS_BAR_SERVICE) == PackageManager.PERMISSION_GRANTED; mPolicy.adjustWindowParamsLw(win, win.mAttrs, hasStatusBarServicePermission); win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs)); res = mPolicy.prepareAddWindowLw(win, attrs); ...... final boolean openInputChannels = (outInputChannel != null && (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0 ); if (openInputChannels) { win.openInputChannel(outInputChannel); } ...... res = WindowManagerGlobal.ADD_OKAY; ...... origId = Binder.clearCallingIdentity(); win.attach(); mWindowMap.put(client.asBinder(), win); win.initAppOpsState(); final boolean suspended = mPmInternal.isPackageSuspended(win.getOwningPackage(), UserHandle.getUserId(win.getOwningUid())); win.setHiddenWhileSuspended(suspended); final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty(); win.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows); final AppWindowToken aToken = token.asAppWindowToken(); if (type == TYPE_APPLICATION_STARTING && aToken != null ) { aToken.startingWindow = win; if (DEBUG_STARTING_WINDOW) Slog.v (TAG_WM, "addWindow: " + aToken + " startingWindow=" + win); } boolean imMayMove = true ; win.mToken.addWindow(win); if (type == TYPE_INPUT_METHOD) { win.mGivenInsetsPending = true ; setInputMethodWindowLocked(win); imMayMove = false ; } else if (type == TYPE_INPUT_METHOD_DIALOG) { displayContent.computeImeTarget(true ); imMayMove = false ; } else { if (type == TYPE_WALLPAPER) { displayContent.mWallpaperController.clearLastWallpaperTimeoutTime(); displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0 ) { displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; } else if (displayContent.mWallpaperController.isBelowWallpaperTarget(win)) { displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; } } win.applyAdjustForImeIfNeeded(); if (type == TYPE_DOCK_DIVIDER) { mRoot.getDisplayContent(displayId).getDockedDividerController().setWindow(win); } final WindowStateAnimator winAnimator = win.mWinAnimator; winAnimator.mEnterAnimationPending = true ; winAnimator.mEnteringAnimation = true ; if (atoken != null && atoken.isVisible() && !prepareWindowReplacementTransition(atoken)) { prepareNoneTransitionForRelaunching(atoken); } final DisplayFrames displayFrames = displayContent.mDisplayFrames; final DisplayInfo displayInfo = displayContent.getDisplayInfo(); displayFrames.onDisplayInfoUpdated(displayInfo, displayContent.calculateDisplayCutoutForRotation(displayInfo.rotation)); final Rect taskBounds; if (atoken != null && atoken.getTask() != null ) { taskBounds = mTmpRect; atoken.getTask().getBounds(mTmpRect); } else { taskBounds = null ; } if (mPolicy.getLayoutHintLw(win.mAttrs, taskBounds, displayFrames, outFrame, outContentInsets, outStableInsets, outOutsets, outDisplayCutout)) { res |= WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_NAV_BAR; } if (mInTouchMode) { res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE; } if (win.mAppToken == null || !win.mAppToken.isClientHidden()) { res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE; } mInputMonitor.setUpdateInputWindowsNeededLw(); boolean focusChanged = false ; if (win.canReceiveKeys()) { focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS, false ); if (focusChanged) { imMayMove = false ; } } if (imMayMove) { displayContent.computeImeTarget(true ); } win.getParent().assignChildLayers(); if (focusChanged) { mInputMonitor.setInputFocusLw(mCurrentFocus, false ); } ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :36.967 D/WindowManager( 1049 ): addInputWindowHandle: Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}, Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}, layer=0 , frame=[0 ,0 ,0 ,0 ], touchableRegion=SkRegion((0 ,0 ,480 ,854 )), visible=false ---------------------------------------------------------------- mInputMonitor.updateInputWindowsLw(false ); ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :36.968 V/WindowManager( 1049 ): addWindow: New client android.os.BinderProxy@b9baf64 : window=Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity} Callers=com.android.server.wm.Session.addToDisplay:205 android.view.IWindowSession$Stub.onTransact:129 com.android.server.wm.Session.onTransact:164 android.os.Binder.execTransact:731 <bottom of call stack> ---------------------------------------------------------------- if (localLOGV || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addWindow: New client " + client.asBinder() + ": window=" + win + " Callers=" + Debug.getCallers(5 )); if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(displayId)) { reportNewConfig = true ; } } if (reportNewConfig) { sendNewConfiguration(displayId); } Binder.restoreCallingIdentity(origId); return res; }
5.3.1.1、WindowState创建 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\WindowState.java WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, WindowState parentWindow, int appOp, int seq, WindowManager.LayoutParams a, int viewVisibility, int ownerId, boolean ownerCanAddInternalSystemWindow, PowerManagerWrapper powerManagerWrapper) { super (service); mSession = s; mClient = c; mAppOp = appOp; mToken = token; mAppToken = mToken.asAppWindowToken(); mOwnerUid = ownerId; mOwnerCanAddInternalSystemWindow = ownerCanAddInternalSystemWindow; mWindowId = new WindowId(this ); mAttrs.copyFrom(a); mLastSurfaceInsets.set(mAttrs.surfaceInsets); mViewVisibility = viewVisibility; mPolicy = mService.mPolicy; mContext = mService.mContext; DeathRecipient deathRecipient = new DeathRecipient(); mSeq = seq; mEnforceSizeCompat = (mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0 ; mPowerManagerWrapper = powerManagerWrapper; ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :36.964 V/WindowState( 1049 ): Window Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity} client=android.os.BinderProxy@b9baf64 token=AppWindowToken{1579134 token=Token{ce2ac07 ActivityRecord{65 cc87a u0 com.android.testred/.TestActivity t5}}} (Token{ce2ac07 ActivityRecord{65 cc87a u0 com.android.testred/.TestActivity t5}}) params={(0 ,0 )(fillxfill) sim={forwardNavigation} ty=BASE_APPLICATION fmt=TRANSPARENT wanim=0x1030000 04 -16 13 :08 :36.964 V/WindowState( 1049 ): fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED}---------------------------------------------------------------- if (localLOGV) Slog.v( TAG, "Window " + this + " client=" + c.asBinder() + " token=" + token + " (" + mAttrs.token + ")" + " params=" + a); try { c.asBinder().linkToDeath(deathRecipient, 0 ); } catch (RemoteException e) { mDeathRecipient = null ; mIsChildWindow = false ; mLayoutAttached = false ; mIsImWindow = false ; mIsWallpaper = false ; mIsFloatingLayer = false ; mBaseLayer = 0 ; mSubLayer = 0 ; mInputWindowHandle = null ; mWinAnimator = null ; return ; } mDeathRecipient = deathRecipient; if ("com.android.testred" .equals(mAttrs.packageName) || "com.android.testgreen" .equals(mAttrs.packageName) || "com.android.testblue" .equals(mAttrs.packageName)){ mBaseLayer = 21010 ; mSubLayer = 0 ; mIsChildWindow = false ; mLayoutAttached = false ; mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD || mAttrs.type == TYPE_INPUT_METHOD_DIALOG; mIsWallpaper = mAttrs.type == TYPE_WALLPAPER; } else { if (mAttrs.type >= FIRST_SUB_WINDOW && mAttrs.type <= LAST_SUB_WINDOW) { mBaseLayer = mPolicy.getWindowLayerLw(parentWindow) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET; mSubLayer = mPolicy.getSubWindowLayerFromTypeLw(a.type); mIsChildWindow = true ; if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + parentWindow); parentWindow.addChild(this , sWindowSubLayerComparator); mLayoutAttached = mAttrs.type != WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; mIsImWindow = parentWindow.mAttrs.type == TYPE_INPUT_METHOD || parentWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG; mIsWallpaper = parentWindow.mAttrs.type == TYPE_WALLPAPER; } else { mBaseLayer = mPolicy.getWindowLayerLw(this ) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET; mSubLayer = 0 ; mIsChildWindow = false ; mLayoutAttached = false ; mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD || mAttrs.type == TYPE_INPUT_METHOD_DIALOG; mIsWallpaper = mAttrs.type == TYPE_WALLPAPER; } } mIsFloatingLayer = mIsImWindow || mIsWallpaper; if (mAppToken != null && mAppToken.mShowForAllUsers) { mAttrs.flags |= FLAG_SHOW_WHEN_LOCKED; } mWinAnimator = new WindowStateAnimator(this ); mWinAnimator.mAlpha = a.alpha; mRequestedWidth = 0 ; mRequestedHeight = 0 ; mLastRequestedWidth = 0 ; mLastRequestedHeight = 0 ; mLayer = 0 ; mInputWindowHandle = new InputWindowHandle( mAppToken != null ? mAppToken.mInputApplicationHandle : null , this , c, getDisplayId()); }
5.3.1.2、WindowState.attach() 在WMS服务端创建了所需对象后,接着调用了WindowState的attach()来进一步完成窗口添加。
1 2 3 4 5 6 7 8 9 10 11 12 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\WindowState.java ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :36.964 V/WindowState( 1049 ): Attaching Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity} token=AppWindowToken{1579134 token=Token{ce2ac07 ActivityRecord{65 cc87a u0 com.android.testred/.TestActivity t5}}}---------------------------------------------------------------- void attach () { if (localLOGV) Slog.v(TAG, "Attaching " + this + " token=" + mToken); mSession.windowAddedLocked(mAttrs.packageName); }
5.3.1.3、mSession.windowAddedLocked(mAttrs.packageName) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\Session.java void windowAddedLocked (String packageName) { mPackageName = packageName; mRelayoutTag = "relayoutWindow: " + mPackageName; if (mSurfaceSession == null ) { ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :36.964 V/WindowManager( 1049 ): First window added to Session{e6e78f6 2602 :u0a10088}, creating SurfaceSession04 -16 13 :08 :36.965 I/WindowManager( 1049 ): NEW SURFACE SESSION android.view.SurfaceSession@3812e82 ---------------------------------------------------------------- if (WindowManagerService.localLOGV) Slog.v( TAG_WM, "First window added to " + this + ", creating SurfaceSession" ); mSurfaceSession = new SurfaceSession(); if (SHOW_TRANSACTIONS) Slog.i( TAG_WM, " NEW SURFACE SESSION " + mSurfaceSession); mService.mSessions.add(this ); if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) { mService.dispatchNewAnimatorScaleLocked(this ); } } mNumWindow++; }
5.3.1.4、SurfaceSession建立过程 SurfaceSession对象承担了应用程序与SurfaceFlinger之间的通信过程,每一个需要与SurfaceFlinger进程交互的应用程序端都需要创建一个SurfaceSession对象。
客户端请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 G:\android9.0 \frameworks\base\core\java\android\view\SurfaceSession.java public final class SurfaceSession { private long mNativeClient; public SurfaceSession () { mNativeClient = nativeCreate(); } ...... }
Java层的SurfaceSession对象构造过程会通过JNI在native层创建一个SurfaceComposerClient对象。
1 2 3 4 5 6 7 8 G:\android9.0 \frameworks\base\core\jni\android_view_SurfaceSession.cpp static jlong nativeCreate (JNIEnv* env, jclass clazz) { SurfaceComposerClient* client = new SurfaceComposerClient(); client->incStrong((void *)nativeCreate); return reinterpret_cast <jlong>(client); }
Java层的SurfaceSession对象与C++层的SurfaceComposerClient对象之间是一对一关系。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 G:\android9.0 \frameworks\native\libs\gui\SurfaceComposerClient.cpp SurfaceComposerClient::SurfaceComposerClient() : mStatus(NO_INIT) { } void SurfaceComposerClient::onFirstRef () { sp<ISurfaceComposer> sf (ComposerService::getComposerService()) ; if (sf != 0 && mStatus == NO_INIT) { auto rootProducer = mParent.promote(); sp<ISurfaceComposerClient> conn; conn = (rootProducer != nullptr ) ? sf->createScopedConnection(rootProducer) : sf->createConnection(); if (conn != 0 ) { mClient = conn; mStatus = NO_ERROR; } } }
SurfaceComposerClient继承于RefBase类,当第一次被强引用时,onFirstRef函数被回调,在该函数中SurfaceComposerClient会请求SurfaceFlinger为当前应用程序创建一个Client对象,专门接收该应用程序的请求,在SurfaceFlinger端创建好Client本地Binder对象后,将该Binder代理对象返回给应用程序端,并保存在SurfaceComposerClient的成员变量mClient中。
服务端处理 在SurfaceFlinger服务端为应用程序创建交互的Client对象 [SurfaceFlinger.cpp]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 G:\android9.0 \frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp sp<ISurfaceComposerClient> SurfaceFlinger::createConnection () { return initClient(new Client(this )); } sp<ISurfaceComposerClient> SurfaceFlinger::createScopedConnection ( const sp<IGraphicBufferProducer>& gbp) { if (authenticateSurfaceTexture(gbp) == false ) { return nullptr ; } const auto & layer = (static_cast <MonitoredProducer*>(gbp.get()))->getLayer(); if (layer == nullptr ) { return nullptr ; } return initClient(new Client(this , layer)); }
5.3.1.5、win.mToken.addWindow(win) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\WindowToken.java ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :36.965 D/WindowManager( 1049 ): addWindow: win=Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity} Callers=com.android.server.wm.AppWindowToken.addWindow:989 com.android.server.wm.WindowManagerService.addWindow:1426 com.android.server.wm.Session.addToDisplay:205 android.view.IWindowSession$Stub.onTransact:129 com.android.server.wm.Session.onTransact:164 04 -16 13 :08 :36.965 V/WindowManager( 1049 ): Adding Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity} to AppWindowToken{1579134 token=Token{ce2ac07 ActivityRecord{65 cc87a u0 com.android.testred/.TestActivity t5}}}---------------------------------------------------------------- void addWindow (final WindowState win) { if (DEBUG_FOCUS) Slog.d(TAG_WM, "addWindow: win=" + win + " Callers=" + Debug.getCallers(5 )); if (win.isChildWindow()) { return ; } if (!mChildren.contains(win)) { if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + this ); addChild(win, mWindowComparator); mService.mWindowsChanged = true ; } }
/** Vsync start****** / (二)、Vsync trigger #####(1)、DisplayEventReceiver::sendEvents
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 G:\android9.0 \frameworks\native\services\surfaceflinger\EventThread.cpp void EventThread::threadMain () NO_THREAD_SAFETY_ANALYSIS { std ::unique_lock<std ::mutex> lock (mMutex) ; while (mKeepRunning) { DisplayEventReceiver::Event event; Vector<sp<EventThread::Connection> > signalConnections; signalConnections = waitForEventLocked(&lock, &event); const size_t count = signalConnections.size(); for (size_t i = 0 ; i < count; i++) { const sp<Connection>& conn (signalConnections[i]) ; status_t err = conn->postEvent(event); if (err == -EAGAIN || err == -EWOULDBLOCK) { ALOGW("EventThread: dropping event (%08x) for connection %p" , event.header.type, conn.get()); } else if (err < 0 ) { removeDisplayEventConnectionLocked(signalConnections[i]); } } } } status_t EventThread::Connection::postEvent(const DisplayEventReceiver::Event& event) { ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1 ); return size < 0 ? status_t (size) : status_t (NO_ERROR); }
当有Vsync信号来到时,会调用conn->postEvent(event)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 G:\android9.0 \frameworks\native\libs\gui\DisplayEventReceiver.cpp ssize_t DisplayEventReceiver::sendEvents (gui::BitTube* dataChannel, Event const * events, size_t count) { return gui::BitTube::sendObjects(dataChannel, events, count); } G:\android9.0 \frameworks\native\libs\sensor\BitTube.cpp ssize_t BitTube::sendObjects (const sp<BitTube>& tube, void const * events, size_t count, size_t objSize) { const char * vaddr = reinterpret_cast <const char *>(events); ssize_t size = tube->write(vaddr, count*objSize); LOG_ALWAYS_FATAL_IF((size >= 0 ) && (size % static_cast <ssize_t >(objSize)), "BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were sent!)" , count, objSize, size); return size < 0 ? size : size / static_cast <ssize_t >(objSize); } ssize_t BitTube::write (void const * vaddr, size_t size) { ssize_t err, len; do { len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL); err = len < 0 ? errno : 0 ; } while (err == EINTR); return err == 0 ? len : -err; }
从BitTube的初始化函数可以看出使用了套接来通讯
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 G:\android9.0 \frameworks\native\libs\sensor\BitTube.cpp void BitTube::init (size_t rcvbuf, size_t sndbuf) { int sockets[2 ]; if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0 , sockets) == 0 ) { size_t size = DEFAULT_SOCKET_BUFFER_SIZE; setsockopt(sockets[0 ], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof (rcvbuf)); setsockopt(sockets[1 ], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof (sndbuf)); setsockopt(sockets[0 ], SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)); setsockopt(sockets[1 ], SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)); fcntl(sockets[0 ], F_SETFL, O_NONBLOCK); fcntl(sockets[1 ], F_SETFL, O_NONBLOCK); mReceiveFd = sockets[0 ]; mSendFd = sockets[1 ]; } else { mReceiveFd = -errno; ALOGE("BitTube: pipe creation failed (%s)" , strerror(-mReceiveFd)); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 G:\android9.0 \frameworks\native\libs\sensor\BitTube.cpp ssize_t BitTube::recvObjects (BitTube* tube, void * events, size_t count, size_t objSize) { char * vaddr = reinterpret_cast <char *>(events); ssize_t size = tube->read(vaddr, count * objSize); LOG_ALWAYS_FATAL_IF((size >= 0 ) && (size % static_cast <ssize_t >(objSize)), "BitTube::recvObjects(count=%zu, size=%zu), res=%zd (partial events were " "received!)" , count, objSize, size); return size < 0 ? size : size / static_cast <ssize_t >(objSize); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 G:\android9.0 \frameworks\native\libs\sensor\BitTube.cpp ssize_t BitTube::read (void * vaddr, size_t size) { ssize_t err, len; do { len = ::recv(mReceiveFd, vaddr, size, MSG_DONTWAIT); err = len < 0 ? errno : 0 ; } while (err == EINTR); if (err == EAGAIN || err == EWOULDBLOCK) { return 0 ; } return err == 0 ? len : -err; }
#####(2)、DisplayEventDispatcher::handleEvent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 G:\android9.0 \frameworks\base\libs\androidfw\DisplayEventDispatcher.cpp DisplayEventDispatcher::DisplayEventDispatcher(const sp<Looper>& looper, ISurfaceComposer::VsyncSource vsyncSource) : mLooper(looper), mReceiver(vsyncSource), mWaitingForVsync(false ) { ALOGV("dispatcher %p ~ Initializing display event dispatcher." , this ); } status_t DisplayEventDispatcher::initialize () { status_t result = mReceiver.initCheck(); if (result) { ALOGW("Failed to initialize display event receiver, status=%d" , result); return result; } int rc = mLooper->addFd(mReceiver.getFd(), 0 , Looper::EVENT_INPUT, this , NULL ); if (rc < 0 ) { return UNKNOWN_ERROR; } return OK; }
而最终在addFd中注册的回调时this,这个我们之前在分析Looper的时候分析过,也就是会调用这个类的handleEvent函数,在这个函数中调用dispatchVsync继续分发VSync信号。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 G:\android9.0 \frameworks\base\libs\androidfw\DisplayEventDispatcher.cpp int DisplayEventDispatcher::handleEvent (int , int events, void *) { if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) { ALOGE("Display event receiver pipe was closed or an error occurred. " "events=0x%x" , events); return 0 ; } if (!(events & Looper::EVENT_INPUT)) { ALOGW("Received spurious callback for unhandled poll event. " "events=0x%x" , events); return 1 ; } nsecs_t vsyncTimestamp; int32_t vsyncDisplayId; uint32_t vsyncCount; if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) { ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", id=%d, count=%d" , this , ns2ms(vsyncTimestamp), vsyncDisplayId, vsyncCount); mWaitingForVsync = false ; dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount); } return 1 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 G:\android9.0 \frameworks\base\core\jni\android_view_DisplayEventReceiver.cpp void NativeDisplayEventReceiver::dispatchVsync (nsecs_t timestamp, int32_t id, uint32_t count) { JNIEnv* env = AndroidRuntime::getJNIEnv(); ScopedLocalRef<jobject> receiverObj (env, jniGetReferent(env, mReceiverWeakGlobal)) ; if (receiverObj.get()) { ALOGV("receiver %p ~ Invoking vsync handler." , this ); env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, id, count); ALOGV("receiver %p ~ Returned from vsync handler." , this ); } mMessageQueue->raiseAndClearException(env, "dispatchVsync" ); }
这里是利用jni反调了DisplayEventReceiver.java类的dispatchVsync函数。 #####(3)、DisplayEventReceiver.dispatchVsync()(Java层回调)
我们再来看看DisplayEventReceiver java类的dispatchVsync函数,调用了onVsync函数。
1 2 3 4 5 G:\android9.0 \frameworks\base\core\java\android\view\DisplayEventReceiver.java private void dispatchVsync (long timestampNanos, int builtInDisplayId, int frame) { onVsync(timestampNanos, builtInDisplayId, frame); }
而这个onVsync是一个空函数,具体在其子类中实现了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 G:\android9.0 \frameworks\base\core\java\android\view\Choreographer.java private final class FrameDisplayEventReceiver extends DisplayEventReceiver implements Runnable { private boolean mHavePendingVsync; private long mTimestampNanos; private int mFrame; public FrameDisplayEventReceiver (Looper looper, int vsyncSource) { super (looper, vsyncSource); } @Override public void onVsync (long timestampNanos, int builtInDisplayId, int frame) { ...... if (builtInDisplayId != SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) { ...... scheduleVsync(); return ; } ...... long now = System.nanoTime(); if (timestampNanos > now) { ...... timestampNanos = now; } if (mHavePendingVsync) { ...... } else { mHavePendingVsync = true ; } mTimestampNanos = timestampNanos; mFrame = frame; Message msg = Message.obtain(mHandler, this ); msg.setAsynchronous(true ); mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS); } @Override public void run () { mHavePendingVsync = false ; doFrame(mTimestampNanos, mFrame); } }
Message msg = Message.obtain(mHandler, this)最终会调用run()。
#####(4)、 doFrame(mTimestampNanos, mFrame)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 G:\android9.0 \frameworks\base\core\java\android\view\Choreographer.java void doFrame (long frameTimeNanos, int frame) { final long startNanos; synchronized (mLock) { long intendedFrameTimeNanos = frameTimeNanos; startNanos = System.nanoTime(); final long jitterNanos = startNanos - frameTimeNanos; if (jitterNanos >= mFrameIntervalNanos) { final long skippedFrames = jitterNanos / mFrameIntervalNanos; ...... final long lastFrameOffset = jitterNanos % mFrameIntervalNanos; ...... frameTimeNanos = startNanos - lastFrameOffset; } if (frameTimeNanos < mLastFrameTimeNanos) { ...... scheduleVsyncLocked(); return ; } if (mFPSDivisor > 1 ) { long timeSinceVsync = frameTimeNanos - mLastFrameTimeNanos; if (timeSinceVsync < (mFrameIntervalNanos * mFPSDivisor) && timeSinceVsync > 0 ) { scheduleVsyncLocked(); return ; } } mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos); mFrameScheduled = false ; mLastFrameTimeNanos = frameTimeNanos; } try { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Choreographer#doFrame" ); AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS); mFrameInfo.markInputHandlingStart(); doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos); mFrameInfo.markAnimationsStart(); doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos); mFrameInfo.markPerformTraversalsStart(); doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos); doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos); } finally { AnimationUtils.unlockAnimationClock(); Trace.traceEnd(Trace.TRACE_TAG_VIEW); } ..... }
Choreographer类中分别定义了CallbackRecord、CallbackQueue内部类,CallbackQueue是一个按时间先后顺序保存CallbackRecord的单向循环链表。
在Choreographer中定义了三个CallbackQueue队列,用数组mCallbackQueues表示,用于分别保存CALLBACK_INPUT、CALLBACK_ANIMATION、CALLBACK_TRAVERSAL这三种类型的Callback,当调用Choreographer类的postCallback()函数时,就是往指定类型的CallbackQueue队列中通过addCallbackLocked()函数添加一个CallbackRecord项:首先构造一个CallbackRecord对象,然后按时间先后顺序插入到CallbackQueue链表中。从代码注释中,我们可以知道CALLBACK_INPUT是指输入回调,该回调优先级最高,首先得到执行,而CALLBACK_TRAVERSAL是指处理布局和绘图的回调,只有在所有异步消息都执行完后才得到执行,CALLBACK_ANIMATION是指动画回调,比CALLBACK_TRAVERSAL优先执行,从doFrame()函数中的doCallbacks调用就能印证这点。 当Vsync事件到来时,顺序执行CALLBACK_INPUT、CALLBACK_ANIMATION、CALLBACK_TRAVERSAL 和CALLBACK_COMMIT 对应CallbackQueue队列中注册的回调。
关于Choreographer的postCallback()用法在前面进行了详细的介绍,当Vsync事件到来时,mTraversalRunnable对象的run()函数将被调用。
mTraversalRunnable对象的类型为TraversalRunnable,该类实现了Runnable接口,在其run()函数中调用了doTraversal()函数来完成窗口布局。
1 2 3 4 5 6 7 8 G:\android9.0 \frameworks\base\core\java\android\view\ViewRootImpl.java final class TraversalRunnable implements Runnable { @Override public void run () { doTraversal(); } }
#####(5)、 ViewRootImpl.doTraversal()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 G:\android9.0 \frameworks\base\core\java\android\view\ViewRootImpl.java void doTraversal () { if (mTraversalScheduled) { mTraversalScheduled = false ; mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier); if (mProfile) { Debug.startMethodTracing("ViewAncestor" ); } performTraversals(); if (mProfile) { Debug.stopMethodTracing(); mProfile = false ; } } }
(三)、Vsync 信号处理 performTraversals函数相当复杂,其主要实现以下几个重要步骤:
1.执行窗口测量;
2.执行窗口注册;
3.执行窗口布局;
4.执行窗口绘图;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 G:\android9.0 \frameworks\base\core\java\android\view\ViewRootImpl.java private void performTraversals () { final View host = mView; ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :36.978 I/System.out( 2602 ): ======================================04 -16 13 :08 :36.978 I/System.out( 2602 ): performTraversals04 -16 13 :08 :36.978 D/View ( 2602 ): + DecorView@515e1 ca[TestActivity]04 -16 13 :08 :36.978 D/View ( 2602 ): frame={0 , 0 , 0 , 0 } scroll={0 , 0 } 04 -16 13 :08 :36.978 D/View ( 2602 ): mMeasureWidth=0 mMeasureHeight=0 view.java ===>>> output = mLayoutParams.debug(output); 04 -16 13 :08 :36.991 D/Debug ( 2602 ): Contents of {(0 ,0 )(fillxfill) sim={forwardNavigation} ty=BASE_APPLICATION fmt=TRANSPARENT wanim=0x1030000 04 -16 13 :08 :36.991 D/Debug ( 2602 ): fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED}:04 -16 13 :08 :36.991 D/Debug ( 2602 ): ViewGroup.LayoutParams={ width=match-parent, height=match-parent }04 -16 13 :08 :36.991 D/Debug ( 2602 ): 04 -16 13 :08 :36.991 D/Debug ( 2602 ): WindowManager.LayoutParams={title=com.android.testred/com.android.testred.TestActivity}---------------------------------------------------------------- if (DBG) { System.out.println("======================================" ); System.out.println("performTraversals" ); host.debug(); } if (host == null || !mAdded) return ; mIsInTraversal = true ; mWillDrawSoon = true ; boolean windowSizeMayChange = false ; boolean newSurface = false ; boolean surfaceChanged = false ; WindowManager.LayoutParams lp = mWindowAttributes; int desiredWindowWidth; int desiredWindowHeight; final int viewVisibility = getHostVisibility(); ...... final boolean viewUserVisibilityChanged = !mFirst && ((mViewVisibility == View.VISIBLE) != (viewVisibility == View.VISIBLE)); WindowManager.LayoutParams params = null ; if (mWindowAttributesChanged) { mWindowAttributesChanged = false ; surfaceChanged = true ; params = lp; } CompatibilityInfo compatibilityInfo = mDisplay.getDisplayAdjustments().getCompatibilityInfo(); if (compatibilityInfo.supportsScreen() == mLastInCompatMode) { params = lp; mFullRedrawNeeded = true ; mLayoutRequested = true ; if (mLastInCompatMode) { params.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; mLastInCompatMode = false ; } else { params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; mLastInCompatMode = true ; } } mWindowAttributesChangesFlag = 0 ; Rect frame = mWinFrame; if (mFirst) { mFullRedrawNeeded = true ; mLayoutRequested = true ; final Configuration config = mContext.getResources().getConfiguration(); if (shouldUseDisplaySize(lp)) { Point size = new Point(); mDisplay.getRealSize(size); desiredWindowWidth = size.x; desiredWindowHeight = size.y; } else { desiredWindowWidth = mWinFrame.width(); desiredWindowHeight = mWinFrame.height(); } ...... if (mViewLayoutDirectionInitial == View.LAYOUT_DIRECTION_INHERIT) { host.setLayoutDirection(config.getLayoutDirection()); } host.dispatchAttachedToWindow(mAttachInfo, 0 ); mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true ); dispatchApplyInsets(host); } else { desiredWindowWidth = frame.width(); desiredWindowHeight = frame.height(); ...... } ...... boolean insetsChanged = false ; boolean layoutRequested = mLayoutRequested && (!mStopped || mReportNextDraw); if (layoutRequested) { final Resources res = mView.getContext().getResources(); if (mFirst) { mAttachInfo.mInTouchMode = !mAddedTouchMode; ensureTouchModeLocally(mAddedTouchMode); } else { ...... if (!mPendingVisibleInsets.equals(mAttachInfo.mVisibleInsets)) { mAttachInfo.mVisibleInsets.set(mPendingVisibleInsets); if (DEBUG_LAYOUT) Log.v(mTag, "Visible insets changing to: " + mAttachInfo.mVisibleInsets); } ...... if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) { windowSizeMayChange = true ; if (shouldUseDisplaySize(lp)) { Point size = new Point(); mDisplay.getRealSize(size); desiredWindowWidth = size.x; desiredWindowHeight = size.y; } else { Configuration config = res.getConfiguration(); desiredWindowWidth = dipToPx(config.screenWidthDp); desiredWindowHeight = dipToPx(config.screenHeightDp); } } } windowSizeMayChange |= measureHierarchy(host, lp, res, desiredWindowWidth, desiredWindowHeight); } if (collectViewAttributes()) { params = lp; } if (mAttachInfo.mForceReportNewAttributes) { mAttachInfo.mForceReportNewAttributes = false ; params = lp; } ...... if (mApplyInsetsRequested) { mApplyInsetsRequested = false ; mLastOverscanRequested = mAttachInfo.mOverscanRequested; dispatchApplyInsets(host); if (mLayoutRequested) { ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :36.985 V/ViewRootImpl[TestActivity]( 2602 ): Measuring DecorView@515e1 ca[TestActivity] in display 480 x782...04 -16 13 :08 :36.988 I/System.out( 2602 ): ======================================04 -16 13 :08 :36.988 I/System.out( 2602 ): performTraversals -- after measure---------------------------------------------------------------- windowSizeMayChange |= measureHierarchy(host, lp, mView.getContext().getResources(), desiredWindowWidth, desiredWindowHeight); } } if (layoutRequested) { mLayoutRequested = false ; } boolean windowShouldResize ...; windowShouldResize |= mDragResizing && mResizeMode == RESIZE_MODE_FREEFORM; windowShouldResize |= mActivityRelaunched; final boolean computesInternalInsets ...; boolean insetsPending = false ; int relayoutResult = 0 ; boolean updatedConfiguration = false ; final int surfaceGenerationId = mSurface.getGenerationId(); final boolean isViewVisible = viewVisibility == View.VISIBLE; final boolean windowRelayoutWasForced = mForceNextWindowRelayout; if (mFirst || windowShouldResize || insetsChanged || viewVisibilityChanged || params != null || mForceNextWindowRelayout) { mForceNextWindowRelayout = false ; if (isViewVisible) { insetsPending = computesInternalInsets && (mFirst || viewVisibilityChanged); } if (mSurfaceHolder != null ) { mSurfaceHolder.mSurfaceLock.lock(); mDrawingAllowed = true ; } boolean hwInitialized = false ; boolean contentInsetsChanged = false ; boolean hadSurface = mSurface.isValid(); try { ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :36.995 I/ViewRootImpl[TestActivity]( 2602 ): host=w:480 , h:782 , params={(0 ,0 )(fillxfill) sim={adjust=pan forwardNavigation} ty=BASE_APPLICATION fmt=TRANSPARENT wanim=0x1030000 04 -16 13 :08 :36.995 I/ViewRootImpl[TestActivity]( 2602 ): fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED}---------------------------------------------------------------- if (DEBUG_LAYOUT) { Log.i(mTag, "host=w:" + host.getMeasuredWidth() + ", h:" + host.getMeasuredHeight() + ", params=" + params); } if (mAttachInfo.mThreadedRenderer != null ) { if (mAttachInfo.mThreadedRenderer.pauseSurface(mSurface)) { mDirty.set(0 , 0 , mWidth, mHeight); } mChoreographer.mFrameInfo.addFlags(FrameInfo.FLAG_WINDOW_LAYOUT_CHANGED); } ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :36.997 D/ViewRootImpl[TestActivity]( 2602 ): WindowLayout in layoutWindow:{(0 ,0 )(fillxfill) sim={adjust=pan forwardNavigation} ty=BASE_APPLICATION fmt=TRANSPARENT wanim=0x1030000 04 -16 13 :08 :36.997 D/ViewRootImpl[TestActivity]( 2602 ): fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED}---------------------------------------------------------------- relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
(1)、请求WMS服务relayout窗口mWindowSession.relayout() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 G:\android9.0 \frameworks\base\core\java\android\view\ViewRootImpl.java private int relayoutWindow (WindowManager.LayoutParams params, int viewVisibility, boolean insetsPending) throws RemoteException { float appScale = mAttachInfo.mApplicationScale; boolean restore = false ; if (params != null && mTranslator != null ) { restore = true ; params.backup(); mTranslator.translateWindowLayout(params); } if (params != null ) { if (DBG) Log.d(mTag, "WindowLayout in layoutWindow:" + params); if (mOrigWindowType != params.type) { if (mTargetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { Slog.w(mTag, "Window type can not be changed after " + "the window is added; ignoring change of " + mView); params.type = mOrigWindowType; } } } long frameNumber = -1 ; if (mSurface.isValid()) { frameNumber = mSurface.getNextFrameNumber(); } int relayoutResult = 0 ; if (params != null ){ if ("com.android.testred" .equals(params.packageName) || "com.android.testgreen" .equals(params.packageName) || "com.android.testblue" .equals(params.packageName)){ Point size = new Point(); mDisplay.getRealSize(size); params.width = (int ) size.x / 3 ; params.height = (int ) size.y; relayoutResult = mWindowSession.relayout(mWindow, mSeq, params, (int ) size.x / 3 , (int ) size.y, viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0 , frameNumber, mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets, mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingDisplayCutout, mPendingMergedConfiguration, mSurface); }else { relayoutResult = mWindowSession.relayout(mWindow, mSeq, params, (int ) (mView.getMeasuredWidth() * appScale + 0.5f ), (int ) (mView.getMeasuredHeight() * appScale + 0.5f ), viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0 , frameNumber, mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets, mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingDisplayCutout, mPendingMergedConfiguration, mSurface); } } mPendingAlwaysConsumeNavBar = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR) != 0 ; if (restore) { params.restore(); } if (mTranslator != null ) { mTranslator.translateRectInScreenToAppWinFrame(mWinFrame); mTranslator.translateRectInScreenToAppWindow(mPendingOverscanInsets); mTranslator.translateRectInScreenToAppWindow(mPendingContentInsets); mTranslator.translateRectInScreenToAppWindow(mPendingVisibleInsets); mTranslator.translateRectInScreenToAppWindow(mPendingStableInsets); } return relayoutResult; }
这里通过前面获取的IWindowSession代理对象请求WMS服务执行窗口布局,mSurface是ViewRootImpl的成员变量 [->ViewRootImpl.java]
该Surface构造函数仅仅创建了一个空Surface对象,并没有对该Surface进程native层的初始化,到此我们知道应用程序进程为每个窗口对象都创建了一个Surface对象。并且将该Surface通过跨进程方式传输给WMS服务进程,我们知道,在Android系统中,如果一个对象需要在不同进程间传输,必须实现Parcelable接口,Surface类正好实现了Parcelable接口。ViewRootImpl通过IWindowSession接口请求WMS的完整过程如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 Android 9.0 已改变没有直接提供Java源码,而是.class文件打包为classes-header.jar和classes.jar。 android\out\target\common\obj\JAVA_LIBRARIES\framework_intermediates\ classes-header.jar classes.jar解压: classes/android/view/ IWindowSession.class IWindowSession$Stub.class IWindowSession$Stub$Proxy.class [解压后在线反编译](http: or [解压后在线反编译](http: ----------------------------------------------------------------------------------------------- IWindowSession.java public interface IWindowSession extends IInterface { ...... int addToDisplay (IWindow var1, int var2, LayoutParams var3, int var4, int var5, Rect var6, Rect var7, Rect var8, Rect var9, ParcelableWrapper var10, InputChannel var11) throws RemoteException ; ...... int relayout (IWindow var1, int var2, LayoutParams var3, int var4, int var5, int var6, int var7, long var8, Rect var10, Rect var11, Rect var12, Rect var13, Rect var14, Rect var15, Rect var16, ParcelableWrapper var17, MergedConfiguration var18, Surface var19) throws RemoteException ; ...... } ----------------------------------------------------------------------------------------------- IWindowSession$Stub.java public abstract class IWindowSession $Stub extends Binder implements IWindowSession { private static final String DESCRIPTOR = "android.view.IWindowSession" ; static final int TRANSACTION_addToDisplay = 2 ; static final int TRANSACTION_relayout = 6 ; public boolean onTransact (int code, Parcel data, Parcel reply, int flags) throws RemoteException { String descriptor = "android.view.IWindowSession" ; IWindow _arg0; ...... switch (code) { case 2 : data.enforceInterface(descriptor); _arg0 = Stub.asInterface(data.readStrongBinder()); _arg1 = data.readInt(); if (0 != data.readInt()) { _arg25 = (LayoutParams)LayoutParams.CREATOR.createFromParcel(data); } else { _arg25 = null ; } _arg3 = data.readInt(); _arg4 = data.readInt(); _arg53 = new Rect(); _arg63 = new Rect(); Rect _result6 = new Rect(); Rect _arg81 = new Rect(); ParcelableWrapper _result8 = new ParcelableWrapper(); InputChannel _arg91 = new InputChannel(); int _arg101 = this .addToDisplay(_arg0, _arg1, _arg25, _arg3, _arg4, _arg53, _arg63, _result6, _arg81, _result8, _arg91); ...... return true ; case 6 : data.enforceInterface(descriptor); _arg0 = Stub.asInterface(data.readStrongBinder()); _arg1 = data.readInt(); if (0 != data.readInt()) { _arg25 = (LayoutParams)LayoutParams.CREATOR.createFromParcel(data); } else { _arg25 = null ; } ...... ParcelableWrapper _arg15 = new ParcelableWrapper(); MergedConfiguration _arg16 = new MergedConfiguration(); Surface _arg17 = new Surface(); int _result2 = this .relayout(_arg0, _arg1, _arg25, _arg3, _arg4, _arg5, _arg62, _result4, _result7, _arg9, _arg10, _arg11, _arg12, _arg13, _arg14, _arg15, _arg16, _arg17); ...... if (_arg17 != null ) { reply.writeInt(1 ); _arg17.writeToParcel(reply, 1 ); } else { reply.writeInt(0 ); } return true ; }
从该函数的实现可以看出,应用程序进程中创建的Surface对象并没有传递到WMS服务进程,只是读取WMS服务进程返回来的Surface。那么WMS服务进程是如何响应应用程序进程布局请求的呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 ----------------------------------------------------------------------------------------------- IWindowSession$Stub$Proxy.java class IWindowSession $Stub $Proxy implements IWindowSession { private IBinder mRemote; IWindowSession$Stub$Proxy(IBinder remote) { mRemote = remote; } public IBinder asBinder () { return mRemote; } public String getInterfaceDescriptor () { return "android.view.IWindowSession" ; } public int addToDisplay (IWindow window, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int layerStackId, Rect outFrame, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, DisplayCutout.ParcelableWrapper displayCutout, InputChannel outInputChannel) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); try { _data.writeInterfaceToken("android.view.IWindowSession" ); _data.writeStrongBinder(window != null ? window.asBinder() : null ); _data.writeInt(seq); if (attrs != null ) { _data.writeInt(1 ); attrs.writeToParcel(_data, 0 ); } else { _data.writeInt(0 ); } _data.writeInt(viewVisibility); _data.writeInt(layerStackId); mRemote.transact(2 , _data, _reply, 0 ); _reply.readException(); int _result = _reply.readInt(); ...... } finally { _reply.recycle(); _data.recycle(); } int _result; return _result; } public int relayout (IWindow window, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame, DisplayCutout.ParcelableWrapper displayCutout, MergedConfiguration outMergedConfiguration, Surface outSurface) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); try { _data.writeInterfaceToken("android.view.IWindowSession" ); _data.writeStrongBinder(window != null ? window.asBinder() : null ); _data.writeInt(seq); if (attrs != null ) { _data.writeInt(1 ); attrs.writeToParcel(_data, 0 ); } else { _data.writeInt(0 ); } _data.writeInt(requestedWidth); _data.writeInt(requestedHeight); _data.writeInt(viewVisibility); _data.writeInt(flags); _data.writeLong(frameNumber); mRemote.transact(6 , _data, _reply, 0 ); _reply.readException(); int _result = _reply.readInt(); ...... if (0 != _reply.readInt()) { outSurface.readFromParcel(_reply); } } finally { _reply.recycle(); _data.recycle(); } int _result; return _result; } } -----------------------------------------------------------------------------------------------
该函数可以看出,WMS服务在响应应用程序进程请求添加窗口时,首先在当前进程空间创建一个Surface对象,然后调用Session的relayout()函数进一步完成窗口添加过程,最后将WMS服务中创建的Surface返回给应用程序进程。
1.1、Session.relayout() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\Session.java @Override public int relayout (IWindow window, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Rect outStableInsets, Rect outsets, Rect outBackdropFrame, DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration, Surface outSurface) { if (false ) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from " + Binder.getCallingPid()); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag); int res = mService.relayoutWindow(this , window, seq, attrs, requestedWidth, requestedHeight, viewFlags, flags, frameNumber, outFrame, outOverscanInsets, outContentInsets, outVisibleInsets, outStableInsets, outsets, outBackdropFrame, cutout, mergedConfiguration, outSurface); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); if (false ) Slog.d(TAG_WM, "<<<<<< EXITING relayout to " + Binder.getCallingPid()); return res; }
1.2、WindowManagerService.relayoutWindow() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java public int relayoutWindow (Session session, IWindow client, int seq, LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame, DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration, Surface outSurface) { int result = 0 ; boolean configChanged; ...... long origId = Binder.clearCallingIdentity(); final int displayId; synchronized (mWindowMap) { ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :36.998 V/WindowManager( 1049 ): Looking up client android.os.BinderProxy@b9baf64 : Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity} final WindowState windowForClientLocked (Session session, IBinder client, boolean throwOnError) { WindowState win = mWindowMap.get(client); if (localLOGV) Slog.v(TAG_WM, "Looking up client " + client + ": " + win); return win; } ---------------------------------------------------------------- WindowState win = windowForClientLocked(session, client, false ); displayId = win.getDisplayId(); WindowStateAnimator winAnimator = win.mWinAnimator; ...... win.setFrameNumber(frameNumber); int attrChanges = 0 ; int flagChanges = 0 ; if (attrs != null ) { mPolicy.adjustWindowParamsLw(win, attrs, hasStatusBarServicePermission); ...... } ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.000 V/WindowManager( 1049 ): Relayout Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}: viewVisibility=0 req=160 x854 {(0 ,0 )(160 x854) sim={adjust=pan forwardNavigation} ty=BASE_APPLICATION fmt=TRANSPARENT wanim=0x1030000 04 -16 13 :08 :37.000 V/WindowManager( 1049 ): fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED}---------------------------------------------------------------- if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Relayout " + win + ": viewVisibility=" + viewVisibility + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs); ...... win.setWindowScale(win.mRequestedWidth, win.mRequestedHeight); ...... final int oldVisibility = win.mViewVisibility; ....... win.mViewVisibility = viewVisibility; if (DEBUG_SCREEN_ON) { ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.001 I/WindowManager( 1049 ): Relayout Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}: oldVis=4 newVis=0 04 -16 13 :08 :37.001 I/WindowManager( 1049 ): java.lang.RuntimeException04 -16 13 :08 :37.001 I/WindowManager( 1049 ): at com.android.server.wm.WindowManagerService.relayoutWindow(WindowManagerService.java:1994 )04 -16 13 :08 :37.001 I/WindowManager( 1049 ): at com.android.server.wm.Session.relayout(Session.java:244 )04 -16 13 :08 :37.001 I/WindowManager( 1049 ): at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:309 )04 -16 13 :08 :37.001 I/WindowManager( 1049 ): at com.android.server.wm.Session.onTransact(Session.java:164 )04 -16 13 :08 :37.001 I/WindowManager( 1049 ): at android.os.Binder.execTransact(Binder.java:731 )---------------------------------------------------------------- RuntimeException stack = new RuntimeException(); stack.fillInStackTrace(); Slog.i(TAG_WM, "Relayout " + win + ": oldVis=" + oldVisibility + " newVis=" + viewVisibility, stack); } ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.001 W/WindowManager( 1049 ): setLayoutNeeded: callers=com.android.server.wm.WindowState.setDisplayLayoutNeeded:2250 com.android.server.wm.WindowManagerService.relayoutWindow:1999 com.android.server.wm.Session.relayout:244 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\WindowState.java void setLayoutNeeded () { if (DEBUG_LAYOUT) Slog.w(TAG_WM, "setLayoutNeeded: callers=" + Debug.getCallers(3 )); mLayoutNeeded = true ; } ---------------------------------------------------------------- win.setDisplayLayoutNeeded(); win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0 ; ...... mWindowPlacerLocked.performSurfacePlacement(true ); if (shouldRelayout) { result = win.relayoutVisibleWindow(result, attrChanges, oldVisibility); try { result = createSurfaceControl(outSurface, result, win, winAnimator); } catch (Exception e) { ...... return 0 ; } } else { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_2" ); winAnimator.mEnterAnimationPending = false ; winAnimator.mEnteringAnimation = false ; if (viewVisibility == View.VISIBLE && winAnimator.hasSurface()) { winAnimator.mSurfaceController.getSurface(outSurface); } else { if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win); try { outSurface.release(); } finally { Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } } Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } if (focusMayChange) { if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES, false )) { imMayMove = false ; } } boolean toBeDisplayed = (result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0 ; final DisplayContent dc = win.getDisplayContent(); if (imMayMove) { dc.computeImeTarget(true ); if (toBeDisplayed) { dc.assignWindowLayers(false ); } } ....... ---------------------------------------------------------------- 对应Log: Line 3541 : 04 -16 13 :08 :37.071 V/WindowManager( 1049 ): Relayout given client android.os.BinderProxy@b9baf64 , requestedWidth=160 , requestedHeight=854 , viewVisibility=0 Line 3542 : 04 -16 13 :08 :37.071 V/WindowManager( 1049 ): Relayout returning frame=Rect(0 , 0 - 160 , 854 ), surface=Surface(name=null )/@0xc820bda Line 3543 : 04 -16 13 :08 :37.071 V/WindowManager( 1049 ): Relayout of Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}: focusMayChange=true ---------------------------------------------------------------- if (localLOGV) Slog.v( TAG_WM, "Relayout given client " + client.asBinder() + ", requestedWidth=" + requestedWidth + ", requestedHeight=" + requestedHeight + ", viewVisibility=" + viewVisibility + "\nRelayout returning frame=" + outFrame + ", surface=" + outSurface); if (localLOGV || DEBUG_FOCUS) Slog.v( TAG_WM, "Relayout of " + win + ": focusMayChange=" + focusMayChange); result |= mInTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0 ; mInputMonitor.updateInputWindowsLw(true ); if (DEBUG_LAYOUT) { Slog.v(TAG_WM, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString()); } win.mInRelayout = false ; } ...... return result; }
首先看下堆栈信息:
1 2 04 -16 13 :08 :37.001 V/RootWindowContainer( 1049 ): performSurfacePlacementInner: entry. Called by com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop:207 com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement:155 com.android.server.wm.WindowManagerService.relayoutWindow:2031
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\WindowSurfacePlacer.java final void performSurfacePlacement (boolean force) { if (mDeferDepth > 0 && !force) { return ; } int loopCount = 6 ; do { mTraversalScheduled = false ; performSurfacePlacementLoop(); mService.mAnimationHandler.removeCallbacks(mPerformSurfacePlacement); loopCount--; } while (mTraversalScheduled && loopCount > 0 ); mService.mRoot.mWallpaperActionPending = false ; } private void performSurfacePlacementLoop () { ...... mInLayout = true ; boolean recoveringMemory = false ; ...... try { mService.mRoot.performSurfacePlacement(recoveringMemory); mInLayout = false ; if (mService.mRoot.isLayoutNeeded()) { if (++mLayoutRepeatCount < 6 ) { requestTraversal(); } else { Slog.e(TAG, "Performed 6 layouts in a row. Skipping" ); mLayoutRepeatCount = 0 ; } } else { mLayoutRepeatCount = 0 ; } if (mService.mWindowsChanged && !mService.mWindowChangeListeners.isEmpty()) { mService.mH.removeMessages(REPORT_WINDOWS_CHANGE); mService.mH.sendEmptyMessage(REPORT_WINDOWS_CHANGE); } } catch (RuntimeException e) { mInLayout = false ; Slog.wtf(TAG, "Unhandled exception while laying out windows" , e); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\RootWindowContainer.java void performSurfacePlacement (boolean recoveringMemory) { if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by " + Debug.getCallers(3 )); int i; boolean updateInputWindowsNeeded = false ; if (mService.mFocusMayChange) { mService.mFocusMayChange = false ; updateInputWindowsNeeded = mService.updateFocusedWindowLocked( UPDATE_FOCUS_WILL_PLACE_SURFACES, false ); } final int numDisplays = mChildren.size(); for (int displayNdx = 0 ; displayNdx < numDisplays; ++displayNdx) { final DisplayContent displayContent = mChildren.get(displayNdx); displayContent.setExitingTokensHasVisible(false ); } mHoldScreen = null ; mScreenBrightness = -1 ; mUserActivityTimeout = -1 ; mObscureApplicationContentOnSecondaryDisplays = false ; mSustainedPerformanceModeCurrent = false ; mService.mTransactionSequence++; final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked(); final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo(); final int defaultDw = defaultInfo.logicalWidth; final int defaultDh = defaultInfo.logicalHeight; ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.001 I/RootWindowContainer( 1049 ): >>> OPEN TRANSACTION performLayoutAndPlaceSurfaces04 -16 13 :08 :37.001 W/WindowManager( 1049 ): clearLayoutNeeded: callers=com.android.server.wm.DisplayContent.performLayout:2967 com.android.server.wm.DisplayContent.applySurfaceChangesTransaction:2880 com.android.server.wm.RootWindowContainer.applySurfaceChangesTransaction:852 ...... 04 -16 13 :08 :37.009 I/RootWindowContainer( 1049 ): <<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces---------------------------------------------------------------- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces" ); mService.openSurfaceTransaction(); try { applySurfaceChangesTransaction(recoveringMemory, defaultDw, defaultDh); } catch (RuntimeException e) { Slog.wtf(TAG, "Unhandled exception in Window Manager" , e); } finally { mService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces" ); if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces" ); } mService.mAnimator.executeAfterPrepareSurfacesRunnables(); final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked; if (mService.mAppTransition.isReady()) { final int layoutChanges = surfacePlacer.handleAppTransitionReadyLocked(); defaultDisplay.pendingLayoutChanges |= layoutChanges; if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("after handleAppTransitionReadyLocked" , defaultDisplay.pendingLayoutChanges); } ...... mService.enableScreenIfNeededLocked(); mService.scheduleAnimationLocked(); if (DEBUG_WINDOW_TRACE) Slog.e(TAG, "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating()); }
1.2.2.1、applySurfaceChangesTransaction(recoveringMemory, defaultDw, defaultDh) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\RootWindowContainer.java private void applySurfaceChangesTransaction (boolean recoveringMemory, int defaultDw, int defaultDh) { mHoldScreenWindow = null ; mObscuringWindow = null ; ...... boolean focusDisplayed = false ; final int count = mChildren.size(); for (int j = 0 ; j < count; ++j) { final DisplayContent dc = mChildren.get(j); focusDisplayed |= dc.applySurfaceChangesTransaction(recoveringMemory); } if (focusDisplayed) { mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS); } mService.mDisplayManagerInternal.performTraversal(mDisplayTransaction); SurfaceControl.mergeToGlobalTransaction(mDisplayTransaction); }
1.2.2.2、DisplayContent.applySurfaceChangesTransaction(recoveringMemory) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\DisplayContent.java boolean applySurfaceChangesTransaction (boolean recoveringMemory) { final int dw = mDisplayInfo.logicalWidth; final int dh = mDisplayInfo.logicalHeight; final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked; mTmpUpdateAllDrawn.clear(); int repeats = 0 ; do { ...... if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0 ) { setLayoutNeeded(); } if (repeats < LAYOUT_REPEAT_THRESHOLD) { performLayout(repeats == 1 , false ); } else { Slog.w(TAG, "Layout repeat skipped after too many iterations" ); } pendingLayoutChanges = 0 ; if (isDefaultDisplay) { mService.mPolicy.beginPostLayoutPolicyLw(dw, dh); ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.003 I/WindowManager( 1049 ): Win Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}: affectsSystemUi=false ...... ---------------------------------------------------------------- forAllWindows(mApplyPostLayoutPolicy, true ); pendingLayoutChanges |= mService.mPolicy.finishPostLayoutPolicyLw(); if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats( "after finishPostLayoutPolicyLw" , pendingLayoutChanges); } } while (pendingLayoutChanges != 0 ); mTmpApplySurfaceChangesTransactionState.reset(); resetDimming(); mTmpRecoveringMemory = recoveringMemory; ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.007 V/AppWindowToken( 1049 ): Eval win Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}: isDrawn=false , isAnimationSet=true 04 -16 13 :08 :37.007 V/AppWindowToken( 1049 ): Not displayed: s=null pv=true mDrawState=NO_SURFACE ph=false th=false a=true ---------------------------------------------------------------- forAllWindows(mApplySurfaceChangesTransaction, true ); ...... return mTmpApplySurfaceChangesTransactionState.focusDisplayed; }
1.2.2.3、DisplayContent.performLayout() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\DisplayContent.java void performLayout (boolean initial, boolean updateInputWindows) { if (!isLayoutNeeded()) { return ; } clearLayoutNeeded(); final int dw = mDisplayInfo.logicalWidth; final int dh = mDisplayInfo.logicalHeight; ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.001 V/DisplayContent( 1049 ): -------------------------------------04 -16 13 :08 :37.001 V/DisplayContent( 1049 ): performLayout: needed=false dw=480 dh=854 ---------------------------------------------------------------- if (DEBUG_LAYOUT) { Slog.v(TAG, "-------------------------------------" ); Slog.v(TAG, "performLayout: needed=" + isLayoutNeeded() + " dw=" + dw + " dh=" + dh); } mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo, calculateDisplayCutoutForRotation(mDisplayInfo.rotation)); mDisplayFrames.mRotation = mRotation; mService.mPolicy.beginLayoutLw(mDisplayFrames, getConfiguration().uiMode); if (isDefaultDisplay) { mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw(); mService.mScreenRect.set(0 , 0 , dw, dh); } int seq = mLayoutSeq + 1 ; if (seq < 0 ) seq = 0 ; mLayoutSeq = seq; mTmpWindow = null ; mTmpInitial = initial; forAllWindows(mPerformLayout, true ); mTmpWindow2 = mTmpWindow; mTmpWindow = null ; forAllWindows(mPerformLayoutAttached, true ); mService.mInputMonitor.layoutInputConsumers(dw, dh); mService.mInputMonitor.setUpdateInputWindowsNeededLw(); if (updateInputWindows) { mService.mInputMonitor.updateInputWindowsLw(false ); } mService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER); }
1.2.2.4、DisplayContent.forAllWindows(mPerformLayout, …) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\DisplayContent.java private final Consumer<WindowState> mPerformLayout = w -> { final boolean gone = (mTmpWindow != null && mService.mPolicy.canBeHiddenByKeyguardLw(w)) || w.isGoneForLayoutLw(); ---------------------------------------------------------------- 对应Log: ...... 04 -16 13 :08 :37.002 V/DisplayContent( 1049 ): 1 ST PASS Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}: gone=false mHaveFrame=false mLayoutAttached=false screen changed=true 04 -16 13 :08 :37.002 V/DisplayContent( 1049 ): VIS: mViewVisibility=0 mRelayoutCalled=true hidden=true hiddenRequested=false parentHidden=false ...... ---------------------------------------------------------------- if (DEBUG_LAYOUT && !w.mLayoutAttached) { Slog.v(TAG, "1ST PASS " + w + ": gone=" + gone + " mHaveFrame=" + w.mHaveFrame + " mLayoutAttached=" + w.mLayoutAttached + " screen changed=" + w.isConfigChanged()); final AppWindowToken atoken = w.mAppToken; if (gone) Slog.v(TAG, " GONE: mViewVisibility=" + w.mViewVisibility + " mRelayoutCalled=" + w.mRelayoutCalled + " hidden=" + w.mToken.isHidden() + " hiddenRequested=" + (atoken != null && atoken.hiddenRequested) + " parentHidden=" + w.isParentWindowHidden()); else Slog.v(TAG, " VIS: mViewVisibility=" + w.mViewVisibility + " mRelayoutCalled=" + w.mRelayoutCalled + " hidden=" + w.mToken.isHidden() + " hiddenRequested=" + (atoken != null && atoken.hiddenRequested) + " parentHidden=" + w.isParentWindowHidden()); } if (!gone || !w.mHaveFrame || w.mLayoutNeeded || ((w.isConfigChanged() || w.setReportResizeHints()) && !w.isGoneForLayoutLw() && ((w.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 || (w.mHasSurface && w.mAppToken != null && w.mAppToken.layoutConfigChanges)))) { if (!w.mLayoutAttached) { if (mTmpInitial) { w.mContentChanged = false ; } if (w.mAttrs.type == TYPE_DREAM) { mTmpWindow = w; } w.mLayoutNeeded = false ; w.prelayout(); final boolean firstLayout = !w.isLaidOut(); mService.mPolicy.layoutWindowLw(w, null , mDisplayFrames); w.mLayoutSeq = mLayoutSeq; if (firstLayout) { w.updateLastInsetValues(); } if (w.mAppToken != null ) { w.mAppToken.layoutLetterbox(w); } ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.002 V/DisplayContent( 1049 ): LAYOUT: mFrame=Rect(0 , 0 - 160 , 854 ) mContainingFrame=Rect(0 , 0 - 160 , 854 ) mDisplayFrame=Rect(0 , 0 - 160 , 854 )---------------------------------------------------------------- if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.mFrame + " mContainingFrame=" + w.mContainingFrame + " mDisplayFrame=" + w.mDisplayFrame); } } };
1.2.2.5、mService.mPolicy[PhoneWindowManager].layoutWindowLw(w, null, mDisplayFrames) 由之前加入的patch可以知道,我们将App(com.android.testred)的Window宽度强制设置为1/3屏幕宽度,即160。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 @Override public void layoutWindowLw (WindowState win, WindowState attached, DisplayFrames displayFrames) { if ((win == mStatusBar && !canReceiveInput(win)) || win == mNavigationBar || mScreenDecorWindows.contains(win)) { return ; } final WindowManager.LayoutParams attrs = win.getAttrs(); final boolean isDefaultDisplay = win.isDefaultDisplay(); final boolean needsToOffsetInputMethodTarget = isDefaultDisplay && (win == mLastInputMethodTargetWindow && mLastInputMethodWindow != null ); if (needsToOffsetInputMethodTarget) { if (DEBUG_LAYOUT) Slog.i(TAG, "Offset ime target window by the last ime window state" ); offsetInputMethodWindowLw(mLastInputMethodWindow, displayFrames); } final int type = attrs.type; final int fl = PolicyControl.getWindowFlags(win, attrs); final int pfl = attrs.privateFlags; final int sim = attrs.softInputMode; final int requestedSysUiFl = PolicyControl.getSystemUiVisibility(null , attrs); final int sysUiFl = requestedSysUiFl | getImpliedSysUiFlagsForLayout(attrs); final Rect pf = mTmpParentFrame; final Rect df = mTmpDisplayFrame; final Rect of = mTmpOverscanFrame; final Rect cf = mTmpContentFrame; final Rect vf = mTmpVisibleFrame; final Rect dcf = mTmpDecorFrame; final Rect sf = mTmpStableFrame; Rect osf = null ; dcf.setEmpty(); ....... if (layoutInScreen && layoutInsetDecor) { if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): IN_SCREEN, INSET_DECOR" ); ...... } ..... if ("com.android.testred" .equals(win.getAttrs().packageName)) { pf.left = df.left = of.left = cf.left = displayFrames.mOverscan.left; pf.top = df.top = of.top = cf.top = displayFrames.mOverscan.top; pf.right = df.right = of.right = cf.right = displayFrames.mOverscan.left + displayFrames.mOverscan.right / 3 ; pf.bottom = df.bottom = of.bottom = cf.bottom = displayFrames.mOverscan.top + displayFrames.mOverscan.bottom; } if ("com.android.testgreen" .equals(win.getAttrs().packageName)) { pf.left = df.left = of.left = cf.left = displayFrames.mOverscan.left + displayFrames.mOverscan.right / 3 ; pf.top = df.top = of.top = cf.top = displayFrames.mOverscan.top; pf.right = df.right = of.right = cf.right = displayFrames.mOverscan.left + displayFrames.mOverscan.right * 2 / 3 ; pf.bottom = df.bottom = of.bottom = cf.bottom = displayFrames.mOverscan.top + displayFrames.mOverscan.bottom; } if ("com.android.testblue" .equals(win.getAttrs().packageName)) { pf.left = df.left = of.left = cf.left = displayFrames.mOverscan.left + displayFrames.mOverscan.right * 2 / 3 ; pf.top = df.top = of.top = cf.top = displayFrames.mOverscan.top; pf.right = df.right = of.right = cf.right = displayFrames.mOverscan.left + displayFrames.mOverscan.right * 3 / 3 ; pf.bottom = df.bottom = of.bottom = cf.bottom = displayFrames.mOverscan.top + displayFrames.mOverscan.bottom; } ---------------------------------------------------------------- 对应Log: ...... 04 -16 13 :08 :37.002 V/WindowManager( 1049 ): layoutWindowLw(com.android.testred/com.android.testred.TestActivity): IN_SCREEN, INSET_DECOR04-16 13:08:37.002 V/WindowManager( 1049): Compute frame com.android.testred/com.android.testred.TestActivity: sim=#120 attach=null type=1 flags=0x01810100 pf=[0,0][160,854] df=[0,0][160,854] of=[0,0][160,854] cf=[0,0][160,854] vf=[0,36][480,782] dcf=[0,36][480,782] sf=[0,36][480,782] osf=null ---------------------------------------------------------------- if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle() + ": sim=#" + Integer.toHexString(sim) + " attach=" + attached + " type=" + type + String.format(" flags=0x%08x" , fl) + " pf=" + pf.toShortString() + " df=" + df.toShortString() + " of=" + of.toShortString() + " cf=" + cf.toShortString() + " vf=" + vf.toShortString() + " dcf=" + dcf.toShortString() + " sf=" + sf.toShortString() + " osf=" + (osf == null ? "null" : osf.toShortString())); win.computeFrameLw(pf, df, of, cf, vf, dcf, sf, osf, displayFrames.mDisplayCutout, parentFrameWasClippedByDisplayCutout); if (type == TYPE_INPUT_METHOD && win.isVisibleLw() && !win.getGivenInsetsPendingLw()) { setLastInputMethodWindowLw(null , null ); offsetInputMethodWindowLw(win, displayFrames); } if (type == TYPE_VOICE_INTERACTION && win.isVisibleLw() && !win.getGivenInsetsPendingLw()) { offsetVoiceInputWindowLw(win, displayFrames); } }
1.2.2.5、WindowState.computeFrameLw() WindowState大小复杂计算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 @Override public void computeFrameLw (Rect parentFrame, Rect displayFrame, Rect overscanFrame, Rect contentFrame, Rect visibleFrame, Rect decorFrame, Rect stableFrame, Rect outsetFrame, WmDisplayCutout displayCutout, boolean parentFrameWasClippedByDisplayCutout) { ...... mHaveFrame = true ; mParentFrameWasClippedByDisplayCutout = parentFrameWasClippedByDisplayCutout; final Task task = getTask(); final boolean inFullscreenContainer = inFullscreenContainer(); final boolean windowsAreFloating = task != null && task.isFloating(); final DisplayContent dc = getDisplayContent(); ...... final int pw = mContainingFrame.width(); final int ph = mContainingFrame.height(); ...... mOverscanFrame.set(overscanFrame); mContentFrame.set(contentFrame); mVisibleFrame.set(visibleFrame); mDecorFrame.set(decorFrame); mStableFrame.set(stableFrame); final boolean hasOutsets = outsetFrame != null ; if (hasOutsets) { mOutsetFrame.set(outsetFrame); } final int fw = mFrame.width(); final int fh = mFrame.height(); applyGravityAndUpdateFrame(layoutContainingFrame, layoutDisplayFrame); ...... if (windowsAreFloating && !mFrame.isEmpty()) { ...... } else { mContentFrame.set(Math.max(mContentFrame.left, mFrame.left), Math.max(mContentFrame.top, mFrame.top), Math.min(mContentFrame.right, mFrame.right), Math.min(mContentFrame.bottom, mFrame.bottom)); mVisibleFrame.set(Math.max(mVisibleFrame.left, mFrame.left), Math.max(mVisibleFrame.top, mFrame.top), Math.min(mVisibleFrame.right, mFrame.right), Math.min(mVisibleFrame.bottom, mFrame.bottom)); mStableFrame.set(Math.max(mStableFrame.left, mFrame.left), Math.max(mStableFrame.top, mFrame.top), Math.min(mStableFrame.right, mFrame.right), Math.min(mStableFrame.bottom, mFrame.bottom)); } ...... if (mAttrs.type == TYPE_DOCK_DIVIDER) { ...... } else { getDisplayContent().getBounds(mTmpRect); boolean overrideRightInset = !windowsAreFloating && !inFullscreenContainer && mFrame.right > mTmpRect.right; boolean overrideBottomInset = !windowsAreFloating && !inFullscreenContainer && mFrame.bottom > mTmpRect.bottom; mContentInsets.set(mContentFrame.left - mFrame.left, mContentFrame.top - mFrame.top, overrideRightInset ? mTmpRect.right - mContentFrame.right : mFrame.right - mContentFrame.right, overrideBottomInset ? mTmpRect.bottom - mContentFrame.bottom : mFrame.bottom - mContentFrame.bottom); mVisibleInsets.set(mVisibleFrame.left - mFrame.left, mVisibleFrame.top - mFrame.top, overrideRightInset ? mTmpRect.right - mVisibleFrame.right : mFrame.right - mVisibleFrame.right, overrideBottomInset ? mTmpRect.bottom - mVisibleFrame.bottom : mFrame.bottom - mVisibleFrame.bottom); mStableInsets.set(Math.max(mStableFrame.left - mFrame.left, 0 ), Math.max(mStableFrame.top - mFrame.top, 0 ), overrideRightInset ? Math.max(mTmpRect.right - mStableFrame.right, 0 ) : Math.max(mFrame.right - mStableFrame.right, 0 ), overrideBottomInset ? Math.max(mTmpRect.bottom - mStableFrame.bottom, 0 ) : Math.max(mFrame.bottom - mStableFrame.bottom, 0 )); } mDisplayCutout = displayCutout.calculateRelativeTo(mFrame); mFrame.offset(-layoutXDiff, -layoutYDiff); mCompatFrame.offset(-layoutXDiff, -layoutYDiff); mContentFrame.offset(-layoutXDiff, -layoutYDiff); mVisibleFrame.offset(-layoutXDiff, -layoutYDiff); mStableFrame.offset(-layoutXDiff, -layoutYDiff); mCompatFrame.set(mFrame); ...... ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.002 V/WindowState( 1049 ): Resolving (mRequestedWidth=160 , mRequestedheight=854 ) to (pw=160 , ph=854 ): frame=[0 ,0 ][160 ,854 ] ci=[0 ,0 ][0 ,0 ] vi=[0 ,36 ][0 ,72 ] si=[0 ,36 ][0 ,72 ] of=[0 ,0 ][0 ,0 ]---------------------------------------------------------------- if (DEBUG_LAYOUT || localLOGV) Slog.v(TAG, "Resolving (mRequestedWidth=" + mRequestedWidth + ", mRequestedheight=" + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph + "): frame=" + mFrame.toShortString() + " ci=" + mContentInsets.toShortString() + " vi=" + mVisibleInsets.toShortString() + " si=" + mStableInsets.toShortString() + " of=" + mOutsets.toShortString()); }
继续看看DisplayContent方法中的RootWindowContainer.performSurfacePlacement(recoveringMemory)
1.2.3、surfacePlacer.handleAppTransitionReadyLocked() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\WindowSurfacePlacer.java int handleAppTransitionReadyLocked () { int appsCount = mService.mOpeningApps.size(); if (!transitionGoodToGo(appsCount, mTempTransitionReasons)) { return 0 ; } private boolean transitionGoodToGo (int appsCount, SparseIntArray outReasons) { if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Checking " + appsCount + " opening apps (frozen=" + mService.mDisplayFrozen + " timeout=" + mService.mAppTransition.isTimeout() + ")..." ); final ScreenRotationAnimation screenRotationAnimation = mService.mAnimator.getScreenRotationAnimationLocked( Display.DEFAULT_DISPLAY); outReasons.clear(); if (!mService.mAppTransition.isTimeout()) { ...... ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.009 V/WindowSurfacePlacer( 1049 ): Checking 1 opening apps (frozen=false timeout=false ) ... 04-16 13:08:37.009 V/WindowSurfacePlacer ( 1049 ) : Check opening app =AppWindowToken{1579134 token=Token{ce2ac07 ActivityRecord{65 cc87a u0 com.android.testred/.TestActivity t5}}}: allDrawn=false startingDisplayed=false startingMoved=false isRelaunching () =false startingWindow=null ---------------------------------------------------------------- for (int i = 0 ; i < appsCount; i++) { AppWindowToken wtoken = mService.mOpeningApps.valueAt(i); if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Check opening app=" + wtoken + ": allDrawn=" + wtoken.allDrawn + " startingDisplayed=" + wtoken.startingDisplayed + " startingMoved=" + wtoken.startingMoved + " isRelaunching()=" + wtoken.isRelaunching() + " startingWindow=" + wtoken.startingWindow); final boolean allDrawn = wtoken.allDrawn && !wtoken.isRelaunching(); if (!allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) { return false ; } final int windowingMode = wtoken.getWindowingMode(); if (allDrawn) { outReasons.put(windowingMode, APP_TRANSITION_WINDOWS_DRAWN); } else { outReasons.put(windowingMode, wtoken.startingData instanceof SplashScreenStartingData ? APP_TRANSITION_SPLASH_SCREEN : APP_TRANSITION_SNAPSHOT); } } ...... } return true ; }
根据前面分析可知道,现在App(com.android.testred)的大小和布局都处理好了,等待显示,但现在还么有mDrawState=NO_SURFACE ,肯定无法显示出来的,接下来看看Surface创建过程。
1 2 04 -16 13 :08 :37.007 V/AppWindowToken( 1049 ): Eval win Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}: isDrawn=false , isAnimationSet=true 04 -16 13 :08 :37.007 V/AppWindowToken( 1049 ): Not displayed: s=null pv=true mDrawState=NO_SURFACE ph=false th=false a=true
继续看看WindowManagerService.relayoutWindow()
(2)、Surface创建过程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java private int createSurfaceControl (Surface outSurface, int result, WindowState win, WindowStateAnimator winAnimator) { if (!win.mHasSurface) { result |= RELAYOUT_RES_SURFACE_CHANGED; } WindowSurfaceController surfaceController; try { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl" ); surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid); } finally { Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } if (surfaceController != null ) { surfaceController.getSurface(outSurface); if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " OUT SURFACE " + outSurface + ": copied" ); } else { Slog.w(TAG_WM, "Failed to create surface control for " + win); outSurface.release(); } return result; }
2.1、winAnimator.createSurfaceLocked() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\WindowStateAnimator.java WindowSurfaceController createSurfaceLocked (int windowType, int ownerUid) { final WindowState w = mWin; if (mSurfaceController != null ) { return mSurfaceController; } mChildrenDetached = false ; if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0 ) { windowType = SurfaceControl.WINDOW_TYPE_DONT_SCREENSHOT; } w.setHasSurface(false ); if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG, "createSurface " + this + ": mDrawState=DRAW_PENDING" ); ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.010 I/WindowStateAnimator( 1049 ): createSurface WindowStateAnimator{4f b81c9 com.android.testred/com.android.testred.TestActivity}: mDrawState=DRAW_PENDING---------------------------------------------------------------- resetDrawState(); mService.makeWindowFreezingScreenIfNeededLocked(w); int flags = SurfaceControl.HIDDEN; final WindowManager.LayoutParams attrs = w.mAttrs; if (mService.isSecureLocked(w)) { flags |= SurfaceControl.SECURE; } mTmpSize.set(0 , 0 , 0 , 0 ); calculateSurfaceBounds(w, attrs); final int width = mTmpSize.width(); final int height = mTmpSize.height(); if (DEBUG_VISIBILITY) { Slog.v(TAG, "Creating surface in session " + mSession.mSurfaceSession + " window " + this + " w=" + width + " h=" + height + " x=" + mTmpSize.left + " y=" + mTmpSize.top + " format=" + attrs.format + " flags=" + flags); } ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.010 V/WindowStateAnimator( 1049 ): Creating surface in session android.view.SurfaceSession@3812e82 window WindowStateAnimator{4f b81c9 com.android.testred/com.android.testred.TestActivity} w=160 h=854 x=0 y=0 format=-2 flags=4 ---------------------------------------------------------------- mLastClipRect.set(0 , 0 , 0 , 0 ); try { final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0 ; final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format; if (!PixelFormat.formatHasAlpha(attrs.format) && attrs.surfaceInsets.left == 0 && attrs.surfaceInsets.top == 0 && attrs.surfaceInsets.right == 0 && attrs.surfaceInsets.bottom == 0 && !w.isDragResizing()) { flags |= SurfaceControl.OPAQUE; } mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession, attrs.getTitle().toString(), width, height, format, flags, this , windowType, ownerUid); setOffsetPositionForStackResize(false ); mSurfaceFormat = format; w.setHasSurface(true ); if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { Slog.i(TAG, " CREATE SURFACE " + mSurfaceController + " IN SESSION " + mSession.mSurfaceSession + ": pid=" + mSession.mPid + " format=" + attrs.format + " flags=0x" + Integer.toHexString(flags) + " / " + this ); } ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.012 I/WindowStateAnimator( 1049 ): CREATE SURFACE Surface (name=com.android.testred/com.android.testred.TestActivity) /@0xb17b0ce IN SESSION android.view.SurfaceSession@3812e82: pid =2602 format=-2 flags=0x4 / WindowStateAnimator{4f b81c9 com.android.testred/com.android.testred.TestActivity}---------------------------------------------------------------- } catch (OutOfResourcesException e) { Slog.w(TAG, "OutOfResourcesException creating surface" ); mService.mRoot.reclaimSomeSurfaceMemory(this , "create" , true ); mDrawState = NO_SURFACE; return null ; } catch (Exception e) { Slog.e(TAG, "Exception creating surface (parent dead?)" , e); mDrawState = NO_SURFACE; return null ; } if (WindowManagerService.localLOGV) Slog.v(TAG, "Got surface: " + mSurfaceController + ", set left=" + w.mFrame.left + " top=" + w.mFrame.top + ", animLayer=" + mAnimLayer); ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.012 V/WindowStateAnimator( 1049 ): Got surface: Surface(name=com.android.testred/com.android.testred.TestActivity)/@0xb17b0ce , set left=0 top=0 , animLayer=0 ---------------------------------------------------------------- if (SHOW_LIGHT_TRANSACTIONS) { Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked" ); WindowManagerService.logSurface(w, "CREATE pos=(" + w.mFrame.left + "," + w.mFrame.top + ") (" + width + "x" + height + "), layer=" + mAnimLayer + " HIDE" , false ); } mLastHidden = true ; if (WindowManagerService.localLOGV) Slog.v(TAG, "Created surface " + this ); ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.012 I/WindowStateAnimator( 1049 ): >>> OPEN TRANSACTION createSurfaceLocked04 -16 13 :08 :37.012 I/WindowManager( 1049 ): SURFACE CREATE pos=(0 ,0 ) (160 x854), layer=0 HIDE: Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}04 -16 13 :08 :37.012 V/WindowStateAnimator( 1049 ): Created surface WindowStateAnimator{4f b81c9 com.android.testred/com.android.testred.TestActivity}---------------------------------------------------------------- return mSurfaceController; }
2.1.1、new WindowSurfaceController() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\WindowSurfaceController.java public WindowSurfaceController (SurfaceSession s, String name, int w, int h, int format, int flags, WindowStateAnimator animator, int windowType, int ownerUid) { mAnimator = animator; mSurfaceW = w; mSurfaceH = h; title = name; mService = animator.mService; final WindowState win = animator.mWin; mWindowType = windowType; mWindowSession = win.mSession; Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl" ); final SurfaceControl.Builder b = win.makeSurface() .setParent(win.getSurfaceControl()) .setName(name) .setSize(w, h) .setFormat(format) .setFlags(flags) .setMetadata(windowType, ownerUid); mSurfaceControl = b.build(); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); }
2.1.1.1、创建SurfaceControl build() 1 2 3 4 5 6 7 8 9 10 G:\android9.0 \frameworks\base\core\java\android\view\SurfaceControl.java public SurfaceControl build () { if (mWidth <= 0 || mHeight <= 0 ) { throw new IllegalArgumentException( "width and height must be set" ); } return new SurfaceControl(mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mWindowType, mOwnerUid); }
2.1.1.2、new SurfaceControl() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 private SurfaceControl (SurfaceSession session, String name, int w, int h, int format, int flags, SurfaceControl parent, int windowType, int ownerUid) throws OutOfResourcesException, IllegalArgumentException { ...... if ((flags & SurfaceControl.HIDDEN) == 0 ) { Log.w(TAG, "Surfaces should always be created with the HIDDEN flag set " + "to ensure that they are not made visible prematurely before " + "all of the surface's properties have been configured. " + "Set the other properties and make the surface visible within " + "a transaction. New surface name: " + name, new Throwable()); } mName = name; mWidth = w; mHeight = h; mNativeObject = nativeCreate(session, name, w, h, format, flags, parent != null ? parent.mNativeObject : 0 , windowType, ownerUid); ...... mCloseGuard.open("release" ); } G:\android9.0 \frameworks\base\core\jni\android_view_SurfaceControl.cpp static jlong nativeCreate (JNIEnv* env, jclass clazz, jobject sessionObj, jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject, jint windowType, jint ownerUid) { ScopedUtfChars name (env, nameStr) ; sp<SurfaceComposerClient> client (android_view_SurfaceSession_getClient(env, sessionObj) ) ; SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject); sp<SurfaceControl> surface; status_t err = client->createSurfaceChecked( String8(name.c_str()), w, h, format, &surface, flags, parent, windowType, ownerUid); if (err == NAME_NOT_FOUND) { jniThrowException(env, "java/lang/IllegalArgumentException" , NULL); return 0 ; } else if (err != NO_ERROR) { jniThrowException(env, OutOfResourcesException, NULL); return 0 ; } surface->incStrong((void *)nativeCreate); return reinterpret_cast<jlong>(surface.get()); }
该函数首先得到前面创建好的SurfaceComposerClient对象,通过该对象向SurfaceFlinger端的Client对象发送创建Surface的请求,最后得到一个SurfaceControl对象 看看createSurfaceChecked()函数实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 G:\android9.0 \frameworks\native\libs\gui\SurfaceComposerClient.cpp status_t SurfaceComposerClient::createSurfaceChecked ( const String8& name, uint32_t w, uint32_t h, PixelFormat format, sp<SurfaceControl>* outSurface, uint32_t flags, SurfaceControl* parent, int32_t windowType, int32_t ownerUid) { sp<SurfaceControl> sur; status_t err = mStatus; if (mStatus == NO_ERROR) { sp<IBinder> handle; sp<IBinder> parentHandle; sp<IGraphicBufferProducer> gbp; if (parent != nullptr ) { parentHandle = parent->getHandle(); } err = mClient->createSurface(name, w, h, format, flags, parentHandle, windowType, ownerUid, &handle, &gbp); ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s" , strerror(-err)); if (err == NO_ERROR) { *outSurface = new SurfaceControl(this , handle, gbp, true ); } } return err; } G:\android9.0 \frameworks\native\libs\gui\SurfaceControl.cpp SurfaceControl::SurfaceControl( const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle, const sp<IGraphicBufferProducer>& gbp, bool owned) : mClient(client), mHandle(handle), mGraphicBufferProducer(gbp), mOwned(owned) { }
SurfaceComposerClient将Surface创建请求转交给保存在其成员变量中的Bp SurfaceComposerClient对象来完成,在SurfaceFlinger端的Client本地对象会返回一个ISurface代理对象给应用程序,通过该代理对象为应用程序当前创建的Surface创建一个SurfaceControl对象。 [ISurfaceComposerClient.cpp]
1 2 3 4 5 6 7 8 9 10 11 12 G:\android9.0 \frameworks\native\libs\gui\ISurfaceComposerClient.cpp status_t createSurface (const String8& name, uint32_t width, uint32_t height, PixelFormat format, uint32_t flags, const sp<IBinder>& parent, int32_t windowType, int32_t ownerUid, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) override { return callRemote<decltype (&ISurfaceComposerClient::createSurface)>(Tag::CREATE_SURFACE, name, width, height, format, flags, parent, windowType, ownerUid, handle, gbp); }
2.1.1.3、Client->createSurface() MessageCreateSurface消息是专门为应用程序请求创建Surface而定义的一种消息类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 G:\android9.0 \frameworks\native\services\surfaceflinger\Client.cpp status_t Client::createSurface ( const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, const sp<IBinder>& parentHandle, int32_t windowType, int32_t ownerUid, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) { sp<Layer> parent = nullptr ; if (parentHandle != nullptr ) { auto layerHandle = reinterpret_cast <Layer::Handle*>(parentHandle.get()); parent = layerHandle->owner.promote(); if (parent == nullptr ) { return NAME_NOT_FOUND; } } if (parent == nullptr ) { bool parentDied; parent = getParentLayer(&parentDied); if (parentDied) { return NAME_NOT_FOUND; } } class MessageCreateLayer : public MessageBase { SurfaceFlinger* flinger; Client* client; sp<IBinder>* handle; sp<IGraphicBufferProducer>* gbp; status_t result; const String8& name; uint32_t w, h; PixelFormat format; uint32_t flags; sp<Layer>* parent; int32_t windowType; int32_t ownerUid; public : MessageCreateLayer(SurfaceFlinger* flinger, const String8& name, Client* client, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, sp<IBinder>* handle, int32_t windowType, int32_t ownerUid, sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent) : flinger(flinger), client(client), handle(handle), gbp(gbp), result(NO_ERROR), name(name), w(w), h(h), format(format), flags(flags), parent(parent), windowType(windowType), ownerUid(ownerUid) { } status_t getResult () const { return result; } virtual bool handler () { result = flinger->createLayer(name, client, w, h, format, flags, windowType, ownerUid, handle, gbp, parent); return true ; } }; sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(), name, this , w, h, format, flags, handle, windowType, ownerUid, gbp, &parent); mFlinger->postMessageSync(msg); return static_cast <MessageCreateLayer*>( msg.get() )->getResult(); }
SurfaceFlinger根据标志位创建对应类型的Surface,当前系统定义了2种类型的Layer
1 2 3 4 G:\android9.0 \frameworks\native \libs\gui\include\gui\ISurfaceComposerClient.h eFXSurfaceNormal = 0x00000000 , eFXSurfaceColor = 0x00020000 ,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 G:\android9.0 \frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp status_t SurfaceFlinger::createLayer ( const String8& name, const sp<Client>& client, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, int32_t windowType, int32_t ownerUid, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent) { if (int32_t (w|h) < 0 ) { ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)" , int (w), int (h)); return BAD_VALUE; } status_t result = NO_ERROR; sp<Layer> layer; String8 uniqueName = getUniqueLayerName(name); switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { case ISurfaceComposerClient::eFXSurfaceNormal: result = createBufferLayer(client, uniqueName, w, h, flags, format, handle, gbp, &layer); break ; case ISurfaceComposerClient::eFXSurfaceColor: result = createColorLayer(client, uniqueName, w, h, flags, handle, &layer); break ; default : result = BAD_VALUE; break ; } if (result != NO_ERROR) { return result; } if (windowType == 441731 ) { windowType = 2024 ; layer->setPrimaryDisplayOnly(); } layer->setInfo(windowType, ownerUid); result = addClientLayer(client, *handle, *gbp, layer, *parent); if (result != NO_ERROR) { return result; } mInterceptor->saveSurfaceCreation(layer); setTransactionFlags(eTransactionNeeded); return result; }
有前面java层可知flags = SurfaceControl.HIDDEN,flags & ISurfaceComposerClient::eFXSurfaceMask == eFXSurfaceNormal = 0x00000000,所以此外走createBufferLayer()分支
2.1.1.4、createBufferLayer() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 G:\android9.0 \frameworks\native \services\surfaceflinger\SurfaceFlinger.cpp status_t SurfaceFlinger::createBufferLayer(const sp<Client>& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) { switch (format) { case PIXEL_FORMAT_TRANSPARENT: case PIXEL_FORMAT_TRANSLUCENT: format = PIXEL_FORMAT_RGBA_8888; break ; case PIXEL_FORMAT_OPAQUE: format = PIXEL_FORMAT_RGBX_8888; break ; } sp<BufferLayer> layer = DisplayUtils::getInstance()->getBufferLayerInstance( this , client, name, w, h, flags); status_t err = layer->setBuffers(w, h, format, flags); ---------------------------------------------------------------- 对应Log: status_t BufferLayer::setBuffers(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { uint32_t const maxSurfaceDims = min(mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims()); if ((uint32_t(w) > maxSurfaceDims) || (uint32_t(h) > maxSurfaceDims)) { ALOGE("dimensions too large %u x %u" , uint32_t(w), uint32_t(h)); return BAD_VALUE; } mFormat = format; mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false ; mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false ; mCurrentOpacity = getOpacityForFormat(format); mConsumer->setDefaultBufferSize(w, h); mConsumer->setDefaultBufferFormat(format); mConsumer->setConsumerUsageBits(getEffectiveUsage(0 )); return NO_ERROR; } 04-16 13:08:37.011 V/BufferQueueConsumer( 739): [com.android.testred/com.android.testred.TestActivity#0] setDefaultBufferSize: width=160 height=854 04-16 13:08:37.011 V/BufferQueueConsumer( 739): [com.android.testred/com.android.testred.TestActivity#0] setDefaultBufferFormat: 1 04-16 13:08:37.011 V/BufferQueueConsumer( 739): [com.android.testred/com.android.testred.TestActivity#0] setConsumerUsageBits: 0x900 ---------------------------------------------------------------- if (err == NO_ERROR) { *handle = layer->getHandle(); *gbp = layer->getProducer(); *outLayer = layer; } ALOGE_IF(err, "createBufferLayer() failed (%s)" , strerror(-err)); return err; }
2.1.1.5、DisplayUtils::getInstance()->getBufferLayerInstance() 1 2 3 4 5 6 7 8 9 10 11 G:\android9.0 \frameworks\native\services\surfaceflinger\DisplayUtils.cpp BufferLayer* DisplayUtils::getBufferLayerInstance (SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags) { if (sUseExtendedImpls) { return new ExBufferLayer(flinger, client, name, w, h, flags); } else { return new BufferLayer(flinger, client, name, w, h, flags); } }
2.1.1.6、new BufferLayer() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 G:\android9.0 \frameworks\native\services\surfaceflinger\BufferLayer.cpp BufferLayer::BufferLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags) : Layer(flinger, client, name, w, h, flags), mConsumer(nullptr ), mTextureName(UINT32_MAX), mFormat(PIXEL_FORMAT_NONE), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mBufferLatched(false ), mPreviousFrameNumber(0 ), mUpdateTexImageFailed(false ), mRefreshPending(false ) { ALOGV("Creating Layer %s" , name.string ()); ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.011 V/BufferLayer( 739 ): Creating Layer com.android.testred/com.android.testred.TestActivity#0 ---------------------------------------------------------------- mFlinger->getRenderEngine().genTextures(1 , &mTextureName); mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName); if (flags & ISurfaceComposerClient::eNonPremultiplied) mPremultipliedAlpha = false ; mCurrentState.requested = mCurrentState.active; mDrawingState = mCurrentState; }
回到SurfaceComposerClient.cpp中 继续看看,根据回传的 sp handle和 sp gbp 创建SurfaceControloutSurface = new SurfaceControl(this, handle, gbp, true / owned */)
然后android_view_SurfaceControl.cpp nativeCreate()函数中将 reinterpret_cast(surface.get()) 的地址返回给Java层。
2.1.1.7、BufferLayer->onFirstRef() 第一次强引用Layer对象时,onFirstRef()函数被回调
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 G:\android9.0 \frameworks\native\services\surfaceflinger\BufferLayer.cpp void BufferLayer::onFirstRef () { sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer, true ); mProducer = new MonitoredProducer(producer, mFlinger, this ); mConsumer = new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName, this ); ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.011 V/BufferQueueConsumer( 739 ): [unnamed-739 -40 ] setConsumerUsageBits: 0x900 04 -16 13 :08 :37.011 V/ConsumerBase( 739 ): [unnamed-739 -40 ] setFrameAvailableListener04-16 13:08:37.011 V/BufferQueueConsumer( 739): [unnamed-739-40] setConsumerName: 'com.android.testred/com.android.testred.TestActivity#0' 04 -16 13 :08 :37.011 V/BufferQueueProducer( 739 ): [] setMaxDequeuedBufferCount: maxDequeuedBuffers = 2 ---------------------------------------------------------------- mConsumer->setConsumerUsageBits(getEffectiveUsage(0 )); mConsumer->setContentsChangedListener(this ); mConsumer->setName(mName); if (mFlinger->isLayerTripleBufferingDisabled()) { mProducer->setMaxDequeuedBufferCount(2 ); } const sp<const DisplayDevice> hw (mFlinger->getDefaultDisplayDevice()) ; ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.011 V/BufferQueueConsumer( 739 ): [com.android.testred/com.android.testred.TestActivity#0 ] setTransformHint: 0 ---------------------------------------------------------------- updateTransformHint(hw); }
2.1.1.8、BufferQueue::createBufferQueue() 所以核心都是这个BufferQueueCore,他是管理图形缓冲区的中枢。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 G:\android9.0 \frameworks\native\libs\gui\BufferQueue.cpp void BufferQueue::createBufferQueue (sp<IGraphicBufferProducer>* outProducer, sp<IGraphicBufferConsumer>* outConsumer, bool consumerIsSurfaceFlinger) { ...... sp<BufferQueueCore> core (new BufferQueueCore()) ; sp<IGraphicBufferProducer> producer (new BufferQueueProducer(core, consumerIsSurfaceFlinger)) ; sp<IGraphicBufferConsumer> consumer (new BufferQueueConsumer(core)) ; *outProducer = producer; *outConsumer = consumer; } G:\android9.0 \frameworks\native\libs\gui\BufferQueueCore.cpp BufferQueueCore::BufferQueueCore() : ...... mUniqueId(getUniqueId()) { int numStartingBuffers = getMaxBufferCountLocked(); for (int s = 0 ; s < numStartingBuffers; s++) { mFreeSlots.insert(s); } for (int s = numStartingBuffers; s < BufferQueueDefs::NUM_BUFFER_SLOTS; s++) { mUnusedSlots.push_front(s); } }
2.1.1.9、new BufferLayerConsumer() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 G:\android9.0 \frameworks\native\services\surfaceflinger\BufferLayerConsumer.cpp BufferLayerConsumer::BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, RE::RenderEngine& engine, uint32_t tex, Layer* layer) : ConsumerBase(bq, false ), mCurrentCrop(Rect::EMPTY_RECT), mCurrentTransform(0 ), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mCurrentFence(Fence::NO_FENCE), mCurrentTimestamp(0 ), mCurrentDataSpace(ui::Dataspace::UNKNOWN), mCurrentFrameNumber(0 ), mCurrentTransformToDisplayInverse(false ), mCurrentSurfaceDamage(), mCurrentApi(0 ), mDefaultWidth(1 ), mDefaultHeight(1 ), mFilteringEnabled(true ), mRE(engine), mTexName(tex), mLayer(layer), mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT) { ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.011 V/BufferLayerConsumer( 739 ): [unnamed-739 -40 ] BufferLayerConsumer---------------------------------------------------------------- BLC_LOGV("BufferLayerConsumer" ); memcpy (mCurrentTransformMatrix, mtxIdentity.asArray(), sizeof (mCurrentTransformMatrix)); ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.011 V/BufferQueueConsumer( 739 ): [unnamed-739 -40 ] setConsumerUsageBits: 0x100 ---------------------------------------------------------------- mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS); }
BufferLayerConsumer会首先初始化ConsumerBase
2.1.1.10、ConsumerBase() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 G:\android9.0 \frameworks\native\libs\gui\ConsumerBase.cpp ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) : mAbandoned(false ), mConsumer(bufferQueue), mPrevFinalReleaseFence(Fence::NO_FENCE) { mName = String8::format("unnamed-%d-%d" , getpid(), createProcessUniqueId()); wp<ConsumerListener> listener = static_cast <ConsumerListener*>(this ); sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener); ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.011 V/BufferQueueConsumer( 739 ): [] connect: controlledByApp=false 04-16 13:08:37.011 V/BufferQueueConsumer( 739): [] setConsumerName: 'unnamed-739-40' ---------------------------------------------------------------- status_t err = mConsumer->consumerConnect(proxy, controlledByApp); if (err != NO_ERROR) { CB_LOGE("ConsumerBase: error connecting to BufferQueue: %s (%d)" , strerror(-err), err); } else { mConsumer->setConsumerName(mName); } }
2.2、winAnimator.createSurfaceLocked() 饶了一大圈,现在Surface创建好了,现象看看如何传回App进程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java private int createSurfaceControl (Surface outSurface, int result, WindowState win, WindowStateAnimator winAnimator) { if (!win.mHasSurface) { result |= RELAYOUT_RES_SURFACE_CHANGED; } WindowSurfaceController surfaceController; try { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl" ); surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid); } finally { Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } if (surfaceController != null ) { surfaceController.getSurface(outSurface); ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.012 I/WindowManager( 1049 ): OUT SURFACE Surface (name=null ) /@0xe493bef: copied ---------------------------------------------------------------- if (SHOW_TRANSACTIONS) Slog.i (TAG_WM, " OUT SURFACE " + outSurface + ": copied" ) ; } else { Slog.w(TAG_WM, "Failed to create surface control for " + win); outSurface.release(); } return result; }
2.2.1、surfaceController.getSurface(outSurface) 1 2 3 4 5 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\WindowSurfaceController.java void getSurface (Surface outSurface) { outSurface.copyFrom(mSurfaceControl); }
2.2.2、outSurface.copyFrom(mSurfaceControl) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 G:\android9.0 \frameworks\base\core\java\android\view\Surface.java public void copyFrom (SurfaceControl other) { ...... long surfaceControlPtr = other.mNativeObject; ....... long newNativeObject = nativeGetFromSurfaceControl(surfaceControlPtr); synchronized (mLock) { if (mNativeObject != 0 ) { nativeRelease(mNativeObject); } setNativeObjectLocked(newNativeObject); } }
2.2.3、nativeGetFromSurfaceControl() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 G:\android9.0 \frameworks\base\core\jni\android_view_Surface.cpp static jlong nativeGetFromSurfaceControl (JNIEnv* env, jclass clazz, jlong surfaceControlNativeObj) { sp<SurfaceControl> ctrl (reinterpret_cast <SurfaceControl *>(surfaceControlNativeObj)) ; sp<Surface> surface (ctrl->getSurface()) ; if (surface != NULL ) { surface->incStrong(&sRefBaseOwner); } return reinterpret_cast <jlong>(surface.get()); } G:\android9.0 \frameworks\native\libs\gui\SurfaceControl.cpp sp<Surface> SurfaceControl::generateSurfaceLocked () const { mSurfaceData = new Surface(mGraphicBufferProducer, false ); return mSurfaceData; } sp<Surface> SurfaceControl::getSurface () const { Mutex::Autolock _l(mLock); if (mSurfaceData == 0 ) { return generateSurfaceLocked(); } return mSurfaceData; }
2.2.4、Nativie Surface创建过程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp) : mGraphicBufferProducer(bufferProducer), mCrop(Rect::EMPTY_RECT), mBufferAge(0 ), mGenerationNumber(0 ), mSharedBufferMode(false ), mAutoRefresh(false ), mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT), mSharedBufferHasBeenQueued(false ), mQueriedSupportedTimestamps(false ), mFrameTimestampsSupportsPresent(false ), mEnableFrameTimestamps(false ), mFrameEventHistory(std ::make_unique<ProducerFrameEventHistory>()) { ANativeWindow::setSwapInterval = hook_setSwapInterval; ANativeWindow::dequeueBuffer = hook_dequeueBuffer; ANativeWindow::cancelBuffer = hook_cancelBuffer; ANativeWindow::queueBuffer = hook_queueBuffer; ANativeWindow::query = hook_query; ANativeWindow::perform = hook_perform; ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED; ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED; ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED; ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED; const_cast <int &>(ANativeWindow::minSwapInterval) = 0 ; const_cast <int &>(ANativeWindow::maxSwapInterval) = 1 ; mReqWidth = 0 ; mReqHeight = 0 ; mReqFormat = 0 ; mReqUsage = 0 ; mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO; mDataSpace = Dataspace::UNKNOWN; mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; mTransform = 0 ; mStickyTransform = 0 ; mDefaultWidth = 0 ; mDefaultHeight = 0 ; mUserWidth = 0 ; mUserHeight = 0 ; mTransformHint = 0 ; mConsumerRunningBehind = false ; mConnectedToCpu = false ; mProducerControlledByApp = controlledByApp; mSwapIntervalZero = false ; }
2.2.5、Surface跨进程传递( WMS->App)writeToParcel() 得到真正的Surface后,[->IWindowSession$Stub.java]
1 2 3 4 5 6 7 8 9 10 11 12 case 6 : ...... Surface _arg17 = new Surface(); int _result2 = this .relayout(_arg0, _arg1, _arg25, _arg3, _arg4, _arg5, _arg62, _result4, _result7, _arg9, _arg10, _arg11, _arg12, _arg13, _arg14, _arg15, _arg16, _arg17); ...... if (_arg17 != null) { reply.writeInt(1 ); _arg17.writeToParcel(reply, 1 ); } else { reply.writeInt(0 ); } return true ;
WMS会首先通过writeToParcel()函数将Surface对象写入App 进程端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 G:\android9.0 \frameworks\base\core\java\android\view\Surface.java @Override public void writeToParcel (Parcel dest, int flags) { if (dest == null ) { throw new IllegalArgumentException("dest must not be null" ); } synchronized (mLock) { dest.writeString(mName); dest.writeInt(mIsSingleBuffered ? 1 : 0 ); nativeWriteToParcel(mNativeObject, dest); } if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0 ) { release(); } } G:\android9.0 \frameworks\base\core\jni\android_view_Surface.cpp static void nativeWriteToParcel (JNIEnv* env, jclass clazz, jlong nativeObject, jobject parcelObj) { Parcel* parcel = parcelForJavaObject(env, parcelObj); if (parcel == NULL) { doThrowNPE(env); return ; } sp<Surface> self (reinterpret_cast<Surface *>(nativeObject) ) ; android::view::Surface surfaceShim; if (self != nullptr) { surfaceShim.graphicBufferProducer = self->getIGraphicBufferProducer(); } surfaceShim.writeToParcel(parcel, true ); }
2.2.6、Surface跨进程传递( App->WMS)readFromParcel() [->IWindowSession$Stub$Proxy.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public int relayout (IWindow window, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame, DisplayCutout.ParcelableWrapper displayCutout, MergedConfiguration outMergedConfiguration, Surface outSurface) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); try { ...... mRemote.transact(6 , _data, _reply, 0 ); _reply.readException(); int _result = _reply.readInt(); ...... if (0 != _reply.readInt()) { outSurface.readFromParcel(_reply); } }
APP进程通过readFromParcel() 读取WMS写入的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 G:\android9.0 \frameworks\base\core\java\android\view\Surface.java public void readFromParcel (Parcel source) { if (source == null ) { throw new IllegalArgumentException("source must not be null" ); } synchronized (mLock) { mName = source.readString(); mIsSingleBuffered = source.readInt() != 0 ; setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source)); } } G:\android9.0 \frameworks\base\core\jni\android_view_Surface.cpp static jlong nativeReadFromParcel (JNIEnv* env, jclass clazz, jlong nativeObject, jobject parcelObj) { Parcel* parcel = parcelForJavaObject(env, parcelObj); if (parcel == NULL) { doThrowNPE(env); return 0 ; } android::view::Surface surfaceShim; surfaceShim.readFromParcel(parcel, true ); sp<Surface> self (reinterpret_cast<Surface *>(nativeObject) ) ; if (self != nullptr && (IInterface::asBinder(self->getIGraphicBufferProducer()) == IInterface::asBinder(surfaceShim.graphicBufferProducer))) { return jlong(self.get()); } sp<Surface> sur; if (surfaceShim.graphicBufferProducer != nullptr) { sur = new Surface(surfaceShim.graphicBufferProducer, true ); sur->incStrong(&sRefBaseOwner); } if (self != NULL) { self->decStrong(&sRefBaseOwner); } return jlong(sur.get()); }
(3)、焦点窗口更新updateFocusedWindowLocked() 继续看看relayoutWindow()方法,createSurfaceControl()之后会更新焦点窗口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java boolean updateFocusedWindowLocked (int mode, boolean updateInputWindows) { WindowState newFocus = mRoot.computeFocusedWindow(); if (mCurrentFocus != newFocus) { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus" ); ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.018 I/WindowManager( 1049 ): Focus moving from null to Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}04 -16 13 :08 :37.018 I/WindowManager( 1049 ): Gaining focus: Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}---------------------------------------------------------------- mH.removeMessages(H.REPORT_FOCUS_CHANGE); mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE); final DisplayContent displayContent = getDefaultDisplayContentLocked(); boolean imWindowChanged = false ; ...... ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.012 V/WindowManager( 1049 ): Changing focus from null to Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity} Callers=com.android.server.wm.WindowManagerService.relayoutWindow:2088 com.android.server.wm.Session.relayout:244 android.view.IWindowSession$Stub.onTransact:309 com.android.server.wm.Session.onTransact:164 ---------------------------------------------------------------- if (DEBUG_FOCUS_LIGHT || localLOGV) Slog.v(TAG_WM, "Changing focus from " + mCurrentFocus + " to " + newFocus + " Callers=" + Debug.getCallers(4 )); final WindowState oldFocus = mCurrentFocus; mCurrentFocus = newFocus; mLosingFocus.remove(newFocus); if (mCurrentFocus != null ) { mWinAddedSinceNullFocus.clear(); mWinRemovedSinceNullFocus.clear(); } int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus); ...... ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.013 D/WindowManager( 1049 ): Input focus has changed to Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}---------------------------------------------------------------- if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) { mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows); } displayContent.adjustForImeIfNeeded(); displayContent.scheduleToastWindowsTimeoutIfNeededLocked(oldFocus, newFocus); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); return true ; } return false ; }
3.1、RootWindowContainer.computeFocusedWindow() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\RootWindowContainer.java WindowState computeFocusedWindow () { final boolean forceDefaultDisplay = mService.isKeyguardShowingAndNotOccluded(); for (int i = mChildren.size() - 1 ; i >= 0 ; i--) { final DisplayContent dc = mChildren.get(i); final WindowState win = dc.findFocusedWindow(); if (win != null ) { if (forceDefaultDisplay && !dc.isDefaultDisplay) { EventLog.writeEvent(0x534e4554 , "71786287" , win.mOwnerUid, "" ); continue ; } return win; } } return null ; }
3.1.1、DisplayContent.findFocusedWindow() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\DisplayContent.java WindowState findFocusedWindow () { mTmpWindow = null ; forAllWindows(mFindFocusedWindow, true ); return mTmpWindow; } private final ToBooleanFunction<WindowState> mFindFocusedWindow = w -> { final AppWindowToken focusedApp = mService.mFocusedApp; ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.012 V/WindowManager( 1049 ): Looking for focus: Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}, flags=25231616 , canReceive=true 04 -16 13 :08 :37.012 V/WindowManager( 1049 ): findFocusedWindow: Found new focus @ Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}---------------------------------------------------------------- if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + w + ", flags=" + w.mAttrs.flags + ", canReceive=" + w.canReceiveKeys()); ....... final AppWindowToken wtoken = w.mAppToken; ...... if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ " + w); mTmpWindow = w; return true ; };
3.2、Visibility更新AppWindowToken.updateReportedVisibilityLocked() 根据WindowState 的 mDrawState=1 可知,现在WindowState 状态是DRAW_PENDING。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 G:\android9.0 \frameworks\base\services\core\java\com\android\server\wm\AppWindowToken.java ---------------------------------------------------------------- 对应Log: 08 :37.013 V/AppWindowToken( 1049 ): Update reported visibility: AppWindowToken{1579134 token=Token{ce2ac07 ActivityRecord{65 cc87a u0 com.android.testred/.TestActivity t5}}}04 -16 13 :08 :37.013 V/WindowState( 1049 ): Win Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}: isDrawn=false , isAnimationSet=true 04 -16 13 :08 :37.013 V/WindowState( 1049 ): Not displayed: s=Surface(name=com.android.testred/com.android.testred.TestActivity)/@0xb17b0ce pv=true mDrawState=1 ph=false th=false a=true 04 -16 13 :08 :37.013 V/AppWindowToken( 1049 ): VIS AppWindowToken{1579134 token=Token{ce2ac07 ActivityRecord{65 cc87a u0 com.android.testred/.TestActivity t5}}}: interesting=1 visible=0 ---------------------------------------------------------------- void updateReportedVisibilityLocked () { if (appToken == null ) { return ; } if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this ); final int count = mChildren.size(); mReportedVisibilityResults.reset(); for (int i = 0 ; i < count; i++) { final WindowState win = mChildren.get(i); win.updateReportedVisibility(mReportedVisibilityResults); } int numInteresting = mReportedVisibilityResults.numInteresting; int numVisible = mReportedVisibilityResults.numVisible; int numDrawn = mReportedVisibilityResults.numDrawn; boolean nowGone = mReportedVisibilityResults.nowGone; boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting; boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting && !isHidden(); if (!nowGone) { if (!nowDrawn) { nowDrawn = reportedDrawn; } if (!nowVisible) { nowVisible = reportedVisible; } } if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting=" + numInteresting + " visible=" + numVisible); final AppWindowContainerController controller = getController(); if (nowDrawn != reportedDrawn) { if (nowDrawn) { if (controller != null ) { controller.reportWindowsDrawn(); } } reportedDrawn = nowDrawn; } if (nowVisible != reportedVisible) { if (DEBUG_VISIBILITY) Slog.v(TAG, "Visibility changed in " + this + ": vis=" + nowVisible); reportedVisible = nowVisible; if (controller != null ) { if (nowVisible) { controller.reportWindowsVisible(); } else { controller.reportWindowsGone(); } } } }
至此 ViewRootImpl.java 的 performTraversals() 方法中的relayoutWindow(params, viewVisibility, insetsPending)终于完成了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 G:\android9.0 \frameworks\base\core\java\android\view\ViewRootImpl.java private void performTraversals () { ...... ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.015 V/ViewRootImpl[TestActivity]( 2602 ): relayout: frame=[0 ,0 ][160 ,854 ] overscan=[0 ,0 ][0 ,0 ] content=[0 ,0 ][0 ,0 ] visible=[0 ,36 ][0 ,72 ] stable=[0 ,36 ][0 ,72 ] cutout=DisplayCutout{insets=Rect(0 , 0 - 0 , 0 ) boundingRect=Rect(0 , 0 - 0 , 0 )} outsets=[0 ,0 ][0 ,0 ] surface=Surface(name=null )/@0x266c9a5 ---------------------------------------------------------------- if (DEBUG_LAYOUT) Log.v(mTag, "relayout: frame=" + frame.toShortString() + " overscan=" + mPendingOverscanInsets.toShortString() + " content=" + mPendingContentInsets.toShortString() + " visible=" + mPendingVisibleInsets.toShortString() + " stable=" + mPendingStableInsets.toShortString() + " cutout=" + mPendingDisplayCutout.get().toString() + " outsets=" + mPendingOutsets.toShortString() + " surface=" + mSurface); ...... ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.015 V/ViewRootImpl[TestActivity]( 2602 ): Visible with new config: {1.0 ?mcc?mnc [en_US] ldltr sw320dp w320dp h497dp 240d pi nrml port finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0 , 0 - 480 , 854 ) mAppBounds=Rect(0 , 0 - 480 , 782 ) mWindowingMode=fullscreen mActivityType=standard} s.5 }04 -16 13 :08 :37.015 V/ViewRootImpl[TestActivity]( 2602 ): Applying new config to window com.android.testred/com.android.testred.TestActivity, globalConfig: {1.0 ?mcc?mnc [en_US] ldltr sw320dp w320dp h497dp 240d pi nrml port finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0 , 0 - 480 , 782 ) mAppBounds=Rect(0 , 0 - 480 , 782 ) mWindowingMode=fullscreen mActivityType=undefined} s.5 }, overrideConfig: {1.0 ?mcc?mnc [en_US] ldltr sw320dp w320dp h497dp 240d pi nrml port finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0 , 0 - 480 , 854 ) mAppBounds=Rect(0 , 0 - 480 , 782 ) mWindowingMode=fullscreen mActivityType=standard} s.5 } ---------------------------------------------------------------- if (!mPendingMergedConfiguration.equals(mLastReportedMergedConfiguration)) { if (DEBUG_CONFIGURATION) Log.v(mTag, "Visible with new config: " + mPendingMergedConfiguration.getMergedConfiguration()); performConfigurationChange(mPendingMergedConfiguration, !mFirst, INVALID_DISPLAY ); updatedConfiguration = true ; } ...... if (contentInsetsChanged) { ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.015 V/ViewRootImpl[TestActivity]( 2602 ): Content insets changing to: Rect(0 , 0 - 0 , 0 )---------------------------------------------------------------- mAttachInfo.mContentInsets.set(mPendingContentInsets); if (DEBUG_LAYOUT) Log.v(mTag, "Content insets changing to: " + mAttachInfo.mContentInsets); } ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.015 V/ViewRootImpl[TestActivity]( 2602 ): Decor insets changing to: Rect(0 , 36 - 0 , 72 )---------------------------------------------------------------- if (stableInsetsChanged) { mAttachInfo.mStableInsets.set(mPendingStableInsets); if (DEBUG_LAYOUT) Log.v(mTag, "Decor insets changing to: " + mAttachInfo.mStableInsets); contentInsetsChanged = true ; } ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.015 V/ViewRootImpl[TestActivity]( 2602 ): Visible insets changing to: Rect(0 , 36 - 0 , 72 )---------------------------------------------------------------- if (visibleInsetsChanged) { mAttachInfo.mVisibleInsets.set(mPendingVisibleInsets); if (DEBUG_LAYOUT) Log.v(mTag, "Visible insets changing to: " + mAttachInfo.mVisibleInsets); } ....... if (DEBUG_ORIENTATION) Log.v( TAG, "Relayout returned: frame=" + frame + ", surface=" + mSurface); mAttachInfo.mWindowLeft = frame.left; mAttachInfo.mWindowTop = frame.top; if (mWidth != frame.width() || mHeight != frame.height()) { mWidth = frame.width(); mHeight = frame.height(); } ...... final ThreadedRenderer threadedRenderer = mAttachInfo.mThreadedRenderer; if (threadedRenderer != null && threadedRenderer.isEnabled()) { if (hwInitialized || mWidth != threadedRenderer.getWidth() || mHeight != threadedRenderer.getHeight() || mNeedsRendererSetup) { threadedRenderer.setup(mWidth, mHeight, mAttachInfo, mWindowAttributes.surfaceInsets); mNeedsRendererSetup = false ; } } if (!mStopped || mReportNextDraw) { boolean focusChangedDueToTouchMode = ensureTouchModeLocally( (relayoutResult&WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE) != 0 ); if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight() || contentInsetsChanged || updatedConfiguration) { int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width); int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height); ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.016 V/ViewRootImpl[TestActivity]( 2602 ): Ooops, something changed! mWidth=160 measuredWidth=480 mHeight=854 measuredHeight=782 coveredInsetsChanged=true ---------------------------------------------------------------- if (DEBUG_LAYOUT) Log.v(mTag, "Ooops, something changed! mWidth=" + mWidth + " measuredWidth=" + host.getMeasuredWidth() + " mHeight=" + mHeight + " measuredHeight=" + host.getMeasuredHeight() + " coveredInsetsChanged=" + contentInsetsChanged); performMeasure(childWidthMeasureSpec, childHeightMeasureSpec); int width = host.getMeasuredWidth(); int height = host.getMeasuredHeight(); boolean measureAgain = false ; if (lp.horizontalWeight > 0.0f ) { width += (int ) ((mWidth - width) * lp.horizontalWeight); childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); measureAgain = true ; } if (lp.verticalWeight > 0.0f ) { height += (int ) ((mHeight - height) * lp.verticalWeight); childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); measureAgain = true ; } ...... layoutRequested = true ; } } } else { ...... } final boolean didLayout = layoutRequested && (!mStopped || mReportNextDraw); boolean triggerGlobalLayoutListener = didLayout || mAttachInfo.mRecomputeGlobalAttributes; if (didLayout) { performLayout(lp, mWidth, mHeight); if ((host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0 ) { host.getLocationInWindow(mTmpLocation); mTransparentRegion.set(mTmpLocation[0 ], mTmpLocation[1 ], mTmpLocation[0 ] + host.mRight - host.mLeft, mTmpLocation[1 ] + host.mBottom - host.mTop); host.gatherTransparentRegion(mTransparentRegion); if (mTranslator != null ) { mTranslator.translateRegionInWindowToScreen(mTransparentRegion); } if (!mTransparentRegion.equals(mPreviousTransparentRegion)) { mPreviousTransparentRegion.set(mTransparentRegion); mFullRedrawNeeded = true ; try { mWindowSession.setTransparentRegion(mWindow, mTransparentRegion); } catch (RemoteException e) { } } } ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.017 I/System.out( 2602 ): ======================================04 -16 13 :08 :37.017 I/System.out( 2602 ): performTraversals -- after setFrame---------------------------------------------------------------- if (DBG) { System.out.println("======================================" ); System.out.println("performTraversals -- after setFrame" ); host.debug(); ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.017 D/View ( 2602 ): + DecorView@515e1 ca[TestActivity]04 -16 13 :08 :37.017 D/View ( 2602 ): frame={0 , 0 , 160 , 854 } scroll={0 , 0 } 04 -16 13 :08 :37.018 D/View ( 2602 ): mMeasureWidth=160 mMeasureHeight=854 04 -16 13 :08 :37.020 D/Debug ( 2602 ): Contents of {(0 ,0 )(fillxfill) sim={forwardNavigation} ty=BASE_APPLICATION fmt=TRANSPARENT wanim=0x1030000 04 -16 13 :08 :37.020 D/Debug ( 2602 ): fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED}:04 -16 13 :08 :37.020 D/Debug ( 2602 ): ViewGroup.LayoutParams={ width=match-parent, height=match-parent }04 -16 13 :08 :37.020 D/Debug ( 2602 ): 04 -16 13 :08 :37.020 D/Debug ( 2602 ): WindowManager.LayoutParams={title=com.android.testred/com.android.testred.TestActivity}04 -16 13 :08 :37.020 D/View ( 2602 ): 04 -16 13 :08 :37.020 D/View ( 2602 ): flags={}04 -16 13 :08 :37.020 D/View ( 2602 ): privateFlags={IS_ROOT_NAMESPACE HAS_BOUNDS DRAWN}04 -16 13 :08 :37.020 D/View ( 2602 ): {04 -16 13 :08 :37.020 D/View ( 2602 ): + android.widget.LinearLayout{c1507be V.ED..... ......ID 0 ,0 -160 ,854 }04 -16 13 :08 :37.020 D/View ( 2602 ): frame={0 , 0 , 160 , 854 } scroll={0 , 0 } 04 -16 13 :08 :37.020 D/View ( 2602 ): mMeasureWidth=160 mMeasureHeight=854 04 -16 13 :08 :37.020 D/View ( 2602 ): ViewGroup.LayoutParams={ width=match-parent, height=match-parent }04 -16 13 :08 :37.020 D/View ( 2602 ): flags={}04 -16 13 :08 :37.020 D/View ( 2602 ): privateFlags={HAS_BOUNDS}04 -16 13 :08 :37.020 D/View ( 2602 ): {04-16 13:08:37.020 D/View ( 2602): + android.view.ViewStub{870dc6e G.E...... ......I. 0,0-0,0 #102018a android:id/action_mode_bar_stub} (id=16908682) 04 -16 13 :08 :37.020 D/View ( 2602 ): frame={0 , 0 , 0 , 0 } scroll={0 , 0 } 04 -16 13 :08 :37.020 D/View ( 2602 ): mMeasureWidth=0 mMeasureHeight=0 04 -16 13 :08 :37.020 D/View ( 2602 ): LinearLayout.LayoutParams={width=match-parent, height=wrap-content weight=0.0 }04 -16 13 :08 :37.020 D/View ( 2602 ): flags={GONE}04 -16 13 :08 :37.020 D/View ( 2602 ): privateFlags={DRAWN}04 -16 13 :08 :37.020 D/View ( 2602 ): + android.widget.FrameLayout{b582935 V.ED..... ......ID 0 ,0 -160 ,38 }04 -16 13 :08 :37.020 D/View ( 2602 ): frame={0 , 0 , 160 , 38 } scroll={0 , 0 } 04 -16 13 :08 :37.020 D/View ( 2602 ): padding={6 , 1 , 6 , 2 }04 -16 13 :08 :37.020 D/View ( 2602 ): mMeasureWidth=160 mMeasureHeight=38 04 -16 13 :08 :37.020 D/View ( 2602 ): LinearLayout.LayoutParams={width=match-parent, height=38 weight=0.0 }04 -16 13 :08 :37.020 D/View ( 2602 ): flags={}04 -16 13 :08 :37.020 D/View ( 2602 ): privateFlags={HAS_BOUNDS}04 -16 13 :08 :37.020 D/View ( 2602 ): {04-16 13:08:37.020 D/View ( 2602): + android.widget.TextView{64b8f0f V.ED..... ......ID 6,1-154,36 #1020016 android:id/title} (id=16908310) 04 -16 13 :08 :37.020 D/View ( 2602 ): frame={6 , 1 , 154 , 36 } scroll={0 , 0 } 04 -16 13 :08 :37.020 D/View ( 2602 ): mMeasureWidth=148 mMeasureHeight=35 04 -16 13 :08 :37.020 D/View ( 2602 ): ViewGroup.LayoutParams={ width=match-parent, height=match-parent }04 -16 13 :08 :37.021 D/View ( 2602 ): flags={}04 -16 13 :08 :37.021 D/View ( 2602 ): privateFlags={HAS_BOUNDS}04 -16 13 :08 :37.021 D/View ( 2602 ): frame={6 , 1 , 154 , 36 } scroll={0 , 0 } mText="Test Viewport" mLayout width=1048576 height=29 04 -16 13 :08 :37.021 D/View ( 2602 ): }04-16 13:08:37.021 D/View ( 2602): + android.widget.FrameLayout{158df3b V.ED..... ......ID 0,38-160,854 #1020002 android:id/content} (id=16908290) 04 -16 13 :08 :37.021 D/View ( 2602 ): frame={0 , 38 , 160 , 854 } scroll={0 , 0 } 04 -16 13 :08 :37.021 D/View ( 2602 ): mMeasureWidth=160 mMeasureHeight=816 04 -16 13 :08 :37.021 D/View ( 2602 ): LinearLayout.LayoutParams={width=match-parent, height=0 weight=1.0 }04 -16 13 :08 :37.021 D/View ( 2602 ): flags={}04 -16 13 :08 :37.021 D/View ( 2602 ): privateFlags={HAS_BOUNDS}04 -16 13 :08 :37.021 D/View ( 2602 ): {04 -16 13 :08 :37.021 D/View ( 2602 ): + com.android.testred.TestView{85 cab9c VFE...... ......ID 0 ,0 -160 ,816 }04 -16 13 :08 :37.021 D/View ( 2602 ): frame={0 , 0 , 160 , 816 } scroll={0 , 0 } 04 -16 13 :08 :37.021 D/View ( 2602 ): mMeasureWidth=160 mMeasureHeight=816 04 -16 13 :08 :37.021 D/View ( 2602 ): ViewGroup.LayoutParams={ width=match-parent, height=match-parent }04 -16 13 :08 :37.021 D/View ( 2602 ): flags={TAKES_FOCUS}04 -16 13 :08 :37.021 D/View ( 2602 ): privateFlags={HAS_BOUNDS}04 -16 13 :08 :37.021 D/View ( 2602 ): }04 -16 13 :08 :37.021 D/View ( 2602 ): }04 -16 13 :08 :37.021 D/View ( 2602 ): }---------------------------------------------------------------- } } ...... if (mFirst) { if (sAlwaysAssignFocus || !isInTouchMode()) { ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.021 V/ViewRootImpl[TestActivity]( 2602 ): First: mView.hasFocus()=false ---------------------------------------------------------------- if (DEBUG_INPUT_RESIZE) { Log.v(mTag, "First: mView.hasFocus()=" + mView.hasFocus()); } if (mView != null ) { if (!mView.hasFocus()) { ---------------------------------------------------------------- mView.restoreDefaultFocus();对应Log: 04 -16 13 :08 :37.021 I/System.out( 2602 ): DecorView@515e1 ca[TestActivity] ViewGroup.requestFocus direction=130 04 -16 13 :08 :37.021 I/System.out( 2602 ): android.widget.LinearLayout{c1507be V.ED..... ......ID 0 ,0 -160 ,854 } ViewGroup.requestFocus direction=130 04 -16 13 :08 :37.021 I/System.out( 2602 ): android.widget.FrameLayout{b582935 V.ED..... ......ID 0 ,0 -160 ,38 } ViewGroup.requestFocus direction=130 04-16 13:08:37.021 I/System.out( 2602): android.widget.FrameLayout{158df3b V.ED..... ......ID 0,38-160,854 #1020002 android:id/content} ViewGroup.requestFocus direction=130 04 -16 13 :08 :37.021 I/System.out( 2602 ): com.android.testred.TestView{85 cab9c VFE...... ......ID 0 ,0 -160 ,816 } requestFocus()04 -16 13 :08 :37.021 I/System.out( 2602 ): Find focus in DecorView@515e1 ca[TestActivity]: flags=false , child=null 04-16 13:08:37.021 I/System.out( 2602): android.widget.FrameLayout{158df3b V.ED..... ......ID 0,38-160,854 #1020002 android:id/content} requestChildFocus() 04-16 13:08:37.021 I/System.out( 2602): android.widget.FrameLayout{158df3b V.ED..... ......ID 0,38-160,854 #1020002 android:id/content} unFocus() 04 -16 13 :08 :37.022 I/System.out( 2602 ): android.widget.LinearLayout{c1507be V.ED..... ......ID 0 ,0 -160 ,854 } requestChildFocus()04 -16 13 :08 :37.022 I/System.out( 2602 ): android.widget.LinearLayout{c1507be V.ED..... ......ID 0 ,0 -160 ,854 } unFocus()04 -16 13 :08 :37.022 I/System.out( 2602 ): DecorView@515e1 ca[TestActivity] requestChildFocus()04 -16 13 :08 :37.022 I/System.out( 2602 ): DecorView@515e1 ca[TestActivity] unFocus()04 -16 13 :08 :37.022 V/ViewRootImpl[TestActivity]( 2602 ): Request child focus: focus now com.android.testred.TestView{85 cab9c VFE...... .F....ID 0 ,0 -160 ,816 }04 -16 13 :08 :37.022 I/System.out( 2602 ): Find focus in DecorView@515e1 ca[TestActivity]: flags=false , child=android.widget.LinearLayout{c1507be V.ED..... ......ID 0 ,0 -160 ,854 }04-16 13:08:37.022 I/System.out( 2602): Find focus in android.widget.LinearLayout{c1507be V.ED..... ......ID 0,0-160,854}: flags=false, child=android.widget.FrameLayout{158df3b V.ED..... ......ID 0,38-160,854 #1020002 android:id/content} 04-16 13:08:37.022 I/System.out( 2602): Find focus in android.widget.FrameLayout{158df3b V.ED..... ......ID 0,38-160,854 #1020002 android:id/content}: flags=false, child=com.android.testred.TestView{85cab9c VFE...... .F....ID 0,0-160,816} 04 -16 13 :08 :37.022 V/ViewRootImpl[TestActivity]( 2602 ): First: requested focused view=com.android.testred.TestView{85 cab9c VFE...... .F....ID 0 ,0 -160 ,816 }---------------------------------------------------------------- mView.restoreDefaultFocus(); if (DEBUG_INPUT_RESIZE) { Log.v(mTag, "First: requested focused view=" + mView.findFocus()); } } else { if (DEBUG_INPUT_RESIZE) { Log.v(mTag, "First: existing focused view=" + mView.findFocus()); } } } } else { View focused = mView.findFocus(); if (focused instanceof ViewGroup && ((ViewGroup) focused).getDescendantFocusability() == ViewGroup.FOCUS_AFTER_DESCENDANTS) { focused.restoreDefaultFocus(); } } } ...... if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0 ) { reportNextDraw(); } boolean cancelDraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || !isViewVisible; if (!cancelDraw && !newSurface) { ...... performDraw(); } else { if (isViewVisible) { scheduleTraversals(); } ...... } mIsInTraversal = false ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 G:\android9.0 \frameworks\base\core\java\android\view\ViewRootImpl.java private void performLayout (WindowManager.LayoutParams lp, int desiredWindowWidth, int desiredWindowHeight) { mLayoutRequested = false ; mScrollMayChange = true ; mInLayout = true ; final View host = mView; ...... ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.017 V/ViewRootImpl[TestActivity]( 2602 ): Laying out DecorView@515e1 ca[TestActivity] to (160 , 854 )---------------------------------------------------------------- if (DEBUG_ORIENTATION || DEBUG_LAYOUT) { Log.v(mTag, "Laying out " + host + " to (" + host.getMeasuredWidth() + ", " + host.getMeasuredHeight() + ")" ); } Trace.traceBegin(Trace.TRACE_TAG_VIEW, "layout" ); try { host.layout(0 , 0 , host.getMeasuredWidth(), host.getMeasuredHeight()); mInLayout = false ; int numViewsRequestingLayout = mLayoutRequesters.size(); ...... mInLayout = false ; }
4.1、View.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight()) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 G:\android9.0 \frameworks\base\core\java\android\view\View.java public void layout (int l, int t, int r, int b) { if ((mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) != 0 ) { onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec); mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT; } int oldL = mLeft; int oldT = mTop; int oldB = mBottom; int oldR = mRight; boolean changed = isLayoutModeOptical(mParent) ? setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b); if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) { onLayout(changed, l, t, r, b); ...... mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED; ListenerInfo li = mListenerInfo; if (li != null && li.mOnLayoutChangeListeners != null ) { ArrayList<OnLayoutChangeListener> listenersCopy = (ArrayList<OnLayoutChangeListener>)li.mOnLayoutChangeListeners.clone(); int numListeners = listenersCopy.size(); for (int i = 0 ; i < numListeners; ++i) { listenersCopy.get(i).onLayoutChange(this , l, t, r, b, oldL, oldT, oldR, oldB); } } } final boolean wasLayoutValid = isLayoutValid(); mPrivateFlags &= ~PFLAG_FORCE_LAYOUT; mPrivateFlags3 |= PFLAG3_IS_LAID_OUT; ...... }
4.1.1、View.setFrame 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 G:\android9.0 \frameworks\base\core\java\android\view\View.java protected boolean setFrame (int left, int top, int right, int bottom) { boolean changed = false ; if (DBG) { Log.d(VIEW_LOG_TAG, this + " View.setFrame(" + left + "," + top + "," + right + "," + bottom + ")" ); } ---------------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.017 D/View ( 2602 ): DecorView@515e1 ca[TestActivity] View.setFrame(0 ,0 ,160 ,854 )04 -16 13 :08 :37.017 V/ViewRootImpl[TestActivity]( 2602 ): Invalidate child: Rect(0 , 0 - 160 , 854 )04 -16 13 :08 :37.017 D/View ( 2602 ): android.widget.LinearLayout{c1507be V.ED..... ......I. 0 ,0 -0 ,0 } View.setFrame(0 ,0 ,160 ,854 )04 -16 13 :08 :37.017 D/View ( 2602 ): android.widget.FrameLayout{b582935 V.ED..... ......ID 0 ,0 -0 ,0 } View.setFrame(0 ,0 ,160 ,38 )04-16 13:08:37.017 D/View ( 2602): android.widget.TextView{64b8f0f V.ED..... ......ID 0,0-0,0 #1020016 android:id/title} View.setFrame(6,1,154,36) 04-16 13:08:37.017 D/View ( 2602): android.widget.FrameLayout{158df3b V.ED..... ......I. 0,0-0,0 #1020002 android:id/content} View.setFrame(0,38,160,854) 04 -16 13 :08 :37.017 D/View ( 2602 ): com.android.testred.TestView{85 cab9c VFE...... ......I. 0 ,0 -0 ,0 } View.setFrame(0 ,0 ,160 ,816 )---------------------------------------------------------------- if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) { changed = true ; int drawn = mPrivateFlags & PFLAG_DRAWN; int oldWidth = mRight - mLeft; int oldHeight = mBottom - mTop; int newWidth = right - left; int newHeight = bottom - top; boolean sizeChanged = (newWidth != oldWidth) || (newHeight != oldHeight); invalidate(sizeChanged); mLeft = left; mTop = top; mRight = right; mBottom = bottom; mRenderNode.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom); mPrivateFlags |= PFLAG_HAS_BOUNDS; if (sizeChanged) { sizeChange(newWidth, newHeight, oldWidth, oldHeight); } if ((mViewFlags & VISIBILITY_MASK) == VISIBLE || mGhostView != null ) { mPrivateFlags |= PFLAG_DRAWN; invalidate(sizeChanged); invalidateParentCaches(); } mPrivateFlags |= drawn; mBackgroundSizeChanged = true ; mDefaultFocusHighlightSizeChanged = true ; if (mForegroundInfo != null ) { mForegroundInfo.mBoundsChanged = true ; } notifySubtreeAccessibilityStateChangedIfNeeded(); } return changed; }
4.1.2、SurfaceView.setFrame 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 G:\android9.0 \frameworks\base\core\java\android\view\SurfaceView.java Override protected boolean setFrame (int left, int top, int right, int bottom) { boolean result = super .setFrame(left, top, right, bottom); updateSurface(); return result; } protected void updateSurface () { ViewRootImpl viewRoot = getViewRootImpl(); ...... if (creating || formatChanged || sizeChanged || visibleChanged || windowVisibleChanged) { getLocationInWindow(mLocation); try { final boolean visible = mVisible = mRequestedVisible; ....... if (creating) { mSurfaceSession = new SurfaceSession(viewRoot.mSurface); mDeferredDestroySurfaceControl = mSurfaceControl; updateOpaqueFlag(); final String name = "SurfaceView - " + viewRoot.getTitle().toString(); mSurfaceControl = new SurfaceControlWithBackground( name, (mSurfaceFlags & SurfaceControl.OPAQUE) != 0 , new SurfaceControl.Builder(mSurfaceSession) .setSize(mSurfaceWidth, mSurfaceHeight) .setFormat(mFormat) .setFlags(mSurfaceFlags)); } else if (mSurfaceControl == null ) { return ; } ...... } ---------------------------------------------------------------- 对应Log: 04-16 13:08:37.023 V/BufferLayer( 739): Creating Layer SurfaceView - com.android.testred/com.android.testred.TestActivity#0 04 -16 13 :08 :37.023 V/BufferQueueConsumer( 739 ): [] connect: controlledByApp=false 04 -16 13 :08 :37.023 V/BufferQueueConsumer( 739 ): [] setConsumerName: 'unnamed-739-41' 04 -16 13 :08 :37.023 V/BufferLayerConsumer( 739 ): [unnamed-739 -41 ] BufferLayerConsumer04 -16 13 :08 :37.023 V/BufferQueueConsumer( 739 ): [unnamed-739 -41 ] setConsumerUsageBits: 0x100 04 -16 13 :08 :37.023 V/BufferQueueConsumer( 739 ): [unnamed-739 -41 ] setConsumerUsageBits: 0x900 04 -16 13 :08 :37.023 V/ConsumerBase( 739 ): [unnamed-739 -41 ] setFrameAvailableListener04 -16 13 :08 :37.023 V/BufferQueueConsumer( 739 ): [unnamed-739 -41 ] setConsumerName: 'SurfaceView - com.android.testred/com.android.testred.TestActivity#0' 04 -16 13 :08 :37.023 V/BufferQueueProducer( 739 ): [] setMaxDequeuedBufferCount: maxDequeuedBuffers = 2 04-16 13:08:37.023 V/BufferQueueConsumer( 739): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0] setTransformHint: 0 04-16 13:08:37.023 V/BufferQueueConsumer( 739): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0] setDefaultBufferSize: width=160 height=816 04-16 13:08:37.023 V/BufferQueueConsumer( 739): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0] setDefaultBufferFormat: 4 04-16 13:08:37.023 V/BufferQueueConsumer( 739): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0] setConsumerUsageBits: 0x900 ----------------------------------------------------------------
updateSurface()会请求创建surface,创建过程前面已经分析过了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 /frameworks/base/core/java/android/view/ViewRootImpl.java private void performDraw () { if (mAttachInfo.mDisplayState == Display.STATE_OFF && !mReportNextDraw) { return ; } else if (mView == null ) { return ; } final boolean fullRedrawNeeded = mFullRedrawNeeded || mReportNextDraw; mFullRedrawNeeded = false ; mIsDrawing = true ; Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw" ); boolean usingAsyncReport = false ; if (mReportNextDraw && mAttachInfo.mThreadedRenderer != null && mAttachInfo.mThreadedRenderer.isEnabled()) { usingAsyncReport = true ; mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> { pendingDrawFinished(); }); } try { boolean canUseAsync = draw(fullRedrawNeeded); if (usingAsyncReport && !canUseAsync) { mAttachInfo.mThreadedRenderer.setFrameCompleteCallback(null ); usingAsyncReport = false ; } } finally { mIsDrawing = false ; Trace.traceEnd(Trace.TRACE_TAG_VIEW); } if (mAttachInfo.mPendingAnimatingRenderNodes != null ) { final int count = mAttachInfo.mPendingAnimatingRenderNodes.size(); for (int i = 0 ; i < count; i++) { mAttachInfo.mPendingAnimatingRenderNodes.get(i).endAllAnimators(); } mAttachInfo.mPendingAnimatingRenderNodes.clear(); } if (mReportNextDraw) { mReportNextDraw = false ; if (mWindowDrawCountDown != null ) { try { mWindowDrawCountDown.await(); } catch (InterruptedException e) { Log.e(mTag, "Window redraw count down interrupted!" ); } mWindowDrawCountDown = null ; } if (mAttachInfo.mThreadedRenderer != null ) { mAttachInfo.mThreadedRenderer.setStopped(mStopped); } --------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.113 V/ViewRootImpl[TestActivity]( 2602 ): FINISHED DRAWING: com.android.testred/com.android.testred.TestActivity--------------------------------------------------------- if (LOCAL_LOGV) { Log.v(mTag, "FINISHED DRAWING: " + mWindowAttributes.getTitle()); } if (mSurfaceHolder != null && mSurface.isValid()) { SurfaceCallbackHelper sch = new SurfaceCallbackHelper(this ::postDrawFinished); SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks(); sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks); } else if (!usingAsyncReport) { if (mAttachInfo.mThreadedRenderer != null ) { mAttachInfo.mThreadedRenderer.fence(); } pendingDrawFinished(); } } } private boolean draw (boolean fullRedrawNeeded) { Surface surface = mSurface; if (!surface.isValid()) { return false ; } if (DEBUG_FPS) { trackFPS(); } if (!sFirstDrawComplete) { synchronized (sFirstDrawHandlers) { sFirstDrawComplete = true ; final int count = sFirstDrawHandlers.size(); for (int i = 0 ; i< count; i++) { mHandler.post(sFirstDrawHandlers.get(i)); } } } scrollToRectOrFocus(null , false ); ..... final Rect dirty = mDirty; if (mSurfaceHolder != null ) { dirty.setEmpty(); ...... return false ; } if (fullRedrawNeeded) { mAttachInfo.mIgnoreDirtyState = true ; dirty.set(0 , 0 , (int ) (mWidth * appScale + 0.5f ), (int ) (mHeight * appScale + 0.5f )); } --------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.074 V/ViewRootImpl[TestActivity]( 2602 ): Draw DecorView@515e1 ca[TestActivity]/com.android.testred/com.android.testred.TestActivity: dirty={0 ,0 ,160 ,854 } surface=Surface(name=null )/@0x266c9a5 surface.isValid()=true , appScale:1.0 , width=160 , height=854 --------------------------------------------------------- if (DEBUG_ORIENTATION || DEBUG_DRAW) { Log.v(mTag, "Draw " + mView + "/" + mWindowAttributes.getTitle() + ": dirty={" + dirty.left + "," + dirty.top + "," + dirty.right + "," + dirty.bottom + "} surface=" + surface + " surface.isValid()=" + surface.isValid() + ", appScale:" + appScale + ", width=" + mWidth + ", height=" + mHeight); } mAttachInfo.mTreeObserver.dispatchOnDraw(); ....... return useAsyncReport; }
布局完成后接着Vsync又一次Trigger 。(画图)
GLSurfaceView绘制流程
GLSurfaceView提供了下列特性:
1> 管理一个surface,这个surface就是一块特殊的内存,能直接排版到android的视图view上。 2> 管理一个EGL display,它能让opengl把内容渲染到上述的surface上。 3> 用户自定义渲染器(render)。 4> 让渲染器在独立的线程里运作,和UI线程分离。 5> 支持按需渲染(on-demand)和连续渲染(continuous)。 6> 一些可选工具,如调试。
概念:
Display(EGLDisplay) 是对实际显示设备的抽象。 Surface(EGLSurface)是对用来存储图像的内存区域FrameBuffer的抽象,包括Color Buffer, Stencil Buffer ,Depth Buffer. Context (EGLContext) 存储OpenGL ES绘图的一些状态信息。
步骤:
获取EGLDisplay对象 初始化与EGLDisplay 之间的连接。 获取EGLConfig对象 创建EGLContext 实例 创建EGLSurface实例 连接EGLContext和EGLSurface. 使用GL指令绘制图形 断开并释放与EGLSurface关联的EGLContext对象 删除EGLSurface对象 删除EGLContext对象 终止与EGLDisplay之间的连接。
GLSurfaceView的主要绘制过程都是在一个子线程中完成,即整个绘制最终都是guardenRun()中完成。在这个过程中完成了整个EGL绘制的所有步骤。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 /frameworks/base/opengl/java/android/opengl/GLSurfaceView.java private void guardedRun () throws InterruptedException { mEglHelper = new EglHelper(mGLSurfaceViewWeakRef); mHaveEglContext = false ; mHaveEglSurface = false ; mWantRenderNotification = false ; try { GL10 gl = null ; boolean createEglContext = false ; boolean createEglSurface = false ; boolean createGlInterface = false ; boolean lostEglContext = false ; boolean sizeChanged = false ; boolean wantRenderNotification = false ; boolean doRenderNotification = false ; boolean askedToReleaseEglContext = false ; int w = 0 ; int h = 0 ; Runnable event = null ; Runnable finishDrawingRunnable = null ; while (true ) { synchronized (sGLThreadManager) { while (true ) { ...... ...... if (readyToDraw()) { if (! mHaveEglContext) { if (askedToReleaseEglContext) { askedToReleaseEglContext = false ; } else { try { mEglHelper.start(); } catch (RuntimeException t) { ...... } mHaveEglContext = true ; createEglContext = true ; sGLThreadManager.notifyAll(); } } if (mHaveEglContext && !mHaveEglSurface) { mHaveEglSurface = true ; createEglSurface = true ; createGlInterface = true ; sizeChanged = true ; } if (mHaveEglSurface) { if (mSizeChanged) { sizeChanged = true ; w = mWidth; h = mHeight; mWantRenderNotification = true ; ...... createEglSurface = true ; mSizeChanged = false ; } mRequestRender = false ; ...... } } else { ...... } ....... sGLThreadManager.wait(); } } ...... if (createEglSurface) { if (LOG_SURFACE) { Log.w("GLThread" , "egl createSurface" ); } if (mEglHelper.createSurface()) { synchronized (sGLThreadManager) { mFinishedCreatingEglSurface = true ; sGLThreadManager.notifyAll(); } } else { synchronized (sGLThreadManager) { mFinishedCreatingEglSurface = true ; mSurfaceIsBad = true ; sGLThreadManager.notifyAll(); } continue ; } createEglSurface = false ; } if (createGlInterface) { gl = (GL10) mEglHelper.createGL(); createGlInterface = false ; } if (createEglContext) { if (LOG_RENDERER) { Log.w("GLThread" , "onSurfaceCreated" ); } GLSurfaceView view = mGLSurfaceViewWeakRef.get(); if (view != null ) { try { view.mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig); } finally { } } createEglContext = false ; } if (sizeChanged) { if (LOG_RENDERER) { Log.w("GLThread" , "onSurfaceChanged(" + w + ", " + h + ")" ); } GLSurfaceView view = mGLSurfaceViewWeakRef.get(); if (view != null ) { try { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "onSurfaceChanged" ); view.mRenderer.onSurfaceChanged(gl, w, h); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIEW); } } sizeChanged = false ; } if (LOG_RENDERER_DRAW_FRAME) { Log.w("GLThread" , "onDrawFrame tid=" + getId()); } { GLSurfaceView view = mGLSurfaceViewWeakRef.get(); if (view != null ) { try { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "onDrawFrame" ); if (mFinishDrawingRunnable != null ) { finishDrawingRunnable = mFinishDrawingRunnable; mFinishDrawingRunnable = null ; } view.mRenderer.onDrawFrame(gl); if (finishDrawingRunnable != null ) { finishDrawingRunnable.run(); finishDrawingRunnable = null ; } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIEW); } } } int swapError = mEglHelper.swap(); ....... } } finally { synchronized (sGLThreadManager) { stopEglSurfaceLocked(); stopEglContextLocked(); } } }
我们直接看看GLSurfaceView绘制的过程,绘制过程opengl准备工作。
5.1、EglHelper.start() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 /frameworks/base/opengl/java/android/opengl/GLSurfaceView.java private static class EglHelper { public EglHelper (WeakReference<GLSurfaceView> glSurfaceViewWeakRef) { mGLSurfaceViewWeakRef = glSurfaceViewWeakRef; } public void start () { if (LOG_EGL) { Log.w("EglHelper" , "start() tid=" + Thread.currentThread().getId()); } mEgl = (EGL10) EGLContext.getEGL(); mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); ...... int [] version = new int [2 ]; if (!mEgl.eglInitialize(mEglDisplay, version)) { ...... } GLSurfaceView view = mGLSurfaceViewWeakRef.get(); if (view == null ) { mEglConfig = null ; mEglContext = null ; } else { mEglConfig = view.mEGLConfigChooser.chooseConfig(mEgl, mEglDisplay); mEglContext = view.mEGLContextFactory.createContext(mEgl, mEglDisplay, mEglConfig); } if (mEglContext == null || mEglContext == EGL10.EGL_NO_CONTEXT) { mEglContext = null ; throwEglException("createContext" ); } ...... } mEglSurface = null ; } ....... private WeakReference<GLSurfaceView> mGLSurfaceViewWeakRef; EGL10 mEgl; EGLDisplay mEglDisplay; EGLSurface mEglSurface; EGLConfig mEglConfig; EGLContext mEglContext; }
mEglHelper.start()就完成了4步:
1,获取EGLDisplay对象
2,初始化与EGLDisplay 之间的连接。
3,获取EGLConfig对象
4,创建EGLContext 实例
接下来createSurface()
5.2、EglHelper.createSurface() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 private static class EglHelper { public EglHelper (WeakReference<GLSurfaceView> glSurfaceViewWeakRef) { mGLSurfaceViewWeakRef = glSurfaceViewWeakRef; } ...... public boolean createSurface () { if (LOG_EGL) { Log.w("EglHelper" , "createSurface() tid=" + Thread.currentThread().getId()); } ...... GLSurfaceView view = mGLSurfaceViewWeakRef.get(); if (view != null ) { mEglSurface = view.mEGLWindowSurfaceFactory.createWindowSurface(mEgl, mEglDisplay, mEglConfig, view.getHolder()); } else { mEglSurface = null ; } ...... if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { ...... return false ; } return true ; } ...... private WeakReference<GLSurfaceView> mGLSurfaceViewWeakRef; EGL10 mEgl; EGLDisplay mEglDisplay; EGLSurface mEglSurface; EGLConfig mEglConfig; EGLContext mEglContext; }
最终会调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 /frameworks/native/opengl/libs/EGL/eglApi.cpp EGLSurface eglCreateWindowSurface ( EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) { const EGLint *origAttribList = attrib_list; clearError(); egl_connection_t * cnx = NULL ; egl_display_ptr dp = validate_display_connection(dpy, cnx); if (dp) { ...... int value = 0 ; window->query(window, NATIVE_WINDOW_IS_VALID, &value); ...... int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL); ...... } EGLDisplay iDpy = dp->disp.dpy; android_pixel_format format; getNativePixelFormat(iDpy, cnx, config, &format); EGLint colorSpace = EGL_UNKNOWN; std ::vector <EGLint> strippedAttribList; if (!processAttributes(dp, window, format, attrib_list, &colorSpace, &strippedAttribList)) { ...... } attrib_list = strippedAttribList.data(); { int err = native_window_set_buffers_format(window, format); ...... } } android_dataspace dataSpace = dataSpaceFromEGLColorSpace(colorSpace); if (dataSpace != HAL_DATASPACE_UNKNOWN) { int err = native_window_set_buffers_data_space(window, dataSpace); ...... } } ANativeWindow* anw = reinterpret_cast <ANativeWindow*>(window); anw->setSwapInterval(anw, 1 ); EGLSurface surface = cnx->egl.eglCreateWindowSurface( iDpy, config, window, attrib_list); if (surface != EGL_NO_SURFACE) { egl_surface_t * s = new egl_surface_t (dp.get(), config, window, surface, getReportedColorSpace(colorSpace), cnx); return s; } native_window_set_buffers_format(window, 0 ); native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); } return EGL_NO_SURFACE; } --------------------------------------------------------- 对应Log: I/OpenGLRenderer( 2602 ): Initialized EGL, version 1.4 04 -16 13 :08 :37.030 D/OpenGLRenderer( 2602 ): Swap behavior 2 04 -16 13 :08 :37.040 V/Surface ( 2602 ): Surface::query04 -16 13 :08 :37.040 V/Surface ( 2602 ): Surface::connect04 -16 13 :08 :37.041 V/BufferQueueProducer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] connect: api=1 producerControlledByApp=false 04 -16 13 :08 :37.042 V/Surface ( 2602 ): Surface::setBuffersFormat04 -16 13 :08 :37.042 V/BufferQueueProducer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] setAsyncMode: async = 0 04 -16 13 :08 :37.042 V/Surface ( 2602 ): Surface::query04 -16 13 :08 :37.042 V/BufferQueueProducer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] query: 10 ? 2304 04 -16 13 :08 :37.043 V/Surface ( 2602 ): Surface::setUsage04 -16 13 :08 :37.043 V/Surface ( 2602 ): Surface::query04 -16 13 :08 :37.043 I/chatty ( 2602 ): uid=10088 (com.android.testred) GLThread 199 identical 1 line04 -16 13 :08 :37.043 V/Surface ( 2602 ): Surface::query04 -16 13 :08 :37.043 V/BufferQueueProducer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] query: 10 ? 2304 04 -16 13 :08 :37.043 V/Surface ( 2602 ): Surface::query04 -16 13 :08 :37.044 V/BufferQueueProducer( 739 ): [com.android.testred/com.android.testred.TestActivity#0 ] connect: api=1 producerControlledByApp=true 04 -16 13 :08 :37.045 V/Surface ( 2602 ): Surface::query04 -16 13 :08 :37.045 V/BufferQueueProducer( 739 ): [com.android.testred/com.android.testred.TestActivity#0 ] query: 10 ? 2304 04 -16 13 :08 :37.046 V/Surface ( 2602 ): Surface::query04 -16 13 :08 :37.047 V/Surface ( 2602 ): Surface::setBuffersDimensions---------------------------------------------------------
5.3、 mEgl.eglMakeCurrent() 现在用于绘制图像的Surface已经创建好啦
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 -> eglMakeCurrent -> eglMakeCurrent(OEM EGL) -> egl_window_surface_v2_t ::connect() -> Surface::hook_dequeueBuffer() -> Surface::dequeueBuffer() -> BpGraphicBufferProducer::dequeueBuffer() -> BpGraphicBufferProducer::requestBuffer() 对应log : --------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.047 V/Surface ( 2602 ): Surface::dequeueBuffer04 -16 13 :08 :37.047 V/BufferQueueProducer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] dequeueBuffer: w=160 h=816 format=0x2 , usage=0x10000900 04 -16 13 :08 :37.047 V/BufferQueueProducer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] dequeueBuffer: setting buffer age to 0 04 -16 13 :08 :37.047 V/BufferQueueProducer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] dequeueBuffer: allocating a new buffer for slot 0 04 -16 13 :08 :37.048 V/BufferQueueProducer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] dequeueBuffer: returning slot=0 /0 buf=0x7075427380 flags=0x1 04 -16 13 :08 :37.048 V/BufferQueueProducer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] requestBuffer: slot 0 04 -16 13 :08 :37.059 V/Surface ( 2602 ): Surface::setBuffersTransform04 -16 13 :08 :37.059 V/Surface ( 2602 ): Surface::queueBuffer04 -16 13 :08 :37.059 V/Surface ( 2602 ): Surface::queueBuffer making up timestamp: 83377.24 ms04 -16 13 :08 :37.060 V/BufferQueueProducer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] 04 -16 13 :08 :37.060 V/ConsumerBase( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] onFrameAvailable04 -16 13 :08 :37.060 V/ConsumerBase( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] actually calling onFrameAvailable04 -16 13 :08 :37.060 V/BufferQueueProducer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] addAndGetFrameTimestamps04 -16 13 :08 :37.060 V/BufferQueueProducer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] query: 11 ? 0 04 -16 13 :08 :37.060 V/BufferLayerConsumer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] updateTexImage04 -16 13 :08 :37.060 V/BufferQueueConsumer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] acquireBuffer: accept desire=83377236737 expect=83393818427 (-16581690 ) now=83378380070 04 -16 13 :08 :37.060 V/BufferQueueConsumer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] acquireBuffer: acquiring { slot=0 /1 buffer=0x7075427380 }04 -16 13 :08 :37.060 V/ConsumerBase( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] acquireBufferLocked: -> slot=0 /1 04 -16 13 :08 :37.060 V/BufferLayerConsumer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] syncForReleaseLocked04 -16 13 :08 :37.060 V/BufferLayerConsumer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] updateAndRelease: (slot=-1 buf=0x0 ) -> (slot=0 buf=0x7075427380 )04 -16 13 :08 :37.060 V/BufferLayerConsumer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] computeCurrentTransformMatrixLocked04 -16 13 :08 :37.061 V/BufferLayerConsumer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] getFrameNumber04 -16 13 :08 :37.061 V/BufferLayerConsumer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ] getFrameNumber04 -16 13 :08 :37.061 V/BufferLayerConsumer( 739 ): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0 ]---------------------------------------------------------
此时可以看到进行一了一次queueBuffer()操作。此时由于还没有进行绘制操作,所以屏幕肯定是没有显示的。
5.4、Renderer.onDrawFrame() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 /packages/apps/TestViewportRed/src/com/android/testred/TestView.java class TestView extends GLSurfaceView { TestView(Context context) { super (context); init(); } public TestView (Context context, AttributeSet attrs) { super (context, attrs); init(); } private void init () { setRenderer(new Renderer()); setRenderMode(RENDERMODE_WHEN_DIRTY); } private class Renderer implements GLSurfaceView .Renderer { private static final String TAG = "Renderer" ; @Override public void onSurfaceCreated (GL10 gl, EGLConfig config) { gl.glClearColor(1f , 0f , 0f , 0f ); } @Override public void onSurfaceChanged (GL10 gl, int width, int height) { gl.glViewport(0 , 0 , width, height); } @Override public void onDrawFrame (GL10 gl) { gl.glClear(GL10.GL_COLOR_BUFFER_BIT); } } }
此时图像数据已经用OpenGl绘制好了,一块红色的区域(160x854);
5.5、finishDrawingRunnable.run() 接着会执行ViewRootImpl.java 的 postDrawFinished() 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 /frameworks/base/core/java/android/view/ViewRootImpl.java void pendingDrawFinished () { if (mDrawsNeededToReport == 0 ) { throw new RuntimeException("Unbalanced drawPending/pendingDrawFinished calls" ); } mDrawsNeededToReport--; if (mDrawsNeededToReport == 0 ) { reportDrawFinished(); } } private void postDrawFinished () { mHandler.sendEmptyMessage(MSG_DRAW_FINISHED); } private void reportDrawFinished () { try { mDrawsNeededToReport = 0 ; mWindowSession.finishDrawing(mWindow); } catch (RemoteException e) { } }
mWindowSession.finishDrawing(mWindow) 通过binder通信进入
WMS。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 /frameworks/base/services/core/java/com/android/server/wm/Session.java @Override public void finishDrawing (IWindow window) { if (WindowManagerService.localLOGV) Slog.v( TAG_WM, "IWindow finishDrawing called for " + window); mService.finishDrawingWindow(this , window); } /frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java void finishDrawingWindow (Session session, IWindow client) { final long origId = Binder.clearCallingIdentity(); try { synchronized (mWindowMap) { WindowState win = windowForClientLocked(session, client, false ); if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "finishDrawingWindow: " + win + " mDrawState=" + (win != null ? win.mWinAnimator.drawStateToString() : "null" )); if (win != null && win.mWinAnimator.finishDrawingLocked()) { if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0 ) { win.getDisplayContent().pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; } win.setDisplayLayoutNeeded(); mWindowPlacerLocked.requestTraversal(); } } } finally { Binder.restoreCallingIdentity(origId); } } /frameworks/base/services/core/java/com/android/server/wm/WindowState.java void setDisplayLayoutNeeded () { final DisplayContent dc = getDisplayContent(); if (dc != null ) { dc.setLayoutNeeded(); } } /frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java void setLayoutNeeded () { if (DEBUG_LAYOUT) Slog.w(TAG_WM, "setLayoutNeeded: callers=" + Debug.getCallers(3 )); mLayoutNeeded = true ; } --------------------------------------------------------- 对应Log: 04 -16 13 :08 :37.115 V/WindowManager( 1049 ): IWindow finishDrawing called for android.view.IWindow$Stub$Proxy@44816e8 04 -16 13 :08 :37.115 V/WindowManager( 1049 ): Looking up client android.os.BinderProxy@b9baf64 : Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}04 -16 13 :08 :37.115 D/WindowManager( 1049 ): finishDrawingWindow: Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity} mDrawState=DRAW_PENDING04 -16 13 :08 :37.115 V/WindowStateAnimator( 1049 ): finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity} in Surface (name=com.android.testred/com.android.testred.TestActivity) /@0xb17b0ce 04-16 13:08:37.115 W/WindowManager ( 1049 ) : setLayoutNeeded: callers =com.android.server.wm.WindowState.setDisplayLayoutNeeded:2250 com.android.server.wm.WindowManagerService.finishDrawingWindow:2305 com.android.server.wm.Session.finishDrawing:281 ---------------------------------------------------------
5.6、mEglHelper.swap() swap()最终会调用swapBuffers()函数的queueBuffer()通知SurfaceFlinger合成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [->\frameworks\native\opengl\libagl\egl.cpp] EGLBoolean egl_window_surface_v2_t::swapBuffers () {...... nativeWindow->queueBuffer(nativeWindow, buffer); nativeWindow->dequeueBuffer(nativeWindow, &buffer); ...... } --------------------------------------------------------- 看看Log: 04 -16 13 :08 :37.112 V/Surface ( 2602 ): Surface::queueBuffer04 -16 13 :08 :37.112 V/Surface ( 2602 ): Surface::queueBuffer making up timestamp: 83429.66 ms04 -16 13 :08 :37.112 V/BufferQueueProducer( 739 ): [com.android.testred/com.android.testred.TestActivity#0 ] queueBuffer: slot=0 /1 time=83429663560 dataSpace=0 validHdrMetadataTypes=0x0 crop=[0 ,0 ,0 ,0 ] transform=0 scale=FREEZE04 -16 13 :08 :37.112 V/ConsumerBase( 739 ): [com.android.testred/com.android.testred.TestActivity#0 ] onFrameAvailable04 -16 13 :08 :37.112 V/ConsumerBase( 739 ): [com.android.testred/com.android.testred.TestActivity#0 ] actually calling onFrameAvailable04 -16 13 :08 :37.112 V/BufferQueueProducer( 739 ): [com.android.testred/com.android.testred.TestActivity#0 ] addAndGetFrameTimestamps---------------------------------------------------------
5.7、WindowStateAnimator.commitFinishDrawingLocked() 1 2 3 4 5 6 7 8 --------------------------------------------------------- 看看Log: 04 -16 13 :08 :37.116 V/RootWindowContainer( 1049 ): performSurfacePlacementInner: entry. Called by com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop:207 com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement:155 com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement:145 04 -16 13 :08 :37.116 I/RootWindowContainer( 1049 ): >>> OPEN TRANSACTION performLayoutAndPlaceSurfaces04 -16 13 :08 :37.116 W/WindowManager( 1049 ): clearLayoutNeeded: callers=com.android.server.wm.DisplayContent.performLayout:2967 com.android.server.wm.DisplayContent.applySurfaceChangesTransaction:2880 com.android.server.wm.RootWindowContainer.applySurfaceChangesTransaction:852 04 -16 13 :08 :37.116 V/DisplayContent( 1049 ): -------------------------------------04 -16 13 :08 :37.116 V/DisplayContent( 1049 ): performLayout: needed=false dw=480 dh=854 ---------------------------------------------------------
boolean applySurfaceChangesTransaction(boolean recoveringMemory) 方法中 performLayout(repeats == 1, false /* updateInputWindows */);进行布局
1 2 3 4 04 -16 13 :08 :37.118 V/DisplayContent( 1049 ): 1 ST PASS Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}: gone=false mHaveFrame=true mLayoutAttached=false screen changed=false 04 -16 13 :08 :37.118 V/DisplayContent( 1049 ): VIS: mViewVisibility=0 mRelayoutCalled=true hidden=true hiddenRequested=false parentHidden=false 04 -16 13 :08 :37.118 V/WindowManager( 1049 ): layoutWindowLw(com.android.testred/com.android.testred.TestActivity): IN_SCREEN, INSET_DECOR04-16 13:08:37.118 V/WindowManager( 1049): Compute frame com.android.testred/com.android.testred.TestActivity: sim=#120 attach=null type=1 flags=0x01810100 pf=[0,0][160,854] df=[0,0][160,854] of=[0,0][160,854] cf=[0,0][160,854] vf=[0,36][480,782] dcf=[0,36][480,782] sf=[0,36][480,782] osf=null
接着看看boolean applySurfaceChangesTransaction(boolean recoveringMemory) 方法中的 forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 /frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java private final Consumer<WindowState> mApplySurfaceChangesTransaction = w -> { final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked; final boolean obscuredChanged = w.mObscured != mTmpApplySurfaceChangesTransactionState.obscured; final RootWindowContainer root = mService.mRoot; final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty(); w.mObscured = mTmpApplySurfaceChangesTransactionState.obscured; if (!mTmpApplySurfaceChangesTransactionState.obscured) { final boolean isDisplayed = w.isDisplayedLw(); if (isDisplayed && w.isObscuringDisplay()) { root.mObscuringWindow = w; mTmpApplySurfaceChangesTransactionState.obscured = true ; } mTmpApplySurfaceChangesTransactionState.displayHasContent |= root.handleNotObscuredLocked(w, mTmpApplySurfaceChangesTransactionState.obscured, mTmpApplySurfaceChangesTransactionState.syswin); if (w.mHasSurface && isDisplayed) { final int type = w.mAttrs.type; if (type == TYPE_SYSTEM_DIALOG || type == TYPE_SYSTEM_ERROR || (w.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ) { mTmpApplySurfaceChangesTransactionState.syswin = true ; } if (mTmpApplySurfaceChangesTransactionState.preferredRefreshRate == 0 && w.mAttrs.preferredRefreshRate != 0 ) { mTmpApplySurfaceChangesTransactionState.preferredRefreshRate = w.mAttrs.preferredRefreshRate; } if (mTmpApplySurfaceChangesTransactionState.preferredModeId == 0 && w.mAttrs.preferredDisplayModeId != 0 ) { mTmpApplySurfaceChangesTransactionState.preferredModeId = w.mAttrs.preferredDisplayModeId; } } } if (isDefaultDisplay && obscuredChanged && w.isVisibleLw() && mWallpaperController.isWallpaperTarget(w)) { mWallpaperController.updateWallpaperVisibility(); } w.handleWindowMovedIfNeeded(); final WindowStateAnimator winAnimator = w.mWinAnimator; w.mContentChanged = false ; if (w.mHasSurface) { final boolean committed = winAnimator.commitFinishDrawingLocked(); if (isDefaultDisplay && committed) { if (w.mAttrs.type == TYPE_DREAM) { pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT; if (DEBUG_LAYOUT_REPEATS) { surfacePlacer.debugLayoutRepeats( "dream and commitFinishDrawingLocked true" , pendingLayoutChanges); } } if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0 ) { if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "First draw done in potential wallpaper target " + w); root.mWallpaperMayChange = true ; pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; if (DEBUG_LAYOUT_REPEATS) { surfacePlacer.debugLayoutRepeats( "wallpaper and commitFinishDrawingLocked true" , pendingLayoutChanges); } } } } final AppWindowToken atoken = w.mAppToken; if (atoken != null ) { atoken.updateLetterboxSurface(w); final boolean updateAllDrawn = atoken.updateDrawnWindowStates(w); if (updateAllDrawn && !mTmpUpdateAllDrawn.contains(atoken)) { mTmpUpdateAllDrawn.add(atoken); } } if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus && w.isDisplayedLw()) { mTmpApplySurfaceChangesTransactionState.focusDisplayed = true ; } w.updateResizingWindowIfNeeded(); };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 /frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java boolean commitFinishDrawingLocked () { if (DEBUG_STARTING_WINDOW_VERBOSE && mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) { Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState=" + drawStateToString()); } if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) { return false ; } --------------------------------------------------------- 看看Log: 04 -16 13 :08 :37.123 I/WindowStateAnimator( 1049 ): commitFinishDrawingLocked: mDrawState=READY_TO_SHOW Surface (name=com.android.testred/com.android.testred.TestActivity) /@0xb17b0ce --------------------------------------------------------- if (DEBUG_ANIM) { Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurfaceController); } mDrawState = READY_TO_SHOW; boolean result = false ; final AppWindowToken atoken = mWin.mAppToken; if (atoken == null || atoken.allDrawn || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) { result = mWin.performShowLocked(); } return result; }
5.7.1、AppWindowToken.updateDrawnWindowStates() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 /frameworks/base/services/core/java/com/android/server/wm/AppWindowToken.java --------------------------------------------------------- 看看Log: 04 -16 13 :08 :37.124 V/AppWindowToken( 1049 ): Eval win Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}: isDrawn=true , isAnimationSet=true 04 -16 13 :08 :37.124 V/AppWindowToken( 1049 ): tokenMayBeDrawn: AppWindowToken{1579134 token=Token{ce2ac07 ActivityRecord{65 cc87a u0 com.android.testred/.TestActivity t5}}} w=Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity} numInteresting=1 freezingScreen=false mAppFreezing=false --------------------------------------------------------- boolean updateDrawnWindowStates (WindowState w) { w.setDrawnStateEvaluated(true ); if (DEBUG_STARTING_WINDOW_VERBOSE && w == startingWindow) { Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + allDrawn + " freezingScreen=" + mFreezingScreen); } if (allDrawn && !mFreezingScreen) { return false ; } if (mLastTransactionSequence != mService.mTransactionSequence) { mLastTransactionSequence = mService.mTransactionSequence; mNumDrawnWindows = 0 ; startingDisplayed = false ; mNumInterestingWindows = findMainWindow(false ) != null ? 1 : 0 ; } final WindowStateAnimator winAnimator = w.mWinAnimator; boolean isInterestingAndDrawn = false ; if (!allDrawn && w.mightAffectAllDrawn()) { if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) { Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw() + ", isAnimationSet=" + isSelfAnimating()); if (!w.isDrawnLw()) { Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceController + " pv=" + w.mPolicyVisibility + " mDrawState=" + winAnimator.drawStateToString() + " ph=" + w.isParentWindowHidden() + " th=" + hiddenRequested + " a=" + isSelfAnimating()); } } if (w != startingWindow) { if (w.isInteresting()) { if (findMainWindow(false ) != w) { mNumInterestingWindows++; } if (w.isDrawnLw()) { mNumDrawnWindows++; if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, "tokenMayBeDrawn: " + this + " w=" + w + " numInteresting=" + mNumInterestingWindows + " freezingScreen=" + mFreezingScreen + " mAppFreezing=" + w.mAppFreezing); isInterestingAndDrawn = true ; } } } else if (w.isDrawnLw()) { if (getController() != null ) { getController().reportStartingWindowDrawn(); } startingDisplayed = true ; } } return isInterestingAndDrawn; }
5.8、DisplayContent.prepareSurfaces() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 /frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java @Override void prepareSurfaces () { ...... super .prepareSurfaces(); } /frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java void prepareSurfaces () { SurfaceControl.mergeToGlobalTransaction(getPendingTransaction()); mCommittedReparentToAnimationLeash = mSurfaceAnimator.hasLeash(); for (int i = 0 ; i < mChildren.size(); i++) { mChildren.get(i).prepareSurfaces(); } } /frameworks/base/services/core/java/com/android/server/wm/WindowState.java @Override void prepareSurfaces () { final Dimmer dimmer = getDimmer(); mIsDimming = false ; if (dimmer != null ) { applyDims(dimmer); } updateSurfacePosition(); mWinAnimator.prepareSurfaceLocked(true ); super .prepareSurfaces(); } /frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java void prepareSurfaceLocked (final boolean recoveringMemory) { final WindowState w = mWin; if (!hasSurface()) { if (w.getOrientationChanging() && w.isGoneForLayoutLw()) { if (DEBUG_ORIENTATION) { Slog.v(TAG, "Orientation change skips hidden " + w); } w.setOrientationChanging(false ); } return ; } boolean displayed = false ; computeShownFrameLocked(); setSurfaceBoundariesLocked(recoveringMemory); if (mIsWallpaper && !w.mWallpaperVisible) { hide("prepareSurfaceLocked" ); } else if (w.isParentWindowHidden() || !w.isOnScreen()) { hide("prepareSurfaceLocked" ); mWallpaperControllerLocked.hideWallpapers(w); if (w.getOrientationChanging() && w.isGoneForLayoutLw()) { w.setOrientationChanging(false ); if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change skips hidden " + w); } } else if (mLastLayer != mAnimLayer || mLastAlpha != mShownAlpha || mLastDsDx != mDsDx || mLastDtDx != mDtDx || mLastDsDy != mDsDy || mLastDtDy != mDtDy || w.mLastHScale != w.mHScale || w.mLastVScale != w.mVScale || mLastHidden) { displayed = true ; mLastAlpha = mShownAlpha; mLastLayer = mAnimLayer; mLastDsDx = mDsDx; mLastDtDx = mDtDx; mLastDsDy = mDsDy; mLastDtDy = mDtDy; w.mLastHScale = w.mHScale; w.mLastVScale = w.mVScale; --------------------------------------------------------- 看看Log: 04 -16 13 :08 :37.124 I/WindowManager( 1049 ): SURFACE controller=Surface(name=com.android.testred/com.android.testred.TestActivity)/@0xb17b0ceal pha=1.0 layer=0 matrix=[1.0 *1.0 ,0.0 *1.0 ][0.0 *1.0 ,1.0 *1.0 ]: Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity}--------------------------------------------------------- if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, "controller=" + mSurfaceController + "alpha=" + mShownAlpha + " layer=" + mAnimLayer + " matrix=[" + mDsDx + "*" + w.mHScale + "," + mDtDx + "*" + w.mVScale + "][" + mDtDy + "*" + w.mHScale + "," + mDsDy + "*" + w.mVScale + "]" , false ); boolean prepared = mSurfaceController.prepareToShowInTransaction(mShownAlpha, mDsDx * w.mHScale * mExtraHScale, mDtDx * w.mVScale * mExtraVScale, mDtDy * w.mHScale * mExtraHScale, mDsDy * w.mVScale * mExtraVScale, recoveringMemory); if (prepared && mDrawState == HAS_DRAWN) { if (mLastHidden) { if (showSurfaceRobustlyLocked()) { markPreservedSurfaceForDestroy(); mAnimator.requestRemovalOfReplacedWindows(w); mLastHidden = false ; if (mIsWallpaper) { w.dispatchWallpaperVisibility(true ); } mAnimator.setPendingLayoutChanges(w.getDisplayId(), FINISH_LAYOUT_REDO_ANIM); if (DEBUG_LAYOUT_REPEATS) { mService.mWindowPlacerLocked.debugLayoutRepeats( "showSurfaceRobustlyLocked " + w, mAnimator.getPendingLayoutChanges(w.getDisplayId())); } } else { w.setOrientationChanging(false ); } } } if (hasSurface()) { w.mToken.hasVisible = true ; } } else { if (DEBUG_ANIM && isAnimationSet()) { Slog.v(TAG, "prepareSurface: No changes in animation for " + this ); } displayed = true ; } if (w.getOrientationChanging()) { if (!w.isDrawnLw()) { mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE; mAnimator.mLastWindowFreezeSource = w; if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation continue waiting for draw in " + w); } else { w.setOrientationChanging(false ); if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w); } } if (displayed) { w.mToken.hasVisible = true ; } }
5.8.1、WindowStateAnimator.computeShownFrameLocked() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 /frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java void computeShownFrameLocked () { final int displayId = mWin.getDisplayId(); final ScreenRotationAnimation screenRotationAnimation = mAnimator.getScreenRotationAnimationLocked(displayId); final boolean screenAnimation = screenRotationAnimation != null && screenRotationAnimation.isAnimating(); if (screenAnimation) { final Rect frame = mWin.mFrame; final float tmpFloats[] = mService.mTmpFloats; final Matrix tmpMatrix = mWin.mTmpMatrix; if (screenRotationAnimation.isRotating()) { final float w = frame.width(); final float h = frame.height(); if (w>=1 && h>=1 ) { tmpMatrix.setScale(1 + 2 /w, 1 + 2 /h, w/2 , h/2 ); } else { tmpMatrix.reset(); } } else { tmpMatrix.reset(); } tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale); ...... tmpMatrix.postTranslate(mWin.mAttrs.surfaceInsets.left, mWin.mAttrs.surfaceInsets.top); ...... mHaveMatrix = true ; tmpMatrix.getValues(tmpFloats); mDsDx = tmpFloats[Matrix.MSCALE_X]; mDtDx = tmpFloats[Matrix.MSKEW_Y]; mDtDy = tmpFloats[Matrix.MSKEW_X]; mDsDy = tmpFloats[Matrix.MSCALE_Y]; ...... mShownAlpha = mAlpha; if (!mService.mLimitedAlphaCompositing || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format) || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDtDy, mDsDy)))) { if (screenAnimation) { mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha(); } } else { } if ((DEBUG_ANIM || WindowManagerService.localLOGV) && (mShownAlpha == 1.0 || mShownAlpha == 0.0 )) Slog.v( TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha + " screen=" + (screenAnimation ? screenRotationAnimation.getEnterTransformation().getAlpha() : "null" )); return ; } else if (mIsWallpaper && mService.mRoot.mWallpaperActionPending) { return ; } else if (mWin.isDragResizeChanged()) { return ; } --------------------------------------------------------- 看看Log: 04 -16 13 :08 :37.124 V/WindowStateAnimator( 1049 ): computeShownFrameLocked: WindowStateAnimator{4f b81c9 com.android.testred/com.android.testred.TestActivity} not attached, mAlpha=1.0 --------------------------------------------------------- if (WindowManagerService.localLOGV) Slog.v( TAG, "computeShownFrameLocked: " + this + " not attached, mAlpha=" + mAlpha); mShownAlpha = mAlpha; mHaveMatrix = false ; mDsDx = mWin.mGlobalScale; mDtDx = 0 ; mDtDy = 0 ; mDsDy = mWin.mGlobalScale; }
5.8.2、WindowStateAnimator.setSurfaceBoundariesLocked() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 /frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java void setSurfaceBoundariesLocked (final boolean recoveringMemory) { ...... final WindowState w = mWin; final LayoutParams attrs = mWin.getAttrs(); final Task task = w.getTask(); mTmpSize.set(0 , 0 , 0 , 0 ); calculateSurfaceBounds(w, attrs); mExtraHScale = (float ) 1.0 ; mExtraVScale = (float ) 1.0 ; boolean wasForceScaled = mForceScaleUntilResize; boolean wasSeamlesslyRotated = w.mSeamlesslyRotated; ...... final boolean relayout = !w.mRelayoutCalled || w.mInRelayout; if (relayout) { mSurfaceResized = mSurfaceController.setSizeInTransaction( mTmpSize.width(), mTmpSize.height(), recoveringMemory); } else { mSurfaceResized = false ; } mForceScaleUntilResize = mForceScaleUntilResize && !mSurfaceResized; ....... mService.markForSeamlessRotation(w, w.mSeamlesslyRotated && !mSurfaceResized); Rect clipRect = null ; if (calculateCrop(mTmpClipRect)) { clipRect = mTmpClipRect; } float surfaceWidth = mSurfaceController.getWidth(); float surfaceHeight = mSurfaceController.getHeight(); final Rect insets = attrs.surfaceInsets; if (isForceScaled()) { int hInsets = insets.left + insets.right; int vInsets = insets.top + insets.bottom; float surfaceContentWidth = surfaceWidth - hInsets; float surfaceContentHeight = surfaceHeight - vInsets; if (!mForceScaleUntilResize) { mSurfaceController.forceScaleableInTransaction(true ); } int posX = 0 ; int posY = 0 ; task.mStack.getDimBounds(mTmpStackBounds); boolean allowStretching = false ; task.mStack.getFinalAnimationSourceHintBounds(mTmpSourceBounds); ...... if (mTmpSourceBounds.isEmpty() && (mWin.mLastRelayoutContentInsets.width() > 0 || mWin.mLastRelayoutContentInsets.height() > 0 ) && !task.mStack.lastAnimatingBoundsWasToFullscreen()) { mTmpSourceBounds.set(task.mStack.mPreAnimationBounds); mTmpSourceBounds.inset(mWin.mLastRelayoutContentInsets); allowStretching = true ; } ...... mTmpStackBounds.intersectUnchecked(w.mParentFrame); mTmpSourceBounds.intersectUnchecked(w.mParentFrame); mTmpAnimatingBounds.intersectUnchecked(w.mParentFrame); if (!mTmpSourceBounds.isEmpty()) { task.mStack.getFinalAnimationBounds(mTmpAnimatingBounds); float finalWidth = mTmpAnimatingBounds.width(); float initialWidth = mTmpSourceBounds.width(); float tw = (surfaceContentWidth - mTmpStackBounds.width()) / (surfaceContentWidth - mTmpAnimatingBounds.width()); float th = tw; mExtraHScale = (initialWidth + tw * (finalWidth - initialWidth)) / initialWidth; if (allowStretching) { float finalHeight = mTmpAnimatingBounds.height(); float initialHeight = mTmpSourceBounds.height(); th = (surfaceContentHeight - mTmpStackBounds.height()) / (surfaceContentHeight - mTmpAnimatingBounds.height()); mExtraVScale = (initialHeight + tw * (finalHeight - initialHeight)) / initialHeight; } else { mExtraVScale = mExtraHScale; } ....... clipRect = mTmpClipRect; clipRect.set((int )((insets.left + mTmpSourceBounds.left) * tw), (int )((insets.top + mTmpSourceBounds.top) * th), insets.left + (int )(surfaceWidth - (tw* (surfaceWidth - mTmpSourceBounds.right))), insets.top + (int )(surfaceHeight - (th * (surfaceHeight - mTmpSourceBounds.bottom)))); } else { mExtraHScale = mTmpStackBounds.width() / surfaceContentWidth; mExtraVScale = mTmpStackBounds.height() / surfaceContentHeight; clipRect = null ; } posX -= (int ) (attrs.x * (1 - mExtraHScale)); posY -= (int ) (attrs.y * (1 - mExtraVScale)); posX += insets.left * (1 - mExtraHScale); posY += insets.top * (1 - mExtraVScale); mSurfaceController.setPositionInTransaction((float ) Math.floor(posX), (float ) Math.floor(posY), recoveringMemory); if (mPipAnimationStarted == false ) { mForceScaleUntilResize = true ; mPipAnimationStarted = true ; } } else { mPipAnimationStarted = false ; if (!w.mSeamlesslyRotated) { int xOffset = mXOffset; int yOffset = mYOffset; if (mOffsetPositionForStackResize) { if (relayout) { setOffsetPositionForStackResize(false ); mSurfaceController.deferTransactionUntil(mSurfaceController.getHandle(), mWin.getFrameNumber()); } else { final TaskStack stack = mWin.getStack(); mTmpPos.x = 0 ; mTmpPos.y = 0 ; if (stack != null ) { stack.getRelativePosition(mTmpPos); } xOffset = -mTmpPos.x; yOffset = -mTmpPos.y; if (clipRect != null ) { clipRect.right += mTmpPos.x; clipRect.bottom += mTmpPos.y; } } } mSurfaceController.setPositionInTransaction(xOffset, yOffset, recoveringMemory); } } setGeometryAppliesWithResizeInTransaction accomplishes this for us. if ((wasForceScaled && !mForceScaleUntilResize) || (wasSeamlesslyRotated && !w.mSeamlesslyRotated)) { mSurfaceController.setGeometryAppliesWithResizeInTransaction(true ); mSurfaceController.forceScaleableInTransaction(false ); } if (!w.mSeamlesslyRotated) { applyCrop(clipRect, recoveringMemory); --------------------------------------------------------- 看看Log: 04 -16 13 :08 :37.124 I/WindowSurfaceController( 1049 ): SURFACE MATRIX [1.0 ,0.0 ,0.0 ,1.0 ]: com.android.testred/com.android.testred.TestActivity---------------------------------------------------------mSurfaceController.setMatrixInTransaction(mDsDx * w.mHScale * mExtraHScale, mDtDx * w.mVScale * mExtraVScale, mDtDy * w.mHScale * mExtraHScale, mDsDy * w.mVScale * mExtraVScale, recoveringMemory); } if (mSurfaceResized) { mReportSurfaceResized = true ; mAnimator.setPendingLayoutChanges(w.getDisplayId(), FINISH_LAYOUT_REDO_WALLPAPER); } }
5.8.2.1、WindowStateAnimator.calculateCrop() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 private boolean calculateCrop (Rect clipRect) { final WindowState w = mWin; final DisplayContent displayContent = w.getDisplayContent(); clipRect.setEmpty(); if (displayContent == null ) { return false ; } if (w.inPinnedWindowingMode()) { return false ; } if (w.mAttrs.type == TYPE_WALLPAPER) { return false ; } --------------------------------------------------------- 看看Log: 04 -16 13 :08 :37.124 D/WindowStateAnimator( 1049 ): Updating crop win=Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity} mLastCrop=Rect(0 , 36 - 160 , 782 )04 -16 13 :08 :37.124 D/WindowStateAnimator( 1049 ): Applying decor to crop win=Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity} mDecorFrame=Rect(0 , 36 - 480 , 782 ) mSystemDecorRect=Rect(0 , 36 - 160 , 782 )04 -16 13 :08 :37.124 D/WindowStateAnimator( 1049 ): win=Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity} Initial clip rect: Rect(0 , 36 - 160 , 782 ) fullscreen=true 04 -16 13 :08 :37.124 D/WindowStateAnimator( 1049 ): win=Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity} Clip rect after stack adjustment=Rect(0 , 36 - 160 , 782 )04 -16 13 :08 :37.124 D/WindowStateAnimator( 1049 ): --------------------------------------------------------- if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Updating crop win=" + w + " mLastCrop=" + mLastClipRect); w.calculatePolicyCrop(mSystemDecorRect); if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Applying decor to crop win=" + w + " mDecorFrame=" + w.mDecorFrame + " mSystemDecorRect=" + mSystemDecorRect); final Task task = w.getTask(); final boolean fullscreen = w.fillsDisplay() || (task != null && task.isFullscreen()); final boolean isFreeformResizing = w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM; clipRect.set(mSystemDecorRect); if (DEBUG_WINDOW_CROP) Slog.d(TAG, "win=" + w + " Initial clip rect: " + clipRect + " fullscreen=" + fullscreen); w.expandForSurfaceInsets(clipRect); clipRect.offset(w.mAttrs.surfaceInsets.left, w.mAttrs.surfaceInsets.top); if (DEBUG_WINDOW_CROP) Slog.d(TAG, "win=" + w + " Clip rect after stack adjustment=" + clipRect); w.transformClipRectFromScreenToSurfaceSpace(clipRect); return true ; }
5.8.2.2、WindowStateAnimator.applyCrop() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 --------------------------------------------------------- 看看Log: 04 -16 13 :08 :37.124 D/WindowStateAnimator( 1049 ): applyCrop: win=Window{c1255cd u0 com.android.testred/com.android.testred.TestActivity} clipRect=Rect(0 , 36 - 160 , 782 )04 -16 13 :08 :37.124 I/WindowSurfaceController( 1049 ): SURFACE MATRIX [1.0 ,0.0 ,0.0 ,1.0 ]: com.android.testred/com.android.testred.TestActivity--------------------------------------------------------- private void applyCrop (Rect clipRect, boolean recoveringMemory) { if (DEBUG_WINDOW_CROP) Slog.d(TAG, "applyCrop: win=" + mWin + " clipRect=" + clipRect); if (clipRect != null ) { if (!clipRect.equals(mLastClipRect)) { mLastClipRect.set(clipRect); mSurfaceController.setCropInTransaction(clipRect, recoveringMemory); } } else { mSurfaceController.clearCropInTransaction(recoveringMemory); } }
5.8.3、mSurfaceController.setPositionInTransaction(……) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 /frameworks/base/services/core/java/com/android/server/wm/WindowSurfaceController.java void setPositionInTransaction (float left, float top, boolean recoveringMemory) { setPosition(null , left, top, recoveringMemory); } void setPosition (SurfaceControl.Transaction t, float left, float top, boolean recoveringMemory) { final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top; if (surfaceMoved) { mSurfaceX = left; mSurfaceY = top; try { if (SHOW_TRANSACTIONS) logSurface( "POS (setPositionInTransaction) @ (" + left + "," + top + ")" , null ); if (t == null ) { mSurfaceControl.setPosition(left, top); } else { t.setPosition(mSurfaceControl, left, top); } } catch (RuntimeException e) { Slog.w(TAG, "Error positioning surface of " + this + " pos=(" + left + "," + top + ")" , e); if (!recoveringMemory) { mAnimator.reclaimSomeSurfaceMemory("position" , true ); } } } }
5.9、AppWindowToken.updateAllDrawn() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 /frameworks/base/services/core/java/com/android/server/wm/AppWindowToken.java --------------------------------------------------------- 看看Log: 04 -16 13 :08 :37.125 V/AppWindowToken( 1049 ): allDrawn: AppWindowToken{1579134 token=Token{ce2ac07 ActivityRecord{65 cc87a u0 com.android.testred/.TestActivity t5}}} interesting=1 drawn=1 --------------------------------------------------------- void updateAllDrawn () { if (!allDrawn) { final int numInteresting = mNumInterestingWindows; if (numInteresting > 0 && allDrawnStatesConsidered() && mNumDrawnWindows >= numInteresting && !isRelaunching()) { if (DEBUG_VISIBILITY) Slog.v(TAG, "allDrawn: " + this + " interesting=" + numInteresting + " drawn=" + mNumDrawnWindows); allDrawn = true ; if (mDisplayContent != null ) { mDisplayContent.setLayoutNeeded(); } mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget(); final TaskStack pinnedStack = mDisplayContent.getPinnedStack(); if (pinnedStack != null ) { pinnedStack.onAllWindowsDrawn(); } } } }
(6)、执行窗口合成显示 6.1、WindowStateAnimator.showSurfaceRobustlyLocked() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 /frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java private boolean showSurfaceRobustlyLocked () { if (mWin.getWindowConfiguration().windowsAreScaleable()) { mSurfaceController.forceScaleableInTransaction(true ); } boolean shown = mSurfaceController.showRobustlyInTransaction(); if (!shown) return false ; if (mPendingDestroySurface != null && mDestroyPreservedSurfaceUponRedraw) { mPendingDestroySurface.mSurfaceControl.hide(); mPendingDestroySurface.reparentChildrenInTransaction(mSurfaceController); } return true ; }
6.1.1、WindowSurfaceController.showRobustlyInTransaction() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 WindowSurfaceController.java --------------------------------------------------------- 看看Log: 04 -16 13 :08 :37.153 I/WindowSurfaceController( 1049 ): SURFACE SHOW (performLayout) : com.android.testred/com.android.testred.TestActivity 04-16 13:08:37.153 V/WindowSurfaceController ( 1049 ) : Showing Surface (name=com.android.testred/com.android.testred.TestActivity) /@0xb17b0ce during relayout --------------------------------------------------------- boolean showRobustlyInTransaction () { if (SHOW_TRANSACTIONS) logSurface( "SHOW (performLayout)" , null ); if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this + " during relayout" ); mHiddenForOtherReasons = false ; return updateVisibility(); } private boolean updateVisibility () { if (mHiddenForCrop || mHiddenForOtherReasons) { if (mSurfaceShown) { hideSurface(mTmpTransaction); SurfaceControl.mergeToGlobalTransaction(mTmpTransaction); } return false ; } else { if (!mSurfaceShown) { return showSurface(); } else { return true ; } } } private boolean showSurface () { try { setShown(true ); mSurfaceControl.show(); return true ; } catch (RuntimeException e) { Slog.w(TAG, "Failure showing surface " + mSurfaceControl + " in " + this , e); } mAnimator.reclaimSomeSurfaceMemory("show" , true ); return false ; }
6.1.2、SurfaceControl.show() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 /frameworks/base/core/java/android/view/SurfaceControl.java public void show () { checkNotReleased(); synchronized (SurfaceControl.class) { sGlobalTransaction.show(this ); } } public Transaction show (SurfaceControl sc) { sc.checkNotReleased(); nativeSetFlags(mNativeObject, sc.mNativeObject, 0 , SURFACE_HIDDEN); return this ; }
6.2、SurfaceFlinger 合成显示 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 --------------------------------------------------------- 看看Log: 04 -16 13 :08 :37.161 V/SurfaceFlinger( 739 ): handlePageFlip04 -16 13 :08 :37.161 V/SurfaceFlinger( 739 ): preComposition04 -16 13 :08 :37.161 V/SurfaceFlinger( 739 ): rebuildLayerStacks04 -16 13 :08 :37.161 V/SurfaceFlinger( 739 ): computeVisibleRegions04 -16 13 :08 :37.161 V/SurfaceFlinger( 739 ): setUpHWComposer04 -16 13 :08 :37.162 V/HWC2 ( 739 ): Created layer 8 on display 0 04 -16 13 :08 :37.162 V/HWC2 ( 739 ): Created layer 9 on display 0 ..... 04-16 13:08:37.163 V/BufferLayer( 739): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0] Requesting Device composition 04 -16 13 :08 :37.163 V/Layer ( 739 ): setCompositionType(8 , Device, 1 )04 -16 13 :08 :37.163 V/Layer ( 739 ): actually setting04 -16 13 :08 :37.163 V/BufferLayer( 739 ): setPerFrameData: dataspace = 0 04-16 13:08:37.163 V/BufferLayerConsumer( 739): [SurfaceView - com.android.testred/com.android.testred.TestActivity#0] getCurrentHdrMetadata 04-16 13:08:37.163 V/BufferLayer( 739): [com.android.testred/com.android.testred.TestActivity#0] Requesting Device composition 04 -16 13 :08 :37.163 V/Layer ( 739 ): setCompositionType(9 , Device, 1 )04 -16 13 :08 :37.163 V/Layer ( 739 ): actually setting04 -16 13 :08 :37.163 V/BufferLayer( 739 ): setPerFrameData: dataspace = 0 04-16 13:08:37.163 V/BufferLayerConsumer( 739): [com.android.testred/com.android.testred.TestActivity#0] getCurrentHdrMetadata 04-16 13:08:37.163 V/BufferLayer( 739): [StatusBar#0] Requesting Device composition 04 -16 13 :08 :37.163 V/Layer ( 739 ): setCompositionType(3 , Device, 1 )04 -16 13 :08 :37.163 V/BufferLayer( 739 ): setPerFrameData: dataspace = 0 04-16 13:08:37.163 V/BufferLayerConsumer( 739): [StatusBar#0] getCurrentHdrMetadata 04-16 13:08:37.163 V/BufferLayer( 739): [NavigationBar#0] Requesting Device composition 04 -16 13 :08 :37.163 V/Layer ( 739 ): setCompositionType(4 , Device, 1 )04 -16 13 :08 :37.163 V/BufferLayer( 739 ): setPerFrameData: dataspace = 0 04-16 13:08:37.163 V/BufferLayerConsumer( 739): [NavigationBar#0] getCurrentHdrMetadata ...... 04 -16 13 :08 :37.164 V/HWComposer( 739 ): SkipValidate failed, Falling back to SLOW validate/present04 -16 13 :08 :37.164 V/SurfaceFlinger( 739 ): doComposition04 -16 13 :08 :37.164 V/SurfaceFlinger( 739 ): doDisplayComposition04 -16 13 :08 :37.164 V/SurfaceFlinger( 739 ): doComposeSurfaces04 -16 13 :08 :37.164 V/SurfaceFlinger( 739 ): Rendering client layers04-16 13:08:37.164 V/SurfaceFlinger( 739): Layer: com.android.systemui.ImageWallpaper#0 04 -16 13 :08 :37.164 V/SurfaceFlinger( 739 ): Composition type: Device04-16 13:08:37.164 V/SurfaceFlinger( 739): Layer: com.android.launcher3/com.android.launcher3.Launcher#0 04 -16 13 :08 :37.164 V/SurfaceFlinger( 739 ): Composition type: Device04-16 13:08:37.164 V/SurfaceFlinger( 739): Layer: SurfaceView - com.android.testred/com.android.testred.TestActivity#0 04 -16 13 :08 :37.164 V/SurfaceFlinger( 739 ): Composition type: Device04-16 13:08:37.164 V/SurfaceFlinger( 739): Layer: com.android.testred/com.android.testred.TestActivity#0 04 -16 13 :08 :37.164 V/SurfaceFlinger( 739 ): Composition type: Device04-16 13:08:37.164 V/SurfaceFlinger( 739): Layer: StatusBar#0 04 -16 13 :08 :37.164 V/SurfaceFlinger( 739 ): Composition type: Device04-16 13:08:37.164 V/SurfaceFlinger( 739): Layer: NavigationBar#0 04 -16 13 :08 :37.164 V/SurfaceFlinger( 739 ): Composition type: Device04 -16 13 :08 :37.164 V/SurfaceFlinger( 739 ): postFramebuffer---------------------------------------------------------
关于SurfaceFlinger合成显示之前已经分析过很多次啦,这里就不再分析啦。请参考:{ Android P Graphics System(四):Native Surface 创建 && SurfaceFlinger合成流程分析 }
/** Vsync end****** / (X)、参考文档: (1)【Android Display System】