【基础】2、Surface的创建【Android 12】

文章详细解析了Android中SurfaceControl的初始化过程,从ViewRootImpl.relayoutWindow开始,经过Session.relayout、WindowManagerService.relayoutWindow、WindowManagerService.createSurfaceControl等步骤,最终在SurfaceFlinger服务端创建Layer。同时,介绍了BLASTBufferQueue的创建,包括创建SurfaceControl、BBQBufferQueue、BBQSurface等,以及如何与Surface关联。整个流程涉及了Binder通信、SurfaceFlinger和客户端间的交互。

在这里插入图片描述

文章目录


ViewRootImpl内部有两个成员变量:

    // These can be accessed by any thread, must be protected with a lock.
    // Surface can never be reassigned or cleared (use Surface.clear()).
    @UnsupportedAppUsage
    public final Surface mSurface = new Surface();
    private final SurfaceControl mSurfaceControl = new SurfaceControl();

跟踪一下向mSurface和mSurfaceControl初始化的流程。

一、SurfaceControl的初始化

1 ViewRootImpl.relayoutWindow

    private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
            boolean insetsPending) throws RemoteException {
   
   
        // ......

        int relayoutResult = mWindowSession.relayout(mWindow, params,
                (int) (mView.getMeasuredWidth() * appScale + 0.5f),
                (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
                insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
                mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
                mTempControls, mSurfaceSize);
        mPendingBackDropFrame.set(mTmpFrames.backdropFrame);
        if (mSurfaceControl.isValid()) {
   
   
            if (!useBLAST()) {
   
   
                mSurface.copyFrom(mSurfaceControl);
            } else {
   
   
                final Surface blastSurface = getOrCreateBLASTSurface();
                // If blastSurface == null that means it hasn't changed since the last time we
                // called. In this situation, avoid calling transferFrom as we would then
                // inc the generation ID and cause EGL resources to be recreated.
                if (blastSurface != null) {
   
   p n
                    mSurface.transferFrom(blastSurface);
                }
            }
			// ......
        } else {
   
   
            destroySurface();
        }

		// ......
    }

mWindowSession是IWindowSession的Binder远程代理对象,服务端的实现是Session,那么成员变量mSurfaceControl是通过Binder IPC,在系统进程中加载其中的内容的。

2 Session.relayout

    @Override
    public int relayout(IWindow window, WindowManager.LayoutParams attrs,
            int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber,
            ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
            SurfaceControl outSurfaceControl, InsetsState outInsetsState,
            InsetsSourceControl[] outActiveControls, Point outSurfaceSize) {
   
   
        if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from "
                + Binder.getCallingPid());
        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag);
        int res = mService.relayoutWindow(this, window, attrs,
                requestedWidth, requestedHeight, viewFlags, flags, frameNumber,
                outFrames, mergedConfiguration, outSurfaceControl, outInsetsState,
                outActiveControls, outSurfaceSize);
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to "
                + Binder.getCallingPid());
        return res;
    }

这里继续调用了WindowManagerService.relayoutWindow。

3 WindowManagerService.relayoutWindow

    public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
            int requestedWidth, int requestedHeight, int viewVisibility, int flags,
            long frameNumber, ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
            SurfaceControl outSurfaceControl, InsetsState outInsetsState,
            InsetsSourceControl[] outActiveControls, Point outSurfaceSize) {
   
   
		// ......
        synchronized (mGlobalLock) {
   
   
            // ......
            
            // Create surfaceControl before surface placement otherwise layout will be skipped
            // (because WS.isGoneForLayout() is true when there is no surface.
            if (shouldRelayout) {
   
   
                try {
   
   
                    result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
                }
                // ......
            }
            
            // ......
        }
    }

只关注outSurfaceControl的数据是如何填充的,这里继续调用WindowManagerService.createSurfaceControl方法。

4 WindowManagerService.createSurfaceControl

    private int createSurfaceControl(SurfaceControl outSurfaceControl, 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);
        } finally {
   
   
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
        if (surfaceController != null) {
   
   
            surfaceController.getSurfaceControl(outSurfaceControl);
            ProtoLog.i(WM_SHOW_TRANSACTIONS, "OUT SURFACE %s: copied", outSurfaceControl);

        } else {
   
   
            // For some reason there isn't a surface.  Clear the
            // caller's object so they see the same state.
            ProtoLog.w(WM_ERROR, "Failed to create surface control for %s", win);
            outSurfaceControl.release();
        }

        return result;
    }

有两个流程:

  • 调用WindowStateAnimator.createSurfaceLocked方法来创建一个WindowSurfaceController对象。

  • 调用WindowSurfaceController.getSurfaceControl来对outSurfaceControl赋值。

流程1涉及到Native层SurfaceControl的创建,需要跟踪完流程1才能知道流程2中的outSurfaceControl是怎么得到数据的。

5 WindowStateAnimator.createSurfaceLocked

    WindowSurfaceController createSurfaceLocked(int windowType) {
   
   
		// ......
        
        int flags = SurfaceControl.HIDDEN;
        final WindowManager.LayoutParams attrs = w.mAttrs;

        if (w.isSecureLocked()) {
   
   
            flags |= SurfaceControl.SECURE;
        }

        if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) {
   
   
            flags |= SurfaceControl.SKIP_SCREENSHOT;
        }
        
        // ......

        // Set up surface control with initial size.
        try {
   
   
			// ......

            mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), width,
                    height, format, flags, this, windowType);
			// ......
        }

		// ......

        return mSurfaceController;
    }

忽略非相关的内容,这里根据一些窗口的基本信息,如窗口名字、窗口宽高、窗口类型等,来创建一个WindowSurfaceController对象,并且赋值给WindowStateAnimator的mSurfaceController成员变量。

6 WindowSurfaceController.constructor

    WindowSurfaceController(String name, int w, int h, int format,
            int flags, WindowStateAnimator animator, int windowType) {
   
   
        mAnimator = animator;

        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(
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值