Merge "Fix merged op clipping issue"
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user