显示HWC合成(hwc_display_contents_1_t,hwc_layer_1_t数据结构关系)

在之前的博客中,分析了SurfaceFlinger的流程,以及hwc和Gralloc模块的大致功能,但是对其中一些数据结构不是很清楚. 这篇博客我们主要从创建hwc_display_contents_1_t数据结构入手开始对hal层 hwc的一些数据结构进行分析。

创建hwc_display_contents_1_t

我们先来看看setUpHWComposer函数中如下代码,会遍历各个display(每个显示设备),然后调用HWComposer的createWorkList函数,并且把当前layer的数量count作为参数。后面还会调用hwc的prepare函数。

    ......
    HWComposer& hwc(getHwComposer());
    if (hwc.initCheck() == NO_ERROR) {
        // build the h/w work list
        if (CC_UNLIKELY(mHwWorkListDirty)) {
            mHwWorkListDirty = false;
            for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
                sp<const DisplayDevice> hw(mDisplays[dpy]);
                const int32_t id = hw->getHwcDisplayId();
                if (id >= 0) {
                    const Vector< sp<Layer> >& currentLayers(
                        hw->getVisibleLayersSortedByZ());
                    const size_t count = currentLayers.size();
                    if (hwc.createWorkList(id, count) == NO_ERROR) {
                        ......
                    }
                }
            }
        }
    ......
    status_t err = hwc.prepare();
    ......

我们先来看DisplayData数据结构,它就代表一个显示设备的数据。其中list变量(hwc_display_contents_1_t类型)包括这个显示设备上所有的layer数据,layer数据放在hwLayers中。这个list的最后一个就是framebufferTarget(gpu合成之后的layer),然后在DisplayData数据结构中单独给了一个变量framebufferTarget。

    struct DisplayData {
        DisplayData();
        ~DisplayData();
        Vector<DisplayConfig> configs;
        size_t currentConfig;
        uint32_t format;    // pixel format from FB hal, for pre-hwc-1.1
        bool connected;
        bool hasFbComp;
        bool hasOvComp;
        size_t capacity;
        hwc_display_contents_1* list;//各个layer
        hwc_layer_1* framebufferTarget;//gpu合成之后的layer
        buffer_handle_t fbTargetHandle;
        sp<Fence> lastRetireFence;  // signals when the last set op retires
        sp<Fence> lastDisplayFence; // signals when the last set op takes
                                    // effect on screen
        buffer_handle_t outbufHandle;
        sp<Fence> outbufAcquireFence;

        // protected by mEventControlLock
        int32_t events;
    };

createWorkList函数先是计算我们要申请layer的内存大小,然后通过malloc申请内存,并且地址赋给disp.list.后面我们把disp.list->hwLayers的最后一个其实就是gpu合成之后的layer framebufferTarget。当然我们也就把这个hwc_layer_1赋给了disp.framebufferTarget.

status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {
    if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) {
        return BAD_INDEX;
    }

    if (mHwc) {
        DisplayData& disp(mDisplayData[id]);
        if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
            // we need space for the HWC_FRAMEBUFFER_TARGET
            numLayers++;
        }
        if (disp.capacity < numLayers || disp.list == NULL) {
            size_t size = sizeof(hwc_display_contents_1_t)
                    + numLayers * sizeof(hwc_layer_1_t);//申请内存的大小
            free(disp.list);
            disp.list = (hwc_display_contents_1_t*)malloc(size);//malloc内存
            disp.capacity = numLayers;
        }
        if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
            disp.framebufferTarget = &disp.list->hwLayers[numLayers - 1];//list的hwLayers最后一个就是framebufferTarget
            memset(disp.framebufferTarget, 0, sizeof(hwc_layer_1_t));
            const DisplayConfig& currentConfig =
                    disp.configs[disp.currentConfig];
            const hwc_rect_t r = { 0, 0,
                    (int) currentConfig.width, (int) currentConfig.height };
            disp.framebufferTarget->compositionType = HWC_FRAMEBUFFER_TARGET;//类型变成target的
            disp.framebufferTarget->hints = 0;
            disp.framebufferTarget->flags = 0;
            disp.framebufferTarget->handle = disp.fbTargetHandle;
            disp.framebufferTarget->transform = 0;
            disp.framebufferTarget->blending = HWC_BLENDING_PREMULT;
            if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {
                disp.framebufferTarget->sourceCropf.left = 0;
                disp.framebufferTarget->sourceCropf.top = 0;
                disp.framebufferTarget->sourceCropf.right =
                        currentConfig.width;
                disp.framebufferTarget->sourceCropf.bottom =
                        currentConfig.height;
            } else {
                disp.framebufferTarget->sourceCrop = r;
            }
            disp.framebufferTarget->displayFrame = r;
            disp.framebufferTarget->visibleRegionScreen.numRects = 1;
            disp.framebufferTarget->visibleRegionScreen.rects =
                &disp.framebufferTarget->displayFrame;
            disp.framebufferTarget->acquireFenceFd = -1;
            disp.framebufferTarget->releaseFenceFd = -1;
            disp.framebufferTarget->planeAlpha = 0xFF;
        }
        disp.list->retireFenceFd = -1;
        disp.list->flags = HWC_GEOMETRY_CHANGED;
        disp.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值