Android P的HWC Composer相关

Android P加载Composer

SurfaceFlingerBE封装了HWComposer,处理与HAL层的业务相关业务。SurfaceFlingerBE的mComposerSequenceId代表当前
使用的HWComposer的类型,0为正常SurfaceFlinger使用,1为VR使用,并且只能使用一个显示相关的HAL层。

1、初始化时先构造HWComposer,getHwcServiceName通过属性系统debug.sf.hwcservicename获取const std::string mHwcServiceName并以此来创建HWC2::Device  mHwcDevice, 及HWC2::Device 的成员android::Hwc2::Composer mComposer,此时会根据mHwcServiceName来判断是不是使用的VR及要作为要Binder的服务名,注VrComposer使用的Composer服务名为“vr,具体即Composer调用IComposer::getService()。

2,屏幕个数在hwcomposerdefs.h中定义:

/* Display types and associated mask bits. */
enum {
    HWC_DISPLAY_PRIMARY     = 0,    
    HWC_DISPLAY_EXTERNAL    = 1,    // HDMI, DP, etc.
    HWC_DISPLAY_VIRTUAL     = 2,     
    
    HWC_NUM_PHYSICAL_DISPLAY_TYPES = 2,
    HWC_NUM_DISPLAY_TYPES          = 3,
};   

根据此来创建VSYNC信息资源。  并且在HWComposer类的成员std::vector<DisplayData>        mDisplayData;被默认初始元素个数为2。

3,HAL层调用流程  Composer::Composer类的构造函数中通过IComposer::getService()加载HAL层实现,在Treble项目中会有宏HIDL_FETCH_×××××,其中XXXXX表示的为具体的HIDL脚本中的声名,这里即(HIDL_FETCH_IComposer),HIDL_FETCH_IComposer的实现是在composer/2.1/default/Hwc.cpp中,可以看到HwcHal(即IComposer)。HwcHal的构造函数调用了vendor类实现的HAL接口,获取到hw_device_t,hw_device_t定义了接口函数,   HwcHal::initDispatch 用于关联 实现层hwc2_function_pointer_t ,与HAL接口的对应。调用例子如:mRemainingHwcVirtualDisplays = mHwcDevice->getMaxVirtualDisplayCount();   先是会调用android::Hwc2::Composer的实现getMaxVirtualDisplayCount()然后会调用IComposerClient通过Binder的服务来调用ComposerClient的getMaxVirtualDisplayCount()

4,class ComposerCallbackBridge : public Hwc2::IComposerCallback  用于ComposerHAL层回调。其中onHotplug函数第一次的调用确定了主屏幕。onRefresh用于通知重画屏幕,onVsync用于通知同步信号时间(好像已经不是必须的),Android P 在接收到 onRefresh 后会根据上次的描绘重新通知onVsync信号,详细看SurfaceFlinger及MessageQueue实现的事件处理。

Android P  SurfaceFlinger的事件线程:

1,SurfaceFlinger为主要线程,用于处理SurfaceFlinger接收到的事件

2,EventControlThread,就像是Vsync信号产生的闸门,当然闸门肯定需要人去打开和关闭,这个人就是SF;即控制Vsync信号的开头

3,DispSyncThread,是Vsync信号的模型,首先触发DispSyncThread,然后DispSyncThread再去驱动其他事件,它就是Vsync在SF中的代表;

4,EventThread,具体的事件线程,由DispSyncThread去驱动。EventThread线程有两个一个是用于SF的,别一个是用于APP。

Android O/P  VSYNC及相关

1、onRefresh函数会调用SurfaceFlinger::signalTransaction-->EventQueue.invalidate()并且SurfaceFlinger::signalLayerUpdate()-->EventQueue.invalidate()   最终会调用SurfaceFlinger::resyncWithRateLimit()此函数会判断上次执行是不是超过ms2ns(500)  ==  500毫秒,如果达到显示时长则重置同步信号,见SurfaceFlinger::resyncToHardwareVsync()。以主屏幕的同步信号来刷新屏幕,会重置DispSyncThread线程,修正使用更新周期,见DispSyncThread::updateModel()  此时如果DispSyncThread线程卡住时,mCond将会唤醒此线程。

    void updateModel(nsecs_t period, nsecs_t phase, nsecs_t referenceTime) {
        if (kTraceDetailedInfo) ATRACE_CALL();
        Mutex::Autolock lock(mMutex);
        mPeriod = period;
        mPhase = phase;
        mReferenceTime = referenceTime;
        ALOGV("[%s] updateModel: mPeriod = %" PRId64 ", mPhase = %" PRId64
                " mReferenceTime = %" PRId64, mName, ns2us(mPeriod),
                ns2us(mPhase), ns2us(mReferenceTime));
        mCond.signal();
    } 

注:在HWC2::Device类在Device::onHotplug()收到HAL层新的设备时会创建HWC2::Display对像用于保存显示相关的信息,主要是使用std::map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs;来保存显示屏幕的配置信息。详见HWC2::Display::Config

Android P 图形显示系统   https://blog.csdn.net/chaojiangluo/article/details/81475607

  • 显示周期Vsync

设备显示会按一定速率刷新,在手机和平板电脑上通常为每秒 60 帧。如果显示内容在刷新期间更新,则会出现撕裂现象;因此,请务必只在周期之间更新内容。在可以安全更新内容时,系统便会收到来自显示设备的信号。由于历史原因,我们将该信号称为 VSYNC 信号。

刷新率可能会随时间而变化,例如,一些移动设备的刷新率范围在 58 fps 到 62 fps 之间,具体要视当前条件而定。对于连接了 HDMI 的电视,刷新率在理论上可以下降到 24 Hz 或 48 Hz,以便与视频相匹配。由于每个刷新周期只能更新屏幕一次,因此以 200 fps 的刷新率为显示设备提交缓冲区只是在做无用功,因为大多数帧永远不会被看到。SurfaceFlinger 不会在应用提交缓冲区时执行操作,而是在显示设备准备好接收新的缓冲区时才会唤醒。

当 VSYNC 信号到达时,SurfaceFlinger 会遍历它的层列表,以寻找新的缓冲区。如果找到新的缓冲区,它会获取该缓冲区;否则,它会继续使用以前获取的缓冲区。SurfaceFlinger 总是需要可显示的内容,因此它会保留一个缓冲区。如果在某个层上没有提交缓冲区,则该层会被忽略。

  • 合成方式

目前SurfaceFlinger中支持两种合成方式,一种是Device合成,一种是Client合成。SurfaceFlinger 在收集可见层的所有缓冲区之后,便会询问 Hardware Composer 应如何进行合成。

  • Client合成
    Client合成方式是相对与硬件合成来说的,其合成方式是,将各个Layer的内容用GPU渲染到暂存缓冲区中,最后将暂存缓冲区传送到显示硬件。这个暂存缓冲区,我们称为FBTarget,每个Display设备有各自的FBTarget。Client合成,之前称为GLES合成,我们也可以称之为GPU合成。Client合成,采用RenderEngine进行合成。

  • Device合成
    就是用专门的硬件合成器进行合成HWComposer,所以硬件合成的能力就取决于硬件的实现。其合成方式是将各个Layer的数据全部传给显示硬件,并告知它从不同的缓冲区读取屏幕不同部分的数据。HWComposer是Devicehec的抽象。

SurfaceFlinger与HIDL

        HIDl请参考https://source.android.google.cn/devices/architecture/hidl
关于HIDL的修改,可以增加接口但请注意以下事项:

允许的更改
  • 更改备注(除非这会更改方法的含义)。
  • 更改参数的名称。
  • 更改返回参数的名称。
  • 更改注释。
不允许的更改
  • 重新排列参数、方法等…
  • 重命名接口或将其移至新的软件包。
  • 重命名软件包。
  • 在接口的任意位置添加方法/结构体字段等等…
  • 会破坏 C++ vtable 的任何更改。
  • 等等…

......

转载于:https://my.oschina.net/yuyang/blog/1862234

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值