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

Commit 2c5f6d22 authored by Robert Carr's avatar Robert Carr
Browse files

SurfaceFlinger: Implement merging of transaction objects.

Useful for WindowManager to collect multiple transactions
from independent units.

Test: Transaction_test.cpp
Change-Id: I52e89b038e3b375493169991e41cb75b67550264
parent 026bb7e0
Loading
Loading
Loading
Loading
+96 −0
Original line number Diff line number Diff line
@@ -136,5 +136,101 @@ status_t DisplayState::read(const Parcel& input) {
    return NO_ERROR;
}

void DisplayState::merge(const DisplayState& other) {
    if (other.what & eSurfaceChanged) {
        what |= eSurfaceChanged;
        surface = other.surface;
    }
    if (other.what & eLayerStackChanged) {
        what |= eLayerStackChanged;
        layerStack = other.layerStack;
    }
    if (other.what & eDisplayProjectionChanged) {
        what |= eDisplayProjectionChanged;
        orientation = other.orientation;
        viewport = other.viewport;
        frame = other.frame;
    }
    if (other.what & eDisplaySizeChanged) {
        what |= eDisplaySizeChanged;
        width = other.width;
        height = other.height;
    }
}

void layer_state_t::merge(const layer_state_t& other) {
    if (other.what & ePositionChanged) {
        what |= ePositionChanged;
        x = other.x;
        y = other.y;
    }
    if (other.what & eLayerChanged) {
        what |= eLayerChanged;
        z = other.z;
    }
    if (other.what & eSizeChanged) {
        what |= eSizeChanged;
        w = other.w;
        h = other.h;
    }
    if (other.what & eAlphaChanged) {
        what |= eAlphaChanged;
        alpha = other.alpha;
    }
    if (other.what & eMatrixChanged) {
        what |= eMatrixChanged;
        matrix = other.matrix;
    }
    if (other.what & eTransparentRegionChanged) {
        what |= eTransparentRegionChanged;
        transparentRegion = other.transparentRegion;
    }
    if (other.what & eFlagsChanged) {
        what |= eFlagsChanged;
        flags = other.flags;
        mask = other.mask;
    }
    if (other.what & eLayerStackChanged) {
        what |= eLayerStackChanged;
        layerStack = other.layerStack;
    }
    if (other.what & eCropChanged) {
        what |= eCropChanged;
        crop = other.crop;
    }
    if (other.what & eDeferTransaction) {
        what |= eDeferTransaction;
        barrierHandle = other.barrierHandle;
        barrierGbp = other.barrierGbp;
        frameNumber = other.frameNumber;
    }
    if (other.what & eFinalCropChanged) {
        what |= eFinalCropChanged;
        finalCrop = other.finalCrop;
    }
    if (other.what & eOverrideScalingModeChanged) {
        what |= eOverrideScalingModeChanged;
        overrideScalingMode = other.overrideScalingMode;
    }
    if (other.what & eGeometryAppliesWithResize) {
        what |= eGeometryAppliesWithResize;
    }
    if (other.what & eReparentChildren) {
        what |= eReparentChildren;
        reparentHandle = other.reparentHandle;
    }
    if (other.what & eDetachChildren) {
        what |= eDetachChildren;
    }
    if (other.what & eRelativeLayerChanged) {
        what |= eRelativeLayerChanged;
        z = other.z;
        relativeLayerHandle = other.relativeLayerHandle;
    }
    if (other.what & eReparent) {
        what |= eReparent;
        parentHandleForChild = other.parentHandleForChild;
    }
}

}; // namespace android
+24 −0
Original line number Diff line number Diff line
@@ -104,6 +104,30 @@ SurfaceComposerClient::Transaction::Transaction(const Transaction& other) :
    mComposerStates = other.mComposerStates;
}

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) {
    for (auto const& state : other.mComposerStates) {
        ssize_t index = mComposerStates.indexOf(state);
        if (index < 0) {
            mComposerStates.add(state);
        } else {
            mComposerStates.editItemAt(static_cast<size_t>(index)).state.merge(state.state);
        }
    }
    other.mComposerStates.clear();

    for (auto const& state : other.mDisplayStates) {
        ssize_t index = mDisplayStates.indexOf(state);
        if (index < 0) {
            mDisplayStates.add(state);
        } else {
            mDisplayStates.editItemAt(static_cast<size_t>(index)).merge(state);
        }
    }
    other.mDisplayStates.clear();

    return *this;
}

status_t SurfaceComposerClient::Transaction::apply(bool synchronous) {
    if (mStatus != NO_ERROR) {
        return mStatus;
+2 −0
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ struct layer_state_t {
        matrix.dsdy = matrix.dtdx = 0.0f;
    }

    void merge(const layer_state_t& other);
    status_t    write(Parcel& output) const;
    status_t    read(const Parcel& input);

@@ -144,6 +145,7 @@ struct DisplayState {
    };

    DisplayState();
    void merge(const DisplayState& other);

    uint32_t what;
    sp<IBinder> token;
+3 −3
Original line number Diff line number Diff line
@@ -144,7 +144,9 @@ public:
        Transaction(Transaction const& other);

        status_t apply(bool synchronous = false);

        // Merge another transaction in to this one, clearing other
        // as if it had been applied.
        Transaction& merge(Transaction&& other);
        Transaction& show(const sp<SurfaceControl>& sc);
        Transaction& hide(const sp<SurfaceControl>& sc);
        Transaction& setPosition(const sp<SurfaceControl>& sc,
@@ -175,8 +177,6 @@ public:
                float alpha);
        Transaction& setMatrix(const sp<SurfaceControl>& sc,
                float dsdx, float dtdx, float dtdy, float dsdy);
        Transaction& setOrientation(const sp<SurfaceControl>& sc,
                const Rect& crop);
        Transaction& setCrop(const sp<SurfaceControl>& sc, const Rect& crop);
        Transaction& setFinalCrop(const sp<SurfaceControl>& sc, const Rect& crop);
        Transaction& setLayerStack(const sp<SurfaceControl>& sc, uint32_t layerStack);
+24 −0
Original line number Diff line number Diff line
@@ -891,6 +891,30 @@ TEST_F(LayerUpdateTest, LayerWithNoBuffersResizesImmediately) {
    }
}

TEST_F(LayerUpdateTest, MergingTransactions) {
    sp<ScreenCapture> sc;
    {
        SCOPED_TRACE("before move");
        ScreenCapture::captureScreen(&sc);
        sc->expectBGColor(0, 12);
        sc->expectFGColor(75, 75);
        sc->expectBGColor(145, 145);
    }

    Transaction t1, t2;
    t1.setPosition(mFGSurfaceControl, 128, 128);
    t2.setPosition(mFGSurfaceControl, 0, 0);
    // We expect that the position update from t2 now
    // overwrites the position update from t1.
    t1.merge(std::move(t2));
    t1.apply();

    {
        ScreenCapture::captureScreen(&sc);
        sc->expectFGColor(1, 1);
    }
}

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