掘金限制单篇的字符数,本文不完整,完整文章请移步:ahaoframework.tech/008.%E6%98%…
7. 合成实施阶段
前面都是准备工作,present 发起图层合成过程:
using LayerFESet = std::unordered_set<sp<LayerFE>, LayerFESpHash>;
void CompositionEngine::present(CompositionRefreshArgs& args) {
// 调用 args.layers 所有 layerFE 的 onPreComposition,这个方法里只是更新了 layerFE 的 mCompositionResult.refreshStartTime,记录了一下合成开始的时间
preComposition(args);
{
LayerFESet latchedLayers;
// 关注点 1
// 这里的 output 前面介绍过是 Display 对象
for (const auto& output : args.outputs) {
output->prepare(args, latchedLayers);
}
}
// 关注点 2
for (const auto& output : args.outputs) {
// 对每一个屏幕调用 present
output->present(args);
}
}
- 关注点1,主要是构建 OutputLayer 以及 HwcLayer
- 关注点2,合成图层,包含了 device 合成和 client 合成
7.1 Output::prepare 最后的准备
关注点 1
void Output::prepare(const compositionengine::CompositionRefreshArgs& refreshArgs,
LayerFESet& geomSnapshots) {
rebuildLayerStacks(refreshArgs, geomSnapshots);
uncacheBuffers(refreshArgs.bufferIdsToUncache);
}
调用 rebuildLayerStacks,最后的数据准备:
void Output::rebuildLayerStacks(const compositionengine::CompositionRefreshArgs& refreshArgs,
LayerFESet& layerFESet) {
auto& outputState = editState();
if (!outputState.isEnabled || CC_LIKELY(!refreshArgs.updatingOutputGeometryThisFrame)) {
return;
}
compositionengine::Output::CoverageState coverage{layerFESet};
coverage.aboveCoveredLayersExcludingOverlays = refreshArgs.hasTrustedPresentationListener
? std::make_optional<Region>()
: std::nullopt;
// 构建 OutputLayer,同时会计算每个 layer 的脏区
collectVisibleLayers(refreshArgs, coverage);
// 把所有 layer 最终的区域信息合集(相当于这个屏幕的区域信息合集)存到 OutputState 内。
const ui::Transform& tr = outputState.transform;
Region undefinedRegion{outputState.displaySpace.getBoundsAsRect()};
undefinedRegion.subtractSelf(tr.transform(coverage.aboveOpaqueLayers));
outputState.undefinedRegion = undefinedRegion;
outputState.dirtyRegion.orSelf(coverage.dirtyRegion);
}
Output 代表了一个显示设备,OutputLayer 代表一个图层
这里会构建 OutputLayer,计算各个区域大小。
OutputLayer,这个是一个合成的中间产物,相比于LayerFE,他记录了更多在合成过程中计算出来的信息,比如一些区域信息,比如脏区等。
调用 collectVisibleLayers:
void Output::collectVisibleLayers(const compositionengine::CompositionRefreshArgs& refreshArgs,
compositionengine::Output::CoverageState& coverage) {
for (auto layer : reversed(refreshArgs.layers)) {
// 遍历所有 layerFE,调用 ensureOutputLayerIfVisible,构建 OutputLayer,这些 OutputLayer 会暂时存在 mPendingOutputLayersOrderedByZ 里
ensureOutputLayerIfVisible(layer, coverage);
}
// 把 buffer 有变化的 layer 存到 mReleasedLayers
setReleasedLayers(refreshArgs);
// 将 mPendingOutputLayersOrderedByZ 到数据转移到 mCurrentOutputLayersOrderedByZ
finalizePendingOutputLayers();
}
给每个 layer 构建 OutputLayer,并且计算每个 layer 脏区等区域信息,最后把所有 layer 区域信息合集存到 OutputLayerCompositionState 作为屏幕的区域信息合集,以便后面合成使用。
void Output::ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>& layerFE,
compositionengine::Output::CoverageState& coverage) {
// latchedLayer 存储 layerFE
if (!coverage.latchedLayers.count(layerFE)) {
coverage.latchedLayers.insert(layerFE);
}
// layerStack 标志每个 layerFE 所在 output,如果 layerFE 不在当前Output(即当前屏幕),就直接返回
if (!includesLayer(layerFE)) {
return;
}
// Obtain a read-only pointer to the front-end layer state
// 返回的 LayerSnapshot
const auto* layerFEState = layerFE->getCompositionState();
if (CC_UNLIKELY(!layerFEState)) {
return;
}
// ......
bool computeAboveCoveredExcludingOverlays = coverage.aboveCoveredLayersExcludingOverlays &&
!layerFEState->outputFilter.toInternalDisplay;
// 不透明区域
Region opaqueRegion;
// 可见区域
Region visibleRegion;
// 所有被覆盖的区域
Region coveredRegion;
// 透明区域
Region transparentRegion;
// 阴影区域
Region shadowRegion;
// 上面的覆盖区域,不包括显示器覆盖层
std::optional<Region> coveredRegionExcludingDisplayOverlays = std::nullopt;
// 下面的逻辑都是计算这几个区域的。
const ui::Transform& tr = layerFEState->geomLayerTransform;
// 将layer的边界通过Transform转换,作为初始化的值(就是整个layer显示的区域)
const Rect visibleRect(tr.transform(layerFEState->geomLayerBounds));
visibleRegion.set(visibleRect);
// 如果有配置阴影,半透明可见区域需要减去阴影的区域
if (layerFEState->shadowRadius > 0.0f) {
const auto inset = static_cast<int32_t>(ceilf(layerFEState->shadowRadius) * -1.0f);
Rect visibleRectWithShadows(visibleRect);
visibleRectWithShadows.inset(inset, inset, inset, inset);
visibleRegion.set(visibleRectWithShadows);
shadowRegion = visibleRegion.subtract(visibleRect);
}
if (visibleRegion.isEmpty()) {
return;
}
// 如果layer是透明的,计算全透明区域,如果计算逻辑过于复杂则不计算,因为这里本来计算出来也只是用于合成的优化
if (!layerFEState->isOpaque) {
// 判断Transform里面旋转的flag是否是ROT_INVALID,是的话计算太复杂.如果是其他的旋转90,180这种,可以比较容易计算。
if (tr.preserveRects()) {
// 透明区域和边界交集就是计算出来的透明区域
const Region clippedTransparentRegionHint =
layerFEState->transparentRegionHint.intersect(
Rect(layerFEState->geomLayerBounds));
if (clippedTransparentRegionHint.isEmpty()) {
// 没有透明区域
transparentRegion.clear();
} else {
// 还需要做transform才是最终结果。
transparentRegion = tr.transform(clippedTransparentRegionHint);
}
} else {
// 计算复杂,不计算透明区域
transparentRegion.clear();
}
}
const auto layerOrientation = tr.getOrientation();
// 如果页面不透明,切旋转变换也是常规的变换,不透明区域就是visibleRect,否则我们也不计算不透明区域
if (layerFEState->isOpaque && ((layerOrientation & ui::Transform::ROT_INVALID) == 0)) {
opaqueRegion.set(visibleRect);
}
// aboveCoveredLayers是之前layer的合集,这里的visible还没有剪去,所以是这个layer全部的可见区域
// 交上上层所有可见区域集合,就是被覆盖的集合。
coveredRegion = coverage.aboveCoveredLayers.intersect(visibleRegion);
// 更新aboveCoveredLayers,就是加上当前layer的可见区域,
coverage.aboveCoveredLayers.orSelf(visibleRegion);
if (CC_UNLIKELY(computeAboveCoveredExcludingOverlays)) {
coveredRegionExcludingDisplayOverlays =
coverage.aboveCoveredLayersExcludingOverlays->intersect(visibleRegion);
coverage.aboveCoveredLayersExcludingOverlays->orSelf(visibleRegion);
}
// 可见区域要剪去上层的不透明区域(就是被上层遮挡)
visibleRegion.subtractSelf(coverage.aboveOpaqueLayers);
if (visibleRegion.isEmpty()) {
return;
}
// 这里获取上一次的这个 layerFE 对应的 OutputLayer,获取上一次的可见区域,用于计算脏区
auto prevOutputLayerIndex = findCurrentOutputLayerForLayer(layerFE);
auto prevOutputLayer =
prevOutputLayerIndex ? getOutputLayerOrderedByZByIndex(*prevOutputLayerIndex) : nullptr;
const Region kEmptyRegion;
const Region& oldVisibleRegion =
prevOutputLayer ? prevOutputLayer->getState().visibleRegion : kEmptyRegion;
const Region& oldCoveredRegion =
prevOutputLayer ? prevOutputLayer->getState().coveredRegion : kEmptyRegion;
// compute this layer's dirty region
Region dirty;
// 如果 buffer 内容有更新, 那这次的可见区域加上上一次的可见区域都是脏区
if (layerFEState->contentDirty) {
dirty = visibleRegion;
dirty.orSelf(oldVisibleRegion);
} else {
// Exposed是暴露区域,可见区剪去被覆盖的区域就是暴露的区域
// 脏区 = 这次的可见区域和上次被覆盖的区域交集(就是上次没有显示出来的,但是这次可能会被显示出来,是比较保守的估计)+ 这次暴露出来的-上次暴露出来的(因为内容没有变化,上次暴露出来的部分不需要再管了)
const Region newExposed = visibleRegion - coveredRegion;
const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
dirty = (visibleRegion & oldCoveredRegion) | (newExposed - oldExposed);
}
// 脏区域再剪去上层不透明的区域(上层不透明看不见,所以也不需要重新渲染计算)
dirty.subtractSelf(coverage.aboveOpaqueLayers);
// dirtyRegion 是所有 layer 脏区域的合集
coverage.dirtyRegion.orSelf(dirty);
// 更新 aboveOpaqueLayers(之前所有layer的不透明区域)
coverage.aboveOpaqueLayers.orSelf(opaqueRegion);
Region visibleNonTransparentRegion = visibleRegion.subtract(transparentRegion);
const auto& outputState = getState();
Region drawRegion(outputState.transform.transform(visibleNonTransparentRegion));
drawRegion.andSelf(outputState.displaySpace.getBoundsAsRect());
if (drawRegion.isEmpty()) {
return;
}
Region visibleNonShadowRegion = visibleRegion.subtract(shadowRegion);
// 关注点 根据 layerFE 构建 OutputLayer
auto result = ensureOutputLayer(prevOutputLayerIndex, layerFE);
// 关注点 更新 OutputLayerCompositionState 内的变量
auto& outputLayerState = result->editState();
outputLayerState.visibleRegion = visibleRegion;
outputLayerState.visibleNonTransparentRegion = visibleNonTransparentRegion;
outputLayerState.coveredRegion = coveredRegion;
outputLayerState.outputSpaceVisibleRegion = outputState.transform.transform(
visibleNonShadowRegion.intersect(outputState.layerStackSpace.getContent()));
outputLayerState.shadowRegion = shadowRegion;
outputLayerState.outputSpaceBlockingRegionHint =
layerFEState->compositionType == Composition::DISPLAY_DECORATION
? outputState.transform.transform(
transparentRegion.intersect(outputState.layerStackSpace.getContent()))
: Region();
if (CC_UNLIKELY(computeAboveCoveredExcludingOverlays)) {
outputLayerState.coveredRegionExcludingDisplayOverlays =
std::move(coveredRegionExcludingDisplayOverlays);
}
}
这个方法用于计算 layer 的脏区,经过循环遍历,对每个 layer 都调用了这个方法后,就可以得到所有 layer 的脏区,保存在 coverage,同时附带的产物还有所有 layer 不透明区域,可见区域等。
同时构建 OutputLayer,将每个 layer 这些区域信息存入 OutputLayerState。
ensureOutputLayer 构建 OutputLayer 的过程:
OutputLayer* ensureOutputLayer(std::optional<size_t> prevIndex,
const sp<LayerFE>& layerFE) {
auto outputLayer = (prevIndex && *prevIndex <= mCurrentOutputLayersOrderedByZ.size())
? std::move(mCurrentOutputLayersOrderedByZ[*prevIndex])
: BaseOutput::createOutputLayer(layerFE);
auto result = outputLayer.get();
// 构造的 outputLayer 存放在 mPendingOutputLayersOrderedByZ
mPendingOutputLayersOrderedByZ.emplace_back(std::move(outputLayer));
return result;
}
BaseOutput 实际类型是 android::compositionengine::impl::Display。
接着调用 createOutputLayer:
// frameworks/native/services/surfaceflinger/CompositionEngine/src/Display.cpp
std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer(
const sp<compositionengine::LayerFE>& layerFE) const {
// 关注点1 构造一个 OutputLayer
// android::compositionengine::impl::createOutputLayer
auto outputLayer = impl::createOutputLayer(*this, layerFE);
if (const auto halDisplayId = HalDisplayId::tryCast(mId);
outputLayer && !mIsDisconnected && halDisplayId) {
auto& hwc = getCompositionEngine().getHwComposer();
// 关注点2
// 创建 hwclayer
auto hwcLayer = hwc.createLayer(*halDisplayId);
ALOGE_IF(!hwcLayer, "Failed to create a HWC layer for a HWC supported display %s",
getName().c_str());
outputLayer->setHwcLayer(std::move(hwcLayer));
}
return outputLayer;
}
关注点1,调用 android::compositionengine::impl::createOutputLayer 构建 OutputLayer 对象:
// frameworks/native/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
std::unique_ptr<compositionengine::OutputLayer> Output::createOutputLayer(
const sp<LayerFE>& layerFE) const {
return impl::createOutputLayer(*this, layerFE);
}
std::unique_ptr<OutputLayer> createOutputLayer(const compositionengine::Output& output,
const sp<compositionengine::LayerFE>& layerFE) {
// 模板函数,构造一个 OutputLayer
return createOutputLayerTemplated<OutputLayer>(output, layerFE);
}
template <typename BaseOutputLayer>
std::unique_ptr<BaseOutputLayer> createOutputLayerTemplated(const Output& output,
sp<LayerFE> layerFE) {
class OutputLayer final : public BaseOutputLayer {
public:
// Clang incorrectly complains that these are unused.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-local-typedef"
using OutputLayerCompositionState = std::remove_const_t<
std::remove_reference_t<decltype(std::declval<BaseOutputLayer>().getState())>>;
using Output = std::remove_const_t<
std::remove_reference_t<decltype(std::declval<BaseOutputLayer>().getOutput())>>;
using LayerFE =
std::remove_reference_t<decltype(std::declval<BaseOutputLayer>().getLayerFE())>;
#pragma clang diagnostic pop
OutputLayer(const Output& output, const sp<LayerFE>& layerFE)
: mOutput(output), mLayerFE(layerFE) {}
~OutputLayer() override = default;
private:
// compositionengine::OutputLayer overrides
const Output& getOutput() const override { return mOutput; }
LayerFE& getLayerFE() const override { return *mLayerFE; }
const OutputLayerCompositionState& getState() const override { return mState; }
OutputLayerCompositionState& editState() override { return mState; }
// compositionengine::impl::OutputLayer overrides
void dumpState(std::string& out) const override { mState.dump(out); }
const Output& mOutput;
const sp<LayerFE> mLayerFE;
OutputLayerCompositionState mState;
};
return std::make_unique<OutputLayer>(output, layerFE);
}
这里构建了一个内部类 OutputLayer 的对象,其继承关系如下:
关注点2,创建 hwcLayer:
std::shared_ptr<HWC2::Layer> HWComposer::createLayer(HalDisplayId displayId) {
RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
auto expected = mDisplayData[displayId].hwcDisplay->createLayer();
if (!expected.has_value()) {
auto error = std::move(expected).error();
RETURN_IF_HWC_ERROR(error, displayId, nullptr);
}
return std::move(expected).value();
}
mDisplayData 以及 hwcDisplay 的初始化过程在第三节已经分析过了。
base::expected<std::shared_ptr<HWC2::Layer>, hal::Error> Display::createLayer() {
HWLayerId layerId = 0;
// 拿到 ID
auto intError = mComposer.createLayer(mId, &layerId);
auto error = static_cast<Error>(intError);
if (error != Error::NONE) {
return base::unexpected(error);
}
// 再构建一个 Layer 对象
auto layer = std::make_shared<impl::Layer>(mComposer, mCapabilities, *this, layerId);
// 保存到 mLayers 成员中
mLayers.emplace(layerId, layer);
return layer;
}
最后调用到 AidlComposer::createLayer
:
Error AidlComposer::createLayer(Display display, Layer* outLayer) {
int64_t layer;
// binder 远程调用
const auto status = mAidlComposerClient->createLayer(translate<int64_t>(display),
kMaxLayerBufferCount, &layer);
if (!status.isOk()) {
ALOGE("createLayer failed %s", status.getDescription().c_str());
return static_cast<Error>(status.getServiceSpecificError());
}
*outLayer = translate<Layer>(layer);
return Error::NONE;
}
binder 远程调用 composer hal,返回一个 layer 的 id,然后使用这个 id,构建一个 Layer 对象。
这个 id 在两侧起了索引的作用。
hwcLayer,这个是和 HWC HAL 通信使用的结构,代表 HWC 层的 Layer,只有需要通过 HWC 合成的 Layer 才会有这个。
android::HWC2::impl::Layer 的定义如下
class Layer : public HWC2::Layer {
public:
Layer(android::Hwc2::Composer& composer,
const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability>&
capabilities,
HWC2::Display& display, hal::HWLayerId layerId);
~Layer() override;
void onOwningDisplayDestroyed();
hal::HWLayerId getId() const override { return mId; }
hal::Error setCursorPosition(int32_t x, int32_t y) override;
hal::Error setBuffer(uint32_t slot, const android::sp<android::GraphicBuffer>& buffer,
const android::sp<android::Fence>& acquireFence) override;
hal::Error setBufferSlotsToClear(const std::vector<uint32_t>& slotsToClear,
uint32_t activeBufferSlot) override;
hal::Error setSurfaceDamage(const android::Region& damage) override;
hal::Error setBlendMode(hal::BlendMode mode) override;
hal::Error setColor(aidl::android::hardware::graphics::composer3::Color color) override;
hal::Error setCompositionType(
aidl::android::hardware::graphics::composer3::Composition type) override;
hal::Error setDataspace(hal::Dataspace dataspace) override;
hal::Error setPerFrameMetadata(const int32_t supportedPerFrameMetadata,
const android::HdrMetadata& metadata) override;
hal::Error setDisplayFrame(const android::Rect& frame) override;
hal::Error setPlaneAlpha(float alpha) override;
hal::Error setSidebandStream(const native_handle_t* stream) override;
hal::Error setSourceCrop(const android::FloatRect& crop) override;
hal::Error setTransform(hal::Transform transform) override;
hal::Error setVisibleRegion(const android::Region& region) override;
hal::Error setZOrder(uint32_t z) override;
// Composer HAL 2.3
hal::Error setColorTransform(const android::mat4& matrix) override;
// Composer HAL 2.4
hal::Error setLayerGenericMetadata(const std::string& name, bool mandatory,
const std::vector<uint8_t>& value) override;
// AIDL HAL
hal::Error setBrightness(float brightness) override;
hal::Error setBlockingRegion(const android::Region& region) override;
private:
// These are references to data owned by HWComposer, which will outlive
// this HWC2::Layer, so these references are guaranteed to be valid for
// the lifetime of this object.
android::Hwc2::Composer& mComposer;
const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability>&
mCapabilities;
HWC2::Display* mDisplay;
hal::HWLayerId mId;
// Cached HWC2 data, to ensure the same commands aren't sent to the HWC
// multiple times.
android::Region mVisibleRegion = android::Region::INVALID_REGION;
android::Region mDamageRegion = android::Region::INVALID_REGION;
android::Region mBlockingRegion = android::Region::INVALID_REGION;
hal::Dataspace mDataSpace = hal::Dataspace::UNKNOWN;
android::HdrMetadata mHdrMetadata;
android::mat4 mColorMatrix;
uint32_t mBufferSlot;
};
impl::Layer 的构造函数如下:
// /frameworks/native/services/surfaceflinger/DisplayHardware/HWC2.cpp
Layer::Layer(android::Hwc2::Composer& composer,
const std::unordered_set<AidlCapability>& capabilities, HWC2::Display& display,
HWLayerId layerId)
: mComposer(composer),
mCapabilities(capabilities),
mDisplay(&display),
mId(layerId),
mColorMatrix(android::mat4()) {
ALOGV("Created layer %" PRIu64 " on display %" PRIu64, layerId, display.getId());
}
hwcLayer 构造完成后还有调用 setHwcLayer 方法:
void OutputLayer::setHwcLayer(std::shared_ptr<HWC2::Layer> hwcLayer) {
auto& state = editState();
if (hwcLayer) {
state.hwc.emplace(std::move(hwcLayer));
} else {
state.hwc.reset();
}
}
这里会把 hwcLayer 保存到 OutputLayer 的 OutputLayerCompositionState 成员的 hwc 成员的 hwcLayer 成员中,方便后续的合成操作
OutputLayer 创建完成后,接着调用 setReleasedLayers,把 buffer 有变化的 layer 存到 mReleasedLayers
void Display::setReleasedLayers(const compositionengine::CompositionRefreshArgs& refreshArgs) {
Output::setReleasedLayers(refreshArgs);
if (mIsDisconnected || GpuVirtualDisplayId::tryCast(mId) ||
refreshArgs.layersWithQueuedFrames.empty()) {
return;
}
// For layers that are being removed from a HWC display, and that have
// queued frames, add them to a a list of released layers so we can properly
// set a fence.
compositionengine::Output::ReleasedLayers releasedLayers;
// Any non-null entries in the current list of layers are layers that are no
// longer going to be visible
for (auto* outputLayer : getOutputLayersOrderedByZ()) {
if (!outputLayer) {
continue;
}
compositionengine::LayerFE* layerFE = &outputLayer->getLayerFE();
const bool hasQueuedFrames =
std::any_of(refreshArgs.layersWithQueuedFrames.cbegin(),
refreshArgs.layersWithQueuedFrames.cend(),
[layerFE](sp<compositionengine::LayerFE> layerWithQueuedFrames) {
return layerFE == layerWithQueuedFrames.get();
});
if (hasQueuedFrames) {
releasedLayers.emplace_back(wp<LayerFE>::fromExisting(layerFE));
}
}
setReleasedLayers(std::move(releasedLayers));
}
以上是最后的准备阶段。
7.2 Output::present 开始合成
前面可以说都是准备,接下来的 present 函数才是合成的重头戏:
void Output::present(const compositionengine::CompositionRefreshArgs& refreshArgs) {
// 根据 refresh 里面的参数更新颜色空间等(像素点表示颜色的编码方式),存储在 OutputState
updateColorProfile(refreshArgs);
// 关注点1 调用所有 OutputLayer 的 updateCompositionState
updateCompositionState(refreshArgs);
planComposition();
// 关注点2 将一部分合成状态写到 hwc,这里通过 HWCLayer,将状态同步到HWC侧,也是通过aidl的binder
writeCompositionState(refreshArgs);
// 更新颜色转换矩阵,类似于layer的Transform,只是这里是针对于颜色的。同时会更新state里面的脏区
setColorTransform(refreshArgs);
// 这里会调用RenderSurface的beginFrame,后会调用DisplaySurface的beginFrame,如果是虚拟屏则会有一些刷新hwc的buffer相关的处理,如果不是虚拟盘什么也没做
beginFrame();
GpuCompositionResult result;
// 判断是否同步进行
const bool predictCompositionStrategy = canPredictCompositionStrategy(refreshArgs);
// 无论是否同步最后都会走到 finishPrepareFrame,然后也是调用 renderSurface 的 prepareFrame,再调用 DisplaySurface 的 prepareFrame。如果是主屏这里也什么都没做
// 如果是 prepareFrameAsync,会调用 dequeueRenderBuffer 和 composeSurfaces 进行合成操作,如果是 prepareFrame,合成操作在 finishFrame
// 合成操作就在 finishFrame 里再介绍
if (predictCompositionStrategy) {
result = prepareFrameAsync();
} else {
// 关注点3 看 else 的逻辑
prepareFrame();
}
devOptRepaintFlash(refreshArgs);
// 关注点4
// 如果之前走的是 prepareFrame,会在这里进行合成操作,调用 dequeueRenderBuffer 和 composeSurfaces
finishFrame(std::move(result));
// 关注点5
// 主要调用了 presentAndGetFrameFences 将剩余的 layer 提交给 HWC,让 HWC 进行硬件合成。除此之外会处理一些 buffer 的释放相关工作。
postFramebuffer();
renderCachedSets(refreshArgs);
}
- 关注点1,调用所有 OutputLayer 的 updateCompositionState,更新 OutputLayer 的 state 的部分成员
- 关注点2,将一部分合成状态写到 writer 中
- 关注点3,prepareFrame 完成部分 OutputLayer device 合成的同时从 HWC HAL 中获取到 OutputLayer 们的合成方式
- 关注点4,finishFrame,如果需要,完成 OutputLayer 的 client 合成
- 关注点5,postFramebuffer 完成后续所有 OutputLayer 的 device 合成
7.2.1 AidlComposer 的设计
预备知识点:所有的图层合成操作都需要通过 AidlComposer 这个中介与 hwc hal 通信完成,所有我们需要了解 AidlComposer 的设计与实现。
AidlComposer 是 hwc hal 的客户端包装类,方便客户端使用 binder 服务。系统源码很多这种实现。
AidlComposer 的定义如下:
// /frameworks/native/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
// Composer is a wrapper to IComposer, a proxy to server-side composer.
class AidlComposer final : public Hwc2::Composer {
public:
static bool isDeclared(const std::string& serviceName);
explicit AidlComposer(const std::string& serviceName);
~AidlComposer() override;
bool isSupported(OptionalFeature) const;
std::vector<aidl::android::hardware::graphics::composer3::Capability> getCapabilities()
override;
std::string dumpDebugInfo() override;
void registerCallback(HWC2::ComposerCallback& callback) override;
// .......
// 定义了一堆的函数,省略了,遇到我们直接看实现
// 64KiB minus a small space for metadata such as read/write pointers
static constexpr size_t kWriterInitialSize = 64 * 1024 / sizeof(uint32_t) - 16;
// Max number of buffers that may be cached for a given layer
// We obtain this number by:
// 1. Tightly coupling this cache to the max size of BufferQueue
// 2. Adding an additional slot for the layer caching feature in SurfaceFlinger (see: Planner.h)
static const constexpr uint32_t kMaxLayerBufferCount = BufferQueue::NUM_BUFFER_SLOTS + 1;
// Without DisplayCapability::MULTI_THREADED_PRESENT, we use a single reader
// for all displays. With the capability, we use a separate reader for each
// display.
bool mSingleReader = true;
// Invalid displayId used as a key to mReaders when mSingleReader is true.
static constexpr int64_t kSingleReaderKey = 0;
// TODO (b/256881188): Use display::PhysicalDisplayMap instead of hard-coded `3`
ftl::SmallMap<Display, ComposerClientWriter, 3> mWriters GUARDED_BY(mMutex);
ftl::SmallMap<Display, ComposerClientReader, 3> mReaders GUARDED_BY(mMutex);
// Protect access to mWriters and mReaders with a shared_mutex. Adding and
// removing a display require exclusive access, since the iterator or the
// writer/reader may be invalidated. Other calls need shared access while
// using the writer/reader, so they can use their display's writer/reader
// without it being deleted or the iterator being invalidated.
// TODO (b/257958323): Use std::shared_mutex and RAII once they support
// threading annotations.
ftl::SharedMutex mMutex;
// Whether or not explicitly clearing buffer slots is supported.
bool mSupportsBufferSlotsToClear;
// Buffer slots for layers are cleared by setting the slot buffer to this buffer.
sp<GraphicBuffer> mClearSlotBuffer;
// Aidl interface
using AidlIComposer = aidl::android::hardware::graphics::composer3::IComposer;
using AidlIComposerClient = aidl::android::hardware::graphics::composer3::IComposerClient;
// binder 客户端类
std::shared_ptr<AidlIComposer> mAidlComposer;
std::shared_ptr<AidlIComposerClient> mAidlComposerClient;
std::shared_ptr<AidlIComposerCallbackWrapper> mAidlComposerCallback;
};
两个重要的成员 mWriters mReaders,mWriters 用于暂存数据,远程调用时,使用这些数据,mReaders 用于读取远程调用后返回的数据。
mAidlComposer 和 mAidlComposerClient 是 binder 客户端对象,用于发起远程调用。
ComposerClientWriter 实现如下:
class ComposerClientWriter final {
public:
static constexpr std::optional<ClockMonotonicTimestamp> kNoTimestamp = std::nullopt;
explicit ComposerClientWriter(int64_t display) : mDisplay(display) { reset(); }
~ComposerClientWriter() { reset(); }
ComposerClientWriter(ComposerClientWriter&&) = default;
ComposerClientWriter(const ComposerClientWriter&) = delete;
ComposerClientWriter& operator=(const ComposerClientWriter&) = delete;
void setColorTransform(int64_t display, const float* matrix) {
std::vector<float> matVec;
matVec.reserve(16);
matVec.assign(matrix, matrix + 16);
getDisplayCommand(display).colorTransformMatrix.emplace(std::move(matVec));
}
void setDisplayBrightness(int64_t display, float brightness, float brightnessNits) {
getDisplayCommand(display).brightness.emplace(
DisplayBrightness{.brightness = brightness, .brightnessNits = brightnessNits});
}
void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target,
int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage) {
ClientTarget clientTargetCommand;
clientTargetCommand.buffer = getBufferCommand(slot, target, acquireFence);
clientTargetCommand.dataspace = dataspace;
clientTargetCommand.damage.assign(damage.begin(), damage.end());
getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand));
}
void setOutputBuffer(int64_t display, uint32_t slot, const native_handle_t* buffer,
int releaseFence) {
getDisplayCommand(display).virtualDisplayOutputBuffer.emplace(
getBufferCommand(slot, buffer, releaseFence));
}
void validateDisplay(int64_t display,
std::optional<ClockMonotonicTimestamp> expectedPresentTime) {
auto& command = getDisplayCommand(display);
command.expectedPresentTime = expectedPresentTime;
command.validateDisplay = true;
}
// 关注点
void presentOrvalidateDisplay(int64_t display,
std::optional<ClockMonotonicTimestamp> expectedPresentTime) {
auto& command = getDisplayCommand(display);
command.expectedPresentTime = expectedPresentTime;
command.presentOrValidateDisplay = true;
}
void acceptDisplayChanges(int64_t display) {
getDisplayCommand(display).acceptDisplayChanges = true;
}
void presentDisplay(int64_t display) { getDisplayCommand(display).presentDisplay = true; }
void setLayerCursorPosition(int64_t display, int64_t layer, int32_t x, int32_t y) {
common::Point cursorPosition;
cursorPosition.x = x;
cursorPosition.y = y;
getLayerCommand(display, layer).cursorPosition.emplace(std::move(cursorPosition));
}
void setLayerBuffer(int64_t display, int64_t layer, uint32_t slot,
const native_handle_t* buffer, int acquireFence) {
getLayerCommand(display, layer).buffer = getBufferCommand(slot, buffer, acquireFence);
}
void setLayerBufferWithNewCommand(int64_t display, int64_t layer, uint32_t slot,
const native_handle_t* buffer, int acquireFence) {
flushLayerCommand();
getLayerCommand(display, layer).buffer = getBufferCommand(slot, buffer, acquireFence);
flushLayerCommand();
}
void setLayerBufferSlotsToClear(int64_t display, int64_t layer,
const std::vector<uint32_t>& slotsToClear) {
getLayerCommand(display, layer)
.bufferSlotsToClear.emplace(slotsToClear.begin(), slotsToClear.end());
}
void setLayerSurfaceDamage(int64_t display, int64_t layer, const std::vector<Rect>& damage) {
getLayerCommand(display, layer).damage.emplace(damage.begin(), damage.end());
}
void setLayerBlendMode(int64_t display, int64_t layer, BlendMode mode) {
ParcelableBlendMode parcelableBlendMode;
parcelableBlendMode.blendMode = mode;
getLayerCommand(display, layer).blendMode.emplace(std::move(parcelableBlendMode));
}
void setLayerColor(int64_t display, int64_t layer, Color color) {
getLayerCommand(display, layer).color.emplace(std::move(color));
}
void setLayerCompositionType(int64_t display, int64_t layer, Composition type) {
ParcelableComposition compositionPayload;
compositionPayload.composition = type;
getLayerCommand(display, layer).composition.emplace(std::move(compositionPayload));
}
void setLayerDataspace(int64_t display, int64_t layer, Dataspace dataspace) {
ParcelableDataspace dataspacePayload;
dataspacePayload.dataspace = dataspace;
getLayerCommand(display, layer).dataspace.emplace(std::move(dataspacePayload));
}
void setLayerDisplayFrame(int64_t display, int64_t layer, const Rect& frame) {
getLayerCommand(display, layer).displayFrame.emplace(frame);
}
void setLayerPlaneAlpha(int64_t display, int64_t layer, float alpha) {
PlaneAlpha planeAlpha;
planeAlpha.alpha = alpha;
getLayerCommand(display, layer).planeAlpha.emplace(std::move(planeAlpha));
}
void setLayerSidebandStream(int64_t display, int64_t layer, const native_handle_t* stream) {
NativeHandle handle;
if (stream) handle = ::android::dupToAidl(stream);
getLayerCommand(display, layer).sidebandStream.emplace(std::move(handle));
}
void setLayerSourceCrop(int64_t display, int64_t layer, const FRect& crop) {
getLayerCommand(display, layer).sourceCrop.emplace(crop);
}
void setLayerTransform(int64_t display, int64_t layer, Transform transform) {
ParcelableTransform transformPayload;
transformPayload.transform = transform;
getLayerCommand(display, layer).transform.emplace(std::move(transformPayload));
}
void setLayerVisibleRegion(int64_t display, int64_t layer, const std::vector<Rect>& visible) {
getLayerCommand(display, layer).visibleRegion.emplace(visible.begin(), visible.end());
}
void setLayerZOrder(int64_t display, int64_t layer, uint32_t z) {
ZOrder zorder;
zorder.z = static_cast<int32_t>(z);
getLayerCommand(display, layer).z.emplace(std::move(zorder));
}
void setLayerPerFrameMetadata(int64_t display, int64_t layer,
const std::vector<PerFrameMetadata>& metadataVec) {
getLayerCommand(display, layer)
.perFrameMetadata.emplace(metadataVec.begin(), metadataVec.end());
}
void setLayerColorTransform(int64_t display, int64_t layer, const float* matrix) {
getLayerCommand(display, layer).colorTransform.emplace(matrix, matrix + 16);
}
void setLayerPerFrameMetadataBlobs(int64_t display, int64_t layer,
const std::vector<PerFrameMetadataBlob>& metadata) {
getLayerCommand(display, layer)
.perFrameMetadataBlob.emplace(metadata.begin(), metadata.end());
}
void setLayerBrightness(int64_t display, int64_t layer, float brightness) {
getLayerCommand(display, layer)
.brightness.emplace(LayerBrightness{.brightness = brightness});
}
void setLayerBlockingRegion(int64_t display, int64_t layer, const std::vector<Rect>& blocking) {
getLayerCommand(display, layer).blockingRegion.emplace(blocking.begin(), blocking.end());
}
std::vector<DisplayCommand> takePendingCommands() {
flushLayerCommand();
flushDisplayCommand();
std::vector<DisplayCommand> moved = std::move(mCommands);
mCommands.clear();
return moved;
}
private:
std::optional<DisplayCommand> mDisplayCommand;
std::optional<LayerCommand> mLayerCommand;
std::vector<DisplayCommand> mCommands;
const int64_t mDisplay;
Buffer getBufferCommand(uint32_t slot, const native_handle_t* bufferHandle, int fence) {
Buffer bufferCommand;
bufferCommand.slot = static_cast<int32_t>(slot);
if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle));
if (fence > 0) bufferCommand.fence = ::ndk::ScopedFileDescriptor(fence);
return bufferCommand;
}
void flushLayerCommand() {
if (mLayerCommand.has_value()) {
mDisplayCommand->layers.emplace_back(std::move(*mLayerCommand));
mLayerCommand.reset();
}
}
void flushDisplayCommand() {
if (mDisplayCommand.has_value()) {
mCommands.emplace_back(std::move(*mDisplayCommand));
mDisplayCommand.reset();
}
}
DisplayCommand& getDisplayCommand(int64_t display) {
if (!mDisplayCommand.has_value() || mDisplayCommand->display != display) {
LOG_ALWAYS_FATAL_IF(display != mDisplay);
flushLayerCommand();
flushDisplayCommand();
mDisplayCommand.emplace();
mDisplayCommand->display = display;
}
return *mDisplayCommand;
}
LayerCommand& getLayerCommand(int64_t display, int64_t layer) {
getDisplayCommand(display);
if (!mLayerCommand.has_value() || mLayerCommand->layer != layer) {
flushLayerCommand();
mLayerCommand.emplace();
mLayerCommand->layer = layer;
}
return *mLayerCommand;
}
void reset() {
mDisplayCommand.reset();
mLayerCommand.reset();
mCommands.clear();
}
};
方法一大堆,实际关注三个参数:
std::optional<DisplayCommand> mDisplayCommand;
std::optional<LayerCommand> mLayerCommand;
std::vector<DisplayCommand> mCommands;
其中 LayerCommand 的实现如下:
class LayerCommand {
public:
typedef std::false_type fixed_size;
static const char* descriptor;
int64_t layer = 0L;
// 数据部分
std::optional<::aidl::android::hardware::graphics::common::Point> cursorPosition;
std::optional<::aidl::android::hardware::graphics::composer3::Buffer> buffer;
std::optional<std::vector<std::optional<::aidl::android::hardware::graphics::common::Rect>>> damage;
std::optional<::aidl::android::hardware::graphics::composer3::ParcelableBlendMode> blendMode;
std::optional<::aidl::android::hardware::graphics::composer3::Color> color;
std::optional<::aidl::android::hardware::graphics::composer3::ParcelableComposition> composition;
std::optional<::aidl::android::hardware::graphics::composer3::ParcelableDataspace> dataspace;
std::optional<::aidl::android::hardware::graphics::common::Rect> displayFrame;
std::optional<::aidl::android::hardware::graphics::composer3::PlaneAlpha> planeAlpha;
std::optional<::aidl::android::hardware::common::NativeHandle> sidebandStream;
std::optional<::aidl::android::hardware::graphics::common::FRect> sourceCrop;
std::optional<::aidl::android::hardware::graphics::composer3::ParcelableTransform> transform;
std::optional<std::vector<std::optional<::aidl::android::hardware::graphics::common::Rect>>> visibleRegion;
std::optional<::aidl::android::hardware::graphics::composer3::ZOrder> z;
std::optional<std::vector<float>> colorTransform;
std::optional<::aidl::android::hardware::graphics::composer3::LayerBrightness> brightness;
std::optional<std::vector<std::optional<::aidl::android::hardware::graphics::composer3::PerFrameMetadata>>> perFrameMetadata;
std::optional<std::vector<std::optional<::aidl::android::hardware::graphics::composer3::PerFrameMetadataBlob>>> perFrameMetadataBlob;
std::optional<std::vector<std::optional<::aidl::android::hardware::graphics::common::Rect>>> blockingRegion;
std::optional<std::vector<int32_t>> bufferSlotsToClear;
binder_status_t readFromParcel(const AParcel* parcel);
binder_status_t writeToParcel(AParcel* parcel) const;
inline bool operator!=(const LayerCommand& rhs) const {
return std::tie(layer, cursorPosition, buffer, damage, blendMode, color, composition, dataspace, displayFrame, planeAlpha, sidebandStream, sourceCrop, transform, visibleRegion, z, colorTransform, brightness, perFrameMetadata, perFrameMetadataBlob, blockingRegion, bufferSlotsToClear) != std::tie(rhs.layer, rhs.cursorPosition, rhs.buffer, rhs.damage, rhs.blendMode, rhs.color, rhs.composition, rhs.dataspace, rhs.displayFrame, rhs.planeAlpha, rhs.sidebandStream, rhs.sourceCrop, rhs.transform, rhs.visibleRegion, rhs.z, rhs.colorTransform, rhs.brightness, rhs.perFrameMetadata, rhs.perFrameMetadataBlob, rhs.blockingRegion, rhs.bufferSlotsToClear);
}
inline bool operator<(const LayerCommand& rhs) const {
return std::tie(layer, cursorPosition, buffer, damage, blendMode, color, composition, dataspace, displayFrame, planeAlpha, sidebandStream, sourceCrop, transform, visibleRegion, z, colorTransform, brightness, perFrameMetadata, perFrameMetadataBlob, blockingRegion, bufferSlotsToClear) < std::tie(rhs.layer, rhs.cursorPosition, rhs.buffer, rhs.damage, rhs.blendMode, rhs.color, rhs.composition, rhs.dataspace, rhs.displayFrame, rhs.planeAlpha, rhs.sidebandStream, rhs.sourceCrop, rhs.transform, rhs.visibleRegion, rhs.z, rhs.colorTransform, rhs.brightness, rhs.perFrameMetadata, rhs.perFrameMetadataBlob, rhs.blockingRegion, rhs.bufferSlotsToClear);
}
inline bool operator<=(const LayerCommand& rhs) const {
return std::tie(layer, cursorPosition, buffer, damage, blendMode, color, composition, dataspace, displayFrame, planeAlpha, sidebandStream, sourceCrop, transform, visibleRegion, z, colorTransform, brightness, perFrameMetadata, perFrameMetadataBlob, blockingRegion, bufferSlotsToClear) <= std::tie(rhs.layer, rhs.cursorPosition, rhs.buffer, rhs.damage, rhs.blendMode, rhs.color, rhs.composition, rhs.dataspace, rhs.displayFrame, rhs.planeAlpha, rhs.sidebandStream, rhs.sourceCrop, rhs.transform, rhs.visibleRegion, rhs.z, rhs.colorTransform, rhs.brightness, rhs.perFrameMetadata, rhs.perFrameMetadataBlob, rhs.blockingRegion, rhs.bufferSlotsToClear);
}
inline bool operator==(const LayerCommand& rhs) const {
return std::tie(layer, cursorPosition, buffer, damage, blendMode, color, composition, dataspace, displayFrame, planeAlpha, sidebandStream, sourceCrop, transform, visibleRegion, z, colorTransform, brightness, perFrameMetadata, perFrameMetadataBlob, blockingRegion, bufferSlotsToClear) == std::tie(rhs.layer, rhs.cursorPosition, rhs.buffer, rhs.damage, rhs.blendMode, rhs.color, rhs.composition, rhs.dataspace, rhs.displayFrame, rhs.planeAlpha, rhs.sidebandStream, rhs.sourceCrop, rhs.transform, rhs.visibleRegion, rhs.z, rhs.colorTransform, rhs.brightness, rhs.perFrameMetadata, rhs.perFrameMetadataBlob, rhs.blockingRegion, rhs.bufferSlotsToClear);
}
inline bool operator>(const LayerCommand& rhs) const {
return std::tie(layer, cursorPosition, buffer, damage, blendMode, color, composition, dataspace, displayFrame, planeAlpha, sidebandStream, sourceCrop, transform, visibleRegion, z, colorTransform, brightness, perFrameMetadata, perFrameMetadataBlob, blockingRegion, bufferSlotsToClear) > std::tie(rhs.layer, rhs.cursorPosition, rhs.buffer, rhs.damage, rhs.blendMode, rhs.color, rhs.composition, rhs.dataspace, rhs.displayFrame, rhs.planeAlpha, rhs.sidebandStream, rhs.sourceCrop, rhs.transform, rhs.visibleRegion, rhs.z, rhs.colorTransform, rhs.brightness, rhs.perFrameMetadata, rhs.perFrameMetadataBlob, rhs.blockingRegion, rhs.bufferSlotsToClear);
}
inline bool operator>=(const LayerCommand& rhs) const {
return std::tie(layer, cursorPosition, buffer, damage, blendMode, color, composition, dataspace, displayFrame, planeAlpha, sidebandStream, sourceCrop, transform, visibleRegion, z, colorTransform, brightness, perFrameMetadata, perFrameMetadataBlob, blockingRegion, bufferSlotsToClear) >= std::tie(rhs.layer, rhs.cursorPosition, rhs.buffer, rhs.damage, rhs.blendMode, rhs.color, rhs.composition, rhs.dataspace, rhs.displayFrame, rhs.planeAlpha, rhs.sidebandStream, rhs.sourceCrop, rhs.transform, rhs.visibleRegion, rhs.z, rhs.colorTransform, rhs.brightness, rhs.perFrameMetadata, rhs.perFrameMetadataBlob, rhs.blockingRegion, rhs.bufferSlotsToClear);
}
static const ::ndk::parcelable_stability_t _aidl_stability = ::ndk::STABILITY_VINTF;
inline std::string toString() const {
std::ostringstream os;
os << "LayerCommand{";
os << "layer: " << ::android::internal::ToString(layer);
os << ", cursorPosition: " << ::android::internal::ToString(cursorPosition);
os << ", buffer: " << ::android::internal::ToString(buffer);
os << ", damage: " << ::android::internal::ToString(damage);
os << ", blendMode: " << ::android::internal::ToString(blendMode);
os << ", color: " << ::android::internal::ToString(color);
os << ", composition: " << ::android::internal::ToString(composition);
os << ", dataspace: " << ::android::internal::ToString(dataspace);
os << ", displayFrame: " << ::android::internal::ToString(displayFrame);
os << ", planeAlpha: " << ::android::internal::ToString(planeAlpha);
os << ", sidebandStream: " << ::android::internal::ToString(sidebandStream);
os << ", sourceCrop: " << ::android::internal::ToString(sourceCrop);
os << ", transform: " << ::android::internal::ToString(transform);
os << ", visibleRegion: " << ::android::internal::ToString(visibleRegion);
os << ", z: " << ::android::internal::ToString(z);
os << ", colorTransform: " << ::android::internal::ToString(colorTransform);
os << ", brightness: " << ::android::internal::ToString(brightness);
os << ", perFrameMetadata: " << ::android::internal::ToString(perFrameMetadata);
os << ", perFrameMetadataBlob: " << ::android::internal::ToString(perFrameMetadataBlob);
os << ", blockingRegion: " << ::android::internal::ToString(blockingRegion);
os << ", bufferSlotsToClear: " << ::android::internal::ToString(bufferSlotsToClear);
os << "}";
return os.str();
}
};
DisplayCommand 的实现如下:
class DisplayCommand {
public:
typedef std::false_type fixed_size;
static const char* descriptor;
int64_t display = 0L;
// 数据部分
std::vector<::aidl::android::hardware::graphics::composer3::LayerCommand> layers;
std::optional<std::vector<float>> colorTransformMatrix;
std::optional<::aidl::android::hardware::graphics::composer3::DisplayBrightness> brightness;
std::optional<::aidl::android::hardware::graphics::composer3::ClientTarget> clientTarget;
std::optional<::aidl::android::hardware::graphics::composer3::Buffer> virtualDisplayOutputBuffer;
std::optional<::aidl::android::hardware::graphics::composer3::ClockMonotonicTimestamp> expectedPresentTime;
bool validateDisplay = false;
bool acceptDisplayChanges = false;
bool presentDisplay = false;
bool presentOrValidateDisplay = false;
binder_status_t readFromParcel(const AParcel* parcel);
binder_status_t writeToParcel(AParcel* parcel) const;
inline bool operator!=(const DisplayCommand& rhs) const {
return std::tie(display, layers, colorTransformMatrix, brightness, clientTarget, virtualDisplayOutputBuffer, expectedPresentTime, validateDisplay, acceptDisplayChanges, presentDisplay, presentOrValidateDisplay) != std::tie(rhs.display, rhs.layers, rhs.colorTransformMatrix, rhs.brightness, rhs.clientTarget, rhs.virtualDisplayOutputBuffer, rhs.expectedPresentTime, rhs.validateDisplay, rhs.acceptDisplayChanges, rhs.presentDisplay, rhs.presentOrValidateDisplay);
}
inline bool operator<(const DisplayCommand& rhs) const {
return std::tie(display, layers, colorTransformMatrix, brightness, clientTarget, virtualDisplayOutputBuffer, expectedPresentTime, validateDisplay, acceptDisplayChanges, presentDisplay, presentOrValidateDisplay) < std::tie(rhs.display, rhs.layers, rhs.colorTransformMatrix, rhs.brightness, rhs.clientTarget, rhs.virtualDisplayOutputBuffer, rhs.expectedPresentTime, rhs.validateDisplay, rhs.acceptDisplayChanges, rhs.presentDisplay, rhs.presentOrValidateDisplay);
}
inline bool operator<=(const DisplayCommand& rhs) const {
return std::tie(display, layers, colorTransformMatrix, brightness, clientTarget, virtualDisplayOutputBuffer, expectedPresentTime, validateDisplay, acceptDisplayChanges, presentDisplay, presentOrValidateDisplay) <= std::tie(rhs.display, rhs.layers, rhs.colorTransformMatrix, rhs.brightness, rhs.clientTarget, rhs.virtualDisplayOutputBuffer, rhs.expectedPresentTime, rhs.validateDisplay, rhs.acceptDisplayChanges, rhs.presentDisplay, rhs.presentOrValidateDisplay);
}
inline bool operator==(const DisplayCommand& rhs) const {
return std::tie(display, layers, colorTransformMatrix, brightness, clientTarget, virtualDisplayOutputBuffer, expectedPresentTime, validateDisplay, acceptDisplayChanges, presentDisplay, presentOrValidateDisplay) == std::tie(rhs.display, rhs.layers, rhs.colorTransformMatrix, rhs.brightness, rhs.clientTarget, rhs.virtualDisplayOutputBuffer, rhs.expectedPresentTime, rhs.validateDisplay, rhs.acceptDisplayChanges, rhs.presentDisplay, rhs.presentOrValidateDisplay);
}
inline bool operator>(const DisplayCommand& rhs) const {
return std::tie(display, layers, colorTransformMatrix, brightness, clientTarget, virtualDisplayOutputBuffer, expectedPresentTime, validateDisplay, acceptDisplayChanges, presentDisplay, presentOrValidateDisplay) > std::tie(rhs.display, rhs.layers, rhs.colorTransformMatrix, rhs.brightness, rhs.clientTarget, rhs.virtualDisplayOutputBuffer, rhs.expectedPresentTime, rhs.validateDisplay, rhs.acceptDisplayChanges, rhs.presentDisplay, rhs.presentOrValidateDisplay);
}
inline bool operator>=(const DisplayCommand& rhs) const {
return std::tie(display, layers, colorTransformMatrix, brightness, clientTarget, virtualDisplayOutputBuffer, expectedPresentTime, validateDisplay, acceptDisplayChanges, presentDisplay, presentOrValidateDisplay) >= std::tie(rhs.display, rhs.layers, rhs.colorTransformMatrix, rhs.brightness, rhs.clientTarget, rhs.virtualDisplayOutputBuffer, rhs.expectedPresentTime, rhs.validateDisplay, rhs.acceptDisplayChanges, rhs.presentDisplay, rhs.presentOrValidateDisplay);
}
static const ::ndk::parcelable_stability_t _aidl_stability = ::ndk::STABILITY_VINTF;
inline std::string toString() const {
std::ostringstream os;
os << "DisplayCommand{";
os << "display: " << ::android::internal::ToString(display);
os << ", layers: " << ::android::internal::ToString(layers);
os << ", colorTransformMatrix: " << ::android::internal::ToString(colorTransformMatrix);
os << ", brightness: " << ::android::internal::ToString(brightness);
os << ", clientTarget: " << ::android::internal::ToString(clientTarget);
os << ", virtualDisplayOutputBuffer: " << ::android::internal::ToString(virtualDisplayOutputBuffer);
os << ", expectedPresentTime: " << ::android::internal::ToString(expectedPresentTime);
os << ", validateDisplay: " << ::android::internal::ToString(validateDisplay);
os << ", acceptDisplayChanges: " << ::android::internal::ToString(acceptDisplayChanges);
os << ", presentDisplay: " << ::android::internal::ToString(presentDisplay);
os << ", presentOrValidateDisplay: " << ::android::internal::ToString(presentOrValidateDisplay);
os << "}";
return os.str();
}
};
一堆的设置方法,都是在配置 mDisplayCommand 和 mLayerCommand。当要发起远程调用时,调用两个 flush 函数,mLayerCommand 插入到 mDisplayCommand->layers 中,mDisplayCommand 插入到 mCommands 中。当执行 aidlComposer::execute
时,会发起 binder 远程调用,使用 mCommands 作为参数:
Error AidlComposer::execute(Display display) {
auto writer = getWriter(display);
auto reader = getReader(display);
if (!writer || !reader) {
return Error::BAD_DISPLAY;
}
// 这里就是返回的 mCommands 中存储的内容
auto commands = writer->get().takePendingCommands();
if (commands.empty()) {
return Error::NONE;
}
{ // scope for results
// 远程调用返回的结果
std::vector<CommandResultPayload> results;
// 发起远程调用,传入了 commands
auto status = mAidlComposerClient->executeCommands(commands, &results);
if (!status.isOk()) {
ALOGE("executeCommands failed %s", status.getDescription().c_str());
return static_cast<Error>(status.getServiceSpecificError());
}
// 通过 reader 解析结果
reader->get().parse(std::move(results));
}
const auto commandErrors = reader->get().takeErrors();
Error error = Error::NONE;
for (const auto& cmdErr : commandErrors) {
const auto index = static_cast<size_t>(cmdErr.commandIndex);
if (index < 0 || index >= commands.size()) {
ALOGE("invalid command index %zu", index);
return Error::BAD_PARAMETER;
}
const auto& command = commands[index];
if (command.validateDisplay || command.presentDisplay || command.presentOrValidateDisplay) {
error = translate<Error>(cmdErr.errorCode);
} else {
ALOGW("command '%s' generated error %" PRId32, command.toString().c_str(),
cmdErr.errorCode);
}
}
return error;
}
返回结果 CommandResultPayload 的定义如下:
class CommandResultPayload {
public:
typedef std::false_type fixed_size;
static const char* descriptor;
enum class Tag : int32_t {
error = 0,
changedCompositionTypes = 1,
displayRequest = 2,
presentFence = 3,
releaseFences = 4,
presentOrValidateResult = 5,
clientTargetProperty = 6,
};
// Expose tag symbols for legacy code
static const inline Tag error = Tag::error;
static const inline Tag changedCompositionTypes = Tag::changedCompositionTypes;
static const inline Tag displayRequest = Tag::displayRequest;
static const inline Tag presentFence = Tag::presentFence;
static const inline Tag releaseFences = Tag::releaseFences;
static const inline Tag presentOrValidateResult = Tag::presentOrValidateResult;
static const inline Tag clientTargetProperty = Tag::clientTargetProperty;
template<typename _Tp>
static constexpr bool _not_self = !std::is_same_v<std::remove_cv_t<std::remove_reference_t<_Tp>>, CommandResultPayload>;
CommandResultPayload() : _value(std::in_place_index<static_cast<size_t>(error)>, ::aidl::android::hardware::graphics::composer3::CommandError()) { }
template <typename _Tp, typename = std::enable_if_t<_not_self<_Tp>>>
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr CommandResultPayload(_Tp&& _arg)
: _value(std::forward<_Tp>(_arg)) {}
template <size_t _Np, typename... _Tp>
constexpr explicit CommandResultPayload(std::in_place_index_t<_Np>, _Tp&&... _args)
: _value(std::in_place_index<_Np>, std::forward<_Tp>(_args)...) {}
template <Tag _tag, typename... _Tp>
static CommandResultPayload make(_Tp&&... _args) {
return CommandResultPayload(std::in_place_index<static_cast<size_t>(_tag)>, std::forward<_Tp>(_args)...);
}
template <Tag _tag, typename _Tp, typename... _Up>
static CommandResultPayload make(std::initializer_list<_Tp> _il, _Up&&... _args) {
return CommandResultPayload(std::in_place_index<static_cast<size_t>(_tag)>, std::move(_il), std::forward<_Up>(_args)...);
}
Tag getTag() const {
return static_cast<Tag>(_value.index());
}
template <Tag _tag>
const auto& get() const {
if (getTag() != _tag) { __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "bad access: a wrong tag"); }
return std::get<static_cast<size_t>(_tag)>(_value);
}
template <Tag _tag>
auto& get() {
if (getTag() != _tag) { __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "bad access: a wrong tag"); }
return std::get<static_cast<size_t>(_tag)>(_value);
}
template <Tag _tag, typename... _Tp>
void set(_Tp&&... _args) {
_value.emplace<static_cast<size_t>(_tag)>(std::forward<_Tp>(_args)...);
}
binder_status_t readFromParcel(const AParcel* _parcel);
binder_status_t writeToParcel(AParcel* _parcel) const;
inline bool operator!=(const CommandResultPayload& rhs) const {
return _value != rhs._value;
}
inline bool operator<(const CommandResultPayload& rhs) const {
return _value < rhs._value;
}
inline bool operator<=(const CommandResultPayload& rhs) const {
return _value <= rhs._value;
}
inline bool operator==(const CommandResultPayload& rhs) const {
return _value == rhs._value;
}
inline bool operator>(const CommandResultPayload& rhs) const {
return _value > rhs._value;
}
inline bool operator>=(const CommandResultPayload& rhs) const {
return _value >= rhs._value;
}
static const ::ndk::parcelable_stability_t _aidl_stability = ::ndk::STABILITY_VINTF;
inline std::string toString() const {
std::ostringstream os;
os << "CommandResultPayload{";
switch (getTag()) {
case error: os << "error: " << ::android::internal::ToString(get<error>()); break;
case changedCompositionTypes: os << "changedCompositionTypes: " << ::android::internal::ToString(get<changedCompositionTypes>()); break;
case displayRequest: os << "displayRequest: " << ::android::internal::ToString(get<displayRequest>()); break;
case presentFence: os << "presentFence: " << ::android::internal::ToString(get<presentFence>()); break;
case releaseFences: os << "releaseFences: " << ::android::internal::ToString(get<releaseFences>()); break;
case presentOrValidateResult: os << "presentOrValidateResult: " << ::android::internal::ToString(get<presentOrValidateResult>()); break;
case clientTargetProperty: os << "clientTargetProperty: " << ::android::internal::ToString(get<clientTargetProperty>()); break;
}
os << "}";
return os.str();
}
private:
std::variant<::aidl::android::hardware::graphics::composer3::CommandError, ::aidl::android::hardware::graphics::composer3::ChangedCompositionTypes, ::aidl::android::hardware::graphics::composer3::DisplayRequest, ::aidl::android::hardware::graphics::composer3::PresentFence, ::aidl::android::hardware::graphics::composer3::ReleaseFences, ::aidl::android::hardware::graphics::composer3::PresentOrValidate, ::aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness> _value;
};
主要的数据就是最后的 variant 变量。
我们来看 reader 是如何解析的。
ComposerClientReader 的定义如下,主要看下 parse 的实现:
class ComposerClientReader {
public:
explicit ComposerClientReader(std::optional<int64_t> display = {}) : mDisplay(display) {}
~ComposerClientReader() { resetData(); }
ComposerClientReader(ComposerClientReader&&) = default;
ComposerClientReader(const ComposerClientReader&) = delete;
ComposerClientReader& operator=(const ComposerClientReader&) = delete;
// Parse and execute commands from the command queue. The commands are
// actually return values from the server and will be saved in ReturnData.
void parse(std::vector<CommandResultPayload>&& results) {
resetData();
for (auto& result : results) {
// 根据不同的 tag,调用不同的方法解析
switch (result.getTag()) {
case CommandResultPayload::Tag::error:
parseSetError(std::move(result.get<CommandResultPayload::Tag::error>()));
break;
case CommandResultPayload::Tag::changedCompositionTypes:
parseSetChangedCompositionTypes(std::move(
result.get<CommandResultPayload::Tag::changedCompositionTypes>()));
break;
case CommandResultPayload::Tag::displayRequest:
parseSetDisplayRequests(
std::move(result.get<CommandResultPayload::Tag::displayRequest>()));
break;
case CommandResultPayload::Tag::presentFence:
parseSetPresentFence(
std::move(result.get<CommandResultPayload::Tag::presentFence>()));
break;
case CommandResultPayload::Tag::releaseFences:
parseSetReleaseFences(
std::move(result.get<CommandResultPayload::Tag::releaseFences>()));
break;
case CommandResultPayload::Tag::presentOrValidateResult:
parseSetPresentOrValidateDisplayResult(std::move(
result.get<CommandResultPayload::Tag::presentOrValidateResult>()));
break;
case CommandResultPayload::Tag::clientTargetProperty:
parseSetClientTargetProperty(std::move(
result.get<CommandResultPayload::Tag::clientTargetProperty>()));
break;
}
}
}
std::vector<CommandError> takeErrors() { return std::move(mErrors); }
void hasChanges(int64_t display, uint32_t* outNumChangedCompositionTypes,
uint32_t* outNumLayerRequestMasks) const {
LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
auto found = mReturnData.find(display);
if (found == mReturnData.end()) {
*outNumChangedCompositionTypes = 0;
*outNumLayerRequestMasks = 0;
return;
}
const ReturnData& data = found->second;
*outNumChangedCompositionTypes = static_cast<uint32_t>(data.changedLayers.size());
*outNumLayerRequestMasks = static_cast<uint32_t>(data.displayRequests.layerRequests.size());
}
// Get and clear saved changed composition types.
std::vector<ChangedCompositionLayer> takeChangedCompositionTypes(int64_t display) {
LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
auto found = mReturnData.find(display);
if (found == mReturnData.end()) {
return {};
}
ReturnData& data = found->second;
return std::move(data.changedLayers);
}
// Get and clear saved display requests.
DisplayRequest takeDisplayRequests(int64_t display) {
LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
auto found = mReturnData.find(display);
if (found == mReturnData.end()) {
return {};
}
ReturnData& data = found->second;
return std::move(data.displayRequests);
}
// Get and clear saved release fences.
std::vector<ReleaseFences::Layer> takeReleaseFences(int64_t display) {
LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
auto found = mReturnData.find(display);
if (found == mReturnData.end()) {
return {};
}
ReturnData& data = found->second;
return std::move(data.releasedLayers);
}
// Get and clear saved present fence.
ndk::ScopedFileDescriptor takePresentFence(int64_t display) {
LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
auto found = mReturnData.find(display);
if (found == mReturnData.end()) {
return {};
}
ReturnData& data = found->second;
return std::move(data.presentFence);
}
// Get what stage succeeded during PresentOrValidate: Present or Validate
std::optional<PresentOrValidate::Result> takePresentOrValidateStage(int64_t display) {
LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
auto found = mReturnData.find(display);
if (found == mReturnData.end()) {
return std::nullopt;
}
ReturnData& data = found->second;
return data.presentOrValidateState;
}
// Get the client target properties requested by hardware composer.
ClientTargetPropertyWithBrightness takeClientTargetProperty(int64_t display) {
LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
auto found = mReturnData.find(display);
// If not found, return the default values.
if (found == mReturnData.end()) {
return ClientTargetPropertyWithBrightness{
.clientTargetProperty = {common::PixelFormat::RGBA_8888, Dataspace::UNKNOWN},
.brightness = 1.f,
};
}
ReturnData& data = found->second;
return std::move(data.clientTargetProperty);
}
private:
void resetData() {
mErrors.clear();
mReturnData.clear();
}
void parseSetError(CommandError&& error) { mErrors.emplace_back(error); }
void parseSetChangedCompositionTypes(ChangedCompositionTypes&& changedCompositionTypes) {
LOG_ALWAYS_FATAL_IF(mDisplay && changedCompositionTypes.display != *mDisplay);
auto& data = mReturnData[changedCompositionTypes.display];
data.changedLayers = std::move(changedCompositionTypes.layers);
}
void parseSetDisplayRequests(DisplayRequest&& displayRequest) {
LOG_ALWAYS_FATAL_IF(mDisplay && displayRequest.display != *mDisplay);
auto& data = mReturnData[displayRequest.display];
data.displayRequests = std::move(displayRequest);
}
void parseSetPresentFence(PresentFence&& presentFence) {
LOG_ALWAYS_FATAL_IF(mDisplay && presentFence.display != *mDisplay);
auto& data = mReturnData[presentFence.display];
data.presentFence = std::move(presentFence.fence);
}
void parseSetReleaseFences(ReleaseFences&& releaseFences) {
LOG_ALWAYS_FATAL_IF(mDisplay && releaseFences.display != *mDisplay);
auto& data = mReturnData[releaseFences.display];
data.releasedLayers = std::move(releaseFences.layers);
}
void parseSetPresentOrValidateDisplayResult(const PresentOrValidate&& presentOrValidate) {
LOG_ALWAYS_FATAL_IF(mDisplay && presentOrValidate.display != *mDisplay);
auto& data = mReturnData[presentOrValidate.display];
data.presentOrValidateState = std::move(presentOrValidate.result);
}
void parseSetClientTargetProperty(
const ClientTargetPropertyWithBrightness&& clientTargetProperty) {
LOG_ALWAYS_FATAL_IF(mDisplay && clientTargetProperty.display != *mDisplay);
auto& data = mReturnData[clientTargetProperty.display];
data.clientTargetProperty = std::move(clientTargetProperty);
}
struct ReturnData {
DisplayRequest displayRequests;
std::vector<ChangedCompositionLayer> changedLayers;
ndk::ScopedFileDescriptor presentFence;
std::vector<ReleaseFences::Layer> releasedLayers;
PresentOrValidate::Result presentOrValidateState;
ClientTargetPropertyWithBrightness clientTargetProperty = {
.clientTargetProperty = {common::PixelFormat::RGBA_8888, Dataspace::UNKNOWN},
.brightness = 1.f,
};
};
std::vector<CommandError> mErrors;
std::unordered_map<int64_t, ReturnData> mReturnData;
const std::optional<int64_t> mDisplay;
};
Reader 用于解析远程调用返回的数据。
问题,mWriters 和 mReader 什么时候添加数据的?
看下 AidlComposer 构造函数:
// /frameworks/native/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
AidlComposer::AidlComposer(const std::string& serviceName) {
// This only waits if the service is actually declared
mAidlComposer = AidlIComposer::fromBinder(
ndk::SpAIBinder(AServiceManager_waitForService(instance(serviceName).c_str())));
if (!mAidlComposer) {
LOG_ALWAYS_FATAL("Failed to get AIDL composer service");
return;
}
if (!mAidlComposer->createClient(&mAidlComposerClient).isOk()) {
LOG_ALWAYS_FATAL("Can't create AidlComposerClient, fallback to HIDL");
return;
}
// 是不是添加 reader ?
addReader(translate<Display>(kSingleReaderKey));
// If unable to read interface version, then become backwards compatible.
int32_t version = 1;
const auto status = mAidlComposerClient->getInterfaceVersion(&version);
if (!status.isOk()) {
ALOGE("getInterfaceVersion for AidlComposer constructor failed %s",
status.getDescription().c_str());
}
mSupportsBufferSlotsToClear = version > 1;
if (!mSupportsBufferSlotsToClear) {
if (sysprop::clear_slots_with_set_layer_buffer(false)) {
mClearSlotBuffer = sp<GraphicBuffer>::make(1, 1, PIXEL_FORMAT_RGBX_8888,
GraphicBuffer::USAGE_HW_COMPOSER |
GraphicBuffer::USAGE_SW_READ_OFTEN |
GraphicBuffer::USAGE_SW_WRITE_OFTEN,
"AidlComposer");
if (!mClearSlotBuffer || mClearSlotBuffer->initCheck() != ::android::OK) {
LOG_ALWAYS_FATAL("Failed to allocate a buffer for clearing layer buffer slots");
return;
}
}
}
ALOGI("Loaded AIDL composer3 HAL service");
}
void AidlComposer::addReader(Display display) {
const auto displayId = translate<int64_t>(display);
std::optional<int64_t> displayOpt;
if (displayId != kSingleReaderKey) {
displayOpt.emplace(displayId);
}
// 添加 reader
auto [it, added] = mReaders.try_emplace(display, std::move(displayOpt));
ALOGW_IF(!added, "Attempting to add writer for display %" PRId64 " which is already connected",
displayId);
}
热插拔,or 初始化时:
void AidlComposer::onHotplugConnect(Display display) {
addDisplay(display);
}
//
void AidlComposer::addDisplay(Display display) {
const auto displayId = translate<int64_t>(display);
mMutex.lock();
// 添加 writer
auto [it, added] = mWriters.try_emplace(display, displayId);
ALOGW_IF(!added, "Attempting to add writer for display %" PRId64 " which is already connected",
displayId);
if (mSingleReader) {
if (hasMultiThreadedPresentSupport(display)) {
mSingleReader = false;
removeReader(translate<Display>(kSingleReaderKey));
// Note that this includes the new display.
for (const auto& [existingDisplay, _] : mWriters) {
addReader(existingDisplay);
}
}
} else {
addReader(display);
}
mMutex.unlock();
}
7.2.2 关注点1,updateCompositionState
关注点1,updateCompositionState 会调用所有 OutputLayer 的 updateCompositionState 来更新数据:
void Output::updateCompositionState(const compositionengine::CompositionRefreshArgs& refreshArgs) {
ATRACE_CALL();
ALOGV(__FUNCTION__);
if (!getState().isEnabled) {
return;
}
mLayerRequestingBackgroundBlur = findLayerRequestingBackgroundComposition();
bool forceClientComposition = mLayerRequestingBackgroundBlur != nullptr;
for (auto* layer : getOutputLayersOrderedByZ()) {
layer->updateCompositionState(refreshArgs.updatingGeometryThisFrame,
refreshArgs.devOptForceClientComposition ||
forceClientComposition,
refreshArgs.internalDisplayRotationFlags);
if (mLayerRequestingBackgroundBlur == layer) {
forceClientComposition = false;
}
}
updateCompositionStateForBorder(refreshArgs);
}
遍历调用每个 OutputLayer 的 updateCompositionState,更新每个 OutputLayer 的 state 的一些信息。然后还调用 updateCompositionStateForBorder 同步参数内每个 layer 的同步信息。我们的 Demo 涉及不到,具体细节我们就不看了。
void Output::updateCompositionState(const compositionengine::CompositionRefreshArgs& refreshArgs) {
if (!getState().isEnabled) {
return;
}
// forceClientComposition代表是否需要gpu合成,有模糊的layer这里返回就不为空,forceClientComposition为true
mLayerRequestingBackgroundBlur = findLayerRequestingBackgroundComposition();
bool forceClientComposition = mLayerRequestingBackgroundBlur != nullptr;
for (auto* layer : getOutputLayersOrderedByZ()) {
// 遍历素有 OutputLayer,调用 updateCompositionState
layer->updateCompositionState(refreshArgs.updatingGeometryThisFrame,
refreshArgs.devOptForceClientComposition ||
forceClientComposition,
refreshArgs.internalDisplayRotationFlags);
// 当layer == mLayerRequestingBackgroundBlur,表示后面的layer已经没有模糊的layer,就不需要强制gpu合成。
if (mLayerRequestingBackgroundBlur == layer) {
forceClientComposition = false;
}
}
// 将refreshArgs里面layer的边界信息同步到OutputCompositionState的borderInfoList列表里。
updateCompositionStateForBorder(refreshArgs);
}
7.2.3 writeCompositionState
关注点 2 writeCompositionState:
void Output::writeCompositionState(const compositionengine::CompositionRefreshArgs& refreshArgs) {
ATRACE_CALL();
ALOGV(__FUNCTION__);
if (!getState().isEnabled) {
return;
}
editState().earliestPresentTime = refreshArgs.earliestPresentTime;
editState().expectedPresentTime = refreshArgs.expectedPresentTime;
compositionengine::OutputLayer* peekThroughLayer = nullptr;
sp<GraphicBuffer> previousOverride = nullptr;
bool includeGeometry = refreshArgs.updatingGeometryThisFrame;
uint32_t z = 0;
bool overrideZ = false;
uint64_t outputLayerHash = 0;
// 遍历所有的 OutputLayer
for (auto* layer : getOutputLayersOrderedByZ()) {
if (layer == peekThroughLayer) {
// No longer needed, although it should not show up again, so
// resetting it is not truly needed either.
peekThroughLayer = nullptr;
// peekThroughLayer was already drawn ahead of its z order.
continue;
}
bool skipLayer = false;
const auto& overrideInfo = layer->getState().overrideInfo;
if (overrideInfo.buffer != nullptr) {
if (previousOverride && overrideInfo.buffer->getBuffer() == previousOverride) {
ALOGV("Skipping redundant buffer");
skipLayer = true;
} else {
// First layer with the override buffer.
if (overrideInfo.peekThroughLayer) {
peekThroughLayer = overrideInfo.peekThroughLayer;
// Draw peekThroughLayer first.
overrideZ = true;
includeGeometry = true;
constexpr bool isPeekingThrough = true;
peekThroughLayer->writeStateToHWC(includeGeometry, false, z++, overrideZ,
isPeekingThrough);
outputLayerHash ^= android::hashCombine(
reinterpret_cast<uint64_t>(&peekThroughLayer->getLayerFE()),
z, includeGeometry, overrideZ, isPeekingThrough,
peekThroughLayer->requiresClientComposition());
}
previousOverride = overrideInfo.buffer->getBuffer();
}
}
constexpr bool isPeekingThrough = false;
// 关注点
layer->writeStateToHWC(includeGeometry, skipLayer, z++, overrideZ, isPeekingThrough);
if (!skipLayer) {
outputLayerHash ^= android::hashCombine(
reinterpret_cast<uint64_t>(&layer->getLayerFE()),
z, includeGeometry, overrideZ, isPeekingThrough,
layer->requiresClientComposition());
}
}
editState().outputLayerHash = outputLayerHash;
}
遍历所有的 OutputLayer,然后调用每一个 OutputLayer 的 writeStateToHWC 函数:
void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t z,
bool zIsOverridden, bool isPeekingThrough) {
const auto& state = getState();
// Skip doing this if there is no HWC interface
if (!state.hwc) {
return;
}
//拿到 OutputLayer 对应的 hwclayer
auto& hwcLayer = (*state.hwc).hwcLayer;
if (!hwcLayer) {
ALOGE("[%s] failed to write composition state to HWC -- no hwcLayer for output %s",
getLayerFE().getDebugName(), getOutput().getName().c_str());
return;
}
const auto* outputIndependentState = getLayerFE().getCompositionState();
if (!outputIndependentState) {
return;
}
auto requestedCompositionType = outputIndependentState->compositionType;
if (requestedCompositionType == Composition::SOLID_COLOR && state.overrideInfo.buffer) {
// this should never happen, as SOLID_COLOR is skipped from caching, b/230073351
requestedCompositionType = Composition::DEVICE;
}
// TODO(b/181172795): We now update geometry for all flattened layers. We should update it
// only when the geometry actually changes
const bool isOverridden =
state.overrideInfo.buffer != nullptr || isPeekingThrough || zIsOverridden;
const bool prevOverridden = state.hwc->stateOverridden;
if (isOverridden || prevOverridden || skipLayer || includeGeometry) {
writeOutputDependentGeometryStateToHWC(hwcLayer.get(), requestedCompositionType, z);
writeOutputIndependentGeometryStateToHWC(hwcLayer.get(), *outputIndependentState,
skipLayer);
}
// 写数据到 hwc
writeOutputDependentPerFrameStateToHWC(hwcLayer.get());
writeOutputIndependentPerFrameStateToHWC(hwcLayer.get(), *outputIndependentState,
requestedCompositionType, skipLayer);
writeCompositionTypeToHWC(hwcLayer.get(), requestedCompositionType, isPeekingThrough,
skipLayer);
if (requestedCompositionType == Composition::SOLID_COLOR) {
writeSolidColorStateToHWC(hwcLayer.get(), *outputIndependentState);
}
editState().hwc->stateOverridden = isOverridden;
editState().hwc->layerSkipped = skipLayer;
}
writeOutputDependentPerFrameStateToHWC、writeOutputIndependentPerFrameStateToHWC、writeCompositionTypeToHWC、writeSolidColorStateToHWC 四个函数都是用于写数据到 hwc,逻辑大体一样,我们一个个看:
void OutputLayer::writeOutputDependentPerFrameStateToHWC(HWC2::Layer* hwcLayer) {
const auto& outputDependentState = getState();
// TODO(lpique): b/121291683 outputSpaceVisibleRegion is output-dependent geometry
// state and should not change every frame.
Region visibleRegion = outputDependentState.overrideInfo.buffer
? Region(outputDependentState.overrideInfo.visibleRegion)
: outputDependentState.outputSpaceVisibleRegion;
// 关注点
if (auto error = hwcLayer->setVisibleRegion(visibleRegion); error != hal::Error::NONE) {
ALOGE("[%s] Failed to set visible region: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
visibleRegion.dump(LOG_TAG);
}
// 关注点
if (auto error =
hwcLayer->setBlockingRegion(outputDependentState.outputSpaceBlockingRegionHint);
error != hal::Error::NONE) {
ALOGE("[%s] Failed to set blocking region: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
outputDependentState.outputSpaceBlockingRegionHint.dump(LOG_TAG);
}
const auto dataspace = outputDependentState.overrideInfo.buffer
? outputDependentState.overrideInfo.dataspace
: outputDependentState.dataspace;
// 关注点
if (auto error = hwcLayer->setDataspace(dataspace); error != hal::Error::NONE) {
ALOGE("[%s] Failed to set dataspace %d: %s (%d)", getLayerFE().getDebugName(), dataspace,
to_string(error).c_str(), static_cast<int32_t>(error));
}
// Cached layers are not dimmed, which means that composer should attempt to dim.
// Note that if the dimming ratio is large, then this may cause the cached layer
// to kick back into GPU composition :(
// Also note that this assumes that there are no HDR layers that are able to be cached.
// Otherwise, this could cause HDR layers to be dimmed twice.
const auto dimmingRatio = outputDependentState.overrideInfo.buffer
? (getOutput().getState().displayBrightnessNits != 0.f
? std::clamp(getOutput().getState().sdrWhitePointNits /
getOutput().getState().displayBrightnessNits,
0.f, 1.f)
: 1.f)
: outputDependentState.dimmingRatio;
// 关注点
if (auto error = hwcLayer->setBrightness(dimmingRatio); error != hal::Error::NONE) {
ALOGE("[%s] Failed to set brightness %f: %s (%d)", getLayerFE().getDebugName(),
dimmingRatio, to_string(error).c_str(), static_cast<int32_t>(error));
}
}
- hwcLayer->setVisibleRegion:设置到 writer 中的 LayerCommand 的 visibleRegion
- hwcLayer->setBlockingRegion:设置到 writer 中的 LayerCommand 的 blockingRegion
- hwcLayer->setDataspace:设置到 writer 中的 LayerCommand 的 dataspace
- hwcLayer->setBrightness:设置到 writer 中的 LayerCommand 的 brightness
逻辑都是一样的,我们就看一个:
Error Layer::setVisibleRegion(const Region& region)
{
if (CC_UNLIKELY(!mDisplay)) {
return Error::BAD_DISPLAY;
}
if (region.isRect() && mVisibleRegion.isRect() &&
(region.getBounds() == mVisibleRegion.getBounds())) {
return Error::NONE;
}
mVisibleRegion = region;
const auto hwcRects = convertRegionToHwcRects(region);
auto intError = mComposer.setLayerVisibleRegion(mDisplay->getId(), mId, hwcRects);
return static_cast<Error>(intError);
}
接着调用 mComposer.setLayerVisibleRegion
:
Error AidlComposer::setLayerVisibleRegion(Display display, Layer layer,
const std::vector<IComposerClient::Rect>& visible) {
Error error = Error::NONE;
mMutex.lock_shared();
if (auto writer = getWriter(display)) {
writer->get().setLayerVisibleRegion(translate<int64_t>(display), translate<int64_t>(layer),
translate<AidlRect>(visible));
} else {
error = Error::BAD_DISPLAY;
}
mMutex.unlock_shared();
return error;
}
void setLayerVisibleRegion(int64_t display, int64_t layer, const std::vector<Rect>& visible) {
getLayerCommand(display, layer).visibleRegion.emplace(visible.begin(), visible.end());
}
接下来看 writeOutputIndependentPerFrameStateToHWC 的实现:
void OutputLayer::writeOutputIndependentPerFrameStateToHWC(
HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState,
Composition compositionType, bool skipLayer) {
// 关注点
switch (auto error = hwcLayer->setColorTransform(outputIndependentState.colorTransform)) {
case hal::Error::NONE:
break;
case hal::Error::UNSUPPORTED:
editState().forceClientComposition = true;
break;
default:
ALOGE("[%s] Failed to set color transform: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
}
const Region& surfaceDamage = getState().overrideInfo.buffer
? getState().overrideInfo.damageRegion
: (getState().hwc->stateOverridden ? Region::INVALID_REGION
: outputIndependentState.surfaceDamage);
// 关注点
if (auto error = hwcLayer->setSurfaceDamage(surfaceDamage); error != hal::Error::NONE) {
ALOGE("[%s] Failed to set surface damage: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
outputIndependentState.surfaceDamage.dump(LOG_TAG);
}
// Content-specific per-frame state
switch (compositionType) {
case Composition::SOLID_COLOR:
// For compatibility, should be written AFTER the composition type.
break;
case Composition::SIDEBAND:
writeSidebandStateToHWC(hwcLayer, outputIndependentState);
break;
case Composition::CURSOR:
case Composition::DEVICE: // device 合成走这里
case Composition::DISPLAY_DECORATION:
case Composition::REFRESH_RATE_INDICATOR:
// 关注点
writeBufferStateToHWC(hwcLayer, outputIndependentState, skipLayer);
break;
case Composition::INVALID:
case Composition::CLIENT:
// Ignored
break;
}
}
- hwcLayer->setColorTransform
- hwcLayer->setSurfaceDamage
- writeSidebandStateToHWC
- writeBufferStateToHWC
写数据到 hwc,逻辑类似,挑 writeBufferStateToHWC 看看:
// /frameworks/native/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
void OutputLayer::writeBufferStateToHWC(HWC2::Layer* hwcLayer,
const LayerFECompositionState& outputIndependentState,
bool skipLayer) {
auto supportedPerFrameMetadata =
getOutput().getDisplayColorProfile()->getSupportedPerFrameMetadata();
if (auto error = hwcLayer->setPerFrameMetadata(supportedPerFrameMetadata,
outputIndependentState.hdrMetadata);
error != hal::Error::NONE && error != hal::Error::UNSUPPORTED) {
ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
}
// 关注点 buffrer 的获取过程
HwcSlotAndBuffer hwcSlotAndBuffer;
sp<Fence> hwcFence;
{
// Editing the state only because we update the HWC buffer cache and active buffer.
auto& state = editState();
// Override buffers use a special cache slot so that they don't evict client buffers.
if (state.overrideInfo.buffer != nullptr && !skipLayer) {
hwcSlotAndBuffer = state.hwc->hwcBufferCache.getOverrideHwcSlotAndBuffer(
state.overrideInfo.buffer->getBuffer());
hwcFence = state.overrideInfo.acquireFence;
// Keep track of the active buffer ID so when it's discarded we uncache it last so its
// slot will be used first, allowing the memory to be freed as soon as possible.
state.hwc->activeBufferId = state.overrideInfo.buffer->getBuffer()->getId();
} else {
// hwcBufferCache 用于缓存优化,实际的 buffer 来自 outputIndependentState
hwcSlotAndBuffer =
state.hwc->hwcBufferCache.getHwcSlotAndBuffer(outputIndependentState.buffer);
hwcFence = outputIndependentState.acquireFence;
// Keep track of the active buffer ID so when it's discarded we uncache it last so its
// slot will be used first, allowing the memory to be freed as soon as possible.
state.hwc->activeBufferId = outputIndependentState.buffer->getId();
}
// Keep track of the active buffer slot, so we can restore it after clearing other buffer
// slots.
state.hwc->activeBufferSlot = hwcSlotAndBuffer.slot;
}
// 关注点
if (auto error = hwcLayer->setBuffer(hwcSlotAndBuffer.slot, hwcSlotAndBuffer.buffer, hwcFence);
error != hal::Error::NONE) {
ALOGE("[%s] Failed to set buffer %p: %s (%d)", getLayerFE().getDebugName(),
hwcSlotAndBuffer.buffer->handle, to_string(error).c_str(),
static_cast<int32_t>(error));
}
}
setBuffer 的实现如下:
Error Layer::setBuffer(uint32_t slot, const sp<GraphicBuffer>& buffer,
const sp<Fence>& acquireFence)
{
if (CC_UNLIKELY(!mDisplay)) {aidl
return Error::BAD_DISPLAY;
}
if (buffer == nullptr && mBufferSlot == slot) {
return Error::NONE;
}
mBufferSlot = slot;
int32_t fenceFd = acquireFence->dup();
auto intError = mComposer.setLayerBuffer(mDisplay->getId(), mId, slot, buffer, fenceFd);
return static_cast<Error>(intError);
}
接着调用到 mComposer.setLayerBuffer
:
Error AidlComposer::setLayerBuffer(Display display, Layer layer, uint32_t slot,
const sp<GraphicBuffer>& buffer, int acquireFence) {
const native_handle_t* handle = nullptr;
if (buffer.get()) {
handle = buffer->getNativeBuffer()->handle;
}
Error error = Error::NONE;
mMutex.lock_shared();
if (auto writer = getWriter(display)) {
writer->get().setLayerBuffer(translate<int64_t>(display), translate<int64_t>(layer), slot,
handle, acquireFence);
} else {
error = Error::BAD_DISPLAY;
}
mMutex.unlock_shared();
return error;
}
看下 writer 的 setLayerBuffer:
void setLayerBuffer(int64_t display, int64_t layer, uint32_t slot,
const native_handle_t* buffer, int acquireFence) {
getLayerCommand(display, layer).buffer = getBufferCommand(slot, buffer, acquireFence);
}
Buffer getBufferCommand(uint32_t slot, const native_handle_t* bufferHandle, int fence) {
Buffer bufferCommand;
bufferCommand.slot = static_cast<int32_t>(slot);
if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle));
if (fence > 0) bufferCommand.fence = ::ndk::ScopedFileDescriptor(fence);
return bufferCommand;
}
LayerCommand& getLayerCommand(int64_t display, int64_t layer) {
getDisplayCommand(display);
if (!mLayerCommand.has_value() || mLayerCommand->layer != layer) {
flushLayerCommand();
mLayerCommand.emplace();
mLayerCommand->layer = layer;
}
return *mLayerCommand;
}
实际就是把 buffer 保存到了 mLayerCommand 的 buffer 成员的 handle 成员中。
其他的设置都大体类似。
接着再来看 writeCompositionTypeToHWC
的实现:
void OutputLayer::writeCompositionTypeToHWC(HWC2::Layer* hwcLayer,
Composition requestedCompositionType,
bool isPeekingThrough, bool skipLayer) {
auto& outputDependentState = editState();
if (isClientCompositionForced(isPeekingThrough)) {
// If we are forcing client composition, we need to tell the HWC
requestedCompositionType = Composition::CLIENT;
}
// Set the requested composition type with the HWC whenever it changes
// We also resend the composition type when this layer was previously skipped, to ensure that
// the composition type is up-to-date.
if (outputDependentState.hwc->hwcCompositionType != requestedCompositionType ||
(outputDependentState.hwc->layerSkipped && !skipLayer)) {
outputDependentState.hwc->hwcCompositionType = requestedCompositionType;
// 关注点
if (auto error = hwcLayer->setCompositionType(requestedCompositionType);
error != hal::Error::NONE) {
ALOGE("[%s] Failed to set composition type %s: %s (%d)", getLayerFE().getDebugName(),
to_string(requestedCompositionType).c_str(), to_string(error).c_str(),
static_cast<int32_t>(error));
}
}
}
hwcLayer->setCompositionType,设置到 writer 中的 LayerCommand 的 composition。和前面一样,就不细看。
最后一个 writeSolidColorStateToHWC 和前面三个函数逻辑相同,就留给读者分析了。