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

Commit 93e26b95 authored by Vishnu Nair's avatar Vishnu Nair
Browse files

Set visible region dirty flag when alpha changes

Removes an optimzation which only set the
visible region dirty flag when alpha changed
from 1->0 or 0->1. This optimization broke an
assumption in CE. Alpha is only passed to HWC
when there are geometry changes which are
tracked by the visible region dirty flag.

Fixes: 299256533
Test: presubmit
Test: dim layer alpha animates when showing a dialog
Change-Id: I4c56171d19d582e26b9c2c7be6c555a6c1d7494c
parent a387c08f
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -277,8 +277,8 @@ struct layer_state_t {
            layer_state_t::eLayerStackChanged;

    // Changes that affect the visible region on a display.
    static constexpr uint64_t VISIBLE_REGION_CHANGES =
            layer_state_t::GEOMETRY_CHANGES | layer_state_t::HIERARCHY_CHANGES;
    static constexpr uint64_t VISIBLE_REGION_CHANGES = layer_state_t::GEOMETRY_CHANGES |
            layer_state_t::HIERARCHY_CHANGES | layer_state_t::eAlphaChanged;

    bool hasValidBuffer() const;
    void sanitize(int32_t permissions);
+1 −2
Original line number Diff line number Diff line
@@ -237,8 +237,7 @@ void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerSta
    }
    if (what & (layer_state_t::eAlphaChanged)) {
        if (oldAlpha == 0 || color.a == 0) {
            changes |= RequestedLayerState::Changes::Visibility |
                    RequestedLayerState::Changes::VisibleRegion;
            changes |= RequestedLayerState::Changes::Visibility;
        }
    }

+35 −0
Original line number Diff line number Diff line
@@ -525,4 +525,39 @@ TEST_F(LayerLifecycleManagerTest, roundedCornerChangesSetsVisibilityChangeFlag)
    mLifecycleManager.commitChanges();
}

// Even when it does not change visible region, we should mark alpha changes as affecting
// visible region because HWC impl depends on it. writeOutputIndependentGeometryStateToHWC
// is only called if we are updating geometry.
TEST_F(LayerLifecycleManagerTest, alphaChangesAlwaysSetsVisibleRegionFlag) {
    mLifecycleManager.commitChanges();
    float startingAlpha = 0.5f;
    setAlpha(1, startingAlpha);

    // this is expected because layer alpha changes from 1 to 0.5, it may no longer be opaque
    EXPECT_EQ(mLifecycleManager.getGlobalChanges().string(),
              ftl::Flags<RequestedLayerState::Changes>(
                      RequestedLayerState::Changes::Content |
                      RequestedLayerState::Changes::AffectsChildren |
                      RequestedLayerState::Changes::VisibleRegion)
                      .string());
    EXPECT_EQ(mLifecycleManager.getChangedLayers()[0]->color.a, static_cast<half>(startingAlpha));
    mLifecycleManager.commitChanges();

    float endingAlpha = 0.2f;
    setAlpha(1, endingAlpha);

    // this is not expected but we should make sure this behavior does not change
    EXPECT_EQ(mLifecycleManager.getGlobalChanges().string(),
              ftl::Flags<RequestedLayerState::Changes>(
                      RequestedLayerState::Changes::Content |
                      RequestedLayerState::Changes::AffectsChildren |
                      RequestedLayerState::Changes::VisibleRegion)
                      .string());
    EXPECT_EQ(mLifecycleManager.getChangedLayers()[0]->color.a, static_cast<half>(endingAlpha));
    mLifecycleManager.commitChanges();

    EXPECT_EQ(mLifecycleManager.getGlobalChanges().string(),
              ftl::Flags<RequestedLayerState::Changes>().string());
}

} // namespace android::surfaceflinger::frontend