SF: Split FE and CE
Make LayerFE a standalone class with no links back to Layer. Pass
LayerSnapshot from Layer into LayerFE before CompositionEngine::present
and back after.
Bug: 238781169
Test: go/wm-smoke
Test: presubmit
Change-Id: I5395fb717a931f88e2bf26395acd21e8b308961e
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 8a76d7c..67a226e 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -163,6 +163,7 @@
"HwcSlotGenerator.cpp",
"WindowInfosListenerInvoker.cpp",
"Layer.cpp",
+ "LayerFE.cpp",
"LayerProtoHelper.cpp",
"LayerRenderArea.cpp",
"LayerVector.cpp",
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
index fe8cad5..608c53a 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
@@ -118,6 +118,9 @@
// Requested white point of the layer in nits
const float whitePointNits;
+
+ // True if layers with 170M dataspace should be overridden to sRGB.
+ const bool treat170mAsSrgb;
};
// A superset of LayerSettings required by RenderEngine to compose a layer
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
index 5aec7c2..e309442 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
@@ -72,6 +72,7 @@
SolidColor = 1u << 16,
BackgroundBlurRadius = 1u << 17,
BlurRegions = 1u << 18,
+ HasProtectedContent = 1u << 19,
};
// clang-format on
@@ -245,9 +246,9 @@
ui::Dataspace getDataspace() const { return mOutputDataspace.get(); }
- bool isProtected() const {
- return getOutputLayer()->getLayerFE().getCompositionState()->hasProtectedContent;
- }
+ wp<GraphicBuffer> getBuffer() const { return mBuffer.get(); }
+
+ bool isProtected() const { return mIsProtected.get(); }
bool hasSolidColorCompositionType() const {
return getOutputLayer()->getLayerFE().getCompositionState()->compositionType ==
@@ -482,7 +483,11 @@
return hash;
}};
- static const constexpr size_t kNumNonUniqueFields = 17;
+ OutputLayerState<bool, LayerStateField::HasProtectedContent> mIsProtected{[](auto layer) {
+ return layer->getLayerFE().getCompositionState()->hasProtectedContent;
+ }};
+
+ static const constexpr size_t kNumNonUniqueFields = 18;
std::array<StateInterface*, kNumNonUniqueFields> getNonUniqueFields() {
std::array<const StateInterface*, kNumNonUniqueFields> constFields =
@@ -501,7 +506,7 @@
&mAlpha, &mLayerMetadata, &mVisibleRegion, &mOutputDataspace,
&mPixelFormat, &mColorTransform, &mCompositionType, &mSidebandStream,
&mBuffer, &mSolidColor, &mBackgroundBlurRadius, &mBlurRegions,
- &mFrameNumber,
+ &mFrameNumber, &mIsProtected,
};
}
};
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index e3f3680..0622534 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -900,6 +900,13 @@
ui::Dataspace bestDataSpace = ui::Dataspace::V0_SRGB;
*outHdrDataSpace = ui::Dataspace::UNKNOWN;
+ // An Output's layers may be stale when it is disabled. As a consequence, the layers returned by
+ // getOutputLayersOrderedByZ may not be in a valid state and it is not safe to access their
+ // properties. Return a default dataspace value in this case.
+ if (!getState().isEnabled) {
+ return ui::Dataspace::V0_SRGB;
+ }
+
for (const auto* layer : getOutputLayersOrderedByZ()) {
switch (layer->getLayerFE().getCompositionState()->dataspace) {
case ui::Dataspace::V0_SCRGB:
@@ -1420,7 +1427,8 @@
.realContentIsVisible = realContentIsVisible,
.clearContent = !clientComposition,
.blurSetting = blurSetting,
- .whitePointNits = layerState.whitePointNits};
+ .whitePointNits = layerState.whitePointNits,
+ .treat170mAsSrgb = outputState.treat170mAsSrgb};
if (auto clientCompositionSettings =
layerFE.prepareClientComposition(targetSettings)) {
clientCompositionLayers.push_back(std::move(*clientCompositionSettings));
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index 0731d48..ed9a88d 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -411,8 +411,8 @@
if (mLayers.size() == 1) {
base::StringAppendF(&result, " Layer [%s]\n", mLayers[0].getName().c_str());
- if (auto* buffer = mLayers[0].getBuffer().get()) {
- base::StringAppendF(&result, " Buffer %p", buffer);
+ if (const sp<GraphicBuffer> buffer = mLayers[0].getState()->getBuffer().promote()) {
+ base::StringAppendF(&result, " Buffer %p", buffer.get());
base::StringAppendF(&result, " Format %s",
decodePixelFormat(buffer->getPixelFormat()).c_str());
}
@@ -422,8 +422,8 @@
result.append(" Cached set of:\n");
for (const Layer& layer : mLayers) {
base::StringAppendF(&result, " Layer [%s]\n", layer.getName().c_str());
- if (auto* buffer = layer.getBuffer().get()) {
- base::StringAppendF(&result, " Buffer %p", buffer);
+ if (const sp<GraphicBuffer> buffer = layer.getState()->getBuffer().promote()) {
+ base::StringAppendF(&result, " Buffer %p", buffer.get());
base::StringAppendF(&result, " Format[%s]",
decodePixelFormat(buffer->getPixelFormat()).c_str());
}
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index eb209e9..514a8ff 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -2081,6 +2081,7 @@
mOutput.setDisplayColorProfileForTest(
std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
+ mOutput.editState().isEnabled = true;
EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
.WillRepeatedly(Return(&mLayer1.mOutputLayer));
@@ -4464,6 +4465,7 @@
true /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
Region(kDisplayFrame),
@@ -4476,6 +4478,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
@@ -4516,6 +4519,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
Region(Rect(0, 0, 30, 30)),
@@ -4528,6 +4532,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
Region(Rect(0, 0, 40, 201)),
@@ -4540,6 +4545,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
@@ -4570,6 +4576,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
Region(kDisplayFrame),
@@ -4582,6 +4589,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
Region(kDisplayFrame),
@@ -4594,6 +4602,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
@@ -4624,6 +4633,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
Region(kDisplayFrame),
@@ -4636,6 +4646,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
Region(kDisplayFrame),
@@ -4648,6 +4659,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
@@ -4677,6 +4689,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
Region(kDisplayFrame),
@@ -4689,6 +4702,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
Region(kDisplayFrame),
@@ -4701,6 +4715,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
@@ -4728,6 +4743,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
Region(kDisplayFrame),
@@ -4740,6 +4756,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
Region(kDisplayFrame),
@@ -4752,6 +4769,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
@@ -4936,6 +4954,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
@@ -4954,6 +4973,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
@@ -4987,6 +5007,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
LayerFE::LayerSettings mShadowSettings;
@@ -5029,6 +5050,7 @@
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
kLayerWhitePointNits,
+ false /* treat170mAsSrgb */,
};
EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 9bb9305..c2a0e30 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -40,7 +40,6 @@
#include <ftl/enum.h>
#include <ftl/fake_guard.h>
#include <gui/BufferItem.h>
-#include <gui/GLConsumer.h>
#include <gui/LayerDebugInfo.h>
#include <gui/Surface.h>
#include <gui/TraceUtils.h>
@@ -81,28 +80,8 @@
namespace {
constexpr int kDumpTableRowLength = 159;
-static constexpr float defaultMaxLuminance = 1000.0;
-
const ui::Transform kIdentityTransform;
-constexpr mat4 inverseOrientation(uint32_t transform) {
- const mat4 flipH(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1);
- const mat4 flipV(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1);
- const mat4 rot90(0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1);
- mat4 tr;
-
- if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
- tr = tr * rot90;
- }
- if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
- tr = tr * flipH;
- }
- if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
- tr = tr * flipV;
- }
- return inverse(tr);
-}
-
bool assignTransform(ui::Transform* dst, ui::Transform& from) {
if (*dst == from) {
return false;
@@ -164,7 +143,8 @@
mLayerCreationFlags(args.flags),
mBorderEnabled(false),
mTextureName(args.textureName),
- mHwcSlotGenerator(sp<HwcSlotGenerator>::make()) {
+ mHwcSlotGenerator(sp<HwcSlotGenerator>::make()),
+ mLayerFE(args.flinger->getFactory().createLayerFE(mName)) {
ALOGV("Creating Layer %s", getDebugName());
uint32_t layerFlags = 0;
@@ -652,12 +632,6 @@
snapshot->cursorFrame = frame;
}
-sp<compositionengine::LayerFE> Layer::asLayerFE() const {
- compositionengine::LayerFE* layerFE = const_cast<compositionengine::LayerFE*>(
- static_cast<const compositionengine::LayerFE*>(this));
- return sp<compositionengine::LayerFE>::fromExisting(layerFE);
-}
-
const char* Layer::getDebugName() const {
return mName.c_str();
}
@@ -666,237 +640,6 @@
// drawing...
// ---------------------------------------------------------------------------
-std::optional<compositionengine::LayerFE::LayerSettings> Layer::prepareClientComposition(
- compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
- std::optional<compositionengine::LayerFE::LayerSettings> layerSettings =
- prepareClientCompositionInternal(targetSettings);
- // Nothing to render.
- if (!layerSettings) {
- return {};
- }
-
- // HWC requests to clear this layer.
- if (targetSettings.clearContent) {
- prepareClearClientComposition(*layerSettings, false /* blackout */);
- return layerSettings;
- }
-
- // set the shadow for the layer if needed
- prepareShadowClientComposition(*layerSettings, targetSettings.viewport);
-
- return layerSettings;
-}
-
-std::optional<compositionengine::LayerFE::LayerSettings> Layer::prepareClientCompositionInternal(
- compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
- ATRACE_CALL();
-
- const auto* snapshot = getLayerSnapshot();
- if (!snapshot) {
- return {};
- }
-
- compositionengine::LayerFE::LayerSettings layerSettings;
- layerSettings.geometry.boundaries =
- reduce(snapshot->geomLayerBounds, snapshot->transparentRegionHint);
- layerSettings.geometry.positionTransform = snapshot->geomLayerTransform.asMatrix4();
-
- // skip drawing content if the targetSettings indicate the content will be occluded
- const bool drawContent = targetSettings.realContentIsVisible || targetSettings.clearContent;
- layerSettings.skipContentDraw = !drawContent;
-
- if (hasColorTransform()) {
- layerSettings.colorTransform = snapshot->colorTransform;
- }
-
- const auto& roundedCornerState = snapshot->roundedCorner;
- layerSettings.geometry.roundedCornersRadius = roundedCornerState.radius;
- layerSettings.geometry.roundedCornersCrop = roundedCornerState.cropRect;
-
- layerSettings.alpha = snapshot->alpha;
- layerSettings.sourceDataspace = snapshot->dataspace;
-
- // Override the dataspace transfer from 170M to sRGB if the device configuration requests this.
- // We do this here instead of in buffer info so that dumpsys can still report layers that are
- // using the 170M transfer.
- if (mFlinger->mTreat170mAsSrgb &&
- (layerSettings.sourceDataspace & HAL_DATASPACE_TRANSFER_MASK) ==
- HAL_DATASPACE_TRANSFER_SMPTE_170M) {
- layerSettings.sourceDataspace = static_cast<ui::Dataspace>(
- (layerSettings.sourceDataspace & HAL_DATASPACE_STANDARD_MASK) |
- (layerSettings.sourceDataspace & HAL_DATASPACE_RANGE_MASK) |
- HAL_DATASPACE_TRANSFER_SRGB);
- }
-
- layerSettings.whitePointNits = targetSettings.whitePointNits;
- switch (targetSettings.blurSetting) {
- case LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled:
- layerSettings.backgroundBlurRadius = snapshot->backgroundBlurRadius;
- layerSettings.blurRegions = snapshot->blurRegions;
- layerSettings.blurRegionTransform = snapshot->geomInverseLayerTransform.asMatrix4();
- break;
- case LayerFE::ClientCompositionTargetSettings::BlurSetting::BackgroundBlurOnly:
- layerSettings.backgroundBlurRadius = snapshot->backgroundBlurRadius;
- break;
- case LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly:
- layerSettings.blurRegions = snapshot->blurRegions;
- layerSettings.blurRegionTransform = snapshot->geomInverseLayerTransform.asMatrix4();
- break;
- case LayerFE::ClientCompositionTargetSettings::BlurSetting::Disabled:
- default:
- break;
- }
- layerSettings.stretchEffect = snapshot->stretchEffect;
- // Record the name of the layer for debugging further down the stack.
- layerSettings.name = snapshot->name;
-
- if (hasEffect() && !hasBufferOrSidebandStream()) {
- prepareEffectsClientComposition(layerSettings, targetSettings);
- return layerSettings;
- }
-
- prepareBufferStateClientComposition(layerSettings, targetSettings);
- return layerSettings;
-}
-
-void Layer::prepareClearClientComposition(LayerFE::LayerSettings& layerSettings,
- bool blackout) const {
- layerSettings.source.buffer.buffer = nullptr;
- layerSettings.source.solidColor = half3(0.0, 0.0, 0.0);
- layerSettings.disableBlending = true;
- layerSettings.bufferId = 0;
- layerSettings.frameNumber = 0;
-
- // If layer is blacked out, force alpha to 1 so that we draw a black color layer.
- layerSettings.alpha = blackout ? 1.0f : 0.0f;
- layerSettings.name = getLayerSnapshot()->name;
-}
-
-void Layer::prepareEffectsClientComposition(
- compositionengine::LayerFE::LayerSettings& layerSettings,
- compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
- // If fill bounds are occluded or the fill color is invalid skip the fill settings.
- if (targetSettings.realContentIsVisible && fillsColor()) {
- // Set color for color fill settings.
- layerSettings.source.solidColor = getColor().rgb;
- } else if (hasBlur() || drawShadows()) {
- layerSettings.skipContentDraw = true;
- }
-}
-
-void Layer::prepareBufferStateClientComposition(
- compositionengine::LayerFE::LayerSettings& layerSettings,
- compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
- ATRACE_CALL();
- const auto* snapshot = getLayerSnapshot();
- if (CC_UNLIKELY(!snapshot->externalTexture)) {
- // If there is no buffer for the layer or we have sidebandstream where there is no
- // activeBuffer, then we need to return LayerSettings.
- return;
- }
- const bool blackOutLayer =
- (snapshot->hasProtectedContent && !targetSettings.supportsProtectedContent) ||
- ((snapshot->isSecure || snapshot->hasProtectedContent) && !targetSettings.isSecure);
- const bool bufferCanBeUsedAsHwTexture =
- snapshot->externalTexture->getUsage() & GraphicBuffer::USAGE_HW_TEXTURE;
- if (blackOutLayer || !bufferCanBeUsedAsHwTexture) {
- ALOGE_IF(!bufferCanBeUsedAsHwTexture, "%s is blacked out as buffer is not gpu readable",
- snapshot->name.c_str());
- prepareClearClientComposition(layerSettings, true /* blackout */);
- return;
- }
-
- layerSettings.source.buffer.buffer = snapshot->externalTexture;
- layerSettings.source.buffer.isOpaque = snapshot->contentOpaque;
- layerSettings.source.buffer.fence = snapshot->acquireFence;
- layerSettings.source.buffer.textureName = snapshot->textureName;
- layerSettings.source.buffer.usePremultipliedAlpha = snapshot->premultipliedAlpha;
- layerSettings.source.buffer.isY410BT2020 = snapshot->isHdrY410;
- bool hasSmpte2086 = snapshot->hdrMetadata.validTypes & HdrMetadata::SMPTE2086;
- bool hasCta861_3 = snapshot->hdrMetadata.validTypes & HdrMetadata::CTA861_3;
- float maxLuminance = 0.f;
- if (hasSmpte2086 && hasCta861_3) {
- maxLuminance = std::min(snapshot->hdrMetadata.smpte2086.maxLuminance,
- snapshot->hdrMetadata.cta8613.maxContentLightLevel);
- } else if (hasSmpte2086) {
- maxLuminance = snapshot->hdrMetadata.smpte2086.maxLuminance;
- } else if (hasCta861_3) {
- maxLuminance = snapshot->hdrMetadata.cta8613.maxContentLightLevel;
- } else {
- switch (layerSettings.sourceDataspace & HAL_DATASPACE_TRANSFER_MASK) {
- case HAL_DATASPACE_TRANSFER_ST2084:
- case HAL_DATASPACE_TRANSFER_HLG:
- // Behavior-match previous releases for HDR content
- maxLuminance = defaultMaxLuminance;
- break;
- }
- }
- layerSettings.source.buffer.maxLuminanceNits = maxLuminance;
- layerSettings.frameNumber = snapshot->frameNumber;
- layerSettings.bufferId = snapshot->externalTexture->getId();
-
- const bool useFiltering = targetSettings.needsFiltering ||
- snapshot->geomLayerTransform.needsBilinearFiltering() || snapshot->bufferNeedsFiltering;
-
- // Query the texture matrix given our current filtering mode.
- float textureMatrix[16];
- getDrawingTransformMatrix(useFiltering, textureMatrix);
-
- if (snapshot->geomBufferUsesDisplayInverseTransform) {
- /*
- * the code below applies the primary display's inverse transform to
- * the texture transform
- */
- uint32_t transform = DisplayDevice::getPrimaryDisplayRotationFlags();
- mat4 tr = inverseOrientation(transform);
-
- /**
- * TODO(b/36727915): This is basically a hack.
- *
- * Ensure that regardless of the parent transformation,
- * this buffer is always transformed from native display
- * orientation to display orientation. For example, in the case
- * of a camera where the buffer remains in native orientation,
- * we want the pixels to always be upright.
- */
- const auto parentTransform = snapshot->transform;
- tr = tr * inverseOrientation(parentTransform.getOrientation());
-
- // and finally apply it to the original texture matrix
- const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
- memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
- }
-
- const Rect win{layerSettings.geometry.boundaries};
- float bufferWidth = snapshot->bufferSize.getWidth();
- float bufferHeight = snapshot->bufferSize.getHeight();
-
- // Layers can have a "buffer size" of [0, 0, -1, -1] when no display frame has
- // been set and there is no parent layer bounds. In that case, the scale is meaningless so
- // ignore them.
- if (!snapshot->bufferSize.isValid()) {
- bufferWidth = float(win.right) - float(win.left);
- bufferHeight = float(win.bottom) - float(win.top);
- }
-
- const float scaleHeight = (float(win.bottom) - float(win.top)) / bufferHeight;
- const float scaleWidth = (float(win.right) - float(win.left)) / bufferWidth;
- const float translateY = float(win.top) / bufferHeight;
- const float translateX = float(win.left) / bufferWidth;
-
- // Flip y-coordinates because GLConsumer expects OpenGL convention.
- mat4 tr = mat4::translate(vec4(.5f, .5f, 0.f, 1.f)) * mat4::scale(vec4(1.f, -1.f, 1.f, 1.f)) *
- mat4::translate(vec4(-.5f, -.5f, 0.f, 1.f)) *
- mat4::translate(vec4(translateX, translateY, 0.f, 1.f)) *
- mat4::scale(vec4(scaleWidth, scaleHeight, 1.0f, 1.0f));
-
- layerSettings.source.buffer.useTextureFiltering = useFiltering;
- layerSettings.source.buffer.textureTransform =
- mat4(static_cast<const float*>(textureMatrix)) * tr;
-
- return;
-}
-
aidl::android::hardware::graphics::composer3::Composition Layer::getCompositionType(
const DisplayDevice& display) const {
const auto outputLayer = findOutputLayerForDisplay(&display);
@@ -1816,6 +1559,8 @@
newParent->canDrawShadows() ? 0.f : newParent->mEffectiveShadowRadius;
child->computeBounds(newParent->mBounds, newParent->mEffectiveTransform,
parentShadowRadius);
+ child->updateSnapshot(true /* updateGeometry */);
+ child->updateChildrenSnapshots(true /* updateGeometry */);
}
}
@@ -2139,7 +1884,7 @@
return regionsCopy;
}
-Layer::RoundedCornerState Layer::getRoundedCornerState() const {
+RoundedCornerState Layer::getRoundedCornerState() const {
// Get parent settings
RoundedCornerState parentSettings;
const auto& parent = mDrawingParent.promote();
@@ -2180,21 +1925,6 @@
return {};
}
-void Layer::prepareShadowClientComposition(LayerFE::LayerSettings& caster,
- const Rect& layerStackRect) const {
- const auto* snapshot = getLayerSnapshot();
- renderengine::ShadowSettings state = snapshot->shadowSettings;
- if (state.length <= 0.f || (state.ambientColor.a <= 0.f && state.spotColor.a <= 0.f)) {
- return;
- }
-
- // Shift the spot light x-position to the middle of the display and then
- // offset it by casting layer's screen pos.
- state.lightPos.x = (layerStackRect.width() / 2.f) - snapshot->transformedBounds.left;
- state.lightPos.y -= snapshot->transformedBounds.top;
- caster.shadow = state;
-}
-
bool Layer::findInHierarchy(const sp<Layer>& l) {
if (l == this) {
return true;
@@ -3377,7 +3107,7 @@
return fenceSignaled;
}
-bool Layer::onPreComposition(nsecs_t refreshStartTime, bool /* updatingOutputGeometryThisFrame */) {
+bool Layer::onPreComposition(nsecs_t refreshStartTime) {
for (const auto& handle : mDrawingState.callbackHandles) {
handle->refreshStartTime = refreshStartTime;
}
@@ -3788,26 +3518,31 @@
mBufferInfo.mPixelFormat == HAL_PIXEL_FORMAT_RGBA_1010102);
}
-sp<compositionengine::LayerFE> Layer::getCompositionEngineLayerFE() const {
+sp<LayerFE> Layer::getCompositionEngineLayerFE() const {
// There's no need to get a CE Layer if the layer isn't going to draw anything.
- if (hasSomethingToDraw()) {
- return asLayerFE();
- } else {
- return nullptr;
- }
+ return hasSomethingToDraw() ? mLayerFE : nullptr;
}
-const Layer::LayerSnapshot* Layer::getLayerSnapshot() const {
+const LayerSnapshot* Layer::getLayerSnapshot() const {
return mSnapshot.get();
}
-Layer::LayerSnapshot* Layer::editLayerSnapshot() {
+LayerSnapshot* Layer::editLayerSnapshot() {
return mSnapshot.get();
}
+
const compositionengine::LayerFECompositionState* Layer::getCompositionState() const {
return mSnapshot.get();
}
+void Layer::moveSnapshotToLayerFE() {
+ mLayerFE->mSnapshot = std::move(mSnapshot);
+}
+
+void Layer::moveSnapshotToLayer() {
+ mSnapshot = std::move(mLayerFE->mSnapshot);
+}
+
void Layer::useSurfaceDamage() {
if (mFlinger->mForceFullDamage) {
surfaceDamageRegion = Region::INVALID_REGION;
@@ -4154,17 +3889,6 @@
return mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getBuffer() : nullptr;
}
-void Layer::getDrawingTransformMatrix(bool filteringEnabled, float outMatrix[16]) const {
- sp<GraphicBuffer> buffer = getBuffer();
- if (!buffer) {
- ALOGE("Buffer should not be null!");
- return;
- }
- GLConsumer::computeTransformMatrix(outMatrix, buffer->getWidth(), buffer->getHeight(),
- buffer->getPixelFormat(), mBufferInfo.mCrop,
- mBufferInfo.mTransform, filteringEnabled);
-}
-
void Layer::setTransformHint(ui::Transform::RotationFlags displayTransformHint) {
mTransformHint = getFixedTransformHint();
if (mTransformHint == ui::Transform::ROT_INVALID) {
@@ -4240,9 +3964,17 @@
}
snapshot->bufferSize = getBufferSize(mDrawingState);
snapshot->externalTexture = mBufferInfo.mBuffer;
+ snapshot->hasReadyFrame = hasReadyFrame();
preparePerFrameCompositionState();
}
+void Layer::updateChildrenSnapshots(bool updateGeometry) {
+ for (const sp<Layer>& child : mDrawingChildren) {
+ child->updateSnapshot(updateGeometry);
+ child->updateChildrenSnapshots(updateGeometry);
+ }
+}
+
void Layer::updateMetadataSnapshot(const LayerMetadata& parentMetadata) {
mSnapshot->layerMetadata = parentMetadata;
mSnapshot->layerMetadata.merge(mDrawingState.metadata);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 8ace812..da8be6b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -52,6 +52,7 @@
#include "DisplayHardware/HWComposer.h"
#include "FrameTracker.h"
#include "HwcSlotGenerator.h"
+#include "LayerFE.h"
#include "LayerVector.h"
#include "Scheduler/LayerInfo.h"
#include "SurfaceFlinger.h"
@@ -97,7 +98,7 @@
bool addToRoot = true;
};
-class Layer : public virtual RefBase, compositionengine::LayerFE {
+class Layer : public virtual RefBase {
static std::atomic<int32_t> sSequence;
// The following constants represent priority of the window. SF uses this information when
// deciding which window has a priority when deciding about the refresh rate of the screen.
@@ -129,43 +130,6 @@
inline bool operator!=(const Geometry& rhs) const { return !operator==(rhs); }
};
- struct RoundedCornerState {
- RoundedCornerState() = default;
- RoundedCornerState(const FloatRect& cropRect, const vec2& radius)
- : cropRect(cropRect), radius(radius) {}
-
- // Rounded rectangle in local layer coordinate space.
- FloatRect cropRect = FloatRect();
- // Radius of the rounded rectangle.
- vec2 radius;
- bool hasRoundedCorners() const { return radius.x > 0.0f && radius.y > 0.0f; }
- };
-
- // LayerSnapshot stores Layer state used by Composition Engine and Render Engine. Composition
- // Engine uses a pointer to LayerSnapshot (as LayerFECompositionState*) and the LayerSettings
- // passed to Render Engine are created using properties stored on this struct.
- //
- // TODO(b/238781169) Implement LayerFE as a separate subclass. Migrate LayerSnapshot to that
- // LayerFE subclass.
- struct LayerSnapshot : public compositionengine::LayerFECompositionState {
- int32_t sequence;
- std::string name;
- uint32_t textureName;
- bool contentOpaque;
- RoundedCornerState roundedCorner;
- StretchEffect stretchEffect;
- FloatRect transformedBounds;
- renderengine::ShadowSettings shadowSettings;
- bool premultipliedAlpha;
- bool isHdrY410;
- bool bufferNeedsFiltering;
- ui::Transform transform;
- Rect bufferSize;
- std::shared_ptr<renderengine::ExternalTexture> externalTexture;
- LayerMetadata layerMetadata;
- LayerMetadata relativeLayerMetadata;
- };
-
using FrameRate = scheduler::LayerInfo::FrameRate;
using FrameRateCompatibility = scheduler::LayerInfo::FrameRateCompatibility;
@@ -413,7 +377,16 @@
ui::Dataspace getDataSpace() const;
ui::Dataspace getRequestedDataSpace() const;
- virtual sp<compositionengine::LayerFE> getCompositionEngineLayerFE() const;
+ virtual sp<LayerFE> getCompositionEngineLayerFE() const;
+
+ // Move LayerSnapshot from this layer into its LayerFE. This must be called before passing the
+ // LayerFE to CompositionEngine. Moving the snapshot instead of sharing common state
+ // prevents use of LayerFE outside the main thread by making errors obvious (i.e. use outside
+ // the main thread results in SEGFAULTs due to nullptr dereference).
+ void moveSnapshotToLayerFE();
+ // Move LayerSnapshot into this layer from its LayerFE. This must be called after
+ // CompositionEngine has presented the layer.
+ void moveSnapshotToLayer();
const LayerSnapshot* getLayerSnapshot() const;
LayerSnapshot* editLayerSnapshot();
@@ -557,7 +530,7 @@
// corner crop does not intersect with its own rounded corner crop.
virtual RoundedCornerState getRoundedCornerState() const;
- bool hasRoundedCorners() const override { return getRoundedCornerState().hasRoundedCorners(); }
+ bool hasRoundedCorners() const { return getRoundedCornerState().hasRoundedCorners(); }
PixelFormat getPixelFormat() const;
/**
@@ -598,24 +571,15 @@
// implements compositionengine::LayerFE
const compositionengine::LayerFECompositionState* getCompositionState() const;
bool fenceHasSignaled() const;
- // Called before composition. updatingOutputGeometryThisFrame is used by ARC++'s Layer subclass.
- bool onPreComposition(nsecs_t refreshStartTime, bool updatingOutputGeometryThisFrame);
- std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition(
- compositionengine::LayerFE::ClientCompositionTargetSettings&) const override;
+ bool onPreComposition(nsecs_t refreshStartTime);
void onLayerDisplayed(ftl::SharedFuture<FenceResult>);
- void setWasClientComposed(const sp<Fence>& fence) override {
+ void setWasClientComposed(const sp<Fence>& fence) {
mLastClientCompositionFence = fence;
mClearClientCompositionFenceOnLayerDisplayed = false;
}
- const LayerMetadata* getMetadata() const override { return &mSnapshot->layerMetadata; }
-
- const LayerMetadata* getRelativeMetadata() const override {
- return &mSnapshot->relativeLayerMetadata;
- }
-
- const char* getDebugName() const override;
+ const char* getDebugName() const;
bool setShadowRadius(float shadowRadius);
@@ -640,7 +604,7 @@
// Compute bounds for the layer and cache the results.
void computeBounds(FloatRect parentBounds, ui::Transform parentTransform, float shadowRadius);
- int32_t getSequence() const override { return sequence; }
+ int32_t getSequence() const { return sequence; }
// For tracing.
// TODO: Replace with raw buffer id from buffer metadata when that becomes available.
@@ -902,7 +866,7 @@
// Updates the LayerSnapshot. This must be called prior to sending layer data to
// CompositionEngine or RenderEngine (i.e. before calling CompositionEngine::present or
- // Layer::prepareClientComposition).
+ // LayerFE::prepareClientComposition).
//
// TODO(b/238781169) Remove direct calls to RenderEngine::drawLayers that don't go through
// CompositionEngine to create a single path for composing layers.
@@ -928,7 +892,6 @@
void gatherBufferInfo();
void onSurfaceFrameCreated(const std::shared_ptr<frametimeline::SurfaceFrame>&);
- sp<compositionengine::LayerFE> asLayerFE() const;
sp<Layer> getClonedFrom() { return mClonedFrom != nullptr ? mClonedFrom.promote() : nullptr; }
bool isClone() { return mClonedFrom != nullptr; }
bool isClonedFromAlive() { return getClonedFrom() != nullptr; }
@@ -941,12 +904,6 @@
void addChildToDrawing(const sp<Layer>&);
void updateClonedInputInfo(const std::map<sp<Layer>, sp<Layer>>& clonedLayersMap);
- // Modifies the passed in layer settings to clear the contents. If the blackout flag is set,
- // the settings clears the content with a solid black fill.
- void prepareClearClientComposition(LayerFE::LayerSettings&, bool blackout) const;
- void prepareShadowClientComposition(LayerFE::LayerSettings& caster,
- const Rect& layerStackRect) const;
-
void prepareBasicGeometryCompositionState();
void prepareGeometryCompositionState();
void prepareCursorCompositionState();
@@ -1102,10 +1059,6 @@
// Fills in the frame and transform info for the gui::WindowInfo.
void fillInputFrameInfo(gui::WindowInfo&, const ui::Transform& screenToDisplay);
- // Computes the transform matrix using the setFilteringEnabled to determine whether the
- // transform matrix should be computed for use with bilinear filtering.
- void getDrawingTransformMatrix(bool filteringEnabled, float outMatrix[16]) const;
-
inline void tracePendingBufferCount(int32_t pendingBuffers);
// Latch sideband stream and returns true if the dirty region should be updated.
@@ -1129,8 +1082,6 @@
const sp<Fence>& releaseFence,
uint32_t currentMaxAcquiredBufferCount);
- std::optional<compositionengine::LayerFE::LayerSettings> prepareClientCompositionInternal(
- compositionengine::LayerFE::ClientCompositionTargetSettings&) const;
// Returns true if there is a valid color to fill.
bool fillsColor() const;
// Returns true if this layer has a blur value.
@@ -1141,12 +1092,8 @@
}
bool hasSomethingToDraw() const { return hasEffect() || hasBufferOrSidebandStream(); }
- void prepareBufferStateClientComposition(
- compositionengine::LayerFE::LayerSettings&,
- compositionengine::LayerFE::ClientCompositionTargetSettings&) const;
- void prepareEffectsClientComposition(
- compositionengine::LayerFE::LayerSettings&,
- compositionengine::LayerFE::ClientCompositionTargetSettings&) const;
+
+ void updateChildrenSnapshots(bool updateGeometry);
// Cached properties computed from drawing state
// Effective transform taking into account parent transforms and any parent scaling, which is
@@ -1239,6 +1186,7 @@
sp<HwcSlotGenerator> mHwcSlotGenerator;
+ sp<LayerFE> mLayerFE;
std::unique_ptr<LayerSnapshot> mSnapshot = std::make_unique<LayerSnapshot>();
};
diff --git a/services/surfaceflinger/LayerFE.cpp b/services/surfaceflinger/LayerFE.cpp
new file mode 100644
index 0000000..3bdb521
--- /dev/null
+++ b/services/surfaceflinger/LayerFE.cpp
@@ -0,0 +1,386 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#undef LOG_TAG
+#define LOG_TAG "LayerFE"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include <gui/GLConsumer.h>
+#include <gui/TraceUtils.h>
+#include <math/vec3.h>
+#include <system/window.h>
+#include <utils/Log.h>
+
+#include "DisplayDevice.h"
+#include "LayerFE.h"
+
+namespace android {
+
+namespace {
+constexpr float defaultMaxLuminance = 1000.0;
+
+constexpr mat4 inverseOrientation(uint32_t transform) {
+ const mat4 flipH(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1);
+ const mat4 flipV(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1);
+ const mat4 rot90(0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1);
+ mat4 tr;
+
+ if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+ tr = tr * rot90;
+ }
+ if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
+ tr = tr * flipH;
+ }
+ if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
+ tr = tr * flipV;
+ }
+ return inverse(tr);
+}
+
+FloatRect reduce(const FloatRect& win, const Region& exclude) {
+ if (CC_LIKELY(exclude.isEmpty())) {
+ return win;
+ }
+ // Convert through Rect (by rounding) for lack of FloatRegion
+ return Region(Rect{win}).subtract(exclude).getBounds().toFloatRect();
+}
+
+// Computes the transform matrix using the setFilteringEnabled to determine whether the
+// transform matrix should be computed for use with bilinear filtering.
+void getDrawingTransformMatrix(const std::shared_ptr<renderengine::ExternalTexture>& buffer,
+ Rect bufferCrop, uint32_t bufferTransform, bool filteringEnabled,
+ float outMatrix[16]) {
+ if (!buffer) {
+ ALOGE("Buffer should not be null!");
+ return;
+ }
+ GLConsumer::computeTransformMatrix(outMatrix, static_cast<float>(buffer->getWidth()),
+ static_cast<float>(buffer->getHeight()),
+ buffer->getPixelFormat(), bufferCrop, bufferTransform,
+ filteringEnabled);
+}
+
+} // namespace
+
+LayerFE::LayerFE(const std::string& name) : mName(name) {}
+
+const compositionengine::LayerFECompositionState* LayerFE::getCompositionState() const {
+ return mSnapshot.get();
+}
+
+bool LayerFE::onPreComposition(nsecs_t refreshStartTime, bool) {
+ mCompositionResult.refreshStartTime = refreshStartTime;
+ return mSnapshot->hasReadyFrame;
+}
+
+std::optional<compositionengine::LayerFE::LayerSettings> LayerFE::prepareClientComposition(
+ compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
+ std::optional<compositionengine::LayerFE::LayerSettings> layerSettings =
+ prepareClientCompositionInternal(targetSettings);
+ // Nothing to render.
+ if (!layerSettings) {
+ return {};
+ }
+
+ // HWC requests to clear this layer.
+ if (targetSettings.clearContent) {
+ prepareClearClientComposition(*layerSettings, false /* blackout */);
+ return layerSettings;
+ }
+
+ // set the shadow for the layer if needed
+ prepareShadowClientComposition(*layerSettings, targetSettings.viewport);
+
+ return layerSettings;
+}
+
+std::optional<compositionengine::LayerFE::LayerSettings> LayerFE::prepareClientCompositionInternal(
+ compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
+ ATRACE_CALL();
+ compositionengine::LayerFE::LayerSettings layerSettings;
+ layerSettings.geometry.boundaries =
+ reduce(mSnapshot->geomLayerBounds, mSnapshot->transparentRegionHint);
+ layerSettings.geometry.positionTransform = mSnapshot->geomLayerTransform.asMatrix4();
+
+ // skip drawing content if the targetSettings indicate the content will be occluded
+ const bool drawContent = targetSettings.realContentIsVisible || targetSettings.clearContent;
+ layerSettings.skipContentDraw = !drawContent;
+
+ if (!mSnapshot->colorTransformIsIdentity) {
+ layerSettings.colorTransform = mSnapshot->colorTransform;
+ }
+
+ const auto& roundedCornerState = mSnapshot->roundedCorner;
+ layerSettings.geometry.roundedCornersRadius = roundedCornerState.radius;
+ layerSettings.geometry.roundedCornersCrop = roundedCornerState.cropRect;
+
+ layerSettings.alpha = mSnapshot->alpha;
+ layerSettings.sourceDataspace = mSnapshot->dataspace;
+
+ // Override the dataspace transfer from 170M to sRGB if the device configuration requests this.
+ // We do this here instead of in buffer info so that dumpsys can still report layers that are
+ // using the 170M transfer.
+ if (targetSettings.treat170mAsSrgb &&
+ (layerSettings.sourceDataspace & HAL_DATASPACE_TRANSFER_MASK) ==
+ HAL_DATASPACE_TRANSFER_SMPTE_170M) {
+ layerSettings.sourceDataspace = static_cast<ui::Dataspace>(
+ (layerSettings.sourceDataspace & HAL_DATASPACE_STANDARD_MASK) |
+ (layerSettings.sourceDataspace & HAL_DATASPACE_RANGE_MASK) |
+ HAL_DATASPACE_TRANSFER_SRGB);
+ }
+
+ layerSettings.whitePointNits = targetSettings.whitePointNits;
+ switch (targetSettings.blurSetting) {
+ case LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled:
+ layerSettings.backgroundBlurRadius = mSnapshot->backgroundBlurRadius;
+ layerSettings.blurRegions = mSnapshot->blurRegions;
+ layerSettings.blurRegionTransform = mSnapshot->geomInverseLayerTransform.asMatrix4();
+ break;
+ case LayerFE::ClientCompositionTargetSettings::BlurSetting::BackgroundBlurOnly:
+ layerSettings.backgroundBlurRadius = mSnapshot->backgroundBlurRadius;
+ break;
+ case LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly:
+ layerSettings.blurRegions = mSnapshot->blurRegions;
+ layerSettings.blurRegionTransform = mSnapshot->geomInverseLayerTransform.asMatrix4();
+ break;
+ case LayerFE::ClientCompositionTargetSettings::BlurSetting::Disabled:
+ default:
+ break;
+ }
+ layerSettings.stretchEffect = mSnapshot->stretchEffect;
+ // Record the name of the layer for debugging further down the stack.
+ layerSettings.name = mSnapshot->name;
+
+ if (hasEffect() && !hasBufferOrSidebandStream()) {
+ prepareEffectsClientComposition(layerSettings, targetSettings);
+ return layerSettings;
+ }
+
+ prepareBufferStateClientComposition(layerSettings, targetSettings);
+ return layerSettings;
+}
+
+void LayerFE::prepareClearClientComposition(LayerFE::LayerSettings& layerSettings,
+ bool blackout) const {
+ layerSettings.source.buffer.buffer = nullptr;
+ layerSettings.source.solidColor = half3(0.0f, 0.0f, 0.0f);
+ layerSettings.disableBlending = true;
+ layerSettings.bufferId = 0;
+ layerSettings.frameNumber = 0;
+
+ // If layer is blacked out, force alpha to 1 so that we draw a black color layer.
+ layerSettings.alpha = blackout ? 1.0f : 0.0f;
+ layerSettings.name = mSnapshot->name;
+}
+
+void LayerFE::prepareEffectsClientComposition(
+ compositionengine::LayerFE::LayerSettings& layerSettings,
+ compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
+ // If fill bounds are occluded or the fill color is invalid skip the fill settings.
+ if (targetSettings.realContentIsVisible && fillsColor()) {
+ // Set color for color fill settings.
+ layerSettings.source.solidColor = mSnapshot->color.rgb;
+ } else if (hasBlur() || drawShadows()) {
+ layerSettings.skipContentDraw = true;
+ }
+}
+
+void LayerFE::prepareBufferStateClientComposition(
+ compositionengine::LayerFE::LayerSettings& layerSettings,
+ compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
+ ATRACE_CALL();
+ if (CC_UNLIKELY(!mSnapshot->externalTexture)) {
+ // If there is no buffer for the layer or we have sidebandstream where there is no
+ // activeBuffer, then we need to return LayerSettings.
+ return;
+ }
+ const bool blackOutLayer =
+ (mSnapshot->hasProtectedContent && !targetSettings.supportsProtectedContent) ||
+ ((mSnapshot->isSecure || mSnapshot->hasProtectedContent) && !targetSettings.isSecure);
+ const bool bufferCanBeUsedAsHwTexture =
+ mSnapshot->externalTexture->getUsage() & GraphicBuffer::USAGE_HW_TEXTURE;
+ if (blackOutLayer || !bufferCanBeUsedAsHwTexture) {
+ ALOGE_IF(!bufferCanBeUsedAsHwTexture, "%s is blacked out as buffer is not gpu readable",
+ mSnapshot->name.c_str());
+ prepareClearClientComposition(layerSettings, true /* blackout */);
+ return;
+ }
+
+ layerSettings.source.buffer.buffer = mSnapshot->externalTexture;
+ layerSettings.source.buffer.isOpaque = mSnapshot->contentOpaque;
+ layerSettings.source.buffer.fence = mSnapshot->acquireFence;
+ layerSettings.source.buffer.textureName = mSnapshot->textureName;
+ layerSettings.source.buffer.usePremultipliedAlpha = mSnapshot->premultipliedAlpha;
+ layerSettings.source.buffer.isY410BT2020 = mSnapshot->isHdrY410;
+ bool hasSmpte2086 = mSnapshot->hdrMetadata.validTypes & HdrMetadata::SMPTE2086;
+ bool hasCta861_3 = mSnapshot->hdrMetadata.validTypes & HdrMetadata::CTA861_3;
+ float maxLuminance = 0.f;
+ if (hasSmpte2086 && hasCta861_3) {
+ maxLuminance = std::min(mSnapshot->hdrMetadata.smpte2086.maxLuminance,
+ mSnapshot->hdrMetadata.cta8613.maxContentLightLevel);
+ } else if (hasSmpte2086) {
+ maxLuminance = mSnapshot->hdrMetadata.smpte2086.maxLuminance;
+ } else if (hasCta861_3) {
+ maxLuminance = mSnapshot->hdrMetadata.cta8613.maxContentLightLevel;
+ } else {
+ switch (layerSettings.sourceDataspace & HAL_DATASPACE_TRANSFER_MASK) {
+ case HAL_DATASPACE_TRANSFER_ST2084:
+ case HAL_DATASPACE_TRANSFER_HLG:
+ // Behavior-match previous releases for HDR content
+ maxLuminance = defaultMaxLuminance;
+ break;
+ }
+ }
+ layerSettings.source.buffer.maxLuminanceNits = maxLuminance;
+ layerSettings.frameNumber = mSnapshot->frameNumber;
+ layerSettings.bufferId = mSnapshot->externalTexture->getId();
+
+ const bool useFiltering = targetSettings.needsFiltering ||
+ mSnapshot->geomLayerTransform.needsBilinearFiltering() ||
+ mSnapshot->bufferNeedsFiltering;
+
+ // Query the texture matrix given our current filtering mode.
+ float textureMatrix[16];
+ getDrawingTransformMatrix(layerSettings.source.buffer.buffer, mSnapshot->geomContentCrop,
+ mSnapshot->geomBufferTransform, useFiltering, textureMatrix);
+
+ if (mSnapshot->geomBufferUsesDisplayInverseTransform) {
+ /*
+ * the code below applies the primary display's inverse transform to
+ * the texture transform
+ */
+ uint32_t transform = DisplayDevice::getPrimaryDisplayRotationFlags();
+ mat4 tr = inverseOrientation(transform);
+
+ /**
+ * TODO(b/36727915): This is basically a hack.
+ *
+ * Ensure that regardless of the parent transformation,
+ * this buffer is always transformed from native display
+ * orientation to display orientation. For example, in the case
+ * of a camera where the buffer remains in native orientation,
+ * we want the pixels to always be upright.
+ */
+ const auto parentTransform = mSnapshot->transform;
+ tr = tr * inverseOrientation(parentTransform.getOrientation());
+
+ // and finally apply it to the original texture matrix
+ const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
+ memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
+ }
+
+ const Rect win{layerSettings.geometry.boundaries};
+ float bufferWidth = static_cast<float>(mSnapshot->bufferSize.getWidth());
+ float bufferHeight = static_cast<float>(mSnapshot->bufferSize.getHeight());
+
+ // Layers can have a "buffer size" of [0, 0, -1, -1] when no display frame has
+ // been set and there is no parent layer bounds. In that case, the scale is meaningless so
+ // ignore them.
+ if (!mSnapshot->bufferSize.isValid()) {
+ bufferWidth = float(win.right) - float(win.left);
+ bufferHeight = float(win.bottom) - float(win.top);
+ }
+
+ const float scaleHeight = (float(win.bottom) - float(win.top)) / bufferHeight;
+ const float scaleWidth = (float(win.right) - float(win.left)) / bufferWidth;
+ const float translateY = float(win.top) / bufferHeight;
+ const float translateX = float(win.left) / bufferWidth;
+
+ // Flip y-coordinates because GLConsumer expects OpenGL convention.
+ mat4 tr = mat4::translate(vec4(.5f, .5f, 0.f, 1.f)) * mat4::scale(vec4(1.f, -1.f, 1.f, 1.f)) *
+ mat4::translate(vec4(-.5f, -.5f, 0.f, 1.f)) *
+ mat4::translate(vec4(translateX, translateY, 0.f, 1.f)) *
+ mat4::scale(vec4(scaleWidth, scaleHeight, 1.0f, 1.0f));
+
+ layerSettings.source.buffer.useTextureFiltering = useFiltering;
+ layerSettings.source.buffer.textureTransform =
+ mat4(static_cast<const float*>(textureMatrix)) * tr;
+
+ return;
+}
+
+void LayerFE::prepareShadowClientComposition(LayerFE::LayerSettings& caster,
+ const Rect& layerStackRect) const {
+ renderengine::ShadowSettings state = mSnapshot->shadowSettings;
+ if (state.length <= 0.f || (state.ambientColor.a <= 0.f && state.spotColor.a <= 0.f)) {
+ return;
+ }
+
+ // Shift the spot light x-position to the middle of the display and then
+ // offset it by casting layer's screen pos.
+ state.lightPos.x =
+ (static_cast<float>(layerStackRect.width()) / 2.f) - mSnapshot->transformedBounds.left;
+ state.lightPos.y -= mSnapshot->transformedBounds.top;
+ caster.shadow = state;
+}
+
+void LayerFE::onLayerDisplayed(ftl::SharedFuture<FenceResult> futureFenceResult) {
+ mCompositionResult.releaseFences.emplace_back(std::move(futureFenceResult));
+}
+
+CompositionResult&& LayerFE::stealCompositionResult() {
+ return std::move(mCompositionResult);
+}
+
+const char* LayerFE::getDebugName() const {
+ return mName.c_str();
+}
+
+const LayerMetadata* LayerFE::getMetadata() const {
+ return &mSnapshot->layerMetadata;
+}
+
+const LayerMetadata* LayerFE::getRelativeMetadata() const {
+ return &mSnapshot->relativeLayerMetadata;
+}
+
+int32_t LayerFE::getSequence() const {
+ return mSnapshot->sequence;
+}
+
+bool LayerFE::hasRoundedCorners() const {
+ return mSnapshot->roundedCorner.hasRoundedCorners();
+}
+
+void LayerFE::setWasClientComposed(const sp<Fence>& fence) {
+ mCompositionResult.lastClientCompositionFence = fence;
+}
+
+bool LayerFE::hasBufferOrSidebandStream() const {
+ return mSnapshot->externalTexture || mSnapshot->sidebandStream;
+}
+
+bool LayerFE::fillsColor() const {
+ return mSnapshot->color.r >= 0.0_hf && mSnapshot->color.g >= 0.0_hf &&
+ mSnapshot->color.b >= 0.0_hf;
+}
+
+bool LayerFE::hasBlur() const {
+ return mSnapshot->backgroundBlurRadius > 0 || mSnapshot->blurRegions.size() > 0;
+}
+
+bool LayerFE::drawShadows() const {
+ return mSnapshot->shadowSettings.length > 0.f &&
+ (mSnapshot->shadowSettings.ambientColor.a > 0 ||
+ mSnapshot->shadowSettings.spotColor.a > 0);
+};
+
+const sp<GraphicBuffer> LayerFE::getBuffer() const {
+ return mSnapshot->externalTexture ? mSnapshot->externalTexture->getBuffer() : nullptr;
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/LayerFE.h b/services/surfaceflinger/LayerFE.h
new file mode 100644
index 0000000..e4f6889
--- /dev/null
+++ b/services/surfaceflinger/LayerFE.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <gui/LayerMetadata.h>
+
+#include "compositionengine/LayerFE.h"
+#include "compositionengine/LayerFECompositionState.h"
+#include "renderengine/LayerSettings.h"
+
+namespace android {
+struct RoundedCornerState {
+ RoundedCornerState() = default;
+ RoundedCornerState(const FloatRect& cropRect, const vec2& radius)
+ : cropRect(cropRect), radius(radius) {}
+
+ // Rounded rectangle in local layer coordinate space.
+ FloatRect cropRect = FloatRect();
+ // Radius of the rounded rectangle.
+ vec2 radius;
+ bool hasRoundedCorners() const { return radius.x > 0.0f && radius.y > 0.0f; }
+};
+
+// LayerSnapshot stores Layer state used by CompositionEngine and RenderEngine. Composition
+// Engine uses a pointer to LayerSnapshot (as LayerFECompositionState*) and the LayerSettings
+// passed to Render Engine are created using properties stored on this struct.
+struct LayerSnapshot : public compositionengine::LayerFECompositionState {
+ int32_t sequence;
+ std::string name;
+ uint32_t textureName;
+ bool contentOpaque;
+ RoundedCornerState roundedCorner;
+ StretchEffect stretchEffect;
+ FloatRect transformedBounds;
+ renderengine::ShadowSettings shadowSettings;
+ bool premultipliedAlpha;
+ bool isHdrY410;
+ bool bufferNeedsFiltering;
+ ui::Transform transform;
+ Rect bufferSize;
+ std::shared_ptr<renderengine::ExternalTexture> externalTexture;
+ gui::LayerMetadata layerMetadata;
+ gui::LayerMetadata relativeLayerMetadata;
+ bool contentDirty;
+ bool hasReadyFrame;
+};
+
+struct CompositionResult {
+ // TODO(b/238781169) update CE to no longer pass refreshStartTime to LayerFE::onPreComposition
+ // and remove this field.
+ nsecs_t refreshStartTime = 0;
+ std::vector<ftl::SharedFuture<FenceResult>> releaseFences;
+ sp<Fence> lastClientCompositionFence = nullptr;
+};
+
+class LayerFE : public virtual RefBase, public virtual compositionengine::LayerFE {
+public:
+ LayerFE(const std::string& name);
+
+ // compositionengine::LayerFE overrides
+ const compositionengine::LayerFECompositionState* getCompositionState() const override;
+ bool onPreComposition(nsecs_t refreshStartTime, bool updatingOutputGeometryThisFrame) override;
+ void onLayerDisplayed(ftl::SharedFuture<FenceResult>) override;
+ const char* getDebugName() const override;
+ int32_t getSequence() const override;
+ bool hasRoundedCorners() const override;
+ void setWasClientComposed(const sp<Fence>&) override;
+ const gui::LayerMetadata* getMetadata() const override;
+ const gui::LayerMetadata* getRelativeMetadata() const override;
+ std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition(
+ compositionengine::LayerFE::ClientCompositionTargetSettings&) const;
+ CompositionResult&& stealCompositionResult();
+
+ std::unique_ptr<LayerSnapshot> mSnapshot;
+
+private:
+ std::optional<compositionengine::LayerFE::LayerSettings> prepareClientCompositionInternal(
+ compositionengine::LayerFE::ClientCompositionTargetSettings&) const;
+ // Modifies the passed in layer settings to clear the contents. If the blackout flag is set,
+ // the settings clears the content with a solid black fill.
+ void prepareClearClientComposition(LayerFE::LayerSettings&, bool blackout) const;
+ void prepareShadowClientComposition(LayerFE::LayerSettings& caster,
+ const Rect& layerStackRect) const;
+ void prepareBufferStateClientComposition(
+ compositionengine::LayerFE::LayerSettings&,
+ compositionengine::LayerFE::ClientCompositionTargetSettings&) const;
+ void prepareEffectsClientComposition(
+ compositionengine::LayerFE::LayerSettings&,
+ compositionengine::LayerFE::ClientCompositionTargetSettings&) const;
+
+ bool hasEffect() const { return fillsColor() || drawShadows() || hasBlur(); }
+ bool hasBufferOrSidebandStream() const;
+
+ bool fillsColor() const;
+ bool hasBlur() const;
+ bool drawShadows() const;
+
+ const sp<GraphicBuffer> getBuffer() const;
+
+ CompositionResult mCompositionResult;
+ std::string mName;
+};
+
+} // namespace android
diff --git a/services/surfaceflinger/LayerRenderArea.cpp b/services/surfaceflinger/LayerRenderArea.cpp
index 6bc7dc1..3e6ed41 100644
--- a/services/surfaceflinger/LayerRenderArea.cpp
+++ b/services/surfaceflinger/LayerRenderArea.cpp
@@ -30,6 +30,7 @@
// Compute and cache the bounds for the new parent layer.
newParent->computeBounds(drawingBounds.toFloatRect(), ui::Transform(),
0.f /* shadowRadius */);
+ newParent->updateSnapshot(true /* updateGeometry */);
oldParent->setChildrenDrawingParent(newParent);
};
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e4fee1c..6144a2f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2172,10 +2172,14 @@
refreshArgs.updatingOutputGeometryThisFrame = mVisibleRegionsDirty;
refreshArgs.updatingGeometryThisFrame = mGeometryDirty.exchange(false) || mVisibleRegionsDirty;
- mDrawingState.traverseInZOrder([&refreshArgs](Layer* layer) {
+ std::vector<Layer*> layers;
+
+ mDrawingState.traverseInZOrder([&refreshArgs, &layers](Layer* layer) {
layer->updateSnapshot(refreshArgs.updatingGeometryThisFrame);
if (auto layerFE = layer->getCompositionEngineLayerFE()) {
+ layer->moveSnapshotToLayerFE();
refreshArgs.layers.push_back(layerFE);
+ layers.push_back(layer);
}
});
refreshArgs.blursAreExpensive = mBlursAreExpensive;
@@ -2207,6 +2211,19 @@
mCompositionEngine->present(refreshArgs);
+ for (auto& layer : layers) {
+ layer->moveSnapshotToLayer();
+ CompositionResult compositionResult{
+ layer->getCompositionEngineLayerFE()->stealCompositionResult()};
+ layer->onPreComposition(compositionResult.refreshStartTime);
+ for (auto releaseFence : compositionResult.releaseFences) {
+ layer->onLayerDisplayed(releaseFence);
+ }
+ if (compositionResult.lastClientCompositionFence) {
+ layer->setWasClientComposed(compositionResult.lastClientCompositionFence);
+ }
+ }
+
mTimeStats->recordFrameDuration(frameTime.ns(), systemTime());
// Send a power hint hint after presentation is finished
@@ -3291,7 +3308,21 @@
}
}
+ std::vector<Layer*> cursorLayers;
+ mDrawingState.traverse([&cursorLayers](Layer* layer) {
+ if (layer->getLayerSnapshot()->compositionType ==
+ aidl::android::hardware::graphics::composer3::Composition::CURSOR) {
+ layer->updateSnapshot(false /* updateGeometry */);
+ layer->moveSnapshotToLayerFE();
+ cursorLayers.push_back(layer);
+ }
+ });
+
mCompositionEngine->updateCursorAsync(refreshArgs);
+
+ for (Layer* layer : cursorLayers) {
+ layer->moveSnapshotToLayer();
+ }
}
void SurfaceFlinger::requestDisplayModes(
@@ -6444,8 +6475,16 @@
isHdrLayer(layer) ? displayBrightnessNits : sdrWhitePointNits,
};
+ auto layerFE = layer->getCompositionEngineLayerFE();
+ if (!layerFE) {
+ return;
+ }
+
+ layer->moveSnapshotToLayerFE();
std::optional<compositionengine::LayerFE::LayerSettings> settings =
- layer->prepareClientComposition(targetSettings);
+ layerFE->prepareClientComposition(targetSettings);
+ layer->moveSnapshotToLayer();
+
if (!settings) {
return;
}
diff --git a/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp b/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
index 2f1f263..7e6894d 100644
--- a/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
+++ b/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
@@ -91,6 +91,10 @@
return sp<Layer>::make(args);
}
+sp<LayerFE> DefaultFactory::createLayerFE(const std::string& layerName) {
+ return sp<LayerFE>::make(layerName);
+}
+
std::unique_ptr<FrameTracer> DefaultFactory::createFrameTracer() {
return std::make_unique<FrameTracer>();
}
diff --git a/services/surfaceflinger/SurfaceFlingerDefaultFactory.h b/services/surfaceflinger/SurfaceFlingerDefaultFactory.h
index 447a02f..2c6de0e 100644
--- a/services/surfaceflinger/SurfaceFlingerDefaultFactory.h
+++ b/services/surfaceflinger/SurfaceFlingerDefaultFactory.h
@@ -42,6 +42,7 @@
std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() override;
sp<Layer> createBufferStateLayer(const LayerCreationArgs& args) override;
sp<Layer> createEffectLayer(const LayerCreationArgs& args) override;
+ sp<LayerFE> createLayerFE(const std::string& layerName) override;
std::unique_ptr<FrameTracer> createFrameTracer() override;
std::unique_ptr<frametimeline::FrameTimeline> createFrameTimeline(
std::shared_ptr<TimeStats> timeStats, pid_t surfaceFlingerPid) override;
diff --git a/services/surfaceflinger/SurfaceFlingerFactory.h b/services/surfaceflinger/SurfaceFlingerFactory.h
index 9c4d5c8..d1f21bf 100644
--- a/services/surfaceflinger/SurfaceFlingerFactory.h
+++ b/services/surfaceflinger/SurfaceFlingerFactory.h
@@ -38,6 +38,7 @@
class IGraphicBufferConsumer;
class IGraphicBufferProducer;
class Layer;
+class LayerFE;
class StartPropertySetThread;
class SurfaceFlinger;
class TimeStats;
@@ -88,6 +89,7 @@
virtual sp<Layer> createBufferStateLayer(const LayerCreationArgs& args) = 0;
virtual sp<Layer> createEffectLayer(const LayerCreationArgs& args) = 0;
+ virtual sp<LayerFE> createLayerFE(const std::string& layerName) = 0;
virtual std::unique_ptr<FrameTracer> createFrameTracer() = 0;
virtual std::unique_ptr<frametimeline::FrameTimeline> createFrameTimeline(
std::shared_ptr<TimeStats> timeStats, pid_t surfaceFlingerPid) = 0;
diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
index d0364f2..276b3da 100644
--- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
+++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
@@ -82,6 +82,8 @@
sp<Layer> createEffectLayer(const LayerCreationArgs& args) { return sp<Layer>::make(args); }
+ sp<LayerFE> createLayerFE(const std::string& layerName) { return sp<LayerFE>::make(layerName); }
+
std::unique_ptr<FrameTracer> createFrameTracer() override {
return std::make_unique<testing::NiceMock<mock::FrameTracer>>();
}
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
index ed2fe23..e2ae4f4 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
@@ -354,6 +354,10 @@
return sp<Layer>::make(args);
}
+ sp<LayerFE> createLayerFE(const std::string &layerName) override {
+ return sp<LayerFE>::make(layerName);
+ }
+
std::unique_ptr<FrameTracer> createFrameTracer() override {
return std::make_unique<android::mock::FrameTracer>();
}
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
index 0a142c3..acfc1d4 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
@@ -146,8 +146,7 @@
layer->computeSourceBounds(getFuzzedFloatRect(&mFdp));
layer->fenceHasSignaled();
- layer->onPreComposition(mFdp.ConsumeIntegral<int64_t>(),
- false /*updatingOutputGeometryThisFrame*/);
+ layer->onPreComposition(mFdp.ConsumeIntegral<int64_t>());
const std::vector<sp<CallbackHandle>> callbacks;
layer->setTransactionCompletedListeners(callbacks);
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 29ff5ee..83d852a 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -118,6 +118,10 @@
sp<Layer> createEffectLayer(const LayerCreationArgs&) override { return nullptr; }
+ sp<LayerFE> createLayerFE(const std::string& layerName) override {
+ return sp<LayerFE>::make(layerName);
+ }
+
std::unique_ptr<FrameTracer> createFrameTracer() override {
return std::make_unique<mock::FrameTracer>();
}