Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 91282082 authored by YCairn Overturf's avatar YCairn Overturf
Browse files

Force snapshot update when requested transform changes from invalid to valid

An early out in snapshot builder prevents parent properties from being propagated to children when the parent is hidden (e.g. due to invalid transform).
So we need to force update children snapshots when the parent becomes visible (i.e. transform becomes valid).

I tested removing the early out but the added benchmark takes 2us longer.

Bug: 319757092
Flag: EXEMPT bug fix
Test: atest libsurfaceflinger_unittests
Change-Id: I9c9a996bbc3de4e7f8cbfc947a99cdccae5090b9
parent 4a902602
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -147,6 +147,7 @@ RequestedLayerState::RequestedLayerState(const LayerCreationArgs& args)
}

void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerState) {
    bool transformWasValid = transformIsValid;
    const uint32_t oldFlags = flags;
    const half oldAlpha = color.a;
    const bool hadBuffer = externalTexture != nullptr;
@@ -354,6 +355,14 @@ void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerSta
        clientDrawnCornerRadius = clientState.clientDrawnCornerRadius;
        changes |= RequestedLayerState::Changes::Geometry;
    }

    // We can't just check requestedTransform here because LayerSnapshotBuilder uses
    // getTransform which reads destinationFrame or buffer dimensions.
    // Display rotation does not affect validity so just use ROT_0.
    transformIsValid = LayerSnapshot::isTransformValid(getTransform(ui::Transform::ROT_0));
    if (!transformWasValid && transformIsValid) {
        changes |= RequestedLayerState::Changes::Visibility;
    }
}

ui::Size RequestedLayerState::getUnrotatedBufferSize(uint32_t displayRotationFlags) const {
+1 −0
Original line number Diff line number Diff line
@@ -115,6 +115,7 @@ struct RequestedLayerState : layer_state_t {
    const gui::Pid ownerPid;
    bool dataspaceRequested;
    bool hasColorTransform;
    bool transformIsValid = true;
    bool premultipliedAlpha{true};
    // This layer can be a cursor on some displays.
    bool potentialCursor{false};
+41 −0
Original line number Diff line number Diff line
@@ -90,5 +90,46 @@ static void updateClientStatesNoChanges(benchmark::State& state) {
}
BENCHMARK(updateClientStatesNoChanges);

static void propagateManyHiddenChildren(benchmark::State& state) {
    LayerLifecycleManager lifecycleManager;
    LayerLifecycleManagerHelper helper(lifecycleManager);

    helper.createRootLayer(0);
    for (uint32_t i = 1; i < 50; ++i) {
        helper.createLayer(i, i - 1);
    }

    helper.hideLayer(0);

    LayerHierarchyBuilder hierarchyBuilder;
    DisplayInfo info;
    info.info.logicalHeight = 100;
    info.info.logicalWidth = 100;
    DisplayInfos displayInfos;
    displayInfos.emplace_or_replace(ui::LayerStack::fromValue(1), info);
    ShadowSettings globalShadowSettings;

    LayerSnapshotBuilder snapshotBuilder;

    int i = 1;
    for (auto _ : state) {
        i++;
        helper.setAlpha(0, (1 + (i % 255)) / 255.0f);

        if (lifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy)) {
            hierarchyBuilder.update(lifecycleManager);
        }
        LayerSnapshotBuilder::Args args{.root = hierarchyBuilder.getHierarchy(),
                                        .layerLifecycleManager = lifecycleManager,
                                        .displays = displayInfos,
                                        .globalShadowSettings = globalShadowSettings,
                                        .supportedLayerGenericMetadata = {},
                                        .genericLayerMetadataKeyMap = {}};
        snapshotBuilder.update(args);
        lifecycleManager.commitChanges();
    }
}
BENCHMARK(propagateManyHiddenChildren);

} // namespace
} // namespace android::surfaceflinger
+34 −0
Original line number Diff line number Diff line
@@ -261,6 +261,40 @@ TEST_F(LayerSnapshotTest, AlphaInheritedByChildren) {
    EXPECT_EQ(getSnapshot(1221)->alpha, 0.25f);
}

TEST_F(LayerSnapshotTest, AlphaInheritedByChildWhenParentIsHiddenByInvalidTransform) {
    setMatrix(1, 0, 0, 0, 0);
    update(mSnapshotBuilder);
    mLifecycleManager.commitChanges();

    setAlpha(1, 0.5);
    update(mSnapshotBuilder);
    mLifecycleManager.commitChanges();

    setMatrix(1, 1, 0, 0, 1);
    update(mSnapshotBuilder);
    mLifecycleManager.commitChanges();

    EXPECT_EQ(getSnapshot(1)->alpha, 0.5f);
    EXPECT_EQ(getSnapshot(11)->alpha, 0.5f);
}

TEST_F(LayerSnapshotTest, AlphaInheritedByChildWhenParentIsHidden) {
    hideLayer(1);
    update(mSnapshotBuilder);
    mLifecycleManager.commitChanges();

    setAlpha(1, 0.5);
    update(mSnapshotBuilder);
    mLifecycleManager.commitChanges();

    showLayer(1);
    update(mSnapshotBuilder);
    mLifecycleManager.commitChanges();

    EXPECT_EQ(getSnapshot(1)->alpha, 0.5f);
    EXPECT_EQ(getSnapshot(11)->alpha, 0.5f);
}

// Change states
TEST_F(LayerSnapshotTest, UpdateClearsPreviousChangeStates) {
    setCrop(1, Rect(1, 2, 3, 4));