Android Display Graphics #2 整体框架介绍二

系列文章请扫关注公众号!

1、Android 图形元素

不管开发的小伙伴使用系统的哪个API显示内容,最终都会将显示内容渲染到surface上。前面说了,Surface理解为存储数据的内存块,实际上Surface表示缓冲区队列BufferQueue的生产者角色,而缓冲区队列BufferQueue一般被SurfaceFlinger消费掉,也就是说SurfaceFlinger扮演的是缓冲区队列BufferQueue的消费者。

Android平台上创建的每一个窗口都由Surface提供支持的。所有被渲染的可见的Surface都被SurfaceFlinger合成并送显到Display上。

协作图如下:

上图的系统架构是生产者-消费者模式,从上到下的层次:

  1. Image Stream Producers

•  图像数据的生产者,可以是Media Player视频解码器,Camera预览,NDK调用,OpenGL ES接口。可以分为两类数据的传输,一个是真正的显示帧数据BufferData,即Surface,通过BufferQueue的方式调用libgui的接口入队。一个是窗口信息的传递WindowMetadata,即窗口的大小,位置等。

•  例如view每次执行lockCanvas->draw->unlockCanvas,会存入一帧数据进入BufferQueue中。

  1. Native Framework

•  Framework对上层提供的接口在libgui中,frameworks/native/libs/gui。在这里可以操作Surface出队入队Buffer队列BufferQueue。实现Buffer的生成和BufferQueue数据跨进程之间的传递。

  1. WindowManager

• 计算窗口大小,位置等,并传递相应的参数到SurfaceFlinger,SurfaceFlinger根据这些Window Metadata信息,设置窗口Window的大小、z-order等。

  1. Image Stream Consumers

• 代表的是图像数据的消费者。SurfaceFlinger消耗的是BufferQueue中visible的Surface,并使用WindowManager中的Metadata信息对这些Surface进行合成。SurfaceFlinger是可以修改显示内容的唯一服务,也是显示系统中承上启下的核心服务。

•  SurfaceFlinger 使用 OpenGL 和 Hardware Composer 来合成一组 Surface。OpenGL ES 应用也可以消耗图像流,例如相机应用会消耗相机预览图像流。非 GL 应用也可以是消费者,例如 ImageReader。

5、HAL 硬件混合渲染器

•  这块主要如前一节介绍的HWC,DPU相关。一块是Hardware Composer也用于合成和送显。当SurfaceFlinger中合成的图层时,会请求composer合成,因为它合成的快,功耗又低。如果合成的layer数大于composer支持的最大数了,那剩下的就让SurfaceFlinger通过GPU合成,最后统一送给HardwareComposer送显。

•  SurfaceFlinger在请求HWC Composer合成时,本身充当了一个OpenGL ES的client端。

•  Gralloc 是系统图像显示的内存分配器,用来分配图像生产者请求的内存。和系统的ION是有关的。

GraphicBuffer介绍

应用有显示需求时,应用会向系统申请一块GraphicBuffer内存,这块内存将会共享给GPU用于执行渲染工作,接着会同步给HWC用于合成和显示。

GraphicBuffer是Display系统中的显示内存管理类,在APP、SurfaceFlinger、HardwareComposer之间传递。渲染和合成操作都将在GraphicBuffer上进行的。

定义在/frameworks/native/libs/ui/include/ui/GraphicBuffer.h

class GraphicBuffer

     : public ANativeObjectBase<ANativeWindowBuffer, GraphicBuffer, RefBase>,

       public Flattenable<GraphicBuffer>

{

    friend class Flattenable<GraphicBuffer>;

public:

......

static sp<GraphicBuffer> from(ANativeWindowBuffer *);

static GraphicBuffer* fromAHardwareBuffer(AHardwareBuffer*);

static GraphicBuffer const* fromAHardwareBuffer(AHardwareBuffer const*);

     AHardwareBuffer* toAHardwareBuffer();

     AHardwareBuffer const* toAHardwareBuffer() const;

     // Create a GraphicBuffer to be unflatten'ed into or be reallocated.

     GraphicBuffer();

    // Create a GraphicBuffer by allocating and managing a buffer internally.

     // This function is privileged.  See reallocate for details.

     GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,

             uint32_t inLayerCount, uint64_t inUsage,

             std::string requestorName = "<Unknown>");

......

}

可以与ANativeWindowBufferAHardwareBuffer相互转换。上层JNI的调用封装在android_hardware_HardwareBuffer.cppandroid_graphics_GraphicBuffer.cpp 

Libgui.so中有广泛使用这个对象,并将封装在一个Surface中,例如

/frameworks/native/libs/gui/Surface.cpp

Surface::attachBuffer函数将Surface与GraphicBuffer attached。

GraphicBuffer 的分配和回收由gralloc管理。

Fence机制

一个GraphicBuffer对象完整的生命周期大概是这样:

  • 渲染阶段:应用有绘图需求了,由GPU分配一块内存给应用,应用调用GPU执行绘图,此时使用者是GPU
  • 合成阶段:GPU渲染完成后将图层传递给sf进程,sf进程决定由谁来合成,hwc或者GPU 
    • 如果使用GPU合成,那么此时buffer的使用者依旧是GPU
    • 如果使用hwc合成,那么此时buffer的使用者是hwc
  • 显示阶段:所有的buffer在此阶段的使用者都是hwc,因为hwc控制着显示芯片

从生命周期可以看出GraphicBuffer对象在流转的过程中,会被GPU、CPU、DPU三个不同的硬件访问,此时需要一个同步机制。用来保证跨硬件访问时的数据安全。可以把Fence理解为一把硬件的互斥锁。

每个需要访问GraphicBuffer的角色,在使用前都要检查这把锁是否signaled了才能进行安全的操作,否则就要等待。

  • active状态,该GraphicBuffer正在被占用
  • signaled状态,表明不再控制buffer

BufferQueue

GraphicBuffer的queue队列,BufferQueue的引入是为了解决性能问题。如果只有一个Buffer,是不合理的,因为在渲染、合成、送显这个相当于线性执行,效率太低。所以就有了double和triple缓冲机制,相当于有的Buffer在渲染的同事,另外Buffer可以合成、送显。这样就提高了效率。

Surface的概念是对APP进程讲的,Layer是对系统进程讲的,例如SurfaceFlinger。

前面说的生产者-消费者模型,对于BufferQueue来说就是

这里的producer就是前面说的各app,当app create一个Surface时就向BufferQueue队列申请一个buffer,这个过程称为dequeue。当app绘制(渲染)好这个Surface后就放入BufferQueue中,这个过程称为queue。

这里的Consumer如上面说的,对于可见layer,它就是SurfaceFlinger。当buffer 放入BufferQueue后,通知SurfaceFlinger消费。SurfaceFlinger从BufferQueue拿buffer的过程称为acquire。当SurfaceFlinger合成完后,就将buffer释放并放回BufferQueue中,这个过程称为release。

声明和定义在libgui.so中 /frameworks/native/libs/gui/include/gui/BufferQueue.h

class BufferQueue {

static void createBufferQueue(sp<IGraphicBufferProducer>* outProducer,

            sp<IGraphicBufferConsumer>* outConsumer,

            bool consumerIsSurfaceFlinger = false);

}

创建BufferQueue时需要传入producer和Consumer。

GraphicBuffer在producer、BufferQueue、Consumer之间传递,是有状态的。GraphicBuffer就是在不断地循环FREE->DEQUEUED->QUEUED->ACQUIRED->FREE这个过程。

数据流

。。。。。。

2、Google组件库

。。。。。。。

详细全文关注公众号查看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值