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流程


相关推荐
千里马学框架5 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台5 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone5 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc5 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo5 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077005 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼5 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone5 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen5 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone5 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui