Android Surface对应的Buffer怎么传递给HWC

Android Surface对应的Buffer怎么传递给HWC

引言

因为要预研Android Video overlay,需要将SurfaceView对应的GraphicBuffer从drm_hwcomposer中剥离出来,这就需要们了解SurfaceView对应的GraphicBuffer的前世今生,以及它的数据流向以及在各个模块之间的对应关系。这篇博客,我们分析下该GraphicBuffer是如何传递到HWC的。

参考源码基于Android 13 AOSP!

Surface的Buffer是怎么传递给HWC呢

我们通过代码流程来看看:

c 复制代码
using LayerFESet = std::unordered_set<sp<LayerFE>, LayerFESpHash>;
SurfaceFlinger::composite(...)
    compositionengine::CompositionRefreshArgs refreshArgs;  
        mDrawingState.traverseInZOrder([&refreshArgs](Layer* layer) {
            if (auto layerFE = layer->getCompositionEngineLayerFE())
                refreshArgs.layers.push_back(layerFE);
        });        
        android::compositionengine::impl::CompositionEngine::present
            LayerFESet latchedLayers;
            for (const auto& output : args.outputs) {
                output->prepare(args, latchedLayers);//impl::Output
                   rebuildLayerStacks(refreshArgs, geomSnapshots)
                        compositionengine::Output::CoverageState coverage{layerFESet};
                        collectVisibleLayers(refreshArgs, coverage);                    
                             for (auto layer : reversed(refreshArgs.layers)) {
                                ensureOutputLayerIfVisible(layer, coverage);
                                     if (!coverage.latchedLayers.count(layerFE)) {
                                            coverage.latchedLayers.insert(layerFE);
                                            layerFE->prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry);
                                     }                                
                                     if (!coverage.latchedLayers.count(layerFE)) {
                                        coverage.latchedLayers.insert(layerFE);
                                        layerFE->prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry);
                                    }
                                    const auto* layerFEState = layerFE->getCompositionState();
                                    ensureOutputLayer(prevOutputLayerIndex, layerFE)
                            }               
            }           
        
            updateLayerStateFromFE(args)
        
            for (const auto& output : args.outputs) {
                output->present(args);//impl::Output frameworks/native/services/surfaceflinger/CompositionEngine/src/Output.cpp
                    updateCompositionState(refreshArgs)
                    writeCompositionState(refreshArgs)//impl::Output
                        layer->writeStateToHWC(...)//impl::OutputLayer
                            writeOutputIndependentPerFrameStateToHWC(...)
                                writeBufferStateToHWC(...)
                                    hwcLayer->setBuffer(...)//HWC2::impl::Layer
                                        mComposer.setLayerBuffer(...)//Hwc2::impl::Composer
                                
        }    
        

这里output实际上是Display,但是Display中没有实现prepare,因为Display继承自Output,使用的是父类Output的prepare方法。


ensureOutputLayerIfVisible

这里我们看下ensureOutputLayerIfVisible的作用,主要是构建出来看见的OutputLayer.

c 复制代码
//frameworks/native/services/surfaceflinger/CompositionEngine/src/Output.cpp
void Output::ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>& layerFE,
                                        compositionengine::Output::CoverageState& coverage) 
    layerFE->prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry)
    const auto* layerFEState = layerFE->getCompositionState()
    //图层可见。如果我们有输出图层,可以重复使用现有的输出图层。则重用现有的输出层,否则创建一个新的输出层
    auto result = ensureOutputLayer(prevOutputLayerIndex, layerFE)
 
 ///frameworks/native/services/surfaceflinger/Layer.cpp   
Layer::prepareCompositionState(compositionengine::LayerFE::StateSubset subset) // 传入的参数是BasicGeometry
    prepareBasicGeometryCompositionState()

void Layer::prepareBasicGeometryCompositionState() {
    const auto& drawingState{getDrawingState()};
    const auto alpha = static_cast<float>(getAlpha());
    const bool opaque = isOpaque(drawingState);
    const bool usesRoundedCorners = hasRoundedCorners();

    auto blendMode = Hwc2::IComposerClient::BlendMode::NONE;
    if (!opaque || alpha != 1.0f) {
        blendMode = mPremultipliedAlpha ? Hwc2::IComposerClient::BlendMode::PREMULTIPLIED
                                        : Hwc2::IComposerClient::BlendMode::COVERAGE;
    }

    auto* compositionState = editCompositionState();//实现在BufferLayer中,获取的是LayerFECompositionState
    compositionState->outputFilter = getOutputFilter();
    compositionState->isVisible = isVisible();
    compositionState->isOpaque = opaque && !usesRoundedCorners && alpha == 1.f;
    compositionState->shadowRadius = mEffectiveShadowRadius;

    compositionState->contentDirty = contentDirty;
    contentDirty = false;

    compositionState->geomLayerBounds = mBounds;
    compositionState->geomLayerTransform = getTransform();
    compositionState->geomInverseLayerTransform = compositionState->geomLayerTransform.inverse();
    compositionState->transparentRegionHint = getActiveTransparentRegion(drawingState);

    compositionState->blendMode = static_cast<Hwc2::IComposerClient::BlendMode>(blendMode);
    compositionState->alpha = alpha;
    compositionState->backgroundBlurRadius = drawingState.backgroundBlurRadius;
    compositionState->blurRegions = drawingState.blurRegions;
    compositionState->stretchEffect = getStretchEffect();
}

如果可见,需要生成一个outputLayer,放在mPendingOutputLayersOrderedByZ

这里我们对该函数单独站看来分析下,ensureOutputLayer将创建Output layer,不是所有layer都会创建对应的hwc layer,创建出来的这些layer最后是要显示到屏幕上的。

c 复制代码
//frameworks/native/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h

OutputLayer* ensureOutputLayer(std::optional<size_t> prevIndex,
                                       const sp<LayerFE>& layerFE) {

            // 判断当前的outputlayer 集合里面有没有当前的layer,如果没有则新创建一个
            auto outputLayer = (prevIndex && *prevIndex <= mCurrentOutputLayersOrderedByZ.size())
                    ? std::move(mCurrentOutputLayersOrderedByZ[*prevIndex])
                    : BaseOutput::createOutputLayer(layerFE);
            auto result = outputLayer.get();
            mPendingOutputLayersOrderedByZ.emplace_back(std::move(outputLayer));
            return result;
        }
        
//frameworks/native/services/surfaceflinger/CompositionEngine/src/Display.cpp

std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer(
        const sp<compositionengine::LayerFE>& layerFE) const {
    auto result = impl::createOutputLayer(*this, layerFE);

    if (result && mId) {
        auto& hwc = getCompositionEngine().getHwComposer();
        auto displayId = *mId;
        // 创建hwclayer
        auto hwcLayer = std::shared_ptr<HWC2::Layer>(hwc.createLayer(displayId),
                                                     [&hwc, displayId](HWC2::Layer* layer) {
                                                         hwc.destroyLayer(displayId, layer);
                                                     });
        ALOGE_IF(!hwcLayer, "Failed to create a HWC layer for a HWC supported display %s",
                 getName().c_str());
        // 更新state.hwc
        result->setHwcLayer(std::move(hwcLayer));
    }
    return result;
}        
        

到这里就完成了OutputLayer和hwc layer的创建。


updateLayerStateFromFE

Update the composition state from each front-end layer更新各前端层的组成状态,我们来看其实现:

c 复制代码
//frameworks/native/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
void CompositionEngine::updateLayerStateFromFE(CompositionRefreshArgs& args) {
    // Update the composition state from each front-end layer
    for (const auto& output : args.outputs) {
        output->updateLayerStateFromFE(args);
    }
}
void Output::updateLayerStateFromFE(const CompositionRefreshArgs& args) const {
    for (auto* layer : getOutputLayersOrderedByZ()) {//这个传递的参数是GeometryAndContent
        layer->getLayerFE().prepareCompositionState(
                args.updatingGeometryThisFrame ? LayerFE::StateSubset::GeometryAndContent
                                               : LayerFE::StateSubset::Content);
    }


//frameworks/native/services/surfaceflinger/Layer.cpp
Layer::prepareCompositionState(compositionengine::LayerFE::StateSubset subset)
        case StateSubset::GeometryAndContent:
            prepareBasicGeometryCompositionState();//将相关Layer信息,放到Layer对应的LAyerFEcompositionState
            prepareGeometryCompositionState();
            preparePerFrameCompositionState();//重点看下这个,调用子类的
            break;    



//frameworks/native/services/surfaceflinger/BufferLayer.cpp
void BufferLayer::preparePerFrameCompositionState() {
    Layer::preparePerFrameCompositionState();

    // Sideband layers
    auto* compositionState = editCompositionState();
    if (compositionState->sidebandStream.get() && !compositionState->sidebandStreamHasFrame) {
        compositionState->compositionType =
                aidl::android::hardware::graphics::composer3::Composition::SIDEBAND;
        return;
    } else if ((mDrawingState.flags & layer_state_t::eLayerIsDisplayDecoration) != 0) {
        compositionState->compositionType =
                aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
    } else {
        // Normal buffer layers
        compositionState->hdrMetadata = mBufferInfo.mHdrMetadata;
        compositionState->compositionType = mPotentialCursor
                ? aidl::android::hardware::graphics::composer3::Composition::CURSOR
                : aidl::android::hardware::graphics::composer3::Composition::DEVICE;
    }

    compositionState->buffer = getBuffer();//将从App传递过来的渲染之后的GraphicBuffer保存在LayerFEcompositionState中
    compositionState->bufferSlot = (mBufferInfo.mBufferSlot == BufferQueue::INVALID_BUFFER_SLOT)
            ? 0
            : mBufferInfo.mBufferSlot;
    compositionState->acquireFence = mBufferInfo.mFence;
    compositionState->frameNumber = mBufferInfo.mFrameNumber;
    compositionState->sidebandStreamHasFrame = false;
}

updateCompositionState

这个函数的主要作用是什么呢,什么呢?我先分析下,再告诉你!

c 复制代码
//frameworks/native/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
void Output::updateCompositionState(const compositionengine::CompositionRefreshArgs& refreshArgs) {
    ...
    for (auto* layer : getOutputLayersOrderedByZ()) {
        layer->updateCompositionState(refreshArgs.updatingGeometryThisFrame,
                                      refreshArgs.devOptForceClientComposition ||
                                              forceClientComposition,
                                      refreshArgs.internalDisplayRotationFlags);

    }    
    ...
}


void OutputLayer::updateCompositionState(
        bool includeGeometry, bool forceClientComposition,
        ui::Transform::RotationFlags internalDisplayRotationFlags) {
    const auto* layerFEState = getLayerFE().getCompositionState();
    if (!layerFEState) {
        return;
    }

    const auto& outputState = getOutput().getState();
    const auto& profile = *getOutput().getDisplayColorProfile();
    auto& state = editState();//这里指向的是OutputLayerCompositionState

    if (includeGeometry) {

        state.forceClientComposition = false;

        state.displayFrame = calculateOutputDisplayFrame();
        state.sourceCrop = calculateOutputSourceCrop(internalDisplayRotationFlags);
        state.bufferTransform = static_cast<Hwc2::Transform>(
                calculateOutputRelativeBufferTransform(internalDisplayRotationFlags));

        if ((layerFEState->isSecure && !outputState.isSecure) ||
            (state.bufferTransform & ui::Transform::ROT_INVALID)) {
            state.forceClientComposition = true;
        }
    }


    state.dataspace = layerFEState->isColorspaceAgnostic &&
                    outputState.targetDataspace != ui::Dataspace::UNKNOWN
            ? outputState.targetDataspace
            : layerFEState->dataspace;


    if (outputState.treat170mAsSrgb && !layerFEState->isColorspaceAgnostic &&
        (state.dataspace & HAL_DATASPACE_TRANSFER_MASK) == HAL_DATASPACE_TRANSFER_SMPTE_170M) {
        state.dataspace = static_cast<ui::Dataspace>(
                (state.dataspace & HAL_DATASPACE_STANDARD_MASK) |
                (state.dataspace & HAL_DATASPACE_RANGE_MASK) | HAL_DATASPACE_TRANSFER_SRGB);
    }


    if (isHdrDataspace(state.dataspace) ||
        getOutput().getState().displayBrightnessNits == getOutput().getState().sdrWhitePointNits ||
        getOutput().getState().displayBrightnessNits == 0.f || !layerFEState->dimmingEnabled) {
        state.dimmingRatio = 1.f;
        state.whitePointNits = getOutput().getState().displayBrightnessNits;
    } else {
        state.dimmingRatio = std::clamp(getOutput().getState().sdrWhitePointNits /
                                                getOutput().getState().displayBrightnessNits,
                                        0.f, 1.f);
        state.whitePointNits = getOutput().getState().sdrWhitePointNits;
    }


    if (layerFEState->forceClientComposition || !profile.isDataspaceSupported(state.dataspace) ||
        forceClientComposition) {
        state.forceClientComposition = true;
    }
}

这块竟然没有将LayerFErCompositionState对应的GraphicBuffer传递给OutputLayerCompositionState。并且为啥要搞这么多State的状态呢,感觉有点多余!


writeCompositionState

该函数的核心功能就是设置outputlayer的dispFrame和sourceCrop等以及将outputlayer属性设给hwc。

c 复制代码
//frameworks/native/services/surfaceflinger/CompositionEngine/src/Output.cpp
void Output::writeCompositionState(const compositionengine::CompositionRefreshArgs& refreshArgs) {
    for (auto* layer : getOutputLayersOrderedByZ()) {
        layer->writeStateToHWC(includeGeometry, skipLayer, z++, overrideZ, isPeekingThrough);
            
    }
}


///frameworks/native/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t z,
                                  bool zIsOverridden, bool isPeekingThrough) {
    const auto& state = getState();//这里获取的是OutputLayerCompositionState
    auto& hwcLayer = (*state.hwc).hwcLayer
    const auto* outputIndependentState = getLayerFE().getCompositionState();//这里得到的是LayerFECompostionState
    writeOutputIndependentPerFrameStateToHWC(hwcLayer.get(), *outputIndependentState,
                                             requestedCompositionType, skipLayer)
        writeBufferStateToHWC(hwcLayer, outputIndependentState, skipLayer)
            sp<GraphicBuffer> buffer = outputIndependentState.buffer;
            sp<Fence> acquireFence = outputIndependentState.acquireFence;
            int slot = outputIndependentState.bufferSlot;
            if (getState().overrideInfo.buffer != nullptr && !skipLayer) {
                buffer = getState().overrideInfo.buffer->getBuffer();
                acquireFence = getState().overrideInfo.acquireFence;
                slot = HwcBufferCache::FLATTENER_CACHING_SLOT;
            }        
            sp<GraphicBuffer> hwcBuffer;
            editState().hwc->hwcBufferCache.getHwcBuffer(slot, buffer, &hwcSlot, &hwcBuffer); 
            hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence)
                mComposer.setLayerBuffer(mDisplay->getId(), mId, slot, buffer, fenceFd)//HWC2.cpp
                    const native_handle_t* handle = nullptr;//frameworks/native/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
                    handle = buffer->getNativeBuffer()->handle;
                    mWriter.setLayerBuffer(slot, handle, acquireFence)
}

最终将hwc_layer相关信息传递到HAL层的HWC实现!

SurfaceFinger layer创建过程
SurfaceControl之Transaction事物深入剖析
Surface的Buffer是怎么传递给HWC呢?
SurfaceFlinger layer之间的对应关系
Android Qcom Display学习
SurfaceFlinger处理事务
SurfaceFlinger Refresh流程


相关推荐
长亭外的少年3 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿6 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神7 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
兰琛7 小时前
20241121 android中树结构列表(使用recyclerView实现)
android·gitee
Y多了个想法8 小时前
RK3568 android11 适配敦泰触摸屏 FocalTech-ft5526
android·rk3568·触摸屏·tp·敦泰·focaltech·ft5526
NotesChapter9 小时前
Android吸顶效果,并有着ViewPager左右切换
android
_祝你今天愉快10 小时前
分析android :The binary version of its metadata is 1.8.0, expected version is 1.5.
android
暮志未晚Webgl10 小时前
109. UE5 GAS RPG 实现检查点的存档功能
android·java·ue5
麦田里的守望者江11 小时前
KMP 中的 expect 和 actual 声明
android·ios·kotlin
Dnelic-11 小时前
解决 Android 单元测试 No tests found for given includes:
android·junit·单元测试·问题记录·自学笔记