diff options
author | 2023-02-24 18:08:51 +0000 | |
---|---|---|
committer | 2023-02-24 18:08:51 +0000 | |
commit | d47bceea5a8da823b38eb5ca71bb8206b95c1958 (patch) | |
tree | 2a3af01cf6cf4f5970aee757ba54cd5b6436ff48 | |
parent | 7c41bf2e08cf331dbd1319fe91a0d26a7304d00e (diff) |
SF: Frontend fixes for issues surfaced by SurfaceFlinger_test
- separate color and bgcolor in layer state so we don't set a color
on a layer without a buffer
- avoid using legacy layer state when latching a buffer
- fix callback issue where invisible or offscreen layers were not invoking
the callbacks
- pass in layer snapshot for trusted presentation state
- fix a screenshot issue where the root layer was skipped
- pass in framerate changes to layer history
Test: presubmit
Test: atest SurfaceFlinger_test with new fe
Bug: 238781169
Change-Id: Id9ff8a036dc283e21a05985c1c01ebd070b1df24
24 files changed, 324 insertions, 148 deletions
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index f6bba16899..b391337d1d 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -74,7 +74,7 @@ layer_state_t::layer_state_t() surfaceDamageRegion(), api(-1), colorTransform(mat4()), - bgColorAlpha(0), + bgColor(0), bgColorDataspace(ui::Dataspace::UNKNOWN), colorSpaceAgnostic(false), shadowRadius(0.0f), @@ -140,7 +140,10 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.writeFloat, cornerRadius); SAFE_PARCEL(output.writeUint32, backgroundBlurRadius); SAFE_PARCEL(output.writeParcelable, metadata); - SAFE_PARCEL(output.writeFloat, bgColorAlpha); + SAFE_PARCEL(output.writeFloat, bgColor.r); + SAFE_PARCEL(output.writeFloat, bgColor.g); + SAFE_PARCEL(output.writeFloat, bgColor.b); + SAFE_PARCEL(output.writeFloat, bgColor.a); SAFE_PARCEL(output.writeUint32, static_cast<uint32_t>(bgColorDataspace)); SAFE_PARCEL(output.writeBool, colorSpaceAgnostic); SAFE_PARCEL(output.writeVectorSize, listeners); @@ -259,7 +262,14 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.readUint32, &backgroundBlurRadius); SAFE_PARCEL(input.readParcelable, &metadata); - SAFE_PARCEL(input.readFloat, &bgColorAlpha); + SAFE_PARCEL(input.readFloat, &tmpFloat); + bgColor.r = tmpFloat; + SAFE_PARCEL(input.readFloat, &tmpFloat); + bgColor.g = tmpFloat; + SAFE_PARCEL(input.readFloat, &tmpFloat); + bgColor.b = tmpFloat; + SAFE_PARCEL(input.readFloat, &tmpFloat); + bgColor.a = tmpFloat; SAFE_PARCEL(input.readUint32, &tmpUint32); bgColorDataspace = static_cast<ui::Dataspace>(tmpUint32); SAFE_PARCEL(input.readBool, &colorSpaceAgnostic); @@ -618,8 +628,7 @@ void layer_state_t::merge(const layer_state_t& other) { } if (other.what & eBackgroundColorChanged) { what |= eBackgroundColorChanged; - color.rgb = other.color.rgb; - bgColorAlpha = other.bgColorAlpha; + bgColor = other.bgColor; bgColorDataspace = other.bgColorDataspace; } if (other.what & eMetadataChanged) { @@ -752,7 +761,7 @@ uint64_t layer_state_t::diff(const layer_state_t& other) const { CHECK_DIFF(diff, eColorTransformChanged, other, colorTransform); if (other.what & eHasListenerCallbacksChanged) diff |= eHasListenerCallbacksChanged; if (other.what & eInputInfoChanged) diff |= eInputInfoChanged; - CHECK_DIFF3(diff, eBackgroundColorChanged, other, color.rgb, bgColorAlpha, bgColorDataspace); + CHECK_DIFF2(diff, eBackgroundColorChanged, other, bgColor, bgColorDataspace); if (other.what & eMetadataChanged) diff |= eMetadataChanged; CHECK_DIFF(diff, eShadowRadiusChanged, other, shadowRadius); CHECK_DIFF3(diff, eRenderBorderChanged, other, borderEnabled, borderWidth, borderColor); diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 001d475823..0f138ca157 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1560,8 +1560,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBackg } s->what |= layer_state_t::eBackgroundColorChanged; - s->color.rgb = color; - s->bgColorAlpha = alpha; + s->bgColor.rgb = color; + s->bgColor.a = alpha; s->bgColorDataspace = dataspace; registerSurfaceControlForCallback(sc); diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index da144bd191..29fb989743 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -226,9 +226,9 @@ struct layer_state_t { bool hasBufferChanges() const; // Layer hierarchy updates. - static constexpr uint64_t HIERARCHY_CHANGES = layer_state_t::eBackgroundColorChanged | - layer_state_t::eLayerChanged | layer_state_t::eRelativeLayerChanged | - layer_state_t::eReparent; + static constexpr uint64_t HIERARCHY_CHANGES = layer_state_t::eLayerChanged | + layer_state_t::eRelativeLayerChanged | layer_state_t::eReparent | + layer_state_t::eLayerStackChanged; // Geometry updates. static constexpr uint64_t GEOMETRY_CHANGES = layer_state_t::eBufferCropChanged | @@ -264,9 +264,8 @@ struct layer_state_t { static constexpr uint64_t AFFECTS_CHILDREN = layer_state_t::GEOMETRY_CHANGES | layer_state_t::HIERARCHY_CHANGES | layer_state_t::eAlphaChanged | layer_state_t::eColorTransformChanged | layer_state_t::eCornerRadiusChanged | - layer_state_t::eFlagsChanged | layer_state_t::eLayerStackChanged | - layer_state_t::eTrustedOverlayChanged | layer_state_t::eFrameRateChanged | - layer_state_t::eFixedTransformHintChanged; + layer_state_t::eFlagsChanged | layer_state_t::eTrustedOverlayChanged | + layer_state_t::eFrameRateChanged | layer_state_t::eFixedTransformHintChanged; // Changes affecting data sent to input. static constexpr uint64_t INPUT_CHANGES = layer_state_t::GEOMETRY_CHANGES | @@ -333,7 +332,7 @@ struct layer_state_t { // The following refer to the alpha, and dataspace, respectively of // the background color layer - float bgColorAlpha; + half4 bgColor; ui::Dataspace bgColorDataspace; // A color space agnostic layer means the color of this layer can be diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h index 0b4d20c660..eae5871477 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h @@ -213,9 +213,7 @@ struct LayerFECompositionState { float currentSdrHdrRatio = 1.f; float desiredSdrHdrRatio = 1.f; - bool isInternalDisplayOverlay = false; gui::CachingHint cachingHint = gui::CachingHint::Enabled; - virtual ~LayerFECompositionState(); // Debugging diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp index 7d9431605d..175dd1d825 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -538,8 +538,8 @@ void Output::ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>& layerFE, return; } - bool computeAboveCoveredExcludingOverlays = - coverage.aboveCoveredLayersExcludingOverlays && !layerFEState->isInternalDisplayOverlay; + bool computeAboveCoveredExcludingOverlays = coverage.aboveCoveredLayersExcludingOverlays && + !layerFEState->outputFilter.toInternalDisplay; /* * opaqueRegion: area of a surface that is fully opaque. diff --git a/services/surfaceflinger/FrontEnd/LayerCreationArgs.cpp b/services/surfaceflinger/FrontEnd/LayerCreationArgs.cpp index 6d492c0f4a..66598251cb 100644 --- a/services/surfaceflinger/FrontEnd/LayerCreationArgs.cpp +++ b/services/surfaceflinger/FrontEnd/LayerCreationArgs.cpp @@ -24,9 +24,13 @@ namespace android::surfaceflinger { std::atomic<uint32_t> LayerCreationArgs::sSequence{1}; +uint32_t LayerCreationArgs::getInternalLayerId(uint32_t id) { + return id | INTERNAL_LAYER_PREFIX; +} + LayerCreationArgs::LayerCreationArgs(SurfaceFlinger* flinger, sp<Client> client, std::string name, uint32_t flags, gui::LayerMetadata metadataArg, - std::optional<uint32_t> id) + std::optional<uint32_t> id, bool internalLayer) : flinger(flinger), client(std::move(client)), name(std::move(name)), @@ -46,10 +50,15 @@ LayerCreationArgs::LayerCreationArgs(SurfaceFlinger* flinger, sp<Client> client, if (id) { sequence = *id; - sSequence = *id + 1; + if (internalLayer) { + sequence = getInternalLayerId(*id); + } else { + sSequence = *id + 1; + } } else { sequence = sSequence++; - if (sequence == UNASSIGNED_LAYER_ID) { + if (sequence >= INTERNAL_LAYER_PREFIX) { + sSequence = 1; ALOGW("Layer sequence id rolled over."); sequence = sSequence++; } diff --git a/services/surfaceflinger/FrontEnd/LayerCreationArgs.h b/services/surfaceflinger/FrontEnd/LayerCreationArgs.h index 9d2aaab23d..2cd6b55bc4 100644 --- a/services/surfaceflinger/FrontEnd/LayerCreationArgs.h +++ b/services/surfaceflinger/FrontEnd/LayerCreationArgs.h @@ -25,6 +25,7 @@ #include <optional> constexpr uint32_t UNASSIGNED_LAYER_ID = std::numeric_limits<uint32_t>::max(); +constexpr uint32_t INTERNAL_LAYER_PREFIX = 1u << 31; namespace android { class SurfaceFlinger; @@ -35,10 +36,11 @@ namespace android::surfaceflinger { struct LayerCreationArgs { static std::atomic<uint32_t> sSequence; + static uint32_t getInternalLayerId(uint32_t id); LayerCreationArgs(android::SurfaceFlinger*, sp<android::Client>, std::string name, - uint32_t flags, gui::LayerMetadata, - std::optional<uint32_t> id = std::nullopt); + uint32_t flags, gui::LayerMetadata, std::optional<uint32_t> id = std::nullopt, + bool internalLayer = false); LayerCreationArgs(const LayerCreationArgs&); android::SurfaceFlinger* flinger; diff --git a/services/surfaceflinger/FrontEnd/LayerHierarchy.h b/services/surfaceflinger/FrontEnd/LayerHierarchy.h index 2ab897b35d..0f700a9423 100644 --- a/services/surfaceflinger/FrontEnd/LayerHierarchy.h +++ b/services/surfaceflinger/FrontEnd/LayerHierarchy.h @@ -128,12 +128,18 @@ public: // Traverse the hierarchy and visit all child variants. void traverse(const Visitor& visitor) const { TraversalPath root = TraversalPath::ROOT; + if (mLayer) { + root.id = mLayer->id; + } traverse(visitor, root); } // Traverse the hierarchy in z-order, skipping children that have relative parents. void traverseInZOrder(const Visitor& visitor) const { TraversalPath root = TraversalPath::ROOT; + if (mLayer) { + root.id = mLayer->id; + } traverseInZOrder(visitor, root); } diff --git a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp index 66197be44a..79ffcbf65d 100644 --- a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp +++ b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp @@ -192,35 +192,38 @@ void LayerLifecycleManager::applyTransactions(const std::vector<TransactionState layer->merge(resolvedComposerState); if (layer->what & layer_state_t::eBackgroundColorChanged) { - if (layer->bgColorLayerId == UNASSIGNED_LAYER_ID && layer->bgColorAlpha != 0) { + if (layer->bgColorLayerId == UNASSIGNED_LAYER_ID && layer->bgColor.a != 0) { LayerCreationArgs backgroundLayerArgs{nullptr, nullptr, layer->name + "BackgroundColorLayer", ISurfaceComposerClient::eFXSurfaceEffect, - {}}; + {}, + layer->id, + /*internalLayer=*/true}; std::vector<std::unique_ptr<RequestedLayerState>> newLayers; newLayers.emplace_back( std::make_unique<RequestedLayerState>(backgroundLayerArgs)); RequestedLayerState* backgroundLayer = newLayers.back().get(); + backgroundLayer->bgColorLayer = true; backgroundLayer->handleAlive = false; backgroundLayer->parentId = layer->id; backgroundLayer->z = std::numeric_limits<int32_t>::min(); - backgroundLayer->color.rgb = layer->color.rgb; - backgroundLayer->color.a = layer->bgColorAlpha; + backgroundLayer->color = layer->bgColor; backgroundLayer->dataspace = layer->bgColorDataspace; - layer->bgColorLayerId = backgroundLayer->id; addLayers({std::move(newLayers)}); - } else if (layer->bgColorLayerId != UNASSIGNED_LAYER_ID && - layer->bgColorAlpha == 0) { + } else if (layer->bgColorLayerId != UNASSIGNED_LAYER_ID && layer->bgColor.a == 0) { RequestedLayerState* bgColorLayer = getLayerFromId(layer->bgColorLayerId); - bgColorLayer->parentId = UNASSIGNED_LAYER_ID; - onHandlesDestroyed({layer->bgColorLayerId}); + layer->bgColorLayerId = UNASSIGNED_LAYER_ID; + bgColorLayer->parentId = unlinkLayer(bgColorLayer->parentId, bgColorLayer->id); + onHandlesDestroyed({bgColorLayer->id}); } else if (layer->bgColorLayerId != UNASSIGNED_LAYER_ID) { RequestedLayerState* bgColorLayer = getLayerFromId(layer->bgColorLayerId); - bgColorLayer->color.rgb = layer->color.rgb; - bgColorLayer->color.a = layer->bgColorAlpha; + bgColorLayer->color = layer->bgColor; bgColorLayer->dataspace = layer->bgColorDataspace; + bgColorLayer->what |= layer_state_t::eColorChanged | + layer_state_t::eDataspaceChanged | layer_state_t::eAlphaChanged; + bgColorLayer->changes |= RequestedLayerState::Changes::Content; mGlobalChanges |= RequestedLayerState::Changes::Content; } } @@ -256,8 +259,7 @@ void LayerLifecycleManager::commitChanges() { listener->onLayerAdded(*layer); } } - layer->what = 0; - layer->changes.clear(); + layer->clearChanges(); } for (auto& destroyedLayer : mDestroyedLayers) { diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp index dbb7fbf462..f8661758c1 100644 --- a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp +++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp @@ -139,7 +139,8 @@ std::string LayerSnapshot::getIsVisibleReason() const { // visible std::stringstream reason; if (sidebandStream != nullptr) reason << " sidebandStream"; - if (externalTexture != nullptr) reason << " buffer"; + if (externalTexture != nullptr) + reason << " buffer:" << externalTexture->getId() << " frame:" << frameNumber; if (fillsColor() || color.a > 0.0f) reason << " color{" << color << "}"; if (drawShadows()) reason << " shadowSettings.length=" << shadowSettings.length; if (backgroundBlurRadius > 0) reason << " backgroundBlurRadius=" << backgroundBlurRadius; diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp index d740350cc5..c7f9aa7b42 100644 --- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp +++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp @@ -337,12 +337,12 @@ LayerSnapshot LayerSnapshotBuilder::getRootSnapshot() { LayerSnapshotBuilder::LayerSnapshotBuilder() : mRootSnapshot(getRootSnapshot()) {} LayerSnapshotBuilder::LayerSnapshotBuilder(Args args) : LayerSnapshotBuilder() { - args.forceUpdate = true; + args.forceUpdate = ForceUpdateFlags::ALL; updateSnapshots(args); } bool LayerSnapshotBuilder::tryFastUpdate(const Args& args) { - if (args.forceUpdate || args.displayChanges) { + if (args.forceUpdate != ForceUpdateFlags::NONE || args.displayChanges) { // force update requested, or we have display changes, so skip the fast path return false; } @@ -393,19 +393,31 @@ void LayerSnapshotBuilder::updateSnapshots(const Args& args) { ATRACE_NAME("UpdateSnapshots"); if (args.parentCrop) { mRootSnapshot.geomLayerBounds = *args.parentCrop; - } else if (args.forceUpdate || args.displayChanges) { + } else if (args.forceUpdate == ForceUpdateFlags::ALL || args.displayChanges) { mRootSnapshot.geomLayerBounds = getMaxDisplayBounds(args.displays); } if (args.displayChanges) { mRootSnapshot.changes = RequestedLayerState::Changes::AffectsChildren | RequestedLayerState::Changes::Geometry; } + if (args.forceUpdate == ForceUpdateFlags::HIERARCHY) { + mRootSnapshot.changes |= + RequestedLayerState::Changes::Hierarchy | RequestedLayerState::Changes::Visibility; + } LayerHierarchy::TraversalPath root = LayerHierarchy::TraversalPath::ROOT; - for (auto& [childHierarchy, variant] : args.root.mChildren) { - LayerHierarchy::ScopedAddToTraversalPath addChildToPath(root, - childHierarchy->getLayer()->id, - variant); - updateSnapshotsInHierarchy(args, *childHierarchy, root, mRootSnapshot); + if (args.root.getLayer()) { + // The hierarchy can have a root layer when used for screenshots otherwise, it will have + // multiple children. + LayerHierarchy::ScopedAddToTraversalPath addChildToPath(root, args.root.getLayer()->id, + LayerHierarchy::Variant::Attached); + updateSnapshotsInHierarchy(args, args.root, root, mRootSnapshot); + } else { + for (auto& [childHierarchy, variant] : args.root.mChildren) { + LayerHierarchy::ScopedAddToTraversalPath addChildToPath(root, + childHierarchy->getLayer()->id, + variant); + updateSnapshotsInHierarchy(args, *childHierarchy, root, mRootSnapshot); + } } sortSnapshotsByZ(args); @@ -451,6 +463,7 @@ const LayerSnapshot& LayerSnapshotBuilder::updateSnapshotsInHierarchy( if (newSnapshot) { snapshot = createSnapshot(traversalPath, *layer); } + scheduler::LayerInfo::FrameRate oldFrameRate = snapshot->frameRate; if (traversalPath.isRelative()) { bool parentIsRelative = traversalPath.variant == LayerHierarchy::Variant::Relative; updateRelativeState(*snapshot, parentSnapshot, parentIsRelative, args); @@ -469,6 +482,10 @@ const LayerSnapshot& LayerSnapshotBuilder::updateSnapshotsInHierarchy( updateSnapshotsInHierarchy(args, *childHierarchy, traversalPath, *snapshot); updateChildState(*snapshot, childSnapshot, args); } + + if (oldFrameRate == snapshot->frameRate) { + snapshot->changes.clear(RequestedLayerState::Changes::FrameRate); + } return *snapshot; } @@ -495,7 +512,7 @@ LayerSnapshot* LayerSnapshotBuilder::createSnapshot(const LayerHierarchy::Traver } void LayerSnapshotBuilder::sortSnapshotsByZ(const Args& args) { - if (!mResortSnapshots && !args.forceUpdate && + if (!mResortSnapshots && args.forceUpdate == ForceUpdateFlags::NONE && !args.layerLifecycleManager.getGlobalChanges().any( RequestedLayerState::Changes::Hierarchy | RequestedLayerState::Changes::Visibility)) { @@ -569,7 +586,8 @@ void LayerSnapshotBuilder::updateChildState(LayerSnapshot& snapshot, if (snapshot.childState.hasValidFrameRate) { return; } - if (args.forceUpdate || childSnapshot.changes.test(RequestedLayerState::Changes::FrameRate)) { + if (args.forceUpdate == ForceUpdateFlags::ALL || + childSnapshot.changes.test(RequestedLayerState::Changes::FrameRate)) { // We return whether this layer ot its children has a vote. We ignore ExactOrMultiple votes // for the same reason we are allowing touch boost for those layers. See // RefreshRateSelector::rankFrameRates for details. @@ -618,21 +636,20 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a ftl::Flags<RequestedLayerState::Changes> parentChanges = parentSnapshot.changes & (RequestedLayerState::Changes::Hierarchy | RequestedLayerState::Changes::Geometry | RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Metadata | - RequestedLayerState::Changes::AffectsChildren); + RequestedLayerState::Changes::AffectsChildren | + RequestedLayerState::Changes::FrameRate); snapshot.changes = parentChanges | requested.changes; snapshot.isHiddenByPolicyFromParent = parentSnapshot.isHiddenByPolicyFromParent || parentSnapshot.invalidTransform || requested.isHiddenByPolicy() || (args.excludeLayerIds.find(path.id) != args.excludeLayerIds.end()); snapshot.contentDirty = requested.what & layer_state_t::CONTENT_DIRTY; // TODO(b/238781169) scope down the changes to only buffer updates. - snapshot.hasReadyFrame = - (snapshot.contentDirty || requested.autoRefresh) && (requested.externalTexture); - // TODO(b/238781169) how is this used? ag/15523870 - snapshot.sidebandStreamHasFrame = false; + snapshot.hasReadyFrame = requested.hasReadyFrame(); + snapshot.sidebandStreamHasFrame = requested.hasSidebandStreamFrame(); updateSurfaceDamage(requested, snapshot.hasReadyFrame, args.forceFullDamage, snapshot.surfaceDamage); - const bool forceUpdate = newSnapshot || args.forceUpdate || + const bool forceUpdate = newSnapshot || args.forceUpdate == ForceUpdateFlags::ALL || snapshot.changes.any(RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Created); snapshot.outputFilter.layerStack = requested.parentId != UNASSIGNED_LAYER_ID @@ -708,11 +725,6 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE) ? requested.gameMode : parentSnapshot.gameMode; - snapshot.frameRate = (requested.requestedFrameRate.rate.isValid() || - (requested.requestedFrameRate.type == - scheduler::LayerInfo::FrameRateCompatibility::NoVote)) - ? requested.requestedFrameRate - : parentSnapshot.frameRate; snapshot.fixedTransformHint = requested.fixedTransformHint != ui::Transform::ROT_INVALID ? requested.fixedTransformHint : parentSnapshot.fixedTransformHint; @@ -722,6 +734,16 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a (requested.layerStackToMirror != ui::INVALID_LAYER_STACK); } + if (forceUpdate || + snapshot.changes.any(RequestedLayerState::Changes::FrameRate | + RequestedLayerState::Changes::Hierarchy)) { + snapshot.frameRate = (requested.requestedFrameRate.rate.isValid() || + (requested.requestedFrameRate.type == + scheduler::LayerInfo::FrameRateCompatibility::NoVote)) + ? requested.requestedFrameRate + : parentSnapshot.frameRate; + } + if (forceUpdate || requested.changes.get() != 0) { snapshot.compositionType = requested.getCompositionType(); snapshot.dimmingEnabled = requested.dimmingEnabled; @@ -773,10 +795,11 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a // snapshot.metadata; LLOGV(snapshot.sequence, "%supdated [%d]%s changes parent:%s global:%s local:%s requested:%s %s from parent %s", - args.forceUpdate ? "Force " : "", requested.id, requested.name.c_str(), - parentSnapshot.changes.string().c_str(), snapshot.changes.string().c_str(), - requested.changes.string().c_str(), std::to_string(requested.what).c_str(), - snapshot.getDebugString().c_str(), parentSnapshot.getDebugString().c_str()); + args.forceUpdate == ForceUpdateFlags::ALL ? "Force " : "", requested.id, + requested.name.c_str(), parentSnapshot.changes.string().c_str(), + snapshot.changes.string().c_str(), requested.changes.string().c_str(), + std::to_string(requested.what).c_str(), snapshot.getDebugString().c_str(), + parentSnapshot.getDebugString().c_str()); } void LayerSnapshotBuilder::updateRoundedCorner(LayerSnapshot& snapshot, @@ -912,8 +935,12 @@ void LayerSnapshotBuilder::updateInput(LayerSnapshot& snapshot, } else { snapshot.inputInfo = {}; } - snapshot.inputInfo.displayId = static_cast<int32_t>(snapshot.outputFilter.layerStack.id); + snapshot.inputInfo.name = requested.name; + snapshot.inputInfo.id = static_cast<int32_t>(requested.id); + snapshot.inputInfo.ownerUid = static_cast<int32_t>(requested.ownerUid); + snapshot.inputInfo.ownerPid = requested.ownerPid; + snapshot.inputInfo.displayId = static_cast<int32_t>(snapshot.outputFilter.layerStack.id); if (!needsInputInfo(snapshot, requested)) { return; } diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h index 0902ab8067..d70bdb9920 100644 --- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h +++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h @@ -35,10 +35,15 @@ namespace android::surfaceflinger::frontend { // snapshots when there are only buffer updates. class LayerSnapshotBuilder { public: + enum class ForceUpdateFlags { + NONE, + ALL, + HIERARCHY, + }; struct Args { LayerHierarchy root; const LayerLifecycleManager& layerLifecycleManager; - bool forceUpdate = false; + ForceUpdateFlags forceUpdate = ForceUpdateFlags::NONE; bool includeMetadata = false; const display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& displays; // Set to true if there were display changes since last update. diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp index 09523d3ea3..e2cbe28893 100644 --- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp +++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp @@ -165,8 +165,13 @@ void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerSta if (hadBufferOrSideStream != hasBufferOrSideStream) { changes |= RequestedLayerState::Changes::Geometry | RequestedLayerState::Changes::VisibleRegion | - RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Input | - RequestedLayerState::Changes::Buffer; + RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Input; + } + if (clientState.what & layer_state_t::eBufferChanged) { + changes |= RequestedLayerState::Changes::Buffer; + } + if (clientState.what & layer_state_t::eSidebandStreamChanged) { + changes |= RequestedLayerState::Changes::SidebandStream; } } if (what & (layer_state_t::eAlphaChanged)) { @@ -197,7 +202,9 @@ void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerSta static const mat4 identityMatrix = mat4(); hasColorTransform = colorTransform != identityMatrix; } - if (clientState.what & (layer_state_t::eLayerChanged | layer_state_t::eRelativeLayerChanged)) { + if (clientState.what & + (layer_state_t::eLayerChanged | layer_state_t::eRelativeLayerChanged | + layer_state_t::eLayerStackChanged)) { changes |= RequestedLayerState::Changes::Z; } if (clientState.what & layer_state_t::eReparent) { @@ -453,4 +460,22 @@ bool RequestedLayerState::hasBlur() const { return backgroundBlurRadius > 0 || blurRegions.size() > 0; } +bool RequestedLayerState::hasFrameUpdate() const { + return what & layer_state_t::CONTENT_DIRTY && + (externalTexture || bgColorLayerId != UNASSIGNED_LAYER_ID); +} + +bool RequestedLayerState::hasReadyFrame() const { + return hasFrameUpdate() || changes.test(Changes::SidebandStream) || autoRefresh; +} + +bool RequestedLayerState::hasSidebandStreamFrame() const { + return hasFrameUpdate() && sidebandStream.get(); +} + +void RequestedLayerState::clearChanges() { + what = 0; + changes.clear(); +} + } // namespace android::surfaceflinger::frontend diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.h b/services/surfaceflinger/FrontEnd/RequestedLayerState.h index 6840b25a5b..8b475a3e45 100644 --- a/services/surfaceflinger/FrontEnd/RequestedLayerState.h +++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.h @@ -52,10 +52,13 @@ struct RequestedLayerState : layer_state_t { FrameRate = 1u << 13, VisibleRegion = 1u << 14, Buffer = 1u << 15, + SidebandStream = 1u << 16, }; static Rect reduce(const Rect& win, const Region& exclude); RequestedLayerState(const LayerCreationArgs&); void merge(const ResolvedComposerState&); + void clearChanges(); + // Currently we only care about the primary display ui::Transform getTransform(uint32_t displayRotationFlags) const; ui::Size getUnrotatedBufferSize(uint32_t displayRotationFlags) const; @@ -72,6 +75,9 @@ struct RequestedLayerState : layer_state_t { bool hasValidRelativeParent() const; bool hasInputInfo() const; bool hasBlur() const; + bool hasFrameUpdate() const; + bool hasReadyFrame() const; + bool hasSidebandStreamFrame() const; // Layer serial number. This gives layers an explicit ordering, so we // have a stable sort order when their layer stack and Z-order are @@ -110,6 +116,7 @@ struct RequestedLayerState : layer_state_t { uint32_t touchCropId = UNASSIGNED_LAYER_ID; uint32_t bgColorLayerId = UNASSIGNED_LAYER_ID; ftl::Flags<RequestedLayerState::Changes> changes; + bool bgColorLayer = false; }; } // namespace android::surfaceflinger::frontend diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index dac09169c8..5ee701d617 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2512,7 +2512,20 @@ bool Layer::hasInputInfo() const { compositionengine::OutputLayer* Layer::findOutputLayerForDisplay( const DisplayDevice* display) const { if (!display) return nullptr; - return display->getCompositionDisplay()->getOutputLayerForLayer(getCompositionEngineLayerFE()); + if (!mFlinger->mLayerLifecycleManagerEnabled) { + return display->getCompositionDisplay()->getOutputLayerForLayer( + getCompositionEngineLayerFE()); + } + sp<LayerFE> layerFE; + frontend::LayerHierarchy::TraversalPath path{.id = static_cast<uint32_t>(sequence)}; + for (auto& [p, layer] : mLayerFEs) { + if (p == path) { + layerFE = layer; + } + } + + if (!layerFE) return nullptr; + return display->getCompositionDisplay()->getOutputLayerForLayer(layerFE); } Region Layer::getVisibleRegion(const DisplayDevice* display) const { @@ -3275,11 +3288,11 @@ bool Layer::hasFrameUpdate() const { (c.buffer != nullptr || c.bgColorLayer != nullptr); } -void Layer::updateTexImage(nsecs_t latchTime) { +void Layer::updateTexImage(nsecs_t latchTime, bool bgColorOnly) { const State& s(getDrawingState()); if (!s.buffer) { - if (s.bgColorLayer) { + if (bgColorOnly) { for (auto& handle : mDrawingState.callbackHandles) { handle->latchTime = latchTime; } @@ -3476,7 +3489,7 @@ bool Layer::simpleBufferUpdate(const layer_state_t& s) const { } if (s.what & layer_state_t::eBackgroundColorChanged) { - if (mDrawingState.bgColorLayer || s.bgColorAlpha != 0) { + if (mDrawingState.bgColorLayer || s.bgColor.a != 0) { ALOGV("%s: false [eBackgroundColorChanged changed]", __func__); return false; } @@ -3800,6 +3813,11 @@ void Layer::onPostComposition(const DisplayDevice* display, } bool Layer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) { + const bool bgColorOnly = mDrawingState.bgColorLayer != nullptr; + return latchBufferImpl(recomputeVisibleRegions, latchTime, bgColorOnly); +} + +bool Layer::latchBufferImpl(bool& recomputeVisibleRegions, nsecs_t latchTime, bool bgColorOnly) { ATRACE_FORMAT_INSTANT("latchBuffer %s - %" PRIu64, getDebugName(), getDrawingState().frameNumber); @@ -3816,8 +3834,7 @@ bool Layer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) { mFlinger->onLayerUpdate(); return false; } - - updateTexImage(latchTime); + updateTexImage(latchTime, bgColorOnly); if (mDrawingState.buffer == nullptr) { return false; } @@ -4021,7 +4038,6 @@ void Layer::updateSnapshot(bool updateGeometry) { snapshot->bufferSize = getBufferSize(mDrawingState); snapshot->externalTexture = mBufferInfo.mBuffer; snapshot->hasReadyFrame = hasReadyFrame(); - snapshot->isInternalDisplayOverlay = isInternalDisplayOverlay(); preparePerFrameCompositionState(); } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 7d40774f83..9b7a4059ca 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -427,6 +427,9 @@ public: */ bool latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/); + bool latchBufferImpl(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/, + bool bgColorOnly); + /* * Calls latchBuffer if the buffer has a frame queued and then releases the buffer. * This is used if the buffer is just latched and releases to free up the buffer @@ -846,6 +849,7 @@ public: void callReleaseBufferCallback(const sp<ITransactionCompletedListener>& listener, const sp<GraphicBuffer>& buffer, uint64_t framenumber, const sp<Fence>& releaseFence); + bool setFrameRateForLayerTree(FrameRate); protected: // For unit tests @@ -1018,7 +1022,6 @@ private: void updateTreeHasFrameRateVote(); bool propagateFrameRateForLayerTree(FrameRate parentFrameRate, bool* transactionNeeded); - bool setFrameRateForLayerTree(FrameRate); void setZOrderRelativeOf(const wp<Layer>& relativeOf); bool isTrustedOverlay() const; gui::DropInputMode getDropInputMode() const; @@ -1046,7 +1049,7 @@ private: bool hasFrameUpdate() const; - void updateTexImage(nsecs_t latchTime); + void updateTexImage(nsecs_t latchTime, bool bgColorOnly = false); // Crop that applies to the buffer Rect computeBufferCrop(const State& s); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 5c8579cb4d..29af6d1b7a 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2192,7 +2192,8 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, LifecycleUpdate& upda mLayerLifecycleManager.getDestroyedLayers()); } - applyAndCommitDisplayTransactionStates(update.transactions); + bool mustComposite = false; + mustComposite |= applyAndCommitDisplayTransactionStates(update.transactions); { ATRACE_NAME("LayerSnapshotBuilder:update"); @@ -2216,23 +2217,37 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, LifecycleUpdate& upda mVisibleRegionsDirty = true; } outTransactionsAreEmpty = mLayerLifecycleManager.getGlobalChanges().get() == 0; - const bool mustComposite = mLayerLifecycleManager.getGlobalChanges().get() != 0; - { - ATRACE_NAME("LLM:commitChanges"); - mLayerLifecycleManager.commitChanges(); - } + mustComposite |= mLayerLifecycleManager.getGlobalChanges().get() != 0; + bool newDataLatched = false; if (!mLegacyFrontEndEnabled) { ATRACE_NAME("DisplayCallbackAndStatsUpdates"); applyTransactions(update.transactions, vsyncId); + const nsecs_t latchTime = systemTime(); + bool unused = false; + + for (auto& layer : mLayerLifecycleManager.getLayers()) { + if (layer->changes.test(frontend::RequestedLayerState::Changes::Created) && + layer->bgColorLayer) { + sp<Layer> bgColorLayer = getFactory().createEffectLayer( + LayerCreationArgs(this, nullptr, layer->name, + ISurfaceComposerClient::eFXSurfaceEffect, LayerMetadata(), + std::make_optional(layer->parentId), true)); + mLegacyLayers[bgColorLayer->sequence] = bgColorLayer; + } + if (!layer->hasReadyFrame()) continue; - bool newDataLatched = false; - for (auto& snapshot : mLayerSnapshotBuilder.getSnapshots()) { - if (!snapshot->changes.test(Changes::Buffer)) continue; - auto it = mLegacyLayers.find(snapshot->sequence); + auto it = mLegacyLayers.find(layer->id); LOG_ALWAYS_FATAL_IF(it == mLegacyLayers.end(), "Couldnt find layer object for %s", - snapshot->getDebugString().c_str()); + layer->getDebugString().c_str()); + const bool bgColorOnly = + !layer->externalTexture && (layer->bgColorLayerId != UNASSIGNED_LAYER_ID); + it->second->latchBufferImpl(unused, latchTime, bgColorOnly); mLayersWithQueuedFrames.emplace(it->second); + } + + for (auto& snapshot : mLayerSnapshotBuilder.getSnapshots()) { + if (!snapshot->hasReadyFrame) continue; newDataLatched = true; if (!snapshot->isVisible) break; @@ -2245,6 +2260,11 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, LifecycleUpdate& upda mLegacyLayers.erase(destroyedLayer->id); } + { + ATRACE_NAME("LLM:commitChanges"); + mLayerLifecycleManager.commitChanges(); + } + // enter boot animation on first buffer latch if (CC_UNLIKELY(mBootStage == BootStage::BOOTLOADER && newDataLatched)) { ALOGI("Enter boot animation"); @@ -2252,6 +2272,7 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, LifecycleUpdate& upda } commitTransactions(); } + mustComposite |= (getTransactionFlags() & ~eTransactionFlushNeeded) || newDataLatched; return mustComposite; } @@ -2885,14 +2906,19 @@ void SurfaceFlinger::postComposition(nsecs_t callTime) { } // We avoid any reverse traversal upwards so this shouldn't be too expensive - mDrawingState.traverse([&](Layer* layer) { + traverseLegacyLayers([&](Layer* layer) { if (!layer->hasTrustedPresentationListener()) { return; } - const std::optional<const DisplayDevice*> displayOpt = - layerStackToDisplay.get(layer->getLayerSnapshot()->outputFilter.layerStack); + const frontend::LayerSnapshot* snapshot = (mLayerLifecycleManagerEnabled) + ? mLayerSnapshotBuilder.getSnapshot(layer->sequence) + : layer->getLayerSnapshot(); + std::optional<const DisplayDevice*> displayOpt = std::nullopt; + if (snapshot) { + displayOpt = layerStackToDisplay.get(snapshot->outputFilter.layerStack); + } const DisplayDevice* display = displayOpt.value_or(nullptr); - layer->updateTrustedPresentationState(display, layer->getLayerSnapshot(), + layer->updateTrustedPresentationState(display, snapshot, nanoseconds_to_milliseconds(callTime), false); }); } @@ -4464,6 +4490,7 @@ bool SurfaceFlinger::applyAndCommitDisplayTransactionStates( for (const auto& [_, display] : mDisplays) { mFrontEndDisplayInfos.try_emplace(display->getLayerStack(), display->getFrontEndInfo()); } + needsTraversal = true; } return needsTraversal; @@ -4643,7 +4670,7 @@ uint32_t SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo& frameTime } } if (what & layer_state_t::eBackgroundColorChanged) { - if (layer->setBackgroundColor(s.color.rgb, s.bgColorAlpha, s.bgColorDataspace)) { + if (layer->setBackgroundColor(s.bgColor.rgb, s.bgColor.a, s.bgColorDataspace)) { flags |= eTraversalNeeded; } } @@ -4886,8 +4913,6 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f uint64_t transactionId) { layer_state_t& s = composerState.state; s.sanitize(permissions); - const nsecs_t latchTime = systemTime(); - bool unused; std::vector<ListenerCallbacks> filteredListeners; for (auto& listener : s.listeners) { @@ -4940,6 +4965,12 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f sp<CallbackHandle>::make(listener, callbackIds, s.surface)); } } + // TODO(b/238781169) remove after screenshot refactor, currently screenshots + // requires to read drawing state from binder thread. So we need to fix that + // before removing this. + if (what & layer_state_t::eCropChanged) { + if (layer->setCrop(s.crop)) flags |= eTraversalNeeded; + } if (what & layer_state_t::eSidebandStreamChanged) { if (layer->setSidebandStream(s.sidebandStream)) flags |= eTraversalNeeded; } @@ -4947,7 +4978,6 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f if (layer->setBuffer(composerState.externalTexture, *s.bufferData, postTime, desiredPresentTime, isAutoTimestamp, dequeueBufferTimestamp, frameTimelineInfo)) { - layer->latchBuffer(unused, latchTime); flags |= eTraversalNeeded; } mLayersWithQueuedFrames.emplace(layer); @@ -4960,11 +4990,22 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f s.trustedPresentationListener); } - const auto& snapshot = mLayerSnapshotBuilder.getSnapshot(layer->getSequence()); + const auto& requestedLayerState = mLayerLifecycleManager.getLayerFromId(layer->getSequence()); bool willPresentCurrentTransaction = - snapshot && (snapshot->hasReadyFrame || snapshot->sidebandStreamHasFrame); + requestedLayerState && requestedLayerState->hasReadyFrame(); if (layer->setTransactionCompletedListeners(callbackHandles, willPresentCurrentTransaction)) flags |= eTraversalNeeded; + + for (auto& snapshot : mLayerSnapshotBuilder.getSnapshots()) { + if (snapshot->path.isClone() || + !snapshot->changes.test(frontend::RequestedLayerState::Changes::FrameRate)) + continue; + auto it = mLegacyLayers.find(snapshot->sequence); + LOG_ALWAYS_FATAL_IF(it == mLegacyLayers.end(), "Couldnt find layer object for %s", + snapshot->getDebugString().c_str()); + it->second->setFrameRateForLayerTree(snapshot->frameRate); + } + return flags; } @@ -6922,7 +6963,7 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon( ->schedule([=]() { bool protectedLayerFound = false; auto layers = getLayerSnapshots(); - for (auto& [layer, layerFe] : layers) { + for (auto& [_, layerFe] : layers) { protectedLayerFound |= (layerFe->mSnapshot->isVisible && layerFe->mSnapshot->hasProtectedContent); @@ -7017,7 +7058,7 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( ATRACE_CALL(); auto layers = getLayerSnapshots(); - for (auto& [layer, layerFE] : layers) { + for (auto& [_, layerFE] : layers) { frontend::LayerSnapshot* snapshot = layerFE->mSnapshot.get(); captureResults.capturedSecureLayers |= (snapshot->isVisible && snapshot->isSecure); captureResults.capturedHdrLayers |= isHdrLayer(*snapshot); @@ -7133,6 +7174,16 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( return presentFuture; } +void SurfaceFlinger::traverseLegacyLayers(const LayerVector::Visitor& visitor) const { + if (mLayerLifecycleManagerEnabled) { + for (auto& layer : mLegacyLayers) { + visitor(layer.second.get()); + } + } else { + mDrawingState.traverse(visitor); + } +} + // --------------------------------------------------------------------------- void SurfaceFlinger::State::traverse(const LayerVector::Visitor& visitor) const { @@ -7772,27 +7823,29 @@ std::vector<std::pair<Layer*, LayerFE*>> SurfaceFlinger::moveSnapshotsToComposit std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> SurfaceFlinger::getLayerSnapshotsForScreenshots(std::optional<ui::LayerStack> layerStack, uint32_t uid) { - return [this, layerStack, uid]() { + return [&, layerStack, uid]() { std::vector<std::pair<Layer*, sp<LayerFE>>> layers; - for (auto& snapshot : mLayerSnapshotBuilder.getSnapshots()) { - if (layerStack && snapshot->outputFilter.layerStack != *layerStack) { - continue; - } - if (uid != CaptureArgs::UNSET_UID && snapshot->inputInfo.ownerUid != uid) { - continue; - } - if (!snapshot->isVisible || !snapshot->hasSomethingToDraw()) { - continue; - } + mLayerSnapshotBuilder.forEachVisibleSnapshot( + [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) { + if (layerStack && snapshot->outputFilter.layerStack != *layerStack) { + return; + } + if (uid != CaptureArgs::UNSET_UID && snapshot->inputInfo.ownerUid != uid) { + return; + } + if (!snapshot->hasSomethingToDraw()) { + return; + } - auto it = mLegacyLayers.find(snapshot->sequence); - LOG_ALWAYS_FATAL_IF(it == mLegacyLayers.end(), "Couldnt find layer object for %s", - snapshot->getDebugString().c_str()); - auto& legacyLayer = it->second; - sp<LayerFE> layerFE = getFactory().createLayerFE(legacyLayer->getName()); - layerFE->mSnapshot = std::make_unique<frontend::LayerSnapshot>(*snapshot); - layers.emplace_back(legacyLayer.get(), std::move(layerFE)); - } + auto it = mLegacyLayers.find(snapshot->sequence); + LOG_ALWAYS_FATAL_IF(it == mLegacyLayers.end(), + "Couldnt find layer object for %s", + snapshot->getDebugString().c_str()); + Layer* legacyLayer = (it == mLegacyLayers.end()) ? nullptr : it->second.get(); + sp<LayerFE> layerFE = getFactory().createLayerFE(snapshot->name); + layerFE->mSnapshot = std::make_unique<frontend::LayerSnapshot>(*snapshot); + layers.emplace_back(legacyLayer, std::move(layerFE)); + }); return layers; }; @@ -7802,11 +7855,13 @@ std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> SurfaceFlinger::getLayerSnapshotsForScreenshots(uint32_t rootLayerId, uint32_t uid, std::unordered_set<uint32_t> excludeLayerIds, bool childrenOnly, const FloatRect& parentCrop) { - return [this, excludeLayerIds = std::move(excludeLayerIds), uid, rootLayerId, childrenOnly, + return [&, rootLayerId, uid, excludeLayerIds = std::move(excludeLayerIds), childrenOnly, parentCrop]() { + auto root = mLayerHierarchyBuilder.getPartialHierarchy(rootLayerId, childrenOnly); frontend::LayerSnapshotBuilder::Args - args{.root = mLayerHierarchyBuilder.getPartialHierarchy(rootLayerId, childrenOnly), + args{.root = root, .layerLifecycleManager = mLayerLifecycleManager, + .forceUpdate = frontend::LayerSnapshotBuilder::ForceUpdateFlags::HIERARCHY, .displays = mFrontEndDisplayInfos, .displayChanges = true, .globalShadowSettings = mDrawingState.globalShadowSettings, diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index b41f414f62..adba9b86f9 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -1126,6 +1126,7 @@ private: ui::Rotation getPhysicalDisplayOrientation(DisplayId, bool isPrimary) const REQUIRES(mStateLock); + void traverseLegacyLayers(const LayerVector::Visitor& visitor) const; sp<StartPropertySetThread> mStartPropertySetThread; surfaceflinger::Factory& mFactory; diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp index 2f464873ea..e0ef8a53cf 100644 --- a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp +++ b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp @@ -220,12 +220,12 @@ proto::LayerState TransactionProtoParser::toProto(const layer_state_t& layer) { } } if (layer.what & layer_state_t::eBackgroundColorChanged) { - proto.set_bg_color_alpha(layer.bgColorAlpha); + proto.set_bg_color_alpha(layer.bgColor.a); proto.set_bg_color_dataspace(static_cast<int32_t>(layer.bgColorDataspace)); proto::LayerState_Color3* colorProto = proto.mutable_color(); - colorProto->set_r(layer.color.r); - colorProto->set_g(layer.color.g); - colorProto->set_b(layer.color.b); + colorProto->set_r(layer.bgColor.r); + colorProto->set_g(layer.bgColor.g); + colorProto->set_b(layer.bgColor.b); } if (layer.what & layer_state_t::eColorSpaceAgnosticChanged) { proto.set_color_space_agnostic(layer.colorSpaceAgnostic); @@ -501,12 +501,12 @@ void TransactionProtoParser::fromProto(const proto::LayerState& proto, layer_sta layer.windowInfoHandle = sp<gui::WindowInfoHandle>::make(inputInfo); } if (proto.what() & layer_state_t::eBackgroundColorChanged) { - layer.bgColorAlpha = proto.bg_color_alpha(); + layer.bgColor.a = proto.bg_color_alpha(); layer.bgColorDataspace = static_cast<ui::Dataspace>(proto.bg_color_dataspace()); const proto::LayerState_Color3& colorProto = proto.color(); - layer.color.r = colorProto.r(); - layer.color.g = colorProto.g(); - layer.color.b = colorProto.b(); + layer.bgColor.r = colorProto.r(); + layer.bgColor.g = colorProto.g(); + layer.bgColor.b = colorProto.b(); } if (proto.what() & layer_state_t::eColorSpaceAgnosticChanged) { layer.colorSpaceAgnostic = proto.color_space_agnostic(); diff --git a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp index bf7cae9091..0b8c51ec1d 100644 --- a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp @@ -544,6 +544,7 @@ void LayerRenderTypeTransactionTest::setBackgroundColorHelper(uint32_t layerType .apply(); { + SCOPED_TRACE("final color"); auto shot = screenshot(); shot->expectColor(Rect(0, 0, width, height), finalColor); shot->expectBorder(Rect(0, 0, width, height), Color::BLACK); diff --git a/services/surfaceflinger/tests/MirrorLayer_test.cpp b/services/surfaceflinger/tests/MirrorLayer_test.cpp index e69db7c167..0ea0824732 100644 --- a/services/surfaceflinger/tests/MirrorLayer_test.cpp +++ b/services/surfaceflinger/tests/MirrorLayer_test.cpp @@ -18,6 +18,7 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wconversion" +#include <android-base/properties.h> #include <private/android_filesystem_config.h> #include "LayerTransactionTest.h" #include "utils/TransactionUtils.h" @@ -119,15 +120,20 @@ TEST_F(MirrorLayerTest, MirrorColorLayer) { shot->expectColor(Rect(750, 750, 950, 950), Color::BLACK); } - // Remove child layer + if (base::GetBoolProperty("debug.sf.enable_legacy_frontend", true)) { + GTEST_SKIP() << "Skipping test because mirroring behavior changes with legacy frontend"; + } + + // Remove child layer and verify we can still mirror the layer when + // its offscreen. Transaction().reparent(mChildLayer, nullptr).apply(); { SCOPED_TRACE("Removed Child Layer"); auto shot = screenshot(); // Grandchild mirror - shot->expectColor(Rect(550, 550, 750, 750), Color::RED); + shot->expectColor(Rect(550, 550, 750, 750), Color::BLACK); // Child mirror - shot->expectColor(Rect(750, 750, 950, 950), Color::RED); + shot->expectColor(Rect(750, 750, 950, 950), Color::BLACK); } // Add grandchild layer to offscreen layer @@ -136,9 +142,9 @@ TEST_F(MirrorLayerTest, MirrorColorLayer) { SCOPED_TRACE("Added Grandchild Layer"); auto shot = screenshot(); // Grandchild mirror - shot->expectColor(Rect(550, 550, 750, 750), Color::RED); + shot->expectColor(Rect(550, 550, 750, 750), Color::WHITE); // Child mirror - shot->expectColor(Rect(750, 750, 950, 950), Color::RED); + shot->expectColor(Rect(750, 750, 950, 950), Color::BLACK); } // Add child layer diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.cpp b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.cpp index 763426a9f8..19164049a7 100644 --- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.cpp @@ -437,10 +437,11 @@ TEST_F(LayerHierarchyTest, backgroundLayersAreBehindParentLayer) { updateBackgroundColor(1, 0.5); UPDATE_AND_VERIFY(hierarchyBuilder); - - std::vector<uint32_t> expectedTraversalPath = {1, 1222, 11, 111, 12, 121, 122, 1221, 13, 2}; + auto bgLayerId = LayerCreationArgs::getInternalLayerId(1); + std::vector<uint32_t> expectedTraversalPath = {1, bgLayerId, 11, 111, 12, + 121, 122, 1221, 13, 2}; EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath); - expectedTraversalPath = {1222, 1, 11, 111, 12, 121, 122, 1221, 13, 2}; + expectedTraversalPath = {bgLayerId, 1, 11, 111, 12, 121, 122, 1221, 13, 2}; EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath); expectedTraversalPath = {}; EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath); diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h index 852cb91b2c..cdcc6f4eb2 100644 --- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h +++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h @@ -172,7 +172,7 @@ protected: transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged; - transactions.back().states.front().state.bgColorAlpha = alpha; + transactions.back().states.front().state.bgColor.a = alpha; transactions.back().states.front().state.surface = mHandles[id]; mLifecycleManager.applyTransactions(transactions); } diff --git a/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp b/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp index 89440a689c..99c1d23c2b 100644 --- a/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp @@ -372,7 +372,7 @@ TEST_F(LayerLifecycleManagerTest, canAddBackgroundLayer) { std::vector<TransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); - transactions.back().states.front().state.bgColorAlpha = 0.5; + transactions.back().states.front().state.bgColor.a = 0.5; transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged; sp<LayerHandle> handle = sp<LayerHandle>::make(1u); transactions.back().states.front().state.surface = handle; @@ -383,9 +383,10 @@ TEST_F(LayerLifecycleManagerTest, canAddBackgroundLayer) { EXPECT_TRUE(lifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy)); lifecycleManager.commitChanges(); - listener->expectLayersAdded({1, 2}); + auto bgLayerId = LayerCreationArgs::getInternalLayerId(1); + listener->expectLayersAdded({1, bgLayerId}); listener->expectLayersDestroyed({}); - EXPECT_EQ(getRequestedLayerState(lifecycleManager, 2)->color.a, 0.5_hf); + EXPECT_EQ(getRequestedLayerState(lifecycleManager, bgLayerId)->color.a, 0.5_hf); } TEST_F(LayerLifecycleManagerTest, canDestroyBackgroundLayer) { @@ -400,13 +401,13 @@ TEST_F(LayerLifecycleManagerTest, canDestroyBackgroundLayer) { std::vector<TransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); - transactions.back().states.front().state.bgColorAlpha = 0.5; + transactions.back().states.front().state.bgColor.a = 0.5; transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged; sp<LayerHandle> handle = sp<LayerHandle>::make(1u); transactions.back().states.front().state.surface = handle; transactions.emplace_back(); transactions.back().states.push_back({}); - transactions.back().states.front().state.bgColorAlpha = 0; + transactions.back().states.front().state.bgColor.a = 0; transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged; transactions.back().states.front().state.surface = handle; @@ -417,8 +418,9 @@ TEST_F(LayerLifecycleManagerTest, canDestroyBackgroundLayer) { EXPECT_TRUE(lifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy)); lifecycleManager.commitChanges(); - listener->expectLayersAdded({1, 2}); - listener->expectLayersDestroyed({2}); + auto bgLayerId = LayerCreationArgs::getInternalLayerId(1); + listener->expectLayersAdded({1, bgLayerId}); + listener->expectLayersDestroyed({bgLayerId}); } TEST_F(LayerLifecycleManagerTest, onParentDestroyDestroysBackgroundLayer) { @@ -433,7 +435,7 @@ TEST_F(LayerLifecycleManagerTest, onParentDestroyDestroysBackgroundLayer) { std::vector<TransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); - transactions.back().states.front().state.bgColorAlpha = 0.5; + transactions.back().states.front().state.bgColor.a = 0.5; transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged; sp<LayerHandle> handle = sp<LayerHandle>::make(1u); transactions.back().states.front().state.surface = handle; @@ -446,8 +448,9 @@ TEST_F(LayerLifecycleManagerTest, onParentDestroyDestroysBackgroundLayer) { EXPECT_TRUE(lifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy)); lifecycleManager.commitChanges(); - listener->expectLayersAdded({1, 2}); - listener->expectLayersDestroyed({1, 2}); + auto bgLayerId = LayerCreationArgs::getInternalLayerId(1); + listener->expectLayersAdded({1, bgLayerId}); + listener->expectLayersDestroyed({1, bgLayerId}); } } // namespace android::surfaceflinger::frontend |