Android 源码分析 - 显示 - Native层

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,这两个变量分别是:

  1. VSYNC_EVENT_PHASE_OFFSET_NS(APP)
  2. 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。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Fighting Horse

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值