android 13 WMS/AMS系统开发-窗口层级相关SurfaceFlinger图层创建 第三节

创建Surfacelinger的图层堆栈打印添加:
更多内容qqun:422901085 https://ke.qq.com/course/5992266#term_id=106217431
代码位置:
frameworks/base/core/java/android/view/SurfaceControl.java

      /**
         * Set a debugging-name for the SurfaceControl.
         *
         * @param name A name to identify the Surface in debugging.
         */
        @NonNull
        public Builder setName(@NonNull String name) {
            mName = name;
            if (name != null && name.contains("DefaultTaskDisplayArea") || name.contains("ImePlaceholder") ) {
                android.util.Log.i("test1",this + "setName " + name,new Exception() );
            }
            return this;
        }

这里之对DefaultTaskDisplayArea,ImePlaceholder进行特殊过滤以防打印太多

Line   9965: 02-20 21:53:01.238   558   558 I test1   : android.view.SurfaceControl$Builder@c7e3d28setName DefaultTaskDisplayArea
	Line   9966: 02-20 21:53:01.238   558   558 I test1   : java.lang.Exception
	Line   9967: 02-20 21:53:01.238   558   558 I test1   : 	at android.view.SurfaceControl$Builder.setName(SurfaceControl.java:1249)
	Line   9968: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.DisplayContent.makeChildSurface(DisplayContent.java:5036)
	Line   9969: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.WindowContainer.makeChildSurface(WindowContainer.java:2419)
	Line   9970: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.WindowContainer.makeChildSurface(WindowContainer.java:2419)
	Line   9971: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.WindowContainer.makeChildSurface(WindowContainer.java:2419)
	Line   9972: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.WindowContainer.makeChildSurface(WindowContainer.java:2419)
	Line   9973: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.WindowContainer.makeSurface(WindowContainer.java:2408)
	Line   9974: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.WindowContainer.createSurfaceControl(WindowContainer.java:613)
	Line   9975: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.WindowContainer.onParentChanged(WindowContainer.java:594)
	Line   9976: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.TaskDisplayArea.onParentChanged(TaskDisplayArea.java:818)
	Line   9977: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.WindowContainer.setParent(WindowContainer.java:571)
	Line   9978: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:745)
	Line   9979: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicyBuilder$PendingArea.instantiateChildren(DisplayAreaPolicyBuilder.java:922)
	Line   9980: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicyBuilder$PendingArea.instantiateChildren(DisplayAreaPolicyBuilder.java:926)
	Line   9981: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicyBuilder$PendingArea.instantiateChildren(DisplayAreaPolicyBuilder.java:926)
	Line   9982: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicyBuilder$PendingArea.instantiateChildren(DisplayAreaPolicyBuilder.java:926)
	Line   9983: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicyBuilder$PendingArea.instantiateChildren(DisplayAreaPolicyBuilder.java:926)
	Line   9984: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicyBuilder$HierarchyBuilder.build(DisplayAreaPolicyBuilder.java:588)
	Line   9985: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicyBuilder$HierarchyBuilder.-$$Nest$mbuild(Unknown Source:0)
	Line   9986: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicyBuilder.build(DisplayAreaPolicyBuilder.java:333)
	Line   9987: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicy$DefaultProvider.instantiate(DisplayAreaPolicy.java:117)
	Line   9988: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.DisplayContent.configureSurfaces(DisplayContent.java:1143)
	Line   9989: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.DisplayContent.<init>(DisplayContent.java:1093)
	Line   9990: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.RootWindowContainer.setWindowManager(RootWindowContainer.java:1313)
	Line   9991: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.wm.ActivityTaskManagerService.setWindowManager(ActivityTaskManagerService.java:1006)
	Line   9992: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.am.ActivityManagerService.setWindowManager(ActivityManagerService.java:1923)
	Line   9993: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.SystemServer.startOtherServices(SystemServer.java:1595)
	Line   9994: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.SystemServer.run(SystemServer.java:939)
	Line   9995: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.server.SystemServer.main(SystemServer.java:649)
	Line   9996: 02-20 21:53:01.238   558   558 I test1   : 	at java.lang.reflect.Method.invoke(Native Method)
	Line   9997: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
	Line   9998: 02-20 21:53:01.238   558   558 I test1   : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:914)
	Line  10387: 02-20 21:53:01.245   558   558 I test1   : android.view.SurfaceControl$Builder@ef25bcasetName ImePlaceholder:13:14
	Line  10388: 02-20 21:53:01.245   558   558 I test1   : java.lang.Exception
	Line  10389: 02-20 21:53:01.245   558   558 I test1   : 	at android.view.SurfaceControl$Builder.setName(SurfaceControl.java:1249)
	Line  10390: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.DisplayContent.makeChildSurface(DisplayContent.java:5036)
	Line  10391: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.WindowContainer.makeChildSurface(WindowContainer.java:2419)
	Line  10392: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.WindowContainer.makeChildSurface(WindowContainer.java:2419)
	Line  10393: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.WindowContainer.makeChildSurface(WindowContainer.java:2419)
	Line  10394: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.WindowContainer.makeSurface(WindowContainer.java:2408)
	Line  10395: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.WindowContainer.createSurfaceControl(WindowContainer.java:613)
	Line  10396: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.WindowContainer.onParentChanged(WindowContainer.java:594)
	Line  10397: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.WindowContainer.onParentChanged(WindowContainer.java:581)
	Line  10398: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.WindowContainer.setParent(WindowContainer.java:571)
	Line  10399: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:745)
	Line  10400: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicyBuilder$PendingArea.instantiateChildren(DisplayAreaPolicyBuilder.java:922)
	Line  10401: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicyBuilder$PendingArea.instantiateChildren(DisplayAreaPolicyBuilder.java:926)
	Line  10402: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicyBuilder$PendingArea.instantiateChildren(DisplayAreaPolicyBuilder.java:926)
	Line  10403: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicyBuilder$PendingArea.instantiateChildren(DisplayAreaPolicyBuilder.java:926)
	Line  10404: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicyBuilder$HierarchyBuilder.build(DisplayAreaPolicyBuilder.java:588)
	Line  10405: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicyBuilder$HierarchyBuilder.-$$Nest$mbuild(Unknown Source:0)
	Line  10406: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicyBuilder.build(DisplayAreaPolicyBuilder.java:333)
	Line  10407: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.DisplayAreaPolicy$DefaultProvider.instantiate(DisplayAreaPolicy.java:117)
	Line  10408: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.DisplayContent.configureSurfaces(DisplayContent.java:1143)
	Line  10409: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.DisplayContent.<init>(DisplayContent.java:1093)
	Line  10410: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.RootWindowContainer.setWindowManager(RootWindowContainer.java:1313)
	Line  10411: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.wm.ActivityTaskManagerService.setWindowManager(ActivityTaskManagerService.java:1006)
	Line  10412: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.am.ActivityManagerService.setWindowManager(ActivityManagerService.java:1923)
	Line  10413: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.SystemServer.startOtherServices(SystemServer.java:1595)
	Line  10414: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.SystemServer.run(SystemServer.java:939)
	Line  10415: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.server.SystemServer.main(SystemServer.java:649)
	Line  10416: 02-20 21:53:01.245   558   558 I test1   : 	at java.lang.reflect.Method.invoke(Native Method)
	Line  10417: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
	Line  10418: 02-20 21:53:01.245   558   558 I test1   : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:914)

可以看出最后都会到达最顶层DisplayContent的makeChildSurface方法

@Override
    SurfaceControl.Builder makeChildSurface(WindowContainer child) {
        SurfaceSession s = child != null ? child.getSession() : getSession();
        final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(s).setContainerLayer();//注意这里都是容器type
        if (child == null) {
            return b;
        }
       // if (child.getName()!= null && child.getName().contains("DefaultTask")) {
            android.util.Log.i("test1","mSurfaceControl = " +mSurfaceControl + " child.getName() " + child.getName());
       // }
        return b.setName(child.getName())
                .setParent(mSurfaceControl);//返回一个Builder,但是这注意哈,它是会setParent,但是不要紧每个层级WindowContainer中会重新设置Parent
    }

那么对于我们层级结构可以得出以下结论
每addChild时候其实都会触发WindowContainer.onParentChanged,从而触发DisplayContent中创建对应的SurfaceControl,而且大家注意mWmService.makeSurfaceBuilder(s).setContainerLayer();创建出来的都是容器,而不是真正可以绘制的SurfaceControl

那么这里同学肯定有疑问?
请问那到底哪里才是真正的绘制画面的SurfaceControl呢?
这里其实我们前期知道app调用到wms的relayout才可以获取可以绘制画面的surfacecontrol,而且是wms端创建好传递回去的代码如下:

frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

   public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
            int requestedWidth, int requestedHeight, int viewVisibility, int flags,
            ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
            SurfaceControl outSurfaceControl, InsetsState outInsetsState,
            InsetsSourceControl[] outActiveControls, Bundle outSyncIdBundle) {

可以看到outSurfaceControl参数,这个就是wms端写入数据,然后app端的ViewRootImpl来进行读取的。
那么看看它是在方法中哪里被使用的:

  // 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);
                } catch (Exception e) {
                    displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/);

                    ProtoLog.w(WM_ERROR,
                            "Exception thrown when creating surface for client %s (%s). %s",
                            client, win.mAttrs.getTitle(), e);
                    Binder.restoreCallingIdentity(origId);
                    return 0;
                }
            }

调用是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();
        } 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;
    }

这里首先又调用到了winAnimator.createSurfaceLocked();

 WindowSurfaceController createSurfaceLocked() {
//ignore
  mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), format,
                    flags, this, attrs.type);
//ignore
}

调用到了WindowSurfaceController构造:

WindowSurfaceController(String name, 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()
                .setParent(win.getSurfaceControl())
                .setName(name)
                .setFormat(format)
                .setFlags(flags)
                .setMetadata(METADATA_WINDOW_TYPE, windowType)
                .setMetadata(METADATA_OWNER_UID, mWindowSession.mUid)
                .setMetadata(METADATA_OWNER_PID, mWindowSession.mPid)
                .setCallsite("WindowSurfaceController");//此时其实还是属于Container,因为DisplayerContent创建

        final boolean useBLAST = mService.mUseBLAST && ((win.getAttrs().privateFlags
                & WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0);

        if (useBLAST) {
            b.setBLASTLayer();//非常关键,变成非Container
        }

        mSurfaceControl = b.build();

        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }

哈哈,是不是终于看到对应的代码了图层Buffer图层type而不是Container的type

<think>好的,用户想了解jCanvas的addLayer方法的使用示例和教程。首先,我需要回忆一下jCanvas的相关文档和引用内容。根据提供的引用,特别是引用[1],提到有两种方式添加图层:使用addLayer()方法然后drawLayers(),或者在绘图方法中设置layer属性为true。用户的问题是关于addLayer的,所以应该重点讲解第一种方法。 首先,我应该解释addLayer的基本用法,比如如何创建图层,设置属性如name、visible等。然后,给出一个具体的代码示例,展示如何添加图层并在上面绘制对象。需要确保代码符合用户提到的jCanvas语法,比如使用$('canvas')选择器,并正确调用方法。 接下来,可能需要说明图层的管理,比如如何隐藏或显示图层,引用[2]提到使用setLayer设置visible属性,然后调用drawLayers()。这也应该包含在示例中,让用户了解如何动态控制图层。 另外,用户可能关心图层的叠加顺序,或者如何在不同的图层上绘制不同的元素,比如矩形和圆形。需要确保示例中有多个图层,并演示它们的叠加效果。同时,注意每个图层只能有一个对象,如引用[1]所述,可能需要提醒用户这一点,避免他们在同一图层添加多个对象导致问题。 还要检查是否需要引入jQuery和jCanvas库,确保示例的完整性。可能需要在代码开头添加相关的脚本引用,帮助用户正确设置环境。 最后,总结addLayer方法的优点,比如更好的组织结构、单独控制等,并生成相关问题,引导用户进一步学习。需要确保问题覆盖常见的使用场景,比如性能优化、事件处理等,但根据引用内容,现有的引用中没有提到这些,可能需要避免超出引用范围的问题。</think>### jCanvas 的 `addLayer` 方法使用示例教程 jCanvas 的 `addLayer()` 方法用于向画布添加图层,实现分层绘制与管理[^1]。以下是具体用法示例及说明: --- #### **1. 基础用法** ```javascript // 添加图层并命名 $('canvas').addLayer({ name: 'myLayer', // 必填,图层唯一标识 visible: true, // 是否可见(默认true) // 绘制矩形 type: 'rectangle', fillStyle: '#3498db', x: 100, y: 100, width: 200, height: 100 }).drawLayers(); // 必须调用 drawLayers() 渲染图层 ``` - **说明**:`addLayer()` 接受一个包含图层属性和绘制参数的对象。`name` 属性是必需的,用于后续操作(如隐藏、修改)。调用 `drawLayers()` 后,图层内容才会显示。 --- #### **2. 多图层叠加示例** ```javascript // 添加背景层 $('canvas').addLayer({ name: 'background', type: 'rectangle', fillStyle: '#ecf0f1', x: 0, y: 0, width: 500, height: 300 }); // 添加前景层(圆形) $('canvas').addLayer({ name: 'foreground', type: 'arc', fillStyle: '#e74c3c', x: 250, y: 150, radius: 50 }).drawLayers(); ``` - **说明**:图层按添加顺序堆叠,后添加的图层覆盖先前的图层。通过分层可独立控制元素样式与行为[^1]。 --- #### **3. 动态控制图层可见性** ```javascript // 隐藏名为 "foreground" 的图层 $('canvas').setLayer('foreground', { visible: false }).drawLayers(); // 重新显示图层 $('canvas').setLayer('foreground', { visible: true }).drawLayers(); ``` - **说明**:通过 `setLayer()` 修改图层属性(如 `visible`),再调用 `drawLayers()` 更新画布[^2]。 --- #### **4. 注意事项** - **每个图层仅支持一个对象**:若需在同一图层绘制多个对象,需通过组合图形(如 `group`)实现。 - **性能优化**:频繁操作图层时,建议批量修改属性后统一调用 `drawLayers()`。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值