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

Commit 9b429f41 authored by Robert Carr's avatar Robert Carr
Browse files

SurfaceFlinger: Inherit non-transform Scaling from parent.

When a Layer is fixed-size, we may apply additional scaling
to the buffer not accounted for in the transform. This means
that if the WindowManager calls setSize we will scale the parent
surface but not the child surfaces, breaking the contract that
the WM can treat the child surfaces as pixels in the parent.

Test: Included test in Transaction_test.
Bug: 36820947
Bug: 37344435
Change-Id: I5478bad176388fe8e5407379bc36cdfd6600ab97
parent d537b474
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -2617,6 +2617,21 @@ Transform Layer::getTransform() const {
    const auto& p = getParent();
    if (p != nullptr) {
        t = p->getTransform();

        // If the parent is not using NATIVE_WINDOW_SCALING_MODE_FREEZE (e.g.
        // it isFixedSize) then there may be additional scaling not accounted
        // for in the transform. We need to mirror this scaling in child surfaces
        // or we will break the contract where WM can treat child surfaces as
        // pixels in the parent surface.
        if (p->isFixedSize()) {
            float sx = p->getDrawingState().active.w /
                    static_cast<float>(p->mActiveBuffer->getWidth());
            float sy = p->getDrawingState().active.h /
                    static_cast<float>(p->mActiveBuffer->getHeight());
            Transform extraParentScaling;
            extraParentScaling.set(sx, 0, 0, sy);
            t = t * extraParentScaling;
        }
    }
    return t * getDrawingState().active.transform;
}
+32 −0
Original line number Diff line number Diff line
@@ -909,4 +909,36 @@ TEST_F(ChildLayerTest, DetachChildren) {
    }
}

TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) {
    SurfaceComposerClient::openGlobalTransaction();
    mChild->show();
    mChild->setPosition(0, 0);
    mFGSurfaceControl->setPosition(0, 0);
    SurfaceComposerClient::closeGlobalTransaction(true);

    {
        ScreenCapture::captureScreen(&mCapture);
        // We've positioned the child in the top left.
        mCapture->expectChildColor(0, 0);
        // But it's only 10x10.
        mCapture->expectFGColor(10, 10);
    }

    SurfaceComposerClient::openGlobalTransaction();
    mFGSurfaceControl->setOverrideScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
    // We cause scaling by 2.
    mFGSurfaceControl->setSize(128, 128);
    SurfaceComposerClient::closeGlobalTransaction();

    {
        ScreenCapture::captureScreen(&mCapture);
        // We've positioned the child in the top left.
        mCapture->expectChildColor(0, 0);
        mCapture->expectChildColor(10, 10);
        mCapture->expectChildColor(19, 19);
        // And now it should be scaled all the way to 20x20
        mCapture->expectFGColor(20, 20);
    }
}

}