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

Commit 93e53e09 authored by Chris Craik's avatar Chris Craik
Browse files

Fix merged op clipping issue

Change-Id: I48cd5e92f3e62dcd189a4411a71aa7a40ce5498c
parent 3a0ea625
Loading
Loading
Loading
Loading
+6 −12
Original line number Diff line number Diff line
@@ -91,8 +91,7 @@ public:

    MergingOpBatch(batchid_t batchId, BakedOpState* op)
            : BatchBase(batchId, op, true)
            , mClipSideFlags(op->computedState.clipSideFlags)
            , mClipRect(op->computedState.clipRect) {
            , mClipSideFlags(op->computedState.clipSideFlags) {
    }

    /*
@@ -194,22 +193,17 @@ public:
        mBounds.unionWith(op->computedState.clippedBounds);
        mOps.push_back(op);

        const int newClipSideFlags = op->computedState.clipSideFlags;
        mClipSideFlags |= newClipSideFlags;

        const Rect& opClip = op->computedState.clipRect;
        if (newClipSideFlags & OpClipSideFlags::Left) mClipRect.left = opClip.left;
        if (newClipSideFlags & OpClipSideFlags::Top) mClipRect.top = opClip.top;
        if (newClipSideFlags & OpClipSideFlags::Right) mClipRect.right = opClip.right;
        if (newClipSideFlags & OpClipSideFlags::Bottom) mClipRect.bottom = opClip.bottom;
        // Because a new op must have passed canMergeWith(), we know it's passed the clipping compat
        // check, and doesn't extend past a side of the clip that's in use by the merged batch.
        // Therefore it's safe to simply always merge flags, and use the bounds as the clip rect.
        mClipSideFlags |= op->computedState.clipSideFlags;
    }

    int getClipSideFlags() const { return mClipSideFlags; }
    const Rect& getClipRect() const { return mClipRect; }
    const Rect& getClipRect() const { return mBounds; }

private:
    int mClipSideFlags;
    Rect mClipRect;
};

OpReorderer::LayerReorderer::LayerReorderer(uint32_t width, uint32_t height,
+40 −0
Original line number Diff line number Diff line
@@ -222,6 +222,46 @@ TEST(OpReorderer, simpleBatching) {
            << "Expect number of ops = 2 * loop count";
}

TEST(OpReorderer, clippedMerging) {
    class ClippedMergingTestRenderer : public TestRendererBase {
    public:
        void onMergedBitmapOps(const MergedBakedOpList& opList) override {
            EXPECT_EQ(0, mIndex);
            mIndex += opList.count;
            EXPECT_EQ(4u, opList.count);
            EXPECT_EQ(Rect(10, 10, 90, 90), opList.clip);
            EXPECT_EQ(OpClipSideFlags::Left | OpClipSideFlags::Top | OpClipSideFlags::Right,
                    opList.clipSideFlags);
        }
    };
    auto node = TestUtils::createNode(0, 0, 100, 100,
            [](RenderProperties& props, TestCanvas& canvas) {
        SkBitmap bitmap = TestUtils::createSkBitmap(20, 20);

        // left side clipped (to inset left half)
        canvas.clipRect(10, 0, 50, 100, SkRegion::kReplace_Op);
        canvas.drawBitmap(bitmap, 0, 40, nullptr);

        // top side clipped (to inset top half)
        canvas.clipRect(0, 10, 100, 50, SkRegion::kReplace_Op);
        canvas.drawBitmap(bitmap, 40, 0, nullptr);

        // right side clipped (to inset right half)
        canvas.clipRect(50, 0, 90, 100, SkRegion::kReplace_Op);
        canvas.drawBitmap(bitmap, 80, 40, nullptr);

        // bottom not clipped, just abutting (inset bottom half)
        canvas.clipRect(0, 50, 100, 90, SkRegion::kReplace_Op);
        canvas.drawBitmap(bitmap, 40, 70, nullptr);
    });

    OpReorderer reorderer(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 100), 100, 100,
            createSyncedNodeList(node), sLightCenter);
    ClippedMergingTestRenderer renderer;
    reorderer.replayBakedOps<TestDispatcher>(renderer);
    EXPECT_EQ(4, renderer.getIndex());
}

TEST(OpReorderer, textMerging) {
    class TextMergingTestRenderer : public TestRendererBase {
    public: