创建Surface
- 前言
- ViewRootImpl创建Surface
前言
我们前面已经分析过Activity启动如何去连接到SurfaceFlinger了,接下来就看Activity的Surface的创建到SurfaceFlinger的过程。
ViewRootImpl创建Surface
在调用了WindowManagerGlobal的addView方法之后会首先去创建一个ViewRootImpl将View和Window关联起来,
在new ViewRootImpl的时候就创建了一个Surface对象。
// These can be accessed by any thread, must be protected with a lock.// Surface can never be reassigned or cleared (use Surface.clear()).public final Surface mSurface = new Surface();
其实这个时候的mSurface只是一个空的对象,属性值都没有被赋值,那这个mSurface在什么时候被赋值呢?继续往下追。继续回到WindowManagerGlobal 的 addView方法
public void addView(View view, ViewGroup.LayoutParams params,Display display, Window parentWindow) {... ...root = new ViewRootImpl(view.getContext(), display);view.setLayoutParams(wparams);mViews.add(view);mRoots.add(root);mParams.add(wparams);// do this last because it fires off messages to start doing thingstry {// 在这又调用了viewRootImpl的setView方法root.setView(view, wparams, panelParentView);Slog.e("WindowManager"," root.setView end" );} ... ...
继续看setView里面做了什么事情
/*** We have one child*/public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {synchronized (this) {// mView为null才会走进去,保证在传参进来的view不为空的前提下,一个ViewRootImpl对象mView会被赋值一次if (mView == null) {mView = view;mAttachInfo.mDisplayState = mDisplay.getState();mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);mViewLayoutDirectionInitial = mView.getRawLayoutDirection();mFallbackEventHandler.setView(view);// 将window属性进行保存mWindowAttributes.copyFrom(attrs);if (mWindowAttributes.packageName == null) {mWindowAttributes.packageName = mBasePackageName;}attrs = mWindowAttributes;setTag();... ...if (DEBUG_KEEP_SCREEN_ON && (mClientWindowLayoutFlags& WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) != 0&& (attrs.flags&WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) == 0) {Slog.d(mTag, "setView: FLAG_KEEP_SCREEN_ON changed from true to false!");}... ... // Schedule the first layout -before- adding to the window// manager, to make sure we do the relayout before receiving// any other events from the system.// 在调用这个方法追下去会创建SurfaceControlrequestLayout();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);} ... ...}
我们继续去追requestLayout() 方法。
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,boolean insetsPending) throws RemoteException {int 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);
上的mWindowSession我们知道在new ViewRootImpl的时候进行的赋值,mWindowSession 就是Session
mWindowSession = WindowManagerGlobal.getWindowSession();
调用Session的relayout方法
@Overridepublic 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);// mService就是WindowManagerServiceint 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;}
在windowManagerService的relayoutWindow方法中又会调用createSurfaceControl方法进行创建SurfaceControl
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) {... ...try {result = createSurfaceControl(outSurface, result, win, winAnimator);}... ...}}
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 {// For some reason there isn't a surface. Clear the// caller's object so they see the same state.Slog.w(TAG_WM, "Failed to create surface control for " + win);outSurface.release();}return result;}
winAnimator对象类型是WindowStateAnimator,而WindowStateAnimator中包含了WindowSurfaceController 类型的对象,而在WindowSurfaceController 中又包含了 SurfaceControl的对象。
/frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java
WindowSurfaceController mSurfaceController;
WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) {final WindowState w = mWin;// 在WindowSurfaceController的构造函数里面就会创建SurfaceControlmSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession,attrs.getTitle().toString(), width, height, format, flags, this,windowType, ownerUid);return mSurfaceController;}
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);// 调用到了 SurfaceControl的内部类Builder的build方法,mSurfaceControl = b.build();Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}
public SurfaceControl build() {if (mWidth <= 0 || mHeight <= 0) {throw new IllegalArgumentException("width and height must be set");}// 终于追到了new SurfaceControl的地方return new SurfaceControl(mSession, mName, mWidth, mHeight, mFormat,mFlags, mParent, mWindowType, mOwnerUid);}
private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,SurfaceControl parent, int windowType, int ownerUid)throws OutOfResourcesException, IllegalArgumentException {if (session == null) {throw new IllegalArgumentException("session must not be null");}if (name == null) {throw new IllegalArgumentException("name must not be null");}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;// 从这里就调用到了,native层调用到SurfaceFlinger的createSurface() 方法// 这个之后的方法我们分第二节分析mNativeObject = nativeCreate(session, name, w, h, format, flags,parent != null ? parent.mNativeObject : 0, windowType, ownerUid);if (mNativeObject == 0) {throw new OutOfResourcesException("Couldn't allocate SurfaceControl native object");}mCloseGuard.open("release");}
再回到window ManagerService的createSurfaceControl方法
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;surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);} finally {Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}if (surfaceController != null) {// 在这里给我们viewRootimpl中的mSurface进行赋值surfaceController.getSurface(outSurface);if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " OUT SURFACE " + outSurface + ": copied");} else {// For some reason there isn't a surface. Clear the// caller's object so they see the same state.Slog.w(TAG_WM, "Failed to create surface control for " + win);outSurface.release();}return result;}
frameworks/base/services/core/java/com/android/server/wm/WindowSurfaceController.java
void getSurface(Surface outSurface) {// 看到了吧,在这里将刚创建的mSurfaceControl传递了进去outSurface.copyFrom(mSurfaceControl);}
frameworks/base/core/java/android/view/Surface.java
// Copy another surface to this one.
// copy 一个surface到这对象里面public void copyFrom(SurfaceControl other) {if (other == null) {throw new IllegalArgumentException("other must not be null");}// SurfaceControl的地址指针long surfaceControlPtr = other.mNativeObject;if (surfaceControlPtr == 0) {throw new NullPointerException("null SurfaceControl native object. Are you using a released SurfaceControl?");}// 返回的就是native层创建的Surfacelong newNativeObject = nativeGetFromSurfaceControl(surfaceControlPtr);synchronized (mLock) {if (mNativeObject != 0) {nativeRelease(mNativeObject);}setNativeObjectLocked(newNativeObject);}}