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

Commit 3237758d authored by chaviw's avatar chaviw
Browse files

Don't allow both setRelative and setLayer for the same surface.

Both setRelativeLayer and setLayer are used to set z order. The two will
conflict if set on the same transaction for the same surface.
SurfaceFlinger will just apply setRelativeLayer since it's second in the
setClientState order. Instead, the code should only apply the
transaction that was requested last. This change removes the
setRelativeLayer flag if the setLayer flag is added and vice-versa.

Fixes: 131834423
Test: Steps from bug
Test: LayerTypeTransactionTest.SetLayerAndRelative
Change-Id: Ib14aa5c666e74455e5ccb26a0fea94699bcc5771
parent 6dec1db0
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -245,6 +245,7 @@ void layer_state_t::merge(const layer_state_t& other) {
    }
    if (other.what & eLayerChanged) {
        what |= eLayerChanged;
        what &= ~eRelativeLayerChanged;
        z = other.z;
    }
    if (other.what & eSizeChanged) {
@@ -303,6 +304,7 @@ void layer_state_t::merge(const layer_state_t& other) {
    }
    if (other.what & eRelativeLayerChanged) {
        what |= eRelativeLayerChanged;
        what &= ~eLayerChanged;
        z = other.z;
        relativeLayerHandle = other.relativeLayerHandle;
    }
+2 −0
Original line number Diff line number Diff line
@@ -611,6 +611,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer
        return *this;
    }
    s->what |= layer_state_t::eLayerChanged;
    s->what &= ~layer_state_t::eRelativeLayerChanged;
    s->z = z;

    registerSurfaceControlForCallback(sc);
@@ -624,6 +625,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setRelat
        mStatus = BAD_INDEX;
    }
    s->what |= layer_state_t::eRelativeLayerChanged;
    s->what &= ~layer_state_t::eLayerChanged;
    s->relativeLayerHandle = relativeTo;
    s->z = z;

+47 −0
Original line number Diff line number Diff line
@@ -1056,6 +1056,53 @@ TEST_P(LayerTypeTransactionTest, SetRelativeZNegative) {
    screenshot->expectColor(Rect(0, 0, 32, 32), Color::BLUE);
}

TEST_P(LayerTypeTransactionTest, SetLayerAndRelative) {
    sp<SurfaceControl> parent =
            LayerTransactionTest::createLayer("Parent", 0 /* buffer width */, 0 /* buffer height */,
                                              ISurfaceComposerClient::eFXSurfaceColor);

    sp<SurfaceControl> childLayer;
    ASSERT_NO_FATAL_FAILURE(
            childLayer = LayerTransactionTest::createLayer("childLayer", 0 /* buffer width */,
                                                           0 /* buffer height */,
                                                           ISurfaceComposerClient::eFXSurfaceColor,
                                                           parent.get()));
    Transaction()
            .setColor(childLayer, half3{1.0f, 0.0f, 0.0f})
            .setColor(parent, half3{0.0f, 0.0f, 0.0f})
            .show(childLayer)
            .show(parent)
            .setCrop_legacy(parent, Rect(0, 0, mDisplayWidth, mDisplayHeight))
            .setCrop_legacy(childLayer, Rect(0, 0, 20, 30))
            .apply();

    Transaction()
            .setRelativeLayer(childLayer, parent->getHandle(), -1)
            .setLayer(childLayer, 1)
            .apply();

    {
        SCOPED_TRACE("setLayer above");
        // Set layer should get applied and place the child above.
        std::unique_ptr<ScreenCapture> screenshot;
        ScreenCapture::captureScreen(&screenshot);
        screenshot->expectColor(Rect(0, 0, 20, 30), Color::RED);
    }

    Transaction()
            .setLayer(childLayer, 1)
            .setRelativeLayer(childLayer, parent->getHandle(), -1)
            .apply();

    {
        SCOPED_TRACE("setRelative below");
        // Set relative layer should get applied and place the child below.
        std::unique_ptr<ScreenCapture> screenshot;
        ScreenCapture::captureScreen(&screenshot);
        screenshot->expectColor(Rect(0, 0, 20, 30), Color::BLACK);
    }
}

void LayerRenderTypeTransactionTest::setRelativeZGroupHelper(uint32_t layerType) {
    sp<SurfaceControl> layerR;
    sp<SurfaceControl> layerG;