• Android图形-组件-比较与理解


    目录

    引言

    BufferQueue 和 Gralloc

    概念

    源码位置:

    图形缓冲区的流转情况:

    BufferQueue 的特性:

    BufferQueue的跟踪工具-systrace:

    Gralloc

    受保护的缓冲区

    Surface 和 SurfaceHolder

    Canvas rendering

    SurfaceHolder

    SurfaceView 和 GLSurfaceView

    类的继承:

    SurfaceView 和 TextureView的区别

    SurfaceFlinger 和 WindowManager

    概念

    Surfaceflinger

    WindowManager


    引言

    从架构层面大致了解Android图形的概览,接下来先对一些组件进行更具体深入的理解

    BufferQueue 和 Gralloc
    Surface 和 SurfaceHolder
    SurfaceView 和 GLSurfaceView
    SurfaceFlinger 和 WindowManager

    BufferQueue 和 Gralloc

    概念

    Bufferqueue :连接 图像流的生产者和消费者,几乎所有的图形数据缓冲区的内容都依赖于BufferQueue
    Gralloc 内存分配器会进行缓冲区分配,并通过两个特定于供应商的 HIDL 接口来进行实现。

    源码位置:

    hardware/interfaces/graphics/allocator/

    hardware/interfaces/graphics/mapper/

    allocate() 函数采用预期的参数(宽度、高度、像素格式)以及一组用法标志。

    图形缓冲区的流转情况:

    主要是在生产者和消费者模型中,对BufferQueue的操作,伴随者缓冲区的流转。包括生产者对缓冲区的出列入列操作,消费者对缓冲区的获取和释放操作。

    1)消费者创建并拥有BufferQueue的数据结构,并且可以存在与其他生产者不同的进程中
    2)dequeueBuffer():生产者从 BufferQueue 请求一个可用的缓冲区,并指定缓冲区的宽度、高度、像素格式和用法标志
    3)queueBuffer():生产者填充好缓冲区后,调用该函数将缓冲区返回到队列。
    4)acquireBuffer():消费者获取缓冲区并使用缓冲区的内容
    5)releaseBuffer():消费者用完缓冲区后,调用改函数将缓冲区返回到队列。
    注意:同步框架可控制缓冲区在 Android 图形pipeline中移动的方式。

    BufferQueue 的特性:

    1)如果生产者请求具有不同大小的缓冲区,系统会释放旧的缓冲区,并根据需要分配新的缓冲区。
    2)缓冲区始终通过句柄进行传递而不是通过复制的方式来进行传递。

    BufferQueue的跟踪工具-systrace:

    1)如需了解图形缓冲区如何移动,请使用 Systrace。系统级的图形代码插入了埋点信息都经过充分检测的。
    2)启用gfx、view 和 sched 标记。如:$ python systrace.py -o mynewtrace.html sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory

    Gralloc

    Gralloc 分配器 HAL

    头文件路径:hardware/libhardware/include/hardware/gralloc.h

    通过用法标志执行缓冲区分配。
    用法标志包括以下属性:
    1)从软件 (CPU) 访问内存的频率
    2)从硬件 (GPU) 访问内存的频率
    3)是否将内存用作 OpenGL ES (GLES) 纹理
    4)视频编码器是否会使用内存

    受保护的缓冲区

    Gralloc 用法标志 GRALLOC_USAGE_PROTECTED 允许仅通过受硬件保护的路径显示图形缓冲区。这些叠加平面是显示 DRM (Digital Rights Management数字版权管理)内容的唯一途径(SurfaceFlinger 或 OpenGL ES 驱动程序无法访问受 DRM 保护的缓冲区)。受 DRM 保护的视频只能在叠加平面上呈现。支持受保护内容的视频播放器必须使用 SurfaceView实现。在不受保护的硬件上运行的软件无法读取或写入缓冲区;受硬件保护的路径必须显示在硬件混合渲染器叠加层上(也就是说,如果硬件混合渲染器切换到 OpenGL ES 合成,受保护的视频将从屏幕中消失)。

    Surface 和 SurfaceHolder

    概念

    应用的图像要显示到屏幕上,需要先在Surface对象上进行渲染

    SurfaceHolder接口就可以编辑和控制Surface的大小,格式等。

    Java的类继承:

    1. public class Surface
    2. extends Object implements Parcelable
    3. java.lang.Object
    4.        android.view.Surface
    1. public interface SurfaceHolder
    2. android.view.SurfaceHolder

    大多数客户端使用 OpenGL ES 或 Vulkan 渲染到 Surface 上。但是,有些客户端使用 Canvas 渲染到 Surface 上

    Canvas rendering

    Canvas由Skia图形库提供。

    带锁的Canvas:
    1)lockCanvas() 可锁定缓冲区以在 CPU 上渲染,并返回用于绘图的画布。
    2)unlockCanvasAndPost() 可解锁缓冲区并将其发送到合成器。
    3)lockHardwareCanvas() 可锁定缓冲区以在 GPU 上渲染,并返回用于绘图的画布。
    注意:当应用通过 lockCanvas() 锁定 Surface 时,所获得的画布一概不会获得硬件加速。
    注意:如果您曾调用过 lockCanvas(),则无法使用 GLES 在 Surface 上绘图或从视频解码器向其发送帧。lockCanvas() 会将 CPU 渲染程序连接到 BufferQueue 的生产方,直到 Surface 被销毁时才会断开连接。与大多数生产方(如 GLES 或 Vulkan)不同,基于画布的 CPU 渲染程序无法在断开连接后重新连接到 Surface。
     

    SurfaceHolder

    SurfaceHolder 是系统用于与应用共享 Surface 所有权的接口。
    与 Surface 配合使用的一些客户端需要 SurfaceHolder,因为用于获取和设置 Surface 参数的 API 是通过 SurfaceHolder 实现的。
    一个 SurfaceView 包含一个 SurfaceHolder。
    与 View 交互的大多数组件都涉及到 SurfaceHolder。
    一些其他 API(如 MediaCodec)将在 Surface 本身上运行。

    SurfaceView 和 GLSurfaceView

    类的继承

    1. public class View
    2. extends Object implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource
    3. java.lang.Object
    4. ↳ android.view.View
    1. public class SurfaceView
    2. extends View
    3. java.lang.Object
    4. ↳ android.view.View
    5. ↳ android.view.SurfaceView

    如需在创建或销毁 Surface 时收到回调,请使用 SurfaceHolder 接口。
    默认情况下,新创建的 Surface 放置在应用界面 Surface 的后面。您可以替换默认的 Z 轴顺序,将新的 Surface 放在前面。
    在需要渲染到单独的 Surface(例如,使用 Camera API 或 OpenGL ES 上下文进行渲染)时,使用 SurfaceView 进行渲染很有帮助。
    使用 SurfaceView 进行渲染时,SurfaceFlinger 会直接将缓冲区合成到屏幕上。
    使用 SurfaceView 进行渲染后,请使用界面线程与 activity 生命周期相协调,并根据需要调整 View 的大小或位置。然后,HWC会将应用界面与其他层混合在一起。

    SurfaceView 和 TextureView的区别

    1. public class TextureView
    2. extends View
    3. java.lang.Object
    4. ↳ android.view.View
    5. ↳ android.view.TextureView

    SurfaceView 采用与其他 View 相同的参数,但 SurfaceView 内容在呈现时是透明的。
    TextureView使用OpenGLES渲染

    TextureView 具有更出色的 Alpha 版和旋转处理能力,但在视频上以分层方式合成界面元素时,SurfaceView 具有性能方面的优势。
    当客户端使用 SurfaceView 呈现内容时,SurfaceView 会为客户端提供单独的合成层。如果设备支持,SurfaceFlinger 会将单独的层合成为硬件叠加层。
    当客户端使用 TextureView 呈现内容时,界面工具包会使用 GPU 将 TextureView 的内容合成到视图层次结构中。
    对内容进行的更新可能会导致其他 View 元素重绘,例如,在其他 View 被置于 TextureView 顶部时。View 呈现完成后,SurfaceFlinger 会合成应用界面层和所有其他层,以便每个可见像素合成两次。
    注意:受 DRM 保护的视频只能在叠加平面上呈现。支持受保护内容的视频播放器必须使用 SurfaceView 实现。

    SurfaceFlinger 和 WindowManager

    概念

    Surfaceflinger接受缓冲区,对他们进行合成,然后发送到屏幕。
    WindowManager为Surfaceflinger提供缓冲区和窗口Metadata,Surfaceflinger可以使用这些信息将Surface合成到屏幕

    Surfaceflinger

    在收集可见层的所有缓冲区后,便会询问HWC如何进行合成。如果HWC将层合成类型标记为Client合成,则Surfaceflinger将合成这些层,然后Surfaceflinger会将输出缓冲区传递给HWC

    WindowManager

    WindowManager会控制window对象,他们是用于容纳view的对象容器。window对象始终由Surface对象提供支持。
    WindowManager会监督生命周期,输入和聚焦事件,屏幕方向,转换,动画,位置,Z轴顺序以及窗口的许多方面。
    WindowManager会将所有窗口的Metadata发送到Surfaceflinger

    1. public abstract class Window
    2. extends Object
    3. java.lang.Object
    4. ↳ android.view.Window

  • 相关阅读:
    为什么MySQL默认的隔离级别是RR而大厂使用的是RC?
    Mybatis框架的搭建和基本使用
    冯诺伊曼体系结构和操作系统
    Remmina中VNC、SSH和RDP的区别
    【HCIE】01.IGP高级特性
    我又和redis超时杠上了
    多少得有点升级,才能对得起价格!iPhone15系列电池寿命见长
    c/c++实现网格最短路径问题
    XML快速入门
    【[USACO06NOV]Corn Fields G】【状压DP】
  • 原文地址:https://blog.csdn.net/haigand/article/details/132698630