日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android drm-hwcomposer

發布時間:2024/1/18 Android 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android drm-hwcomposer 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
軟件環境:ubuntu20.04 aosp 硬件環境:X86 PC 模擬環境:在host ubuntu20.04啟動支持圖形(by virtio-gpu)的Android虛擬機

1. 介紹

  • HWC 會執行以下計算:

    1. SurfaceFlinger 向HWC 提供一個完整的層列表,并詢問“您希望如何處理這些層?”2. Hwc的響應方式是將每個層標記為設備或客戶端合成。3. SurfaceFlinger會處理所有客戶端,將輸出緩沖區傳送到 HWC,并讓HWC 處理其余部分。由于硬件供應商可以定制決策代碼,因此可以在每臺設備上實現最佳性能。

1.1 接口

#Hal接口定義,最新版本2.4 /hardware/interfaces/graphics/composer/ #谷歌定義的hwc接口 hardware/libhardware/include/hardware/hwcomposer.h #API 參考: https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=1861
  • API
#SF傳遞GPU圖層buffer,保存client_layer_ SetClientTarget #針對每一個layer設置合成方式,保存sf_type_,值都為2 SetLayerCompositionType #把內容呈現到屏幕上去 PresentDisplay #為每一個Layer選擇合成方式 ValidateDisplay

1.2 實現

Surfaceflinger <----> HWC2 client <----> HWC server <----> Vendor implHWC三類接口: 1. Layer:合成工作 2. Display:與屏幕硬件交互 3. Vsync:Vsync控制以及對SF的回調,通知VSYNC時間
  • Cuttlefish實現

    每個廠商hwc實現可能不同如nxp,rockchip,drm-hwc,ranchu,也有很多廠商實現是閉源的如nxp,而谷歌的drm-hwc,ranchu是開源的
#swiftshader和gfxstream模式 androidboot.hardware.hwcomposer=ranchu //指定hwc為ranchu hwcomposer.ranchu.so #3D drmvirgl模式 androidboot.hardware.gralloc=minigbm hwcomposer.drm_minigbm.so

2. drm_hwcomposer

2. 1 線程

composer進程有1個主線程,幾個HwBinder線程,幾個vndbinder線程,vsync線程 thread #1: name = 'composer@2.4-se' thread #2: name = 'vndbinder:413_1' thread #3: name = 'uevent-listener' thread #4: name = 'HwBinder:413_1' thread #5: name = 'vndbinder:413_2' thread #6: name = 'HwBinder:413_2' thread #7: name = 'composer@2.4-se' thread #8: name = 'vsync' thread #9: name = 'composer@2.4-se' thread #10: name = 'vsync' thread #11: name = 'HwBinder:413_3'

2. 2 模塊構成

#啟動配置文件 android.hardware.graphics.composer@2.1-service.rc #main與cmd分解,ComposerCommandEngine.h android.hardware.graphics.composer@2.4-service #binder消息接收libhidlbase.so#cmd分解,ComposerCommandEngine.handroid.hardware.graphics.composer@2.4-service#ComposerResources.cppandroid.hardware.graphics.composer@2.1-resources.so #對gralloc的處理,BsMapper.handroid.hardware.graphics.mapper@4.0.so#mapper實現,如CrosGralloc4Mapper.ccandroid.hardware.graphics.mapper@4.0-impl.minigbm.so#minigbm實現,drv.c/drv_helpers.c如drv_bo_importlibminigbm_gralloc.so#對libdrm的依賴,DRM_IOCTL_PRIME_FD_TO_HANDLElibdrm.so

2. 3 初始化

2. 4 SF交互

  • Hotplug
1. 檢測到顯示功能更改,onHotplug(display, connection=CONNECTED)通知SF 2. 收到通知后,SF會丟棄其顯示狀態,并通過getActiveConfig 、 getDisplayConfigs 、 getDisplayAttribute 、 getColorModes 、 getHdrCapabilities和getDisplayCapabilities重新創建 3. SF重新創建新的顯示狀態后,它會將onDisplayChanged回調發送到正在偵聽此類事件的應用程序
  • SurfaceFlinger更新顯示. 以2個display,每個display多個layer為例,介紹畫面更新時SurfaceFlinger與hwc交互.

    SF首先讓hwc更新display 0每個layer,然后PRESENT_OR_VALIDATE_DISPLAY,最后PRESENT_DISPLAY; 然后讓hwc更新display 1每個layer,然后PRESENT_OR_VALIDATE_DISPLAY,最后PRESENT_DISPLAY.
#SF通知hwc更新display 0 layer 1-6的COMPOSITION_TYPE;設置SURFACE_DAMAGE;設置LAYER_BUFFER setVsyncEnabled(display=0, enabled=ENABLE) SET_LAYER_COMPOSITION_TYPE SetLayerCompositionType(display=0 layer=6, type=2) SET_LAYER_COMPOSITION_TYPE SetLayerCompositionType(display=0 layer=5, type=2) SET_LAYER_SURFACE_DAMAGE setLayerSurfaceDamage(display=0, layer=4, damage=size=1) SET_LAYER_BUFFER setLayerBuffer(display=0, layer=4, buffer=0xeb882a00, acquireFence=15) SET_LAYER_COMPOSITION_TYPE setLayerCompositionType(display=0, layer=3, type=2) SET_LAYER_COMPOSITION_TYPE setLayerCompositionType(display=0, layer=2, type=2) SET_LAYER_COMPOSITION_TYPE setLayerCompositionType(display=0, layer=1, type=2) ... #顯示校驗 PRESENT_OR_VALIDATE_DISPLAY#Hwchal.h:327validateDisplay_2_4(display=0, ...)GetChangedCompositionTypesGetChangedCompositionTypesgetDisplayRequestsgetDisplayRequests#hwc接收修改 ACCEPT_DISPLAY_CHANGESacceptDisplayChanges(display=0)#GPU合成后設置到Hwc SET_CLIENT_TARGETsetClientTarget(display=0, target=0xe6781820, acquireFence=-1, dataspace=0, damage=size=0)#顯示到屏幕 PRESENT_DISPLAYpresentDisplay(display=0, ... ) getReleaseFences(display=0, ...)getReleaseFences #display 1重復上述操作.更新layer 7-11的COMPOSITION_TYPE,SURFACE_DAMAGE,LAYER_BUFFER #循環給display1所有layer進行處理 SET_LAYER_COMPOSITION_TYPE SetLayerCompositionType(display=1, layer=13, type=2) SET_LAYER_COMPOSITION_TYPE SetLayerCompositionType(display=1, layer=12, type=2) SET_LAYER_SURFACE_DAMAGE setLayerSurfaceDamage(display=1, layer=11, damage=size=1) SET_LAYER_BUFFER setLayerBuffer(display=1, layer=11, buffer=0xea943240, acquireFence=17) SET_LAYER_COMPOSITION_TYPE setLayerCompositionType(display=1, layer=11, type=2) SET_LAYER_COMPOSITION_TYPE setLayerCompositionType(display=1, layer=10, type=2) SET_LAYER_COMPOSITION_TYPE setLayerCompositionType(display=1, layer=8, type=2) SET_LAYER_COMPOSITION_TYPE setLayerCompositionType(display=1, layer=7, type=2) ... #開始校驗和顯示

2. 5 drm交互

drm_hwcomposer與libdrm交互接口和流程.
  • 不更新畫面. drm_hwc周期性drmModeAtomicCommit提交
#drm_hwcomposer向drm提交顯示 PRESENT_DISPLAY PresentDisplay CreateCompositionDrmAtomicStateManager::ExecuteAtomicCommitCommitFramedrmModeAtomicCommit
  • 更新畫面. drm_hwc不斷import buffer,創建framebuffer object,AtomicCommit提交顯示
#SurfaceFlinger設置一個layerBuffer,最終依賴minigbm import SET_LAYER_BUFFER #composer@2.4-serviceexecuteSetLayerBuffergetLayerBuffer #composer@2.1-resources.sogetHandleimportBuffer #該實現從composer@2.1-resources.so調用graphics.mapper@4.0.so,再調用graphics.mapper@4.0-impl.minigbm.soCrosGralloc4Mapper::importBuffercros_gralloc_driver::retaindrv_bo_importdrv_prime_bo_importDRM_IOCTL_PRIME_FD_TO_HANDLE #SurfaceFlinger調用PRESENT_OR_VALIDATE_DISPLAY PRESENT_OR_VALIDATE_DISPLAY #composer@2.4-serviceexecutePresentOrValidateDisplayexecuteValidateDisplayInternalvalidateDisplay #hwcomposer.drm.soCreateCompositionPopulateLayerDataImportFbGetOrCreateFbId#創建FBO需要gem handledrmPrimeFDToHandle#Import dmabufs and register FBDrmFbIdHandle::CreateInstance#創建Framebuffer objectdrmModeAddFB2(width=400, height=600,..) #drm_hwcomposer向drm提交顯示 PRESENT_DISPLAY PresentDisplay CreateCompositionDrmAtomicStateManager::ExecuteAtomicCommitCommitFramedrmModeAtomicCommit #SurfaceFlinger銷毀Layer _hidl_destroyLayer #銷毀一個layer,最終依賴minigbm#composer@2.1-resources.soComposerResources::removeLayerComposerLayerResource::~ComposerLayerResourceComposerHandleCache::~ComposerHandleCacheBsMapper::freeBuffer #mapper@4.0.so#libminigbm_gralloc.socros_gralloc_buffer::~cros_gralloc_bufferdrv_bo_destroyvirgl_bo_destroydrv_gem_bo_destroyDRM_IOCTL_GEM_CLOSE

2.6 bufferinfo

2.7 用例與demo

  • hwc-drm-tests
  • demo
external/drm_hwcomposer/tests

3 drm-hwc多屏

4 DPU合成

若Drm Plane個數不足,如沒有OVERLAY_PALNE,就只能GPU合成 若Gralloc申請的僅是GPU內存,無法Convert為Drm格式,也只能GPU合成

4 .1.Usage

  • GraphicBuffer格式

    決定Layer能否被DPU使用.GRALLOC_USAGE_HW_FB格式的layer才能被drm-hwc ConvertBo,否則Layer只能被GPU合成
STANDARD_USAGE = GRALLOC_USAGE_SW_READ_MASK | /* 0x0FU */ GRALLOC_USAGE_SW_WRITE_MASK | /* 0xF0U */ GRALLOC_USAGE_HW_TEXTURE | /* 1U << 8 */ GRALLOC_USAGE_HW_RENDER | /* 1U << 9 */ GRALLOC_USAGE_HW_2D | /* 1U << 10 */ GRALLOC_USAGE_HW_COMPOSER | /* 1U << 11 */ GRALLOC_USAGE_HW_FB | /* 1U << 12 */ GRALLOC_USAGE_EXTERNAL_DISP | /* 1U << 13 */ GRALLOC_USAGE_PROTECTED | /* 1U << 14 */ GRALLOC_USAGE_CURSOR | /* 1U << 15 */ GRALLOC_USAGE_HW_VIDEO_ENCODER | /* 1U << 16 */ GRALLOC_USAGE_HW_CAMERA_WRITE | /* 1U << 17 */ GRALLOC_USAGE_HW_CAMERA_READ | /* 1U << 18 */ GRALLOC_USAGE_RENDERSCRIPT | /* 1U << 20 */ GRALLOC_USAGE_DECODER | /* 1U << 22 */ /* Producer and consumer usage are combined, but on Gralloc version 1- there is no way to differentiate these as they- are mapped to the same value (1U << 23). */ GRALLOC_USAGE_SENSOR_DIRECT_DATA | /* 1U << 23 */ GRALLOC_USAGE_GPU_DATA_BUFFER | /* 1U << 24 */ GRALLOC_USAGE_FRONTBUFFER; /* 1L << 32 */
  • Buffer申請
#申請buffer 帶 GRALLOC_USAGE_HW_FB usagegralloc_alloc_framebuffer #從/dev/fb或/dev/graphic/fb申請gralloc_alloc_buffer #從dma_heap或ion(cma)

4.2.Plane

  • 類型
#1. Drm plane共有3中格式 DRM_PLANE_TYPE_OVERLAY: DRM_PLANE_TYPE_PRIMARY: DRM_PLANE_TYPE_CURSOR: #2. Drm_hwc只使用了PRIMARY和OVERLAY,CURSOR忽略
  • 數量. 決定了能否hwc合成,至少需要一個PRIMARY
#1. 至少1個PLANE PRIMARY #2. Cuttlefish drmvirgl共4個PLANE,2PRIMARY和2CURSOR
  • Format
#1. HAL format與Drm format對應關系,參考ConvertHalFormatToDrm HAL_PIXEL_FORMAT_RGB_888:3-> DRM_FORMAT_BGR888; HAL_PIXEL_FORMAT_BGRA_8888:5-> DRM_FORMAT_ARGB8888; HAL_PIXEL_FORMAT_RGBX_8888:2-> DRM_FORMAT_XBGR8888; HAL_PIXEL_FORMAT_RGBA_8888:1 //常見于Android Layer-> DRM_FORMAT_ABGR8888; HAL_PIXEL_FORMAT_RGB_565:4-> DRM_FORMAT_BGR565; HAL_PIXEL_FORMAT_YV12:842094169-> DRM_FORMAT_YVU420; HAL_PIXEL_FORMAT_RGBA_1010102:43-> DRM_FORMAT_ABGR2101010; #2. ConvertBo會將Layer轉換為Drm支持格式 #3. 在createComposition也會檢查layer格式是否是Drm支持的

4.3.Property

vendor.hwc.drm.use_overlay_planes vendor.hwc.drm.scale_with_gpu

4.4.數據結構

  • HwcLayer
(android::DrmHwcTwo::HwcLayer) layer = {acquire_fence_ = (fd_ = 36)release_fence_ = (fd_ = -1)sf_type_ = Devicevalidated_type_ = Clientblending_ = Premultipliedbuffer_ = 0xb400e913f81c7630display_frame_ = (left = 0, top = 0, right = 1920, bottom = 1080)alpha_ = 1source_crop_ = (left = 0, top = 0, right = 1920, bottom = 1080)cursor_x_ = 0cursor_y_ = 0layer_color_ = (r = '\0', g = '\0', b = '\0', a = '\0')transform_ = Nonez_order_ = 0dataspace_ = HAL_DATASPACE_UNKNOWN }
  • private_handle_t

    其中buffer_是一個gralloc申請的buffer_handle_t,轉換為private_handle_t后可看到buffer結構

總結

以上是生活随笔為你收集整理的Android drm-hwcomposer的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。