aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-04-10 02:26:33 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-04-10 02:26:33 +0000
commitff2de7cb94847f7e6ad3f5c0047eb6b4815eee2e (patch)
treecf716117706317cd3736f40ca0e93e20051c19b2
parentfe23f7978f4f75c6a9af025f26b583650342766e (diff)
SkRecordDraw: don't bother clipping an empty clip down further
BUG=skia:2378 R=fmalita@chromium.org, mtklein@google.com, fmalita@google.com Author: mtklein@chromium.org Review URL: https://codereview.chromium.org/231933003 git-svn-id: http://skia.googlecode.com/svn/trunk@14126 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--src/record/SkRecordDraw.cpp9
-rw-r--r--tests/RecordDrawTest.cpp9
2 files changed, 13 insertions, 5 deletions
diff --git a/src/record/SkRecordDraw.cpp b/src/record/SkRecordDraw.cpp
index 4782344bed..ddde2fede8 100644
--- a/src/record/SkRecordDraw.cpp
+++ b/src/record/SkRecordDraw.cpp
@@ -37,13 +37,20 @@ template <> void Draw::operator()(const SkRecords::PushCull& r) {
template <> void Draw::operator()(const SkRecords::T& r) { fCanvas->call; this->updateClip(); }
CASE(Restore, restore());
CASE(SaveLayer, saveLayer(r.bounds, r.paint, r.flags));
+#undef CASE
+
+// These certainly do change the clip,
+// but we can skip them if they're intersecting with a clip that's already empty.
+#define CASE(T, call) template <> void Draw::operator()(const SkRecords::T& r) { \
+ if (!(fClipEmpty && SkRegion::kIntersect_Op == r.op)) { fCanvas->call; this->updateClip(); } \
+}
CASE(ClipPath, clipPath(r.path, r.op, r.doAA));
CASE(ClipRRect, clipRRect(r.rrect, r.op, r.doAA));
CASE(ClipRect, clipRect(r.rect, r.op, r.doAA));
CASE(ClipRegion, clipRegion(r.region, r.op));
#undef CASE
-// Commands which must run regardless of the clip.
+// Commands which must run regardless of the clip, but don't change it themselves.
#define CASE(T, call) \
template <> void Draw::operator()(const SkRecords::T& r) { fCanvas->call; }
CASE(Save, save(r.flags));
diff --git a/tests/RecordDrawTest.cpp b/tests/RecordDrawTest.cpp
index 6468e72c9d..98ec506b1e 100644
--- a/tests/RecordDrawTest.cpp
+++ b/tests/RecordDrawTest.cpp
@@ -43,14 +43,15 @@ DEF_TEST(RecordDraw_Clipping, r) {
SkRecord record;
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
- // 8 draw commands.
- // The inner clipRect makes the clip empty, so the inner drawRect does nothing.
+ // 9 draw commands.
recorder.save();
recorder.clipRect(SkRect::MakeLTRB(0, 0, 100, 100));
recorder.drawRect(SkRect::MakeLTRB(20, 20, 40, 40), SkPaint());
recorder.save();
+ // This first clipRect makes the clip empty, so the next two commands do nothing.
recorder.clipRect(SkRect::MakeLTRB(200, 200, 300, 300));
- recorder.drawRect(SkRect::MakeLTRB(220, 220, 240, 240), SkPaint());
+ recorder.clipRect(SkRect::MakeLTRB(210, 210, 250, 250)); // Skipped
+ recorder.drawRect(SkRect::MakeLTRB(220, 220, 240, 240), SkPaint()); // Skipped
recorder.restore();
recorder.restore();
@@ -59,6 +60,6 @@ DEF_TEST(RecordDraw_Clipping, r) {
SkRecorder rerecorder(SkRecorder::kReadWrite_Mode, &rerecord, W, H);
SkRecordDraw(record, &rerecorder);
- // All commands except the drawRect will be preserved.
+ // All commands except the two marked // Skipped above will be preserved.
REPORTER_ASSERT(r, 7 == rerecord.count());
}