summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chris Craik <ccraik@google.com> 2016-02-04 19:08:59 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2016-02-04 19:08:59 +0000
commit37fd29f2842c4b92ba3ddbba2f9a5024ce103783 (patch)
tree9d6540a664b974f36961ddd0eff8802681779b38
parentc8ca8ceba067e5f439560275fd9529646f2b569a (diff)
parent7fc1b0349bc2ac8c880120dc5611f703faa7f06f (diff)
Merge "Fix ripple clipping + quick rejection"
-rw-r--r--libs/hwui/ClipArea.cpp3
-rw-r--r--libs/hwui/FrameBuilder.cpp4
-rw-r--r--libs/hwui/tests/unit/RecordingCanvasTests.cpp17
3 files changed, 23 insertions, 1 deletions
diff --git a/libs/hwui/ClipArea.cpp b/libs/hwui/ClipArea.cpp
index 160090dcd8cc..9c08b4dd22ae 100644
--- a/libs/hwui/ClipArea.cpp
+++ b/libs/hwui/ClipArea.cpp
@@ -213,6 +213,7 @@ void ClipArea::setClip(float left, float top, float right, float bottom) {
void ClipArea::clipRectWithTransform(const Rect& r, const mat4* transform,
SkRegion::Op op) {
+ if (!mPostViewportClipObserved && op == SkRegion::kIntersect_Op) op = SkRegion::kReplace_Op;
onClipUpdated();
switch (mMode) {
case ClipMode::Rectangle:
@@ -228,6 +229,7 @@ void ClipArea::clipRectWithTransform(const Rect& r, const mat4* transform,
}
void ClipArea::clipRegion(const SkRegion& region, SkRegion::Op op) {
+ if (!mPostViewportClipObserved && op == SkRegion::kIntersect_Op) op = SkRegion::kReplace_Op;
onClipUpdated();
enterRegionMode();
mClipRegion.op(region, op);
@@ -236,6 +238,7 @@ void ClipArea::clipRegion(const SkRegion& region, SkRegion::Op op) {
void ClipArea::clipPathWithTransform(const SkPath& path, const mat4* transform,
SkRegion::Op op) {
+ if (!mPostViewportClipObserved && op == SkRegion::kIntersect_Op) op = SkRegion::kReplace_Op;
onClipUpdated();
SkMatrix skTransform;
transform->copyTo(skTransform);
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index 57e5b9d8735a..185accec1ef6 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -203,7 +203,9 @@ void FrameBuilder::deferNodePropsAndOps(RenderNode& node) {
mCanvasState.setClippingOutline(mAllocator, &(properties.getOutline()));
}
- if (!mCanvasState.quickRejectConservative(0, 0, width, height)) {
+ bool quickRejected = properties.getClipToBounds()
+ && mCanvasState.quickRejectConservative(0, 0, width, height);
+ if (!quickRejected) {
// not rejected, so defer render as either Layer, or direct (possibly wrapped in saveLayer)
if (node.getLayer()) {
// HW layer
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index 01bfc5adbbbd..20d2f1f18c58 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -455,6 +455,23 @@ TEST(RecordingCanvas, drawRenderNode_projection) {
}
}
+TEST(RecordingCanvas, firstClipWillReplace) {
+ auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
+ canvas.save(SaveFlags::MatrixClip);
+ // since no explicit clip set on canvas, this should be the one observed on op:
+ canvas.clipRect(-100, -100, 300, 300, SkRegion::kIntersect_Op);
+
+ SkPaint paint;
+ paint.setColor(SK_ColorWHITE);
+ canvas.drawRect(0, 0, 100, 100, paint);
+
+ canvas.restore();
+ });
+ ASSERT_EQ(1u, dl->getOps().size()) << "Must have one op";
+ // first clip must be preserved, even if it extends beyond canvas bounds
+ EXPECT_CLIP_RECT(Rect(-100, -100, 300, 300), dl->getOps()[0]->localClip);
+}
+
TEST(RecordingCanvas, insertReorderBarrier) {
auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
canvas.drawRect(0, 0, 400, 400, SkPaint());