Android14显示系统 - HWComposer
文章目录
1、概述
Android Graphics Overview :https://lucmann.github.io/gfx/hal/
【Android】硬件合成器 HWC :https://blog.csdn.net/lijian2017/article/details/147565151
Android P 图形显示系统(一)硬件合成HWC2 :https://www.cnblogs.com/hellokitty2/p/17637480.html
Android drm-hwcomposer:https://blog.csdn.net/stray2b/article/details/130291840
1)硬件类型:DPU(Data processing Unit) 或 2D渲染芯片,HWC和GPU一样,由于HWC模块有一定的自主性,因此厂家一般闭源;
2)HWC的任务:合成、送显、产生vsync信号(可以是软件也可以是硬件产生);
3)composer任务可以由OpenGL-ES完成(CPU或GPU),也可以是HWC完成;
为什么需要合成?
1、如果一帧图片所有内容都是顺序绘制,那显示延迟会非常大,为了加速显示 不同部分的绘制同步进行,绘制完后再合在一起 送显;
2、合成过程:当Android显示一个应用时,通常有三个图层(Layer) :顶部状态栏、APP区域、底部状态栏,它们由不同应用绘制渲染,在绘制时各应用(系统应用、用户应用)利用GPU生成自身的图像信息(Bitmap),随后HWC将多个Surface按照一定的顺序和透明度进行合成(CPU\GPU\HWC均可完成),最后送显,完成后产生vsync信息通知surfaceflinger开始下一帧的处理;


为什么要使用两种方式进行合成?
HWC 合成效率更高,而 GPU 可以合成更复杂的图层,二者可以搭配着使用,能显著提高合成效率。

1)部分图层会先利用GPU合成,一来硬件HWC合成层数有限,二来合成能力有限,因此需要借助GPU完成;
2)GPU合成和HWCOMPOSER合成统一由HWC软件模块管理;
3)HWC降级为GPU合成的原因分析?HWC硬件加速器不支持某些图像格式或合成方式。
GPU合成方式

1)GPU合成本质上是在同一个FB上依次绘制图形;
2)如果没有GPU硬件,则纯软件实现(即使用CPU绘制,效率低);
图层合成的顺序?
1)由WindowManagerService根据各个界面的Z值决定前后顺序;
2)最后将这些排序好的buffer送往HardwareComposer;
2、HWC硬件介绍
1)RK3568 HWC - VOP2
调试说明 - Rockchip Graphics - DRM Hardware Composer

合成方式
注意HWC支持的层数是有限的
RK3588 VOP图层分配介绍:https://blog.csdn.net/weixin_43245753/article/details/139000705
2)4412 HWC

3、HWC架构
1)HWC的层次结构

2)HWC Composition处理流程

1)使用CPU/GPU硬件 :HWC_FRAMEBUFFER -> OpenGL ES -> CPU/GPU
2)合成专用硬件:HWC_OVERLAY -> HWC HAL -> VOP2…
4、源码分析
1)数据结构

2)client-Surfaceflinger
1、概况
1、AN13上使用HAL库,采用AIDL方式远程调用HAL进程;
2、AN9上使用HAL库,采用HIDL方式远程调用HAL进程;
HWC1和HWC2使用分布:
Android 9以前使用
/android/frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
Android 9以以上使用
/android/frameworks/native/services/surfaceflinger/DisplayHardware/HWC2.h
1、Layer父类
/android/frameworks/native/services/surfaceflinger/Layer.cpp
2、Layer子类
/android/frameworks/native/services/surfaceflinger/BufferLayer.cpp
/android/frameworks/native/services/surfaceflinger/ColorLayer.cpp
/android/frameworks/native/services/surfaceflinger/ContainerLayer.cpp
下面针对两个系统分别介绍,SurfaceFlinger如何使用HWC
源码目录
/android/frameworks/native/services/surfaceflinger/DisplayHardware
2、低版本的使用opengl合成的代码流程
先看低版本的使用opengl合成的代码流程
1、低版本的AOSP(Android 10及以下) 合成流程,Android9的代码
// frameworks/native/services/surfaceflinger/Surfaceflinger.cpp
void SurfaceFlinger::handleMessageRefresh() {
preComposition();
rebuildLayerStacks();
// 判断哪些图层使用 GPU合成、哪些使用 硬件合成
setUpHWComposer();
doDebugFlashRegions(display, repaintEverything);
// 使用GPU合成、送显
doComposition();
//后处理
postComposition();
}
void SurfaceFlinger::setUpHWComposer() {
// ...
for (size_t i = 0; i < currentLayers.size(); i++) {
const auto& layer = currentLayers[i];
// 请求HWC判断合成方式
if (!layer->createHwcLayer(getBE().mHwc.get(), hwcId)) {
// 标记该图层使用GPU合成
layer->forceClientComposition(hwcId);
continue;
}
}
}
void SurfaceFlinger::doComposition() {
// 使用GPU合成部分Layer
doDisplayComposition(hw, dirtyRegion);
// 委托HWC合成所有Layer,并送显
postFramebuffer();
}
2、核心方法doDisplayComposition详细流程
/android/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
doDisplayComposition(hw, dirtyRegion);
--doComposeSurfaces()
----doComposeSurfaces() //绘图(将所有的Layer绘成一个画面,即合成过程)
/android/frameworks/native/services/surfaceflinger/Layer.cpp
------layer->draw(renderArea,clip);
/android/frameworks/native/services/surfaceflinger/BufferLayer.cpp
--------onDraw(); //使用GL库来绘图
----------drawWithOpenGL(renderArea, useIdentityTransform);
/android/frameworks/native/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
------------engine.drawMesh(getBE().mMesh);
/android/frameworks/native/opengl/libagl/array.cpp //使用Android GL库
--------------glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
/android/frameworks/native/services/surfaceflinger/DisplayDevice.cpp
----displayDevice->swapBuffers(getHwComposer()) //送显
/android/frameworks/native/services/surfaceflinger/RenderEngine/Surface.cpp
------mSurface->swapBuffers();
--------eglSwapBuffers(mEGLDisplay, mEGLSurface)
/android/frameworks/native/opengl/libagl/egl.cpp
------------d->swapBuffers(); // post the surface
/android/frameworks/native/opengl/libagl/egl.cpp
--------------struct egl_window_surface_v2_t : public egl_surface_t
/android/frameworks/native/libs/nativewindow/include/system/window.h
/android/frameworks/native/libs/gui/Surface.cpp
----------------nativeWindow->queueBuffer(nativeWindow, buffer, -1);
------------------mGraphicBufferProducer->queueBuffer()
/android/frameworks/native/libs/gui/BufferQueue.cpp
/frameworks/native/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
--------------------listener->onFrameAvailable();
/frameworks/native/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
----------------------mHwc.fbPost(mDisplayType, acquireFence, buf); //Android 8
/frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
------------------------fFbDev->post(mFbDev, buffer->handle) //调用fb驱动进行显示,Android 8,Android 9没有此方法
3、Android13 SurfaceFlinger composite流程分析
https://blog.csdn.net/liuning1985622/article/details/138465549
Android13代码相对Android9更加模块化,抽象出更多的“对象”,让其更加健壮但也更复杂,各个流程相对分散 不好分析;
对比着学习能掌握Android的变化趋势,也让我们更好地应对项目上的变化;
1)初始化
SurfaceFlinger::SurfaceFlinger(Factory& factory,)
mCompositionEngine(mFactory.createCompositionEngine()),
HWComposer& SurfaceFlinger::getHwComposer() const {
return mCompositionEngine->getHwComposer();
}
1)关键参数
android/frameworks/native/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h
struct CompositionRefreshArgs {
Outputs outputs; //等于display
Layers layers;
Layers layersWithQueuedFrames;
std::vector<uint64_t> bufferIdsToUncache;
}
/android/frameworks/native/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
class Output {
}
/android/frameworks/native/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
class LayerFE : public virtual RefBase {
public:
virtual const LayerFECompositionState* getCompositionState() const = 0;
virtual void onLayerDisplayed(ftl::SharedFuture<FenceResult>) = 0;
}
mFlinger->createDisplay(displayName, secure);
mFlinger->mCompositionEngine->setHwComposer(std::make_unique<impl::HWComposer>(std::move(composer)));
2)合成流程
/android/frameworks/native/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
mFlinger->composite(commit(frameTime, vsyncId, expectedVsyncTime), kVsyncId);
--mCompositionEngine->present(refreshArgs);
/android/frameworks/native/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
----preComposition(args);//layer预合成
------layer->onPreComposition(mRefreshStartTime); //遍历所有的layer,进行layer预合成
/android/frameworks/native/services/surfaceflinger/BufferLayer.cpp
--------hasReadyFrame(); //判断是否需要更新
/android/frameworks/native/services/surfaceflinger/CompositionEngine/src/Output.cpp
----output->prepare(args, latchedLayers); //output的预合成
------rebuildLayerStacks(refreshArgs, geomSnapshots); //重新计算Layer的visibility和coverage(相对复杂)
----output->present(args); //output的Layer合成
------updateCompositionState()
--------getOutputLayersOrderedByZ()
----------layer->updateCompositionState()
------planComposition()
--------mPlanner->plan(getOutputLayerOrderedByZ()) //根据Z轴来进行排序计算layer的合成
/android/frameworks/native/services/surfaceflinger/CompositionEngin/src/Planner.cpp
----------Planner::plan()
------writeCompositionState()
------beginFrame()
/android/frameworks/native/services/surfaceflinger/CompositionEngin/src/Output.cpp
--------mRenderSurface->beginFrame(mustRecompose);
----------mDisplaySurface->beginFrame(mustRecompose);
/androidframeworks/native/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
------------refreshOutputBuffer();
--------------mHwc.setOutputBuffer(*halDisplayId, Fence::NO_FENCE, mProducerBUffers[mOutputProducerSlot])
frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
--------------std::unique_ptr<HWC2::Display> hwcDisplay; //调用HWC2::Display的setOutputBuffer方法
--------------displayData.hwcDisplay->setOutputBuffer(buffer, acquireFence);
------prepareFrameAsync() //准备帧数据以进行显示(Async方式)
------postFramebuffer() //将帧缓冲区(framebuffer)的内容发送到显示设备进行显示
/android/frameworks/native/libs/ui/Region.cpp
--------outputState.dirtyRegion.clear(); //清除脏的区域
--------mRenderSurface->flip();
--------mRenderSurface->onPresentDisplayCompleted();
--------layer->onLayerDisplayed();
------renderCachedSets(refreshArgs); //进行渲染缓存设置
--------mPlanner->renderCachedSets()
--mScheduler->onPostComposition() //通知调度器
--postFrame(); //触发后续的帧提交
--postComposition(); //合成后处理
present会使用合成引擎(CompositionEngine),完成以下工作
1)根据图层类型、硬件能力等因素,为每个图层决定合成策略(使用GPU“客户端合成”,还是使用显示硬件“设备合成”)。
2)执行实际的混合、变换等操作,生成最终帧。
3)通过 present 操作将最终帧提交给显示硬件(如通过HWC模块)。
关键参数
1)outputs:遍历 mDisplays 列表(系统当前所有显示设备,如主屏、副屏),收集每个显示设备的 CompositionDisplay 对象。这是合成操作的目标。
2)layers:遍历 mDrawingState 中的所有图层(Layer),并获取其合成引擎前端接口 LayerFE。这代表了所有需要被合成的图形内容。
3)layersWithQueuedFrames:这是一个重要优化,它记录了那些有新帧(新图形数据)等待合成的图层。在合成时,系统可以优先或只处理这些“脏”图层,避免不必要的重复计算。
4)输出与颜色设置:如 outputColorSetting、forceOutputColorMode 等,用于控制色彩管理、是否强制使用GPU合成(客户端合成)等调试或特性开关。
5)时间参数:这是合成同步的关键,函数计算并传递了一系列精确的时间点:
earliestPresentTime:合成结果可以被提交给硬件的最早时间。
expectedPresentTime:预期本帧图像被显示的时间。
previousPresentFence:上一帧的显示栅栏(Fence),用于同步GPU/硬件工作,确保前一帧已显示完毕。
3)如何确定使用哪个HWComposer?
/android/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
--mCompositionEngine(mFactory.createCompositionEngine()),
//通过属性名来确定使用哪个aidl-hwc
--mHwcServiceName(base::GetProperty("debug.sf.hwc_service_name"s, "default"s)),
SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,..)
--auto compositionDisplay = getCompositionEngine().createDisplay(builder.build());
--sp<compositionengine::DisplaySurface> displaySurface;
--sp<IGraphicBufferProducer> producer;
--sp<IGraphicBufferProducer> bqProducer;
--sp<IGraphicBufferConsumer> bqConsumer;
--auto surface = ap<VirualDisplaySurface>::make(getHwComposer(),...)
HWComposer& SurfaceFlinger::getHwComposer() const {
return mCompositionEngine->getHwComposer();
}
/android/frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.h
namespace android {
class HWComposer {
virtual std::shared_ptr<HWC2::Layer> createLayer(HalDisplayId) = 0;
}
}
//对HWComposer进一步扩展
namespace impl {
class HWComposer final : public android::HWComposer {
explicit HWComposer(std::unique_ptr<Hwc2::Composer> composer);
explicit HWComposer(const std::string& composerServiceName);
}
}
4、mFlinger->composite 函数流程图
3)service-hwcomposer
1、service-hwcomposer
Service的职责是去load对应的hal库,并与client通信
2、AIDL-AML厂商的实现
/android/hardware/amlogic/hwcomposer/service/3.0/Main.cpp
main()
--ALOGI("meson (HWComposer3) starting up...");
--auto composer = ndk::ShareRefBase::make<Composer>();
--AServiceManager_addService(composer->asBinder().get(), instance.c_str());
/android/hardware/amlogic/hwcomposer/service/3.0/HwcHal.cpp
HwcHal::init()
--const hw_module_t* module;
--hw_get_module(HWC_HARDWARE_MODULE_ID, &module);
--hwc2_open(module, &mDevice)
--initCapabilities() //
--initDispatch()
----mDevice->getFunction(mDevice, desc) //获取hal的函数
3、不同厂商的hwcomposer HAL是闭源的
4、但也有开源HAL库;基于drm驱动实现的开源hwcomposer HAL库。
/android/external/drm_hwcomposer
/android/external/drm_hwcomposer/Android.bp //hwcomposer.drm.so
4)hwcomposer HAL
概述
HAL hwcomposer 组件通常是由各个设备厂商根据自己的硬件特性实现的,有开源的,也有闭源的,闭源也情有可原,毕竟厂家的核心实现,这也是HAL产生的原因,但导致架构相对繁杂,代码分支多!HAL的分支:
在 AOSP 中有一个通用的基础的 HAL hwcomposer demo实现,主要用于那些不需要特别硬件加速或优化的设备,类似 xserver 中的 modesetting.
我们重点关注开源HAL实现drm-hwcomposer -> arm drm-hwcomposer
1、libhardware
1、各个厂商需要实现HAL libhardware规定的接口
/android/hardware/amlogic/hwcomposer
/android/hardware/libhardware/modules/hwcomposer
/android/hardware/amlogic/hwcomposer/service/3.0/HwcHal.cpp
#define HWC_HARDWARE_MODULE_ID "hwcomposer"
2、HAL接口有多个版本 HWC1和HWC2
/android/hardware/libhardware/include/hardware/hwcomposer_defs.h
HWC1功能相对单一
/android/hardware/libhardware/include/hardware/hwcomposer.h
HWC2功能则丰富很多
/android/hardware/libhardware/include/hardware/hwcomposer2.h
1)HW1
/android/hardware/libhardware/include/hardware/hwcomposer.h
typedef struct hwc_composer_device_1 {
struct hw_device_t common;
int (*prepare)(struct hwc_composer_device_1 *dev, size_t numDisplays, ...);
int (*set)(struct hwc_composer_device_1 *dev, size_t numDisplays, ...);
int (*eventControl)(struct hwc_comoser_device_q* dev, int disp, ...);
int (*blank)(struct hwc_comoser_device_1* dev, int disp, ...);
int (*setPowerMode)(struct hwc_composer_device_1* dev, int disp, ...);
int (*query)(struct hwc_composer_device_1*, int what, ...);
int (*registerProcs)(struct hwc_composer_device_1*);
int (*dump)()
int (*getDisplayConfigs)()
int (*getDisplayAttributes)()
int (*getActiveConfig)()
int (*setAcitveConfig)()
int (*setCursorPositionAsync)()
}
hwc_open_1(struct hw_module_t* module, hwc_composer_device_1_t** device) {
return module->methods-open(module, HWC_HARDWARE_COMPOSER, TO_HW_DEVICE_T_OPEN(device))
}
2)HW2
/android/hardware/libhardware/include/hardware/hwcomposer2.h
typedef enum {
HWC2_FUNCTION_CREATE_LAYER,
HWC2_FUNCTION_PRESENT_DISPLAY,
HWC2_FUNCTION_REGISTER_CALLBACK,
HWC2_FUNCTION_SET_ACTIVE_CONFIG,
HWC2_FUNCTION_SET_CLIENT_TARGET,
HWC2_FUNCTION_SET_COLOR_MODE,
HWC2_FUNCTION_SET_COLOR_TRANSFORM,
HWC2_FUNCTION_SET_CURSOR_POSITION,
HWC2_FUNCTION_SET_LAYER_BLEND_MODE,
HWC2_FUNCTION_SET_LAYER_BUFFER,
// composer 2.3
HWC2_FUNCTION_GET_DISPLAY_IDENTIFICATION_DATA,
HWC2_FUNCTION_GET_DISPLAY_CAPABILITIES,
HWC2_FUNCTION_SET_LAYER_COLOR_TRANSFORM,
HWC2_FUNCTION_GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES,
HWC2_FUNCTION_SET_DISPLAYED_CONTENT_SAMPLING_ENABLED,
HWC2_FUNCTION_GET_DISPLAYED_CONTENT_SAMPLE,
HWC2_FUNCTION_SET_LAYER_PER_FRAME_METADATA_BLOBS,
HWC2_FUNCTION_GET_DISPLAY_BRIGHTNESS_SUPPORT,
HWC2_FUNCTION_SET_DISPLAY_BRIGHTNESS,
// composer 2.4
HWC2_FUNCTION_GET_DISPLAY_CONNECTION_TYPE,
HWC2_FUNCTION_GET_DISPLAY_VSYNC_PERIOD,
HWC2_FUNCTION_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS,
HWC2_FUNCTION_SET_AUTO_LOW_LATENCY_MODE,
HWC2_FUNCTION_GET_SUPPORTED_CONTENT_TYPES,
HWC2_FUNCTION_SET_CONTENT_TYPE,
HWC2_FUNCTION_GET_CLIENT_TARGET_PROPERTY,
HWC2_FUNCTION_SET_LAYER_GENERIC_METADATA,
HWC2_FUNCTION_GET_LAYER_GENERIC_METADATA_KEY,
} hwc2_function_descriptor_t;
static inline int hwc2_open(struct hw_module_t* module, hwc2_device_t** device){
return module->methods->open(module, HWC_HARDWARE_COMPOSER, TO_HW_DEVICE_T_OPEN(device))
}
2、hwcomposer demo
1、Android官方开源HAL模版,各个厂商可以基于此demo完成自己的接口
/android/hardware/libhardware/modules/hwcomposer/hwcomposer.cpp
hwc_module_t HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.methods = &hwc_module_methods,
}
}
static struct hw_module_methods_t hwc_module_methods = {
.open = hwc_device_open
};
hwc_device_open(hw_module_t* module, char *name, hw_device_t** device)
--if (!strcmp(name, HWC_HARDWARE_COMPOSER))
----dev->device.prepare = hwc_prepare;
----dev->device.set = hwc_set;
hwc_prepare
--displays[0]->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
hwc_set
1)实现1
/android/frameworks/native/opengl/libs/eglApi.cpp
--eglSwapBuffers((EGLDisplay)displays[0]->dpy, (EGLSurface)displays[0]->sur); //使用OpenGL-ES合成并显示
----gEGLImpl->platform.eglSwapBUffers(dpy, surface) //最终导致Gralloc hal:post调用
------queueBuffer()
--------surfaceFLinger->onFrameAvailable()
struct egl_connection_t gEGLImpl
--struct platform_impl_t
----/android/frameworks/native/opengl/libs/platform_entries.in
2)
/android/external/mesa3d/src/egl/main/eglapi.c
eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
--disp->Driver->SwapBuffers(disp, surf);
3、drm-hwcomposer
1、基于drm驱动实现的开源hal hwcomposer
2、libdrm的关系?
drm-hwcomposer通过libdrm与驱动交互
3、
drm-kernel有hwcomposer驱动的实现?
hwc的驱动需要按照drm框架,注册对应的component
5)driver
android/common-5.15/common/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
android/common-5.15/common/drivers/gpu/drm/meson/meson_overlay.c
更多推荐



所有评论(0)