| Index: src/core/SkRecordDraw.cpp
|
| diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
|
| index bdebcb7c1560fce0ef6fe0f91306e528f7aadaf9..c693b05c63e10db94c53f362e281f49762da1e23 100644
|
| --- a/src/core/SkRecordDraw.cpp
|
| +++ b/src/core/SkRecordDraw.cpp
|
| @@ -7,7 +7,6 @@
|
|
|
| #include "SkRecordDraw.h"
|
| #include "SkPatchUtils.h"
|
| -#include "SkTLogic.h"
|
|
|
| void SkRecordDraw(const SkRecord& record,
|
| SkCanvas* canvas,
|
| @@ -181,26 +180,40 @@ private:
|
| const SkPaint* paint; // Unowned. If set, adjusts the bounds of all ops in this block.
|
| };
|
|
|
| - template <typename T> void updateCTM(const T&) { /* most ops don't change the CTM */ }
|
| + // Only Restore and SetMatrix change the CTM.
|
| + template <typename T> void updateCTM(const T&) {}
|
| void updateCTM(const Restore& op) { fCTM = &op.matrix; }
|
| void updateCTM(const SetMatrix& op) { fCTM = &op.matrix; }
|
|
|
| - // Most ops don't change the clip. Those that do generally have a field named devBounds.
|
| - SK_CREATE_MEMBER_DETECTOR(devBounds);
|
| + // Most ops don't change the clip.
|
| + template <typename T> void updateClipBounds(const T&) {}
|
|
|
| - template <typename T>
|
| - SK_WHEN(!HasMember_devBounds<T>, void) updateClipBounds(const T& op) {}
|
| + // Clip{Path,RRect,Rect,Region} obviously change the clip. They all know their bounds already.
|
| + void updateClipBounds(const ClipPath& op) { this->updateClipBoundsForClipOp(op.devBounds); }
|
| + void updateClipBounds(const ClipRRect& op) { this->updateClipBoundsForClipOp(op.devBounds); }
|
| + void updateClipBounds(const ClipRect& op) { this->updateClipBoundsForClipOp(op.devBounds); }
|
| + void updateClipBounds(const ClipRegion& op) { this->updateClipBoundsForClipOp(op.devBounds); }
|
|
|
| - // Each of the devBounds fields holds the state of the device bounds after the op.
|
| - // (So Restore's devBounds are those bounds saved by its paired Save or SaveLayer.)
|
| - template <typename T>
|
| - SK_WHEN(HasMember_devBounds<T>, void) updateClipBounds(const T& op) {
|
| - Bounds clip = SkRect::Make(op.devBounds);
|
| + // The bounds of clip ops need to be adjusted for the paints of saveLayers they're inside.
|
| + void updateClipBoundsForClipOp(const SkIRect& devBounds) {
|
| + Bounds clip = SkRect::Make(devBounds);
|
| // We don't call adjustAndMap() because as its last step it would intersect the adjusted
|
| // clip bounds with the previous clip, exactly what we can't do when the clip grows.
|
| fCurrentClipBounds = this->adjustForSaveLayerPaints(&clip) ? clip : Bounds::MakeLargest();
|
| }
|
|
|
| + // Restore holds the devBounds for the clip after the {save,saveLayer}/restore block completes.
|
| + void updateClipBounds(const Restore& op) {
|
| + // This is just like the clip ops above, but we need to skip the effects (if any) of our
|
| + // paired saveLayer (if it is one); it has not yet been popped off the save stack. Our
|
| + // devBounds reflect the state of the world after the saveLayer/restore block is done,
|
| + // so they are not affected by the saveLayer's paint.
|
| + const int kSavesToIgnore = 1;
|
| + Bounds clip = SkRect::Make(op.devBounds);
|
| + fCurrentClipBounds =
|
| + this->adjustForSaveLayerPaints(&clip, kSavesToIgnore) ? clip : Bounds::MakeLargest();
|
| + }
|
| +
|
| // We also take advantage of SaveLayer bounds when present to further cut the clip down.
|
| void updateClipBounds(const SaveLayer& op) {
|
| if (op.bounds) {
|
| @@ -478,8 +491,8 @@ private:
|
| return true;
|
| }
|
|
|
| - bool adjustForSaveLayerPaints(SkRect* rect) const {
|
| - for (int i = fSaveStack.count() - 1; i >= 0; i--) {
|
| + bool adjustForSaveLayerPaints(SkRect* rect, int savesToIgnore = 0) const {
|
| + for (int i = fSaveStack.count() - 1 - savesToIgnore; i >= 0; i--) {
|
| if (!AdjustForPaint(fSaveStack[i].paint, rect)) {
|
| return false;
|
| }
|
|
|