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() { |