Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Unified Diff: src/core/SkRecordDraw.cpp

Issue 496963003: Fix saveLayer() with a pixel-moving filter vs SkBBoxHierarchyRecord / SkRecordDraw (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkBBoxHierarchyRecord.cpp ('k') | tests/ImageFilterTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkRecordDraw.cpp
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index a14b0316955dd0b1c93448c1bcd2410c5f74bae8..c796386f209b7d6ab50a3ab62decaf2e273b1a93 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -160,6 +160,11 @@ private:
const SkPaint* paint; // Unowned. If set, adjusts the bounds of all ops in this block.
};
+ static bool PaintMayAffectTransparentBlack(const SkPaint* paint) {
+ // FIXME: this is very conservative
+ return paint && (paint->getImageFilter() || paint->getColorFilter());
+ }
+
template <typename T> void updateCTM(const T&) { /* most ops don't change the CTM */ }
void updateCTM(const Restore& op) { fCTM = &op.matrix; }
void updateCTM(const SetMatrix& op) { fCTM = &op.matrix; }
@@ -173,7 +178,8 @@ private:
void updateClipBounds(const ClipRect& op) { fCurrentClipBounds = op.devBounds; }
void updateClipBounds(const ClipRegion& op) { fCurrentClipBounds = op.devBounds; }
void updateClipBounds(const SaveLayer& op) {
- if (op.bounds) {
+ // Intersect the clip with the SaveLayer bounds, unless the paint affects transparent black.
+ if (op.bounds && !PaintMayAffectTransparentBlack(op.paint)) {
mtklein 2014/08/22 15:45:58 Just reading again: "Since the bounds we pass to
fCurrentClipBounds.intersect(this->adjustAndMap(*op.bounds, op.paint));
}
}
@@ -208,15 +214,20 @@ private:
// We're done the Save block. Apply the block's bounds to all control ops inside it.
SaveBounds sb;
fSaveStack.pop(&sb);
+
+ // If the paint affects transparent black, we can't trust any of our calculated bounds.
+ const SkIRect& bounds =
+ PaintMayAffectTransparentBlack(sb.paint) ? fCurrentClipBounds : sb.bounds;
+
while (sb.controlOps --> 0) {
- this->popControl(sb.bounds);
+ this->popControl(bounds);
}
// This whole Save block may be part another Save block.
- this->updateSaveBounds(sb.bounds);
+ this->updateSaveBounds(bounds);
// If called from a real Restore (not a phony one for balance), it'll need the bounds.
- return sb.bounds;
+ return bounds;
}
void pushControl() {
« no previous file with comments | « src/core/SkBBoxHierarchyRecord.cpp ('k') | tests/ImageFilterTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698