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/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);