Hello,大家好,我是爱吃香蕉的猴子,记录一下SurfaceView的理论基础


surface是一个接口,供生产方和消耗方交换缓冲区;

用于显示 Surface 的 BufferQueue 通常配置为三重缓冲。缓冲区是按需分配的,因此,如果生产方足够缓慢地生成缓冲区(例如在 60 fps 的显示屏上以 30 fps 的速度进行缓冲),队列中可能只有两个分配的缓冲区。按需分配缓冲区有助于最大限度地减少内存消耗。您可以在 dumpsys SurfaceFlinger 的输出中看到每个层级关联的缓冲区的摘要。

SurfaceHolder 是系统用于与应用共享 Surface 所有权的接口。与 Surface 配合使用的一些客户端需要 SurfaceHolder,因为用于获取和设置 Surface 参数的 API 是通过 SurfaceHolder 实现的。一个 SurfaceView 包含一个 SurfaceHolder。

SurfaceView 是一个组件,可用于在 View 层次结构中嵌入其他合成层。SurfaceView 采用与其他 View 相同的布局参数,因此可以像对待其他任何 View 一样对其进行操作,但 SurfaceView 的内容是透明的。

当 SurfaceView 的 View 组件即将变得可见时,框架会要求 SurfaceControl 从 SurfaceFlinger 请求新的 surface。如需在创建或销毁 Surface 时收到回调,请使用 SurfaceHolder 接口。默认情况下,新创建的 Surface 放置在应用界面 Surface 的后面。您可以替换默认的 Z 轴顺序,将新的 Surface 放在前面。

在需要渲染到单独的 Surface(例如,使用 Camera API 或 OpenGL ES 上下文进行渲染)时,使用 SurfaceView 进行渲染很有帮助。使用 SurfaceView 进行渲染时,SurfaceFlinger 会直接将缓冲区合成到屏幕上。如果没有 SurfaceView,您需要将缓冲区合成到屏幕外的 Surface,然后该 Surface 会合成到屏幕上,而使用 SurfaceView 进行渲染可以省去额外的工作。使用 SurfaceView 进行渲染后,请使用界面线程与 Activity 生命周期相协调,并根据需要调整 View 的大小或位置。然后,硬件混合渲染器会将应用界面与其他层混合在一起。

新的 Surface 是 BufferQueue 的生产方,其使用方是 SurfaceFlinger 层。您可以通过任何可向 BufferQueue 馈送资源的机制更新 Surface,例如,使用提供 Surface 的 Canvas 函数、附加 EGLSurface 并使用 GLES 在 Surface 上绘制,或者配置媒体解码器以写入 Surface。

https://source.android.google.cn/devices/graphics/arch-sv-glsv

在Activity 中 内嵌 SurfaceView的情况下 , UI 是如何绘制的?

  1. Activity 中ViewRoot 自带一个surface,我们叫它aSurface; SurfaceView 也自带一个surface,我们叫它mSurface。
  2. UI 绘制在这个两个surface中进行,surface是按照Z 轴进行Layer 分层的,aSurface 的Z 轴值大于mSurface,所以它们的分层如图:mSurface 躲在aSurface的后面。
    3)aSurface 躲在后面是如何显示的呢?SurfaceView 会对他的所有Parent 设置一个透明块,然后我们就看到了SurfaceView了。
    在这里插入图片描述
                                    Code的搬运工V1.0
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐