Android P 显示流程分析(四)---界面刷新

上篇分析到SurfaceFlinger.signalRefresh()里会调用到SurfaceFlinger里的handleMessageRefresh(), 现在这里面开始涉及到图层合成了,这里面涉及的流程。

handleMessageRefresh()

void SurfaceFlinger::handleMessageRefresh() {
    mRefreshPending = false;
    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
	//合成图像前的准备工作,设置各种状态
    preComposition(refreshStartTime);
    //重建可见区域的所有图层
    rebuildLayerStacks();
    //启动硬件图像合成
    setUpHWComposer();
    //调试信息
    doDebugFlashRegions();
    doTracing("handleRefresh");
    logLayerStats();
    //合成处理
    doComposition();
    //更新状态与下次合成时间
    postComposition(refreshStartTime);
}

上面重点的就是两块,一个setupHWComposer() 启动硬件图像合成, 另一个是doComposition()合成处理。

setUpHWComposer()

void SurfaceFlinger::setUpHWComposer() {
...
    if (CC_UNLIKELY(mGeometryInvalid)) {
        mGeometryInvalid = false;
        //遍历所有的显示设备
        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
            sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
            const auto hwcId = displayDevice->getHwcDisplayId();
            if (hwcId >= 0) {
                const Vector<sp<Layer>>& currentLayers(
                        displayDevice->getVisibleLayersSortedByZ());
                //遍历当前显示设备的所有图层
                for (size_t i = 0; i < currentLayers.size(); i++) {
                    const auto& layer = currentLayers[i];
                    if (!layer->hasHwcLayer(hwcId)) {
                    	//如果没有硬件图层,则创建一个硬件图层
                        if (!layer->createHwcLayer(getBE().mHwc.get(), hwcId)) {
                            layer->forceClientComposition(hwcId);
                            continue;
                        }
                    }
					//设置图层大小,坐标
                    layer->setGeometry(displayDevice, i);
                    if (mDebugDisableHWC || mDebugRegion) {
                        layer->forceClientComposition(hwcId);
                    }
                }
            }
        }
    // Set the per-frame data
    //遍历所有显示屏
    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
        auto& displayDevice = mDisplays[displayId];
        const auto hwcId = displayDevice->getHwcDisplayId();

        if (hwcId < 0) {
            continue;
        }
        //更新颜色变化
        if (mDrawingState.colorMatrixChanged) {
            displayDevice->setColorTransform(mDrawingState.colorMatrix);
            status_t result = getBE().mHwc->setColorTransform(hwcId, mDrawingState.colorMatrix);
            ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
                    "display %zd: %d", displayId, result);
        }
        //遍历当前显示屏的所有图层
        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
        	//设置数据存储格式
            if (layer->isHdrY410()) {
                layer->forceClientComposition(hwcId);
            } else if ((layer->getDataSpace() == Dataspace::BT2020_PQ ||
                        layer->getDataSpace() == Dataspace::BT2020_ITU_PQ) &&
                    !displayDevice->hasHDR10Support()) {
                layer->forceClientComposition(hwcId);
            } else if ((layer->getDataSpace() == Dataspace::BT2020_HLG ||
                        layer->getDataSpace() == Dataspace::BT2020_ITU_HLG) &&
                    !displayDevice->hasHLGSupport()) {
                layer->forceClientComposition(hwcId);
            }
			//设置图层合成类型
            if (layer->getForceClientComposition(hwcId)) {
                ALOGV("[%s] Requesting Client composition", layer->getName().string());
                layer->setCompositionType(hwcId, HWC2::Composition::Client);
                continue;
            }
			//图层的数据设置到显示器
            layer->setPerFrameData(displayDevice);
        }
		//设置颜色模式
        if (hasWideColorDisplay) {
            ColorMode colorMode;
            Dataspace dataSpace;
            RenderIntent renderIntent;
            pickColorMode(displayDevice, &colorMode, &dataSpace, &renderIntent);
            setActiveColorModeInternal(displayDevice, colorMode, dataSpace, renderIntent);
        }
    } 
    mDrawingState.colorMatrixChanged = false;
	//遍历所有显示屏设备,做了prepareFrame
    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
        auto& displayDevice = mDisplays[displayId];
        if (!displayDevice->isDisplayOn()) {
            continue;
        }

        status_t result = displayDevice->prepareFrame(*getBE().mHwc);
        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
                " %d (%s)", displayId, result, strerror(-result));
    }       
    }

因为setUpHWComposer()里做的事情很多,我们一个一个来撸下:

  1. layer->createHwcLayer(getBE().mHwc.get(), hwcId)

    --> HWComposer->createLayer(hwcId)
    

按照我们《Android P 显示流程(一)—Display设备初始化过程分析》
后续最终会调用到HWC2On1Adapter里的createLayer的方法:

Error HWC2On1Adapter::Display::createLayer(hwc2_layer_t* outLayerId) {
    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
	//通过当前Display对象,创建一个新的layer对象,最后添加到mLayers 容器中
    auto layer = *mLayers.emplace(std::make_shared<Layer>(*this));
    mDevice.mLayers.emplace(std::make_pair(layer->getId(), layer));
    *outLayerId = layer->getId();
    ALOGV("[%" PRIu64 "] created layer %" PRIu64, mId, *outLayerId);
    markGeometryChanged();
    return Error::None;
}
  1. layer->setGeometry(displayDevice, i)
    设置图层大小和坐标位置,这个不是重点,我们就不往下分析了,后面更新颜色矩阵变化也直接跳过

  2. 后面有遍历显示屏的所有图层,设置数据存储格式也跳过不研究,来看看设置合成类型。

void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type, bool callIntoHwc) {
    auto& hwcInfo = getBE().mHwcLayers[hwcId];
    auto& hwcLayer = hwcInfo.layer;	
    //判读与目前此图层的合成类型是否一致,如果不一致,更改合成类型
    if (hwcInfo.compositionType != type) {
        ALOGV("    actually setting");
        hwcInfo.compositionType = type;
        if (callIntoHwc) {
            auto error = hwcLayer->setCompositionType(type);
        }
    }
}
Error Layer::setCompositionType(Composition type)
{
    auto intType = static_cast<Hwc2::IComposerClient::Composition>(type);
    auto intError = mComposer.setLayerCompositionType(
            mDisplayId, mId, intType);
    return static_cast<Error>(intError);
}
//同之前分析的流程,最后会调用到HWC2On1Adapter里面
Error HWC2On1Adapter::Layer::setCompositionType(Composition type)
{
    mCompositionType.setPending(type);
    return Error::None;
}                

这个设置图层的类型,那图层到底有哪些类型呢?

  • Composition::Client
  • Composition::Device
  • Composition::SolidColor
  • Composition::Cursor
  • Composition::Sideband
    上面这几种Composition 类型到底有什么区别呢,看看applyCompositionType:
void HWC2On1Adapter::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer,
        bool applyAllState)
{
    // HWC1 never supports color transforms or dataspaces and only sometimes
    // supports plane alpha (depending on the version). These require us to drop
    // some or all layers to client composition.
    if (mHasUnsupportedDataspace || mHasUnsupportedPlaneAlpha ||
            mDisplay.hasColorTransform()) {
        hwc1Layer.compositionType = HWC_FRAMEBUFFER;
        hwc1Layer.flags = HWC_SKIP_LAYER;
        return;
    }

    if (applyAllState || mCompositionType.isDirty()) {
        hwc1Layer.flags = 0;
        switch (mCompositionType.getPendingValue()) {
            case Composition::Client:
                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
                hwc1Layer.flags |= HWC_SKIP_LAYER;
                break;
            case Composition::Device:
                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
                break;
            case Composition::SolidColor:
                // In theory the following line should work, but since the HWC1
                // version of SurfaceFlinger never used HWC_BACKGROUND, HWC1
                // devices may not work correctly. To be on the safe side, we
                // fall back to client composition.
                //
                // hwc1Layer.compositionType = HWC_BACKGROUND;
                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
                hwc1Layer.flags |= HWC_SKIP_LAYER;
                break;
            case Composition::Cursor:
                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
                if (mDisplay.getDevice().getHwc1MinorVersion() >= 4) {
                    hwc1Layer.hints |= HWC_IS_CURSOR_LAYER;
                }
                break;
            case Composition::Sideband:
                if (mDisplay.getDevice().getHwc1MinorVersion() < 4) {
                    hwc1Layer.compositionType = HWC_SIDEBAND;
                } else {
                    hwc1Layer.compositionType = HWC_FRAMEBUFFER;
                    hwc1Layer.flags |= HWC_SKIP_LAYER;
                }
                break;
            default:
                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
                hwc1Layer.flags |= HWC_SKIP_LAYER;
                break;
        }
        ALOGV("Layer %" PRIu64 " %s set to %d", mId,
                to_string(mCompositionType.getPendingValue()).c_str(),
                hwc1Layer.compositionType);
        ALOGV_IF(hwc1Layer.flags & HWC_SKIP_LAYER, "    and skipping");
        mCompositionType.latch();
    }
}

这几种虽然不一样,但对应的hwc1Layer.compositionType都是HWC_FRAMEBUFFER,实际上对应HAL层的实现没什么区别。

  1. 每个图层设置每帧的数据
    layer->setPerFrameData(displayDevice)
    但图层又分BufferLayer和ColorLayer,这两路图层有什么区别呢?
        const sp<Client>& client,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        int32_t windowType, int32_t ownerUid, sp<IBinder>* handle,
        sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent)
{
 switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceNormal:
            result = createBufferLayer(client,
                    uniqueName, w, h, flags, format,
                    handle, gbp, &layer);

            break;
        case ISurfaceComposerClient::eFXSurfaceColor:
            result = createColorLayer(client,
                    uniqueName, w, h, flags,
                    handle, &layer);
            break;
        default:
            result = BAD_VALUE;
            ...

创建图层时,根据Flag 的不同来创建图层的,一种是纯色的,一种是普通数据显示的图层,这里我们一般指的是BufferLayer.
那继续看BufferLayer的setPerFrameData的函数:

void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
    // Apply this display's projection's viewport to the visible region
    // before giving it to the HWC HAL.
    const Transform& tr = displayDevice->getTransform();
    const auto& viewport = displayDevice->getViewport();
    Region visible = tr.transform(visibleRegion.intersect(viewport));
    auto hwcId = displayDevice->getHwcDisplayId();
    auto& hwcInfo = getBE().mHwcLayers[hwcId];
    auto& hwcLayer = hwcInfo.layer;
    //设置可见区域
    auto error = hwcLayer->setVisibleRegion(visible);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
              to_string(error).c_str(), static_cast<int32_t>(error));
        visible.dump(LOG_TAG);
    }
	//设置损坏区域
    error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
              to_string(error).c_str(), static_cast<int32_t>(error));
        surfaceDamageRegion.dump(LOG_TAG);
    }

    //如果是sideband 图层,直接设置sideband流,然后就返回了
    if (getBE().compositionInfo.hwc.sidebandStream.get()) {
        setCompositionType(hwcId, HWC2::Composition::Sideband);
        ALOGV("[%s] Requesting Sideband composition", mName.string());
        error = hwcLayer->setSidebandStream(getBE().compositionInfo.hwc.sidebandStream->handle());
        if (error != HWC2::Error::None) {
            ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(),
                  getBE().compositionInfo.hwc.sidebandStream->handle(), to_string(error).c_str(),
                  static_cast<int32_t>(error));
        }
        return;
    }

	//如果是设备或光标图层,设置相对应的CompositionType
    // Device or Cursor layers
    if (mPotentialCursor) {
        ALOGV("[%s] Requesting Cursor composition", mName.string());
        setCompositionType(hwcId, HWC2::Composition::Cursor);
    } else {
        ALOGV("[%s] Requesting Device composition", mName.string());
        setCompositionType(hwcId, HWC2::Composition::Device);
    }
	//设置Dataspace
    ALOGV("setPerFrameData: dataspace = %d", mCurrentDataSpace);
    error = hwcLayer->setDataspace(mCurrentDataSpace);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentDataSpace,
              to_string(error).c_str(), static_cast<int32_t>(error));
    }
	//设置metadata
    const HdrMetadata& metadata = mConsumer->getCurrentHdrMetadata();
    error = hwcLayer->setPerFrameMetadata(displayDevice->getSupportedPerFrameMetadata(), metadata);
    if (error != HWC2::Error::None && error != HWC2::Error::Unsupported) {
        ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(),
              to_string(error).c_str(), static_cast<int32_t>(error));
    }
	//获取hwcBuffer
    uint32_t hwcSlot = 0;
    sp<GraphicBuffer> hwcBuffer;
    hwcInfo.bufferCache.getHwcBuffer(getBE().compositionInfo.mBufferSlot,
                                     getBE().compositionInfo.mBuffer, &hwcSlot, &hwcBuffer);
	//根据fence,设置buffer
    auto acquireFence = mConsumer->getCurrentFence();
    error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
              getBE().compositionInfo.mBuffer->handle, to_string(error).c_str(),
              static_cast<int32_t>(error));
    }
}

那重点来看看获取hwcBuffer和设置buffer

void HWComposerBufferCache::getHwcBuffer(int slot,
        const sp<GraphicBuffer>& buffer,
        uint32_t* outSlot, sp<GraphicBuffer>* outBuffer)
{
    if (slot == BufferQueue::INVALID_BUFFER_SLOT || slot < 0) {
        // default to slot 0
        slot = 0;
    }

    if (static_cast<size_t>(slot) >= mBuffers.size()) {
        mBuffers.resize(slot + 1);
    }
    *outSlot = slot;
    if (mBuffers[slot] == buffer) {
        // already cached in HWC, skip sending the buffer
        *outBuffer = nullptr;
    } else {
        *outBuffer = buffer;

        // update cache
        mBuffers[slot] = buffer;
    }
}

获取Buffer 其实就是将buffer指向outBuffer, 将slot 赋值给outSlot, 中间经过了一个mBuffer[]的缓存。

  • 那最后看设置Buffer, setBuffer根据之前的调用链分析会调用到HW2On1Adapter::Layer里的setBuffer.
Error HWC2On1Adapter::Layer::setBuffer(buffer_handle_t buffer,
        int32_t acquireFence) {
    ALOGV("Setting acquireFence to %d for layer %" PRIu64, acquireFence, mId);
    mBuffer.setBuffer(buffer);
    mBuffer.setFence(acquireFence);
    return Error::None;
}

到这里setPerFrameData 这个函数分析完了。

  1. 遍历所有显示屏,displayDevice->prepareFrame(*getBE().mHwc), 这里面针对FrameBufferSurface来做,没有做实际的事情。这个就跳过不分析了。
    到这里setUpHWComposer() 就分析完了,下篇我们来关键的doCompostion().
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值