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

Commit e392b55d authored by Robert Carr's avatar Robert Carr
Browse files

SurfaceFlinger: Avoid entering resize-pending state when we don't have a buffer.

We'd like bufferless Surfaces to always behave as if it were scaling mode SCALE_TO_WINDOW.
Some additional discussion in inline comment.

Test: Transaction_test.cpp
Change-Id: Ifb176b7b05954c1d3d9ee885cb8f4c51559b922b
parent 931dc01a
Loading
Loading
Loading
Loading
+20 −15
Original line number Diff line number Diff line
@@ -1687,23 +1687,28 @@ uint32_t Layer::doTransaction(uint32_t flags) {
                c.requested.w, c.requested.h);
    }

    const bool resizePending = (c.requested.w != c.active.w) ||
            (c.requested.h != c.active.h);
    if (!isFixedSize()) {
        if (resizePending && mSidebandStream == NULL) {
            // don't let Layer::doTransaction update the drawing state
    // Don't let Layer::doTransaction update the drawing state
    // if we have a pending resize, unless we are in fixed-size mode.
    // the drawing state will be updated only once we receive a buffer
    // with the correct size.
    //
            // in particular, we want to make sure the clip (which is part
    // In particular, we want to make sure the clip (which is part
    // of the geometry state) is latched together with the size but is
    // latched immediately when no resizing is involved.
    //
    // If a sideband stream is attached, however, we want to skip this
    // optimization so that transactions aren't missed when a buffer
    // never arrives

    //
    // In the case that we don't have a buffer we ignore other factors
    // and avoid entering the resizePending state. At a high level the
    // resizePending state is to avoid applying the state of the new buffer
    // to the old buffer. However in the state where we don't have an old buffer
    // there is no such concern but we may still be being used as a parent layer.
    const bool resizePending = ((c.requested.w != c.active.w) ||
            (c.requested.h != c.active.h)) && (mActiveBuffer != nullptr);
    if (!isFixedSize()) {
        if (resizePending && mSidebandStream == NULL) {
            flags |= eDontUpdateGeometryState;
        }
    }
+35 −0
Original line number Diff line number Diff line
@@ -788,6 +788,41 @@ TEST_F(LayerUpdateTest, LayerSetRelativeLayerWorks) {
    }
}

TEST_F(LayerUpdateTest, LayerWithNoBuffersResizesImmediately) {
    sp<ScreenCapture> sc;

    sp<SurfaceControl> childNoBuffer =
        mComposerClient->createSurface(String8("Bufferless child"),
                10, 10, PIXEL_FORMAT_RGBA_8888,
                0, mFGSurfaceControl.get());
    sp<SurfaceControl> childBuffer = mComposerClient->createSurface(
            String8("Buffered child"), 20, 20,
            PIXEL_FORMAT_RGBA_8888, 0, childNoBuffer.get());
    fillSurfaceRGBA8(childBuffer, 200, 200, 200);

    SurfaceComposerClient::openGlobalTransaction();
    childNoBuffer->show();
    childBuffer->show();
    SurfaceComposerClient::closeGlobalTransaction();


    {
        ScreenCapture::captureScreen(&sc);
        sc->expectChildColor(73, 73);
        sc->expectFGColor(74, 74);
    }

    SurfaceComposerClient::openGlobalTransaction();
    childNoBuffer->setSize(20, 20);
    SurfaceComposerClient::closeGlobalTransaction(true);

    {
        ScreenCapture::captureScreen(&sc);
        sc->expectChildColor(73, 73);
        sc->expectChildColor(74, 74);
    }
}

class ChildLayerTest : public LayerUpdateTest {
protected:
    void SetUp() override {