androidP Surface到SurfaceFlinger -->创建Surface (一)

news/2024/11/29 16:23:26/

创建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);}}

http://www.ppmy.cn/news/535943.html

相关文章

Ansys Speos | 基于 Workbench 和 Speos 的准直全反射透镜优化设计案例

概述 基于Ansys Speos软件&#xff0c;可以准确建立光学系统模型并进行成像效果仿真。在使用Speos进行光学系统设计过程中&#xff0c;当完成初始光学系统建模后&#xff0c;还需要进一步结合仿真结果&#xff0c;调整出满足设计要求的系统参数&#xff0c;如果采用手动调整参…

Android系统Surface机制的SurfaceFlinger服务的启动过程分析

在前面一篇文章中&#xff0c;我们简要介绍了Android系统Surface机制中的SurfaceFlinger服务。SurfaceFlinger服务是在System进程中启动的&#xff0c;并且负责统一管理设备的帧缓冲区。SurfaceFlinger服务在启动的过程中&#xff0c;会创建两个线程&#xff0c;其中一个线程用…

Python三目运算符(三元运算符)用法详解

我们从一个具体的例子切入本节内容。假设现在有两个数字&#xff0c;我们希望获得其中较大的一个&#xff0c;那么可以使用 if else 语句&#xff0c;例如&#xff1a; if a>b:max a; else:max b; 但是 Python 提供了一种更加简洁的写法&#xff0c;如下所示&#xff1a…

中国棒球青训基地建设·棒球1号位

随着中国棒球事业的发展&#xff0c;建设一批现代化的棒球青训基地已经成为了中国棒球发展的必然趋势。下面是有关中国棒球青训基地建设的课题报告&#xff1a; 一、基地选址和规划 中国棒球青训基地的选址应该优先考虑地理位置、气候条件、基础设施和交通便利等因素。基地应该…

OpenGL模型控制(旋转、平移)

1.效果图 2.平移 首先做一个鼠标双击事件&#xff0c;表示平移模型对象&#xff0c;当然&#xff0c;我们需要遍历当前哪个模型对象被选中&#xff0c;才能进行该对象的平移操作。 void AXBOpemglWidget::mouseDoubleClickEvent(QMouseEvent *event) {Q_UNUSED(event);if(m_m…

06- c语言指针 (C语言)

一 指针的引入 1、一般把内存中的一个字节称为一个内存单元。 2、为了正确地访问这些内存单元&#xff0c;必须为每个内存单元编上号。根据一个内存单元的编号即可准确地找到该内存单元。内存单元的编号也叫做地址&#xff0c;通常也把这个地址称为指针。 3、如果在程序中定义…

kubernetes入门案例

kubernetes入门案例 本文我们通过一个 Java Web 应用例子来介绍 kubernetes 的使用&#xff0c;可以让新手快速上手和实践。 此 Java Web 应用的结构比较简单&#xff0c;是一个运行在 Tomcat 里的 Web App&#xff0c;JSP 页面通过 JDBC 直接访问 MySQL 数据库并展示数据。…

975-操作系统内存管理课件(2)

基本分页存储管理 基本地址变换结构 具有快表的地址变换结构 两级页表