aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/core
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-01-30 15:41:43 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-01-30 15:41:43 +0000
commit9efd9a048aebaa6681afb76b18e1a7dd642078d3 (patch)
treeed8ad344b7541b85a3c32d7277a0fd7043023494 /include/core
parentbf6c1e4aff4d233f6502157fb73459cf69d0ab37 (diff)
extend fastbounds impls to include maskfilters and drawloopers. This allows
us to perform quick-rejects when drawing objects with shadows (esp. text). WebKit draws shadows w/ a looper (fg and shadow) and a maskfilter on the shadow layer. git-svn-id: http://skia.googlecode.com/svn/trunk@3103 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include/core')
-rw-r--r--include/core/SkDrawLooper.h14
-rw-r--r--include/core/SkMaskFilter.h13
-rw-r--r--include/core/SkPaint.h20
3 files changed, 39 insertions, 8 deletions
diff --git a/include/core/SkDrawLooper.h b/include/core/SkDrawLooper.h
index 4d9f718fce..e8265dbaf1 100644
--- a/include/core/SkDrawLooper.h
+++ b/include/core/SkDrawLooper.h
@@ -45,6 +45,20 @@ public:
*/
virtual bool next(SkCanvas*, SkPaint* paint) = 0;
+ /**
+ * The fast bounds functions are used to enable the paint to be culled early
+ * in the drawing pipeline. If a subclass can support this feature it must
+ * return true for the canComputeFastBounds() function. If that function
+ * returns false then computeFastBounds behavior is undefined otherwise it
+ * is expected to have the following behavior. Given the parent paint and
+ * the parent's bounding rect the subclass must fill in and return the
+ * storage rect, where the storage rect is with the union of the src rect
+ * and the looper's bounding rect.
+ */
+ virtual bool canComputeFastBounds(const SkPaint& paint);
+ virtual void computeFastBounds(const SkPaint& paint,
+ const SkRect& src, SkRect* dst);
+
protected:
SkDrawLooper() {}
SkDrawLooper(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
diff --git a/include/core/SkMaskFilter.h b/include/core/SkMaskFilter.h
index 1f1d57070e..2808de761f 100644
--- a/include/core/SkMaskFilter.h
+++ b/include/core/SkMaskFilter.h
@@ -79,6 +79,19 @@ public:
*/
virtual BlurType asABlur(BlurInfo*) const;
+ /**
+ * The fast bounds function is used to enable the paint to be culled early
+ * in the drawing pipeline. This function accepts the current bounds of the
+ * paint as its src param and the filter adjust those bounds using its
+ * current mask and returns the result using the dest param. Callers are
+ * allowed to provide the same struct for both src and dest so each
+ * implementation must accomodate that behavior.
+ *
+ * The default impl calls filterMask with the src mask having no image,
+ * but subclasses may override this if they can compute the rect faster.
+ */
+ virtual void computeFastBounds(const SkRect& src, SkRect* dest);
+
protected:
// empty for now, but lets get our subclass to remember to init us for the future
SkMaskFilter(SkFlattenableReadBuffer&) {}
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index f5d98a9875..e4717afa02 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -11,6 +11,7 @@
#define SkPaint_DEFINED
#include "SkColor.h"
+#include "SkDrawLooper.h"
#include "SkXfermode.h"
class SkAutoGlyphCache;
@@ -28,7 +29,6 @@ class SkPath;
class SkPathEffect;
class SkRasterizer;
class SkShader;
-class SkDrawLooper;
class SkTypeface;
typedef const SkGlyph& (*SkDrawCacheProc)(SkGlyphCache*, const char**,
@@ -438,10 +438,11 @@ public:
the bounds computation expensive.
*/
bool canComputeFastBounds() const {
+ if (this->getLooper()) {
+ return this->getLooper()->canComputeFastBounds(*this);
+ }
// use bit-or since no need for early exit
- return (reinterpret_cast<uintptr_t>(this->getMaskFilter()) |
- reinterpret_cast<uintptr_t>(this->getLooper()) |
- reinterpret_cast<uintptr_t>(this->getRasterizer()) |
+ return (reinterpret_cast<uintptr_t>(this->getRasterizer()) |
reinterpret_cast<uintptr_t>(this->getPathEffect())) == 0;
}
@@ -467,8 +468,12 @@ public:
}
*/
const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
- return this->getStyle() == kFill_Style ? orig :
- this->computeStrokeFastBounds(orig, storage);
+ if (this->getStyle() == kFill_Style &&
+ !this->getLooper() && !this->getMaskFilter()) {
+ return orig;
+ }
+
+ return this->doComputeFastBounds(orig, storage);
}
/** Get the paint's shader object.
@@ -892,8 +897,7 @@ private:
void (*proc)(const SkDescriptor*, void*),
void* context, bool ignoreGamma = false) const;
- const SkRect& computeStrokeFastBounds(const SkRect& orig,
- SkRect* storage) const;
+ const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage) const;
enum {
kCanonicalTextSizeForPaths = 64