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


相关推荐
水瓶丫头站住25 分钟前
安卓APP如何适配不同的手机分辨率
android·智能手机
xvch1 小时前
Kotlin 2.1.0 入门教程(五)
android·kotlin
xvch5 小时前
Kotlin 2.1.0 入门教程(七)
android·kotlin
望风的懒蜗牛5 小时前
编译Android平台使用的FFmpeg库
android
浩宇软件开发6 小时前
Android开发,待办事项提醒App的设计与实现(个人中心页)
android·android studio·android开发
ac-er88886 小时前
Yii框架中的多语言支持:如何实现国际化
android·开发语言·php
苏金标7 小时前
The maximum compatible Gradle JVM version is 17.
android
zhangphil7 小时前
Android BitmapShader简洁实现马赛克,Kotlin(一)
android·kotlin
iofomo11 小时前
Android平台从上到下,无需ROOT/解锁/刷机,应用级拦截框架的最后一环,SVC系统调用拦截。
android
我叫特踏实12 小时前
SensorManager开发参考
android·sensormanager