From bf27b995ae1bc36ee0b24effcaf41ec477e7fae3 Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Wed, 13 Apr 2016 15:57:46 -0700 Subject: [PATCH] Avoid reentrance on ClipArea APIs bug:28144676 Calling ClipArea::clipRegion from within ClipArea::clipPathWithTransform has us handling op-based special casing twice, which caused all clip paths to appear to be replace ops. Change-Id: Ib842db53ffed4eee29470f773d59a3a1d07a1a0e --- libs/hwui/ClipArea.cpp | 4 +++- libs/hwui/tests/unit/ClipAreaTests.cpp | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/libs/hwui/ClipArea.cpp b/libs/hwui/ClipArea.cpp index 35fe06dc5e21..fe6823925083 100644 --- a/libs/hwui/ClipArea.cpp +++ b/libs/hwui/ClipArea.cpp @@ -253,7 +253,9 @@ void ClipArea::clipPathWithTransform(const SkPath& path, const mat4* transform, path.transform(skTransform, &transformed); SkRegion region; regionFromPath(transformed, region); - clipRegion(region, op); + enterRegionMode(); + mClipRegion.op(region, op); + onClipRegionUpdated(); } /* diff --git a/libs/hwui/tests/unit/ClipAreaTests.cpp b/libs/hwui/tests/unit/ClipAreaTests.cpp index b864703348b9..54ca68d63dbe 100644 --- a/libs/hwui/tests/unit/ClipAreaTests.cpp +++ b/libs/hwui/tests/unit/ClipAreaTests.cpp @@ -132,6 +132,7 @@ TEST(ClipArea, serializeClip) { auto serializedClip = area.serializeClip(allocator); ASSERT_NE(nullptr, serializedClip); ASSERT_EQ(ClipMode::Rectangle, serializedClip->mode); + ASSERT_FALSE(serializedClip->intersectWithRoot) << "No replace, so no intersectWithRoot"; EXPECT_EQ(Rect(200, 200), serializedClip->rect); EXPECT_EQ(serializedClip, area.serializeClip(allocator)) << "Requery of clip on unmodified ClipArea must return same pointer."; @@ -145,6 +146,7 @@ TEST(ClipArea, serializeClip) { auto serializedClip = area.serializeClip(allocator); ASSERT_NE(nullptr, serializedClip); ASSERT_EQ(ClipMode::RectangleList, serializedClip->mode); + ASSERT_FALSE(serializedClip->intersectWithRoot) << "No replace, so no intersectWithRoot"; auto clipRectList = reinterpret_cast(serializedClip); EXPECT_EQ(2, clipRectList->rectList.getTransformedRectanglesCount()); EXPECT_EQ(Rect(37, 54, 145, 163), clipRectList->rect); @@ -160,6 +162,7 @@ TEST(ClipArea, serializeClip) { auto serializedClip = area.serializeClip(allocator); ASSERT_NE(nullptr, serializedClip); ASSERT_EQ(ClipMode::Region, serializedClip->mode); + ASSERT_TRUE(serializedClip->intersectWithRoot) << "Replace op, so expect intersectWithRoot"; auto clipRegion = reinterpret_cast(serializedClip); EXPECT_EQ(SkIRect::MakeWH(200, 200), clipRegion->region.getBounds()) << "Clip region should be 200x200"; @@ -169,6 +172,18 @@ TEST(ClipArea, serializeClip) { } } +TEST(ClipArea, serializeClip_pathIntersectWithRoot) { + ClipArea area(createClipArea()); + LinearAllocator allocator; + SkPath circlePath; + circlePath.addCircle(100, 100, 100); + area.clipPathWithTransform(circlePath, &Matrix4::identity(), SkRegion::kIntersect_Op); + + auto serializedClip = area.serializeClip(allocator); + ASSERT_NE(nullptr, serializedClip); + EXPECT_FALSE(serializedClip->intersectWithRoot) << "No replace, so no intersectWithRoot"; +} + TEST(ClipArea, serializeIntersectedClip) { ClipArea area(createClipArea()); LinearAllocator allocator; -- 2.11.0