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