Android Surface對應的Buffer怎么傳遞給HWC
引言
因為要預研Android Video overlay,需要將SurfaceView對應的GraphicBuffer從drm_hwcomposer中剝離出來,這就需要們了解SurfaceView對應的GraphicBuffer的前世今生,以及它的數據流向以及在各個模塊之間的對應關系。這篇博客,我們分析下該GraphicBuffer是如何傳遞到HWC的。
參考源碼基于Android 13 AOSP!
Surface的Buffer是怎么傳遞給HWC呢
我們通過代碼流程來看看:
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::presentLayerFESet latchedLayers;for (const auto& output : args.outputs) {output->prepare(args, latchedLayers);//impl::OutputrebuildLayerStacks(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.cppupdateCompositionState(refreshArgs)writeCompositionState(refreshArgs)//impl::Outputlayer->writeStateToHWC(...)//impl::OutputLayerwriteOutputIndependentPerFrameStateToHWC(...)writeBufferStateToHWC(...)hwcLayer->setBuffer(...)//HWC2::impl::LayermComposer.setLayerBuffer(...)//Hwc2::impl::Composer}
這里output實際上是Display,但是Display中沒有實現prepare,因為Display繼承自Output,使用的是父類Output的prepare方法。
ensureOutputLayerIfVisible
這里我們看下ensureOutputLayerIfVisible的作用,主要是構建出來看見的OutputLayer.
//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) // 傳入的參數是BasicGeometryprepareBasicGeometryCompositionState()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中,獲取的是LayerFECompositionStatecompositionState->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最后是要顯示到屏幕上的。
//frameworks/native/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.hOutputLayer* 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.cppstd::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;// 創建hwclayerauto 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.hwcresult->setHwcLayer(std::move(hwcLayer));}return result;
}
到這里就完成了OutputLayer和hwc layer的創建。
updateLayerStateFromFE
Update the composition state from each front-end layer更新各前端層的組成狀態,我們來看其實現:
//frameworks/native/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
void CompositionEngine::updateLayerStateFromFE(CompositionRefreshArgs& args) {// Update the composition state from each front-end layerfor (const auto& output : args.outputs) {output->updateLayerStateFromFE(args);}
}
void Output::updateLayerStateFromFE(const CompositionRefreshArgs& args) const {for (auto* layer : getOutputLayersOrderedByZ()) {//這個傳遞的參數是GeometryAndContentlayer->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對應的LAyerFEcompositionStateprepareGeometryCompositionState();preparePerFrameCompositionState();//重點看下這個,調用子類的break; //frameworks/native/services/surfaceflinger/BufferLayer.cpp
void BufferLayer::preparePerFrameCompositionState() {Layer::preparePerFrameCompositionState();// Sideband layersauto* 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 layerscompositionState->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
這個函數的主要作用是什么呢,什么呢?我先分析下,再告訴你!
//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();//這里指向的是OutputLayerCompositionStateif (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。
//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();//這里獲取的是OutputLayerCompositionStateauto& hwcLayer = (*state.hwc).hwcLayerconst auto* outputIndependentState = getLayerFE().getCompositionState();//這里得到的是LayerFECompostionStatewriteOutputIndependentPerFrameStateToHWC(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.cppconst native_handle_t* handle = nullptr;//frameworks/native/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpphandle = 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流程