diff options
author | 2022-08-02 21:47:40 +0000 | |
---|---|---|
committer | 2022-09-19 20:58:53 +0000 | |
commit | bedb44bb15cd11689b96770a45eccf475778e9eb (patch) | |
tree | 85855a80fee51fae9a09f65e3b6ab3909d67573c | |
parent | 926bb1293231a4d14128c675da081cd215b65e1b (diff) |
SF: Populate RE layer settings from layer snapshot and CE layer state
Make it easier to break FE dependencies to CE by populating
RE layer settings from a layer snapshot and CE layer composition state.
Test: presubmit
Test: go/wm-smoke
Bug: 238781169
Change-Id: I92bdc0a0f605c13e2dc1465c8d1ddfd17e554633
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 311 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 39 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 5 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h | 2 |
4 files changed, 208 insertions, 149 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index e690aaf691..0771e1055b 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -164,7 +164,6 @@ Layer::Layer(const LayerCreationArgs& args) mLayerCreationFlags(args.flags), mBorderEnabled(false), mTextureName(args.textureName), - mCompositionState{mFlinger->getCompositionEngine().createLayerFECompositionState()}, mHwcSlotGenerator(sp<HwcSlotGenerator>::make()) { ALOGV("Creating Layer %s", getDebugName()); @@ -238,6 +237,12 @@ Layer::Layer(const LayerCreationArgs& args) mPotentialCursor = args.flags & ISurfaceComposerClient::eCursorWindow; mProtectedByApp = args.flags & ISurfaceComposerClient::eProtectedByApp; mDrawingState.dataspace = ui::Dataspace::V0_SRGB; + + mSnapshot->sequence = sequence; + mSnapshot->name = getDebugName(); + mSnapshot->textureName = mTextureName; + mSnapshot->premultipliedAlpha = mPremultipliedAlpha; + mSnapshot->transform = {}; } void Layer::onFirstRef() { @@ -503,40 +508,40 @@ void Layer::prepareBasicGeometryCompositionState() { : Hwc2::IComposerClient::BlendMode::COVERAGE; } - auto* compositionState = editCompositionState(); - compositionState->outputFilter = getOutputFilter(); - compositionState->isVisible = isVisible(); - compositionState->isOpaque = opaque && !usesRoundedCorners && alpha == 1.f; - compositionState->shadowRadius = mEffectiveShadowRadius; + auto* snapshot = editLayerSnapshot(); + snapshot->outputFilter = getOutputFilter(); + snapshot->isVisible = isVisible(); + snapshot->isOpaque = opaque && !usesRoundedCorners && alpha == 1.f; + snapshot->shadowRadius = mEffectiveShadowRadius; - compositionState->contentDirty = contentDirty; + snapshot->contentDirty = contentDirty; contentDirty = false; - compositionState->geomLayerBounds = mBounds; - compositionState->geomLayerTransform = getTransform(); - compositionState->geomInverseLayerTransform = compositionState->geomLayerTransform.inverse(); - compositionState->transparentRegionHint = getActiveTransparentRegion(drawingState); + snapshot->geomLayerBounds = mBounds; + snapshot->geomLayerTransform = getTransform(); + snapshot->geomInverseLayerTransform = snapshot->geomLayerTransform.inverse(); + snapshot->transparentRegionHint = getActiveTransparentRegion(drawingState); - compositionState->blendMode = static_cast<Hwc2::IComposerClient::BlendMode>(blendMode); - compositionState->alpha = alpha; - compositionState->backgroundBlurRadius = drawingState.backgroundBlurRadius; - compositionState->blurRegions = drawingState.blurRegions; - compositionState->stretchEffect = getStretchEffect(); + snapshot->blendMode = static_cast<Hwc2::IComposerClient::BlendMode>(blendMode); + snapshot->alpha = alpha; + snapshot->backgroundBlurRadius = drawingState.backgroundBlurRadius; + snapshot->blurRegions = drawingState.blurRegions; + snapshot->stretchEffect = getStretchEffect(); } void Layer::prepareGeometryCompositionState() { const auto& drawingState{getDrawingState()}; - auto* compositionState = editCompositionState(); + auto* snapshot = editLayerSnapshot(); - compositionState->geomBufferSize = getBufferSize(drawingState); - compositionState->geomContentCrop = getBufferCrop(); - compositionState->geomCrop = getCrop(drawingState); - compositionState->geomBufferTransform = getBufferTransform(); - compositionState->geomBufferUsesDisplayInverseTransform = getTransformToDisplayInverse(); - compositionState->geomUsesSourceCrop = usesSourceCrop(); - compositionState->isSecure = isSecure(); + snapshot->geomBufferSize = getBufferSize(drawingState); + snapshot->geomContentCrop = getBufferCrop(); + snapshot->geomCrop = getCrop(drawingState); + snapshot->geomBufferTransform = getBufferTransform(); + snapshot->geomBufferUsesDisplayInverseTransform = getTransformToDisplayInverse(); + snapshot->geomUsesSourceCrop = usesSourceCrop(); + snapshot->isSecure = isSecure(); - compositionState->metadata.clear(); + snapshot->metadata.clear(); const auto& supportedMetadata = mFlinger->getHwComposer().getSupportedLayerGenericMetadata(); for (const auto& [key, mandatory] : supportedMetadata) { const auto& genericLayerMetadataCompatibilityMap = @@ -552,45 +557,45 @@ void Layer::prepareGeometryCompositionState() { continue; } - compositionState->metadata - .emplace(key, compositionengine::GenericLayerMetadataEntry{mandatory, it->second}); + snapshot->metadata.emplace(key, + compositionengine::GenericLayerMetadataEntry{mandatory, + it->second}); } } void Layer::preparePerFrameCompositionState() { const auto& drawingState{getDrawingState()}; - auto* compositionState = editCompositionState(); + auto* snapshot = editLayerSnapshot(); - compositionState->forceClientComposition = false; + snapshot->forceClientComposition = false; - compositionState->isColorspaceAgnostic = isColorSpaceAgnostic(); - compositionState->dataspace = getDataSpace(); - compositionState->colorTransform = getColorTransform(); - compositionState->colorTransformIsIdentity = !hasColorTransform(); - compositionState->surfaceDamage = surfaceDamageRegion; - compositionState->hasProtectedContent = isProtected(); - compositionState->dimmingEnabled = isDimmingEnabled(); + snapshot->isColorspaceAgnostic = isColorSpaceAgnostic(); + snapshot->dataspace = getDataSpace(); + snapshot->colorTransform = getColorTransform(); + snapshot->colorTransformIsIdentity = !hasColorTransform(); + snapshot->surfaceDamage = surfaceDamageRegion; + snapshot->hasProtectedContent = isProtected(); + snapshot->dimmingEnabled = isDimmingEnabled(); const bool usesRoundedCorners = hasRoundedCorners(); - compositionState->isOpaque = - isOpaque(drawingState) && !usesRoundedCorners && getAlpha() == 1.0_hf; + snapshot->isOpaque = isOpaque(drawingState) && !usesRoundedCorners && getAlpha() == 1.0_hf; // Force client composition for special cases known only to the front-end. // Rounded corners no longer force client composition, since we may use a // hole punch so that the layer will appear to have rounded corners. if (isHdrY410() || drawShadows() || drawingState.blurRegions.size() > 0 || - compositionState->stretchEffect.hasEffect()) { - compositionState->forceClientComposition = true; + snapshot->stretchEffect.hasEffect()) { + snapshot->forceClientComposition = true; } // If there are no visible region changes, we still need to update blur parameters. - compositionState->blurRegions = drawingState.blurRegions; - compositionState->backgroundBlurRadius = drawingState.backgroundBlurRadius; + snapshot->blurRegions = drawingState.blurRegions; + snapshot->backgroundBlurRadius = drawingState.backgroundBlurRadius; // Layer framerate is used in caching decisions. // Retrieve it from the scheduler which maintains an instance of LayerHistory, and store it in // LayerFECompositionState where it would be visible to Flattener. - compositionState->fps = mFlinger->getLayerFramerate(systemTime(), getSequence()); + snapshot->fps = mFlinger->getLayerFramerate(systemTime(), getSequence()); if (hasBufferOrSidebandStream()) { preparePerFrameBufferCompositionState(); @@ -601,41 +606,41 @@ void Layer::preparePerFrameCompositionState() { void Layer::preparePerFrameBufferCompositionState() { // Sideband layers - auto* compositionState = editCompositionState(); - if (compositionState->sidebandStream.get() && !compositionState->sidebandStreamHasFrame) { - compositionState->compositionType = + auto* snapshot = editLayerSnapshot(); + if (snapshot->sidebandStream.get() && !snapshot->sidebandStreamHasFrame) { + snapshot->compositionType = aidl::android::hardware::graphics::composer3::Composition::SIDEBAND; return; } else if ((mDrawingState.flags & layer_state_t::eLayerIsDisplayDecoration) != 0) { - compositionState->compositionType = + snapshot->compositionType = aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION; } else { // Normal buffer layers - compositionState->hdrMetadata = mBufferInfo.mHdrMetadata; - compositionState->compositionType = mPotentialCursor + snapshot->hdrMetadata = mBufferInfo.mHdrMetadata; + snapshot->compositionType = mPotentialCursor ? aidl::android::hardware::graphics::composer3::Composition::CURSOR : aidl::android::hardware::graphics::composer3::Composition::DEVICE; } - compositionState->buffer = getBuffer(); - compositionState->bufferSlot = (mBufferInfo.mBufferSlot == BufferQueue::INVALID_BUFFER_SLOT) + snapshot->buffer = getBuffer(); + snapshot->bufferSlot = (mBufferInfo.mBufferSlot == BufferQueue::INVALID_BUFFER_SLOT) ? 0 : mBufferInfo.mBufferSlot; - compositionState->acquireFence = mBufferInfo.mFence; - compositionState->frameNumber = mBufferInfo.mFrameNumber; - compositionState->sidebandStreamHasFrame = false; + snapshot->acquireFence = mBufferInfo.mFence; + snapshot->frameNumber = mBufferInfo.mFrameNumber; + snapshot->sidebandStreamHasFrame = false; } void Layer::preparePerFrameEffectsCompositionState() { - auto* compositionState = editCompositionState(); - compositionState->color = getColor(); - compositionState->compositionType = + auto* snapshot = editLayerSnapshot(); + snapshot->color = getColor(); + snapshot->compositionType = aidl::android::hardware::graphics::composer3::Composition::SOLID_COLOR; } void Layer::prepareCursorCompositionState() { const State& drawingState{getDrawingState()}; - auto* compositionState = editCompositionState(); + auto* snapshot = editLayerSnapshot(); // Apply the layer's transform, followed by the display's global transform // Here we're guaranteed that the layer's transform preserves rects @@ -644,7 +649,7 @@ void Layer::prepareCursorCompositionState() { Rect bounds = reduce(win, getActiveTransparentRegion(drawingState)); Rect frame(getTransform().transform(bounds)); - compositionState->cursorFrame = frame; + snapshot->cursorFrame = frame; } sp<compositionengine::LayerFE> Layer::asLayerFE() const { @@ -686,31 +691,30 @@ std::optional<compositionengine::LayerFE::LayerSettings> Layer::prepareClientCom compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const { ATRACE_CALL(); - if (!getCompositionState()) { + const auto* snapshot = getLayerSnapshot(); + if (!snapshot) { return {}; } - FloatRect bounds = getBounds(); - half alpha = getAlpha(); - compositionengine::LayerFE::LayerSettings layerSettings; - layerSettings.geometry.boundaries = bounds; - layerSettings.geometry.positionTransform = getTransform().asMatrix4(); + 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 = getColorTransform(); + layerSettings.colorTransform = snapshot->colorTransform; } - const auto roundedCornerState = getRoundedCornerState(); + const auto& roundedCornerState = snapshot->roundedCorner; layerSettings.geometry.roundedCornersRadius = roundedCornerState.radius; layerSettings.geometry.roundedCornersCrop = roundedCornerState.cropRect; - layerSettings.alpha = alpha; - layerSettings.sourceDataspace = getDataSpace(); + 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 @@ -727,26 +731,24 @@ std::optional<compositionengine::LayerFE::LayerSettings> Layer::prepareClientCom layerSettings.whitePointNits = targetSettings.whitePointNits; switch (targetSettings.blurSetting) { case LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled: - layerSettings.backgroundBlurRadius = getBackgroundBlurRadius(); - layerSettings.blurRegions = getBlurRegions(); - layerSettings.blurRegionTransform = - getActiveTransform(getDrawingState()).inverse().asMatrix4(); + layerSettings.backgroundBlurRadius = snapshot->backgroundBlurRadius; + layerSettings.blurRegions = snapshot->blurRegions; + layerSettings.blurRegionTransform = snapshot->geomInverseLayerTransform.asMatrix4(); break; case LayerFE::ClientCompositionTargetSettings::BlurSetting::BackgroundBlurOnly: - layerSettings.backgroundBlurRadius = getBackgroundBlurRadius(); + layerSettings.backgroundBlurRadius = snapshot->backgroundBlurRadius; break; case LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly: - layerSettings.blurRegions = getBlurRegions(); - layerSettings.blurRegionTransform = - getActiveTransform(getDrawingState()).inverse().asMatrix4(); + layerSettings.blurRegions = snapshot->blurRegions; + layerSettings.blurRegionTransform = snapshot->geomInverseLayerTransform.asMatrix4(); break; case LayerFE::ClientCompositionTargetSettings::BlurSetting::Disabled: default: break; } - layerSettings.stretchEffect = getStretchEffect(); + layerSettings.stretchEffect = snapshot->stretchEffect; // Record the name of the layer for debugging further down the stack. - layerSettings.name = getName(); + layerSettings.name = snapshot->name; if (hasEffect() && !hasBufferOrSidebandStream()) { prepareEffectsClientComposition(layerSettings, targetSettings); @@ -767,7 +769,7 @@ void Layer::prepareClearClientComposition(LayerFE::LayerSettings& layerSettings, // 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 = getName(); + layerSettings.name = getLayerSnapshot()->name; } void Layer::prepareEffectsClientComposition( @@ -785,39 +787,41 @@ void Layer::prepareEffectsClientComposition( void Layer::prepareBufferStateClientComposition( compositionengine::LayerFE::LayerSettings& layerSettings, compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const { - if (CC_UNLIKELY(!mBufferInfo.mBuffer)) { - // For surfaceview of tv sideband, there is no activeBuffer - // in bufferqueue, we need return LayerSettings. + 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 = (isProtected() && !targetSettings.supportsProtectedContent) || - ((isSecure() || isProtected()) && !targetSettings.isSecure); + const bool blackOutLayer = + (snapshot->hasProtectedContent && !targetSettings.supportsProtectedContent) || + ((snapshot->isSecure || snapshot->hasProtectedContent) && !targetSettings.isSecure); const bool bufferCanBeUsedAsHwTexture = - mBufferInfo.mBuffer->getUsage() & GraphicBuffer::USAGE_HW_TEXTURE; + snapshot->externalTexture->getUsage() & GraphicBuffer::USAGE_HW_TEXTURE; if (blackOutLayer || !bufferCanBeUsedAsHwTexture) { ALOGE_IF(!bufferCanBeUsedAsHwTexture, "%s is blacked out as buffer is not gpu readable", - mName.c_str()); + snapshot->name.c_str()); prepareClearClientComposition(layerSettings, true /* blackout */); return; } - const State& s(getDrawingState()); - layerSettings.source.buffer.buffer = mBufferInfo.mBuffer; - layerSettings.source.buffer.isOpaque = isOpaque(s); - layerSettings.source.buffer.fence = mBufferInfo.mFence; - layerSettings.source.buffer.textureName = mTextureName; - layerSettings.source.buffer.usePremultipliedAlpha = getPremultipledAlpha(); - layerSettings.source.buffer.isY410BT2020 = isHdrY410(); - bool hasSmpte2086 = mBufferInfo.mHdrMetadata.validTypes & HdrMetadata::SMPTE2086; - bool hasCta861_3 = mBufferInfo.mHdrMetadata.validTypes & HdrMetadata::CTA861_3; + 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(mBufferInfo.mHdrMetadata.smpte2086.maxLuminance, - mBufferInfo.mHdrMetadata.cta8613.maxContentLightLevel); + maxLuminance = std::min(snapshot->hdrMetadata.smpte2086.maxLuminance, + snapshot->hdrMetadata.cta8613.maxContentLightLevel); } else if (hasSmpte2086) { - maxLuminance = mBufferInfo.mHdrMetadata.smpte2086.maxLuminance; + maxLuminance = snapshot->hdrMetadata.smpte2086.maxLuminance; } else if (hasCta861_3) { - maxLuminance = mBufferInfo.mHdrMetadata.cta8613.maxContentLightLevel; + maxLuminance = snapshot->hdrMetadata.cta8613.maxContentLightLevel; } else { switch (layerSettings.sourceDataspace & HAL_DATASPACE_TRANSFER_MASK) { case HAL_DATASPACE_TRANSFER_ST2084: @@ -828,17 +832,17 @@ void Layer::prepareBufferStateClientComposition( } } layerSettings.source.buffer.maxLuminanceNits = maxLuminance; - layerSettings.frameNumber = mCurrentFrameNumber; - layerSettings.bufferId = mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getId() : 0; + layerSettings.frameNumber = snapshot->frameNumber; + layerSettings.bufferId = snapshot->externalTexture->getId(); - const bool useFiltering = - targetSettings.needsFiltering || mNeedsFiltering || bufferNeedsFiltering(); + 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 (getTransformToDisplayInverse()) { + if (snapshot->geomBufferUsesDisplayInverseTransform) { /* * the code below applies the primary display's inverse transform to * the texture transform @@ -855,25 +859,22 @@ void Layer::prepareBufferStateClientComposition( * of a camera where the buffer remains in native orientation, * we want the pixels to always be upright. */ - sp<Layer> p = mDrawingParent.promote(); - if (p != nullptr) { - const auto parentTransform = p->getTransform(); - tr = tr * inverseOrientation(parentTransform.getOrientation()); - } + 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{getBounds()}; - float bufferWidth = getBufferSize(s).getWidth(); - float bufferHeight = getBufferSize(s).getHeight(); + 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 (!getBufferSize(s).isValid()) { + if (!snapshot->bufferSize.isValid()) { bufferWidth = float(win.right) - float(win.left); bufferHeight = float(win.bottom) - float(win.top); } @@ -2181,35 +2182,17 @@ Layer::RoundedCornerState Layer::getRoundedCornerState() const { void Layer::prepareShadowClientComposition(LayerFE::LayerSettings& caster, const Rect& layerStackRect) const { - renderengine::ShadowSettings state = mFlinger->mDrawingState.globalShadowSettings; - - // Note: this preserves existing behavior of shadowing the entire layer and not cropping it if - // transparent regions are present. This may not be necessary since shadows are typically cast - // by layers without transparent regions. - state.boundaries = mBounds; + 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) - mScreenBounds.left; - state.lightPos.y -= mScreenBounds.top; - - state.length = mEffectiveShadowRadius; - - if (state.length > 0.f) { - const float casterAlpha = caster.alpha; - const bool casterIsOpaque = - ((caster.source.buffer.buffer != nullptr) && caster.source.buffer.isOpaque); - - // If the casting layer is translucent, we need to fill in the shadow underneath the layer. - // Otherwise the generated shadow will only be shown around the casting layer. - state.casterIsTranslucent = !casterIsOpaque || (casterAlpha < 1.0f); - state.ambientColor *= casterAlpha; - state.spotColor *= casterAlpha; - - if (state.ambientColor.a > 0.f && state.spotColor.a > 0.f) { - caster.shadow = state; - } - } + 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) { @@ -3418,13 +3401,14 @@ void Layer::setAutoRefresh(bool autoRefresh) { bool Layer::latchSidebandStream(bool& recomputeVisibleRegions) { // We need to update the sideband stream if the layer has both a buffer and a sideband stream. - editCompositionState()->sidebandStreamHasFrame = hasFrameUpdate() && mSidebandStream.get(); + auto* snapshot = editLayerSnapshot(); + snapshot->sidebandStreamHasFrame = hasFrameUpdate() && mSidebandStream.get(); if (mSidebandStreamChanged.exchange(false)) { const State& s(getDrawingState()); // mSidebandStreamChanged was true mSidebandStream = s.sidebandStream; - editCompositionState()->sidebandStream = mSidebandStream; + snapshot->sidebandStream = mSidebandStream; if (mSidebandStream != nullptr) { setTransactionFlags(eTransactionNeeded); mFlinger->setTransactionFlags(eTraversalNeeded); @@ -3824,12 +3808,15 @@ sp<compositionengine::LayerFE> Layer::getCompositionEngineLayerFE() const { } } -compositionengine::LayerFECompositionState* Layer::editCompositionState() { - return mCompositionState.get(); +const Layer::LayerSnapshot* Layer::getLayerSnapshot() const { + return mSnapshot.get(); } +Layer::LayerSnapshot* Layer::editLayerSnapshot() { + return mSnapshot.get(); +} const compositionengine::LayerFECompositionState* Layer::getCompositionState() const { - return mCompositionState.get(); + return mSnapshot.get(); } void Layer::useSurfaceDamage() { @@ -4224,10 +4211,44 @@ void Layer::updateSnapshot(bool updateGeometry) { return; } + auto* snapshot = editLayerSnapshot(); if (updateGeometry) { prepareBasicGeometryCompositionState(); prepareGeometryCompositionState(); + snapshot->roundedCorner = getRoundedCornerState(); + snapshot->stretchEffect = getStretchEffect(); + snapshot->transformedBounds = mScreenBounds; + if (mEffectiveShadowRadius > 0.f) { + snapshot->shadowSettings = mFlinger->mDrawingState.globalShadowSettings; + + // Note: this preserves existing behavior of shadowing the entire layer and not cropping + // it if transparent regions are present. This may not be necessary since shadows are + // typically cast by layers without transparent regions. + snapshot->shadowSettings.boundaries = mBounds; + + const float casterAlpha = snapshot->alpha; + const bool casterIsOpaque = + ((mBufferInfo.mBuffer != nullptr) && isOpaque(mDrawingState)); + + // If the casting layer is translucent, we need to fill in the shadow underneath the + // layer. Otherwise the generated shadow will only be shown around the casting layer. + snapshot->shadowSettings.casterIsTranslucent = !casterIsOpaque || (casterAlpha < 1.0f); + snapshot->shadowSettings.ambientColor *= casterAlpha; + snapshot->shadowSettings.spotColor *= casterAlpha; + } + snapshot->shadowSettings.length = mEffectiveShadowRadius; + } + snapshot->contentOpaque = isOpaque(mDrawingState); + snapshot->isHdrY410 = isHdrY410(); + snapshot->bufferNeedsFiltering = bufferNeedsFiltering(); + sp<Layer> p = mDrawingParent.promote(); + if (p != nullptr) { + snapshot->transform = p->getTransform(); + } else { + snapshot->transform.reset(); } + snapshot->bufferSize = getBufferSize(mDrawingState); + snapshot->externalTexture = mBufferInfo.mBuffer; preparePerFrameCompositionState(); } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 5030fd826e..4079d16438 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -38,6 +38,7 @@ #include <utils/Timers.h> #include <compositionengine/LayerFE.h> +#include <compositionengine/LayerFECompositionState.h> #include <scheduler/Fps.h> #include <scheduler/Seamlessness.h> @@ -144,6 +145,29 @@ public: 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; + }; + using FrameRate = scheduler::LayerInfo::FrameRate; using FrameRateCompatibility = scheduler::LayerInfo::FrameRateCompatibility; @@ -392,7 +416,9 @@ public: ui::Dataspace getRequestedDataSpace() const; virtual sp<compositionengine::LayerFE> getCompositionEngineLayerFE() const; - compositionengine::LayerFECompositionState* editCompositionState(); + + const LayerSnapshot* getLayerSnapshot() const; + LayerSnapshot* editLayerSnapshot(); // If we have received a new buffer this frame, we will pass its surface // damage down to hardware composer. Otherwise, we must send a region with @@ -867,6 +893,13 @@ public: bool simpleBufferUpdate(const layer_state_t&) const; static bool isOpaqueFormat(PixelFormat format); + + // 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). + // + // TODO(b/238781169) Remove direct calls to RenderEngine::drawLayers that don't go through + // CompositionEngine to create a single path for composing layers. void updateSnapshot(bool updateGeometry); protected: @@ -1166,8 +1199,6 @@ private: // the mStateLock. ui::Transform::RotationFlags mTransformHint = ui::Transform::ROT_0; - std::unique_ptr<compositionengine::LayerFECompositionState> mCompositionState; - ReleaseCallbackId mPreviousReleaseCallbackId = ReleaseCallbackId::INVALID_ID; uint64_t mPreviousReleasedFrameNumber = 0; @@ -1200,6 +1231,8 @@ private: ui::Transform mRequestedTransform; sp<HwcSlotGenerator> mHwcSlotGenerator; + + std::unique_ptr<LayerSnapshot> mSnapshot = std::make_unique<LayerSnapshot>(); }; std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index bcd2b43a62..9a19f0a6c0 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -6653,6 +6653,11 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( std::vector<Layer*> renderedLayers; bool disableBlurs = false; traverseLayers([&](Layer* layer) { + // Layer::prepareClientComposition uses the layer's snapshot to populate the resulting + // LayerSettings. Calling Layer::updateSnapshot ensures that LayerSettings are + // generated with the layer's current buffer and geometry. + layer->updateSnapshot(true /* updateGeometry */); + disableBlurs |= layer->getDrawingState().sidebandStream != nullptr; Region clip(renderArea.getBounds()); diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index 983fac231c..2c9c451f29 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -285,7 +285,7 @@ public: const sp<NativeHandle>& sidebandStream) { layer->mDrawingState.sidebandStream = sidebandStream; layer->mSidebandStream = sidebandStream; - layer->editCompositionState()->sidebandStream = sidebandStream; + layer->editLayerSnapshot()->sidebandStream = sidebandStream; } void setLayerCompositionType(const sp<Layer>& layer, |