libsync
源代码位于:system/core/libsync。
主要提供sync_wait、sync_merge两个接口分别用来等待、合并fence。fence由文件描述符表示。
window.h
源代码位于:system/core/include/system/window.h。
定义了本地窗口缓存和本地窗口类,用于和EGL对接。
android_native_base_t,是本地对象的虚基类,但是使用C语言方式定义。
| 成员 | 类型 | 说明 |
| magic | int | EGL本地类型的魔术数字 |
| version | int | EGL本地类型的实际大小 |
| incRef | void(*) | 增加引用计数,虚函数 |
| dump | void(*) | 减少引用计数,虚函数 |
ANativeWindowBuffer(android_native_buffer_t)描述本地窗口缓存。
| 成员 | 类型 | 说明 |
| common [继承] | android_native_base_t | 魔术数字:ANDROID_NATIVE_BUFFER_MAGIC |
| incStrong | void(void const *) | 支持智能指针sp<T> |
| decStrong | void(void const *) | 支持智能指针sp<T> |
| width、height | int | 图像尺寸 |
| stride | int | |
| format | int | 图像格式 |
| usage | int | |
| handle | buffer_handle_t | 内存句柄,实际类型const native_handle_t* |
ANativeWindow(android_native_window_t)描述本地窗口。
| 成员 | 类型 | 说明 |
| common [继承] | android_native_base_t | 魔术数字: ANDROID_NATIVE_WINDOW_MAGIC |
| incStrong | void(void const *) | 支持智能指针sp<T> |
| decStrong | void(void const *) | 支持智能指针sp<T> |
| flags | const uint32_t | Surface或者渲染者属性 |
| minSwapInterval | const int | 渲染者支持最小渲染周期 |
| maxSwapInterval | const int | 渲染者支持最大渲染周期 |
| xdpi、ydpi | const float | 每英寸点数(DPI) |
| oem | intptr_t[4] | 厂商自定义数据 |
| setSwapInterval | int(int) | 设置Surface交换周期 |
| dequeueBuffer | int(ANativeWindowBuffer**) | 获取缓存用作渲染,废弃的 |
| lockBuffer | int(ANativeWindowBuffer*) | 在修改缓存前调用,废弃的 |
| queueBuffer | int(ANativeWindowBuffer*) | 修改完成后调用,废弃的 |
| cancelBuffer | int(ANativeWindowBuffer*) | 丢弃获取的缓存,废弃的 |
| query | int(int, int*) | 获取窗口指定的信息 |
| perform | int(int, …) | 执行指定的操作 |
| dequeueBuffer | int(ANativeWindowBuffer**, init*) | 获取缓存用作渲染,需要在修改缓存前等待Fence |
| queueBuffer | int(ANativeWindowBuffer*,int) | 修改完成后调用 |
| cancelBuffer | int(ANativeWindowBuffer*,int) | 丢弃获取的缓存,可能直接用之前拿到的Fence |
ANativeObjectBase用来帮助实现android_native_base_t的引用计数管理。后面的ANativeWindowBuffer、ANativeWindow的派生类都是通过ANativeObjectBase间接继承父类的。
实现ANativeWindowBuffer的类有NativeBuffer(FramebufferNativeWindow.cpp中),另一个是GraphicBuffer。
实现ANativeWindow的类有FramebufferNativeWindow,另一个是Surface。
opengl
源代码位于:frameworks/native/opengl/。
| 库 | 源代码子目录 | 说明 |
| libEGL.so | libs/EGL | EGL库,OpenGL ES库的封装 |
| libGLESv1_CM.so | libs/GLES_CM | OpenGL ES库的封装 |
| libGLESv2.so | libs/GLES2 | OpenGL ES 2.0库的封装 |
| egl/libGLES_android.so | libagl | 基于Android平台的软件实现方案 |
| egl/libGLES_*.so | 硬件厂商实现 | 硬件实现,有这个,就不需要后面三个了 |
| egl/libEGL_*.so | 硬件厂商实现 | 硬件实现 |
| egl/libGLESv1_*_CM.so | 硬件厂商实现 | 硬件实现 |
| egl/libGLESv2_*.so | 硬件厂商实现 | 硬件实现 |
libui
源代码位于:frameworks/native/libs/ui。
头文件位于:frameworks/native/include/ui。

Fence类封装了驱动fence描述符,通过继承Flattenable能够跨进程传递Fence对象。
GraphicBufferAllocator封装了alloc_device_t的缓存申请、释放功能。已经申请的缓存记录在数组sAllocList中。
GraphicBufferMapper封装了gralloc_module_t的缓存注册、注销、锁定、解锁功能。
GraphicBuffer继承实现了ANativeWindowBuffer,管理缓存的申请释放已经跨进程传递(使用util库的Flattenable管理进程传递)。GraphicBuffer对缓存的持有分为持有数据和持有句柄两种情形。自己申请的为持有数据,跨进程传递过来的为持有句柄。这两种情形下释放方式不同。
GraphicBuffer也可以持有外部的ANativeWindowBuffer,并使用引用计数管理。ANativeWindowBuffer使用android_native_base_t的引用管理机制,为此GraphicBuffer通过ANativeObjectBase将引用计数实现在RefBase上。
FramebufferNativeWindow类继承实现ANativeWindow。通过framebuffer HAL设备实现GL本地窗口。除了调用gralloc申请并管理缓存,调用framebuffer交换缓存,还处理了的fence的同步。
libgui
源代码位于:frameworks/native/libs/gui。
头文件位于:frameworks/native/include/gui。
libgui 包含图形GUI系统的基础组件:BufferQueue、Consumer、Surface;也包含SurfaceFlinger客户端的代理类Composer、SurfaceComposerClient、SurfaceControl、Surface。

BufferQueue继承BnGraphicBufferProducer、BnGraphicBufferConsumer,也就是实现了IGraphicBufferProducer、IGraphicBufferConsumer接口。他并不是生产者,消费者,而是为生产者、消费者提供访问BufferQueue的接口。
IGraphicBufferProducer的成员:
| 成员 | 类型 | 说明 |
| requestBuffer | status_t (int, sp<GraphicBuffer>*) | 请求指定slot的缓存,获取实际句柄,与dequeue分两步做,减少传递句柄消耗 |
| setBufferCount | status_t (int) | 设置可以slot数目,会清空所有缓存 |
| dequeueBuffer | status_t (int*, sp<Fence>*, bool, uint32_t, uint32_t, int32_t,uint32_t) | 获取一个缓存slot,可能返回BUFFER_NEEDS_REALLOCATION,此时需要重新requestBuffer |
| queueBuffer | status_t (int, const QueueBufferInput&, QueueBufferOutput*) | 返回缓存,缓存已经填充数据 |
| cancelBuffer | void(int,const sp<Fence>&) | 返回缓存,缓存数据丢弃 |
| query | int (int, int*) | 查询Surface信息 |
| connect | status_t (const sp<IBinder>&, int, bool, QueueBufferOutput*) | 客户端连接,需要在其他接口前调用 |
| disconnect | status_t(int) | 客户端端口连接 |
IGraphicBufferConsumer的成员:
| 成员 | 类型 | 说明 |
| acquireBuffer | status_t(BufferItem*, nsecs_t) | 获取缓存 |
| releaseBuffer | status_t( int, uint64_t, EGLDisplay, EGLSyncKHR, const sp<Fence>&) | 释放缓存 |
| consumerConnect | status_t(const sp<IConsumerListener>&, bool) | 消费者连接 |
| consumerDisconnect | status_t () | 消费者断开 |
| getReleasedBuffers | status_t(uint32_t*) | 获取已经释放的缓存列表,在onBuffersReleased中调用 |
| setDefaultBufferSize | status_t(uint32_t, uint32_t) | 设置deque返回的默认缓存尺寸 |
| setDefaultMaxBufferCount | status_t(int) | 设置默认最大缓存个数,生产者可以setBufferCount覆盖 |
| disableAsyncBuffer | status_t () | 同时设置了isControlledByApp的情况下,使用非阻塞模式 |
| setMaxAcquiredBufferCount | status_t (int) | 设置消费者最大持有缓存数目 |
| setConsumerName | void (const String8&) | 设置消费者名字,用于日志 |
| setDefaultBufferFormat | status_t(uint32_t) | 设置deque返回的默认缓存图像格式 |
| setConsumerUsageBits | status_t (uint32_t) | 设置deque额外的缓存使用标志 |
| setTransformHint | status_t (uint32_t) | 设置缓存旋转角度 |
| dump | void (String8&, const char*) |
ConsumerListener的成员:
| 成员 | 类型 | 说明 |
| onFrameAvailable | void () | 从queueBuffer中调用,异步原来队列空,或者同步 |
| onBuffersReleased | void () | 当消费者持有的缓存被释放了 |
在BufferQueue的内部,缓存存放在数组中,数组单元是BufferSlot。生产者将缓存排队之后,缓存存放在队列中,先入先出,队列单元为BufferItem。
BufferSlot的成员:
| 成员 | 类型 | 说明 |
| mGraphicBuffer | sp<GraphicBuffer> | 缓存, |
| mEglDisplay | EGLDisplay | 用于创建EGLSyncKHR对象 |
| mBufferState | BufferState | 状态FREE、DEQUEUED、QUEUED 、ACQUIRED |
| mRequestBufferCalled | bool | 校验生产者确实调用过requestBuffer |
| mFrameNumber | uint64_t | 队列排队号,用于dequeue时LRU |
| mEglFence | EGLSyncKHR | EGL 同步对象,dequeue时要等待 |
| mFence | sp<Fence> | 等待缓存先前所有者完成工作的同步对象 |
| mAcquireCalled | bool | 是否被消费者拿到过 |
| mNeedsCleanupOnRelease | bool | 当缓存在ACQUIRED状态被释放时设置 |
BufferItem的成员:
| 成员 | 类型 | 说明 |
| mGraphicBuffer | sp<GraphicBuffer> | 缓存, |
| mFence | sp<Fence> | 访问Fence |
| mCrop | Rect | 当前剪裁区域 |
| mTransform | uint32_t | 当前slot转换Flags |
| mScalingMode | uint32_t | 当前slot缩放模式 |
| mTimestamp | int64_t | 当前slot时间戳,queueBuffer设置 |
| mIsAutoTimestamp | bool | 时间戳是否是排队时自动设置 |
| mFrameNumber | uint64_t | 当前slot已经排队过的帧数 |
| mBuf | int | slot编号 |
| mIsDroppable | bool | 是否可以丢弃,保证dequeue不阻塞 |
| mAcquireCalled | bool | 是否被消费者拿到 |
| mTransformToDisplayInverse | bool | 转换方向后是否再翻转 |
ConsumerBase是消费者的基类,也实现了ConsumerListener与BufferQueue连接。ConsumerBase还管理已经获取的缓存。
BufferItemConsumer继承ConsumerBase,允许调用者访问整个BufferItem。支持同时持有多个缓存,支持同步(等待)、异步模式。
CpuConsumer继承ConsumerBase,是一个软件消费者,用LockedBuffer表示锁定的缓存。其lockNextBuffer方法完成了acquireBuffer、等待Fence、映射内存(lock、lockYCbCr)。
GLConsumer继承ConsumerBase,处理到GL Texture的转换,支持GL渲染。

Surface类继承实现了ANativeWindow,同时作为BufferQueue的生产者。
ComposerService持有ISurfaceComposer的实现对象引用,ISurfaceComposer实际由SurfaceFlinger服务实现。ComposerService是一个单例。
Composer是ISurfaceComposer的代理类,主要任务是将Display、Surface状态改变封装为事务发送给SurfaceFlinger。Composer是一个单例。
SurfaceComposerClient是ISurfaceComposerClient的代理类,通过连接(createConnection)ISurfaceComposer获得一个ISurfaceComposerClient实现对象。SurfaceComposerClient也代理Composer的很多接口。SurfaceComposerClient通过createSurface创建的Surface由SurfaceControl管理。
ScreenshotClient封装抓取屏幕功能,使用了CpuConsumer。
SurfaceControl管理SurfaceFlinger创建的Surface句柄(IBinder),这个句柄与SurfaceComposerClient是相关的。
部分类的名称历史:
| 4.2 | 4.3 | 4.4 |
| ISurfaceTexture | IGraphicBufferProducer | IGraphicBufferProducer |
| IGraphicBufferConsumer | ||
| SurfaceTexture | GLConsumer | GLConsumer |
| SurfaceTextureClient | Surface | Surface |
应用程序创建Surface的过程:

BitTube通过UNIX域匿名(socketpair,SOCK_SEQPACKET)管道实现了一个简单的在进程间传递数据结构(二进制报文)的管道。
DisplayEventReceiver负责创建并代理与SurfaceFlinger之间的事件连接(接口为IDisplayEventConnection),提供方法帮助从连接的数据管道(使用BitTube机制)读取事件,包括vsync、显示设备插拔事件。
libhwui
源代码位于:frameworks/base/libs/hwui。
使用opengl渲染UI组件。
libsurfaceflinger
源代码位于:frameworks/native/services/surfaceflinger。
硬件(DisplayHardware)

其中的DisplayHardware子目录中提供对HAL层封装的代码,包括PowerHAL、HWComposer、FramebufferSurface、VirtualDisplaySurface。
PowerHAL。
HWComposer封装hwcomposer HAL。管理显示设备属性DisplayData,转发vsync回调。创建Display的工作图层列表hwc_display_contents_1_t。
HWComposer::HWCLayerVersion1继承HWComposer::HWCLayer,后者继承HWComposer::HWCLayerInterface。HWComposer::HWCLayerVersion1封装了C数据结构hwc_layer_1_t,代理其读写操作。
HWComposer::LayerListIterator是HWComposer::HWCLayer枚举器。
DisplaySurface是一个虚基类,定义了几个回调接口。下面的FramebufferSurface和VirtualDisplaySurface都继承实现了DisplaySurface。
| 成员 | 类型 | 说明 |
| beginFrame | status_t() | 在帧配置前被调用,为HWC提供配置参考信息 |
| prepareFrame | int(CompositionType) | 在帧配置完成后被调用 |
| compositionComplete | status_t() | 帧合成输出后被调用,HWC1.0需要的 |
| advanceFrame | status_t() | GLES合成完成后被调用 |
| onFrameCommitted | void() | 帧提交到HWC后被调用 |
| dump | void(String8&) |
FramebufferSurface作为BufferQueue的消费者,将收到的frame推送给硬件(HWC),HWC将其保存到framebufferTarget。
VirtualDisplaySurface实现一个虚拟屏幕,作为一个BufferQueue的消费者,同时代理另一个BufferQueue的生产者接口。VirtualDisplaySurface使用了HWC的虚拟屏幕支持。
软件(Display与Surface)

DisplayDevice封装了DisplaySurface(内部设备使用FramebufferSurface实现,消费缓存)。DisplayDevice包含一个BufferQueue,使用Surface包装后交给GLES渲染(合成图层),合成后交换缓存会通知到FramebufferSurface,将合成后图像交给HWC作为framebufferTarget。
SurfaceFlingerConsumer继承GLConsumer。
SurfaceTextureLayer继承BufferQueue。是对BufferQueue的简单包装,然后被Layer类使用。
Layer处理剪辑区域的计算,GLES的叠加,内部算法比较复杂。Layer在客户端用句柄IBinder代表,该句柄继承LayerCleaner,在释放时会通知SurfaceFlinger。Layer继承实现了ConsumerBase::FrameAvailableListener,内部持有SurfaceFlingerConsumer对象。在回调onFrameAvailable中调用SurfaceFlinger的signalLayerUpdate,后者向MessageQueue中插入INVALIDATE消息。Layer第一次被引用onFirstRef时创建SurfaceTextureLayer(BufferQueue)以及消费者SurfaceFlingerConsumer。
LayerDim继承Layer。
Client类实现ISurfaceComposerClient,内部保存Layer句柄到Layer的映射集。

软件(Sync与Thread)

DispSync通过统计算法与硬件vsync信号同步,消除vsync信号在软件层传递引起的随机偏移。DispSync通过内部线程(DispSyncThread)为每个侦听者分别增加一定的信号延迟。
DispSync内部保存最近32个硬件vsync采样时间点,用统计方法计算vsync的周期和相位偏移。同步后可以关闭硬件vsync,由DispSyncThread周期唤醒模拟vsync信号。当显示设备重新打开或者通过PresentFence计算的偏移方差超过一定值时,需要重新同步。
DispSyncSource定义在SurfaceFlinger.cpp中。DispSyncSource是对DispSync的包装,可以定义不同的周期偏移(PhaseOffset)。
EventThread实现vsync信号分派线程,EventThread侦听外部传入VSyncSource,在没有VSyncSource的时候会内部模拟一个60fps的vsync信号。EventThread也分派显示设备插拔事件。
外部可以与EventThread建立连接(IDisplayEventConnection,由内部类Connection实现),可以请求只接收一次vsync回调(requestNextVsync),也可以指定按某个频率接收vsync回调(setVsyncRate,参数count表示每count个vsync信号调用一次回调)。连接通过BitTube管道返回事件。
实际上,SurfaceFlinger创建了两个DispSyncSource,分别被上层应用(APP)和SurfaceFlinger内部使用。两个DispSyncSource使用不同的信号延迟,延迟时间由厂商在BoardConfig.mk中定义,没有定义的情况下,默认为0,这两个变量分别是:
- VSYNC_EVENT_PHASE_OFFSET_NS(APP)
- SF_VSYNC_EVENT_PHASE_OFFSET_NS(SurfaceFlinger)
对应两个DispSyncSource,SurfaceFlinger也创建了两个EventThread,并且向其中对应APP的那个发送设备插拔事件。
MessageQueue通过封装Looper实现了消息队列,同时与EventThread建立连接,并将vsync事件转换为消息插入到消息队列。
EventControlThread用来协助SurfaceFlinger,在独立线程控制硬件vsync开启关闭。
surfaceflinger
surfaceflinger进程,创建Binder线程池(4线程),创建SurfaceFlinger对象,调用其init方法,然后注册到ServiceManager中,最后调用SurfaceFlinger的run方法进入SurfaceFlinger的MessageQueue派发循环。
从4.0开始,surfaceflinger不在system_init中启动,而是有独立的进程。但是可以通过init.rc配置从system_init中启动。
surfaceflinger服务init.rc中的定义:
|
# Set this property so surfaceflinger is not started by system_init setprop system_init.startsurfaceflinger 0 |
|
service surfaceflinger /system/bin/surfaceflinger class main user system group graphics drmrpc onrestart restart zygote |
从4.4开始,只有进程启动方式了。
bootanimation
源代码位于:frameworks/base/cmds/bootanimation。
Bootanimation使用opengl在新建的SurfaceFlinger layer上作图。开机启动的动画。
Bootanimation由init进程响应属性设置ctl.start=bootanim启动。Bootanimation检查到系统属性service.bootanim.exit=1退出。
|
service bootanim /system/bin/bootanimation class main user graphics group graphics disabled oneshot |
screencap
源代码位于:frameworks/base/cmds/screencap。
通过ScreenshotClient或者直接从/dev/graphics/fb0抓取图像数据,保存到文件或者通过stdout输出。通过SkBitmap转换为PNG格式。
screenshot
源代码位于:frameworks/native/cmds/screenshot。
直接从/dev/graphics/fb0(字节流方式读取)抓取图像数据,通过libpng(external/libpng)转换为PNG格式,保存到文件。
screenrecord
源代码位于:frameworks/av/cmds/screenrecord。
通过建立虚拟屏幕持续抓取屏幕,并使用编码压缩保存到文件。容器格式:Mp4,编码格式:AVC。
本文详细介绍了Android4.4 KitKat中的图形系统,包括libsync、window.h、opengl、libui、libgui、libhwui以及libsurfaceflinger等关键组件的功能和实现。重点讨论了缓冲区管理、同步机制、EGL与OpenGLES的封装、SurfaceFlinger的运行机制,以及Bootanimation、screencap和screenrecord等实用工具的工作原理。
2698

被折叠的 条评论
为什么被折叠?



