aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2015-09-15 10:20:55 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-09-15 10:20:55 -0700
commit30c4cae7d3a26252e7e45adf6e5722b34adf6848 (patch)
tree51e48fb3326a2a4a76a762d932069357e3b7c56f /include
parentde5973b05be6ecc80309cded8541f9c305135d15 (diff)
Add special case circle blur for Ganesh
This makes the blurcircles bench go from ~33us to ~8us on Windows desktop. It will require layout test suppressions Review URL: https://codereview.chromium.org/1311583005
Diffstat (limited to 'include')
-rw-r--r--include/core/SkColorPriv.h10
-rw-r--r--include/core/SkMaskFilter.h30
-rw-r--r--include/core/SkRRect.h13
-rw-r--r--include/core/SkScalar.h2
4 files changed, 45 insertions, 10 deletions
diff --git a/include/core/SkColorPriv.h b/include/core/SkColorPriv.h
index 3dec49b73e..6347660dbc 100644
--- a/include/core/SkColorPriv.h
+++ b/include/core/SkColorPriv.h
@@ -218,6 +218,16 @@ static inline int SkAlphaBlend255(S16CPU src, S16CPU dst, U8CPU alpha) {
return dst + prod;
}
+static inline U8CPU SkUnitScalarClampToByte(SkScalar x) {
+ if (x < 0) {
+ return 0;
+ }
+ if (x >= SK_Scalar1) {
+ return 255;
+ }
+ return SkScalarToFixed(x) >> 8;
+}
+
#define SK_R16_BITS 5
#define SK_G16_BITS 6
#define SK_B16_BITS 5
diff --git a/include/core/SkMaskFilter.h b/include/core/SkMaskFilter.h
index df9c4ac3fe..50a1e87e00 100644
--- a/include/core/SkMaskFilter.h
+++ b/include/core/SkMaskFilter.h
@@ -78,17 +78,31 @@ public:
/**
* If asFragmentProcessor() fails the filter may be implemented on the GPU by a subclass
- * overriding filterMaskGPU (declared below). That code path requires constructing a src mask
- * as input. Since that is a potentially expensive operation, the subclass must also override
- * this function to indicate whether filterTextureMaskGPU would succeeed if the mask were to be
- * created.
+ * overriding filterMaskGPU (declared below). That code path requires constructing a
+ * src mask as input. Since that is a potentially expensive operation, the subclass must also
+ * override this function to indicate whether filterTextureMaskGPU would succeeed if the mask
+ * were to be created.
*
* 'maskRect' returns the device space portion of the mask that the filter needs. The mask
- * passed into 'filterMaskGPU' should have the same extent as 'maskRect' but be translated
- * to the upper-left corner of the mask (i.e., (maskRect.fLeft, maskRect.fTop) appears at
- * (0, 0) in the mask).
+ * passed into 'filterMaskGPU' should have the same extent as 'maskRect' but be
+ * translated to the upper-left corner of the mask (i.e., (maskRect.fLeft, maskRect.fTop)
+ * appears at (0, 0) in the mask).
+ *
+ * Logically, how this works is:
+ * canFilterMaskGPU is called
+ * if (it returns true)
+ * the returned mask rect is used for quick rejecting
+ * either directFilterMaskGPU or directFilterRRectMaskGPU is then called
+ * if (neither of them handle the blur)
+ * the mask rect is used to generate the mask
+ * filterMaskGPU is called to filter the mask
+ *
+ * TODO: this should work as:
+ * if (canFilterMaskGPU(devShape, ...)) // rect, rrect, drrect, path
+ * filterMaskGPU(devShape, ...)
+ * this would hide the RRect special case and the mask generation
*/
- virtual bool canFilterMaskGPU(const SkRect& devBounds,
+ virtual bool canFilterMaskGPU(const SkRRect& devRRect,
const SkIRect& clipBounds,
const SkMatrix& ctm,
SkRect* maskRect) const;
diff --git a/include/core/SkRRect.h b/include/core/SkRRect.h
index 37766219df..064e7be8e4 100644
--- a/include/core/SkRRect.h
+++ b/include/core/SkRRect.h
@@ -96,8 +96,13 @@ public:
inline bool isRect() const { return kRect_Type == this->getType(); }
inline bool isOval() const { return kOval_Type == this->getType(); }
inline bool isSimple() const { return kSimple_Type == this->getType(); }
+ // TODO: should isSimpleCircular & isCircle take a tolerance? This could help
+ // instances where the mapping to device space is noisy.
inline bool isSimpleCircular() const {
- return this->isSimple() && fRadii[0].fX == fRadii[0].fY;
+ return this->isSimple() && SkScalarNearlyEqual(fRadii[0].fX, fRadii[0].fY);
+ }
+ inline bool isCircle() const {
+ return this->isOval() && SkScalarNearlyEqual(fRadii[0].fX, fRadii[0].fY);
}
inline bool isNinePatch() const { return kNinePatch_Type == this->getType(); }
inline bool isComplex() const { return kComplex_Type == this->getType(); }
@@ -140,6 +145,12 @@ public:
return rr;
}
+ static SkRRect MakeOval(const SkRect& oval) {
+ SkRRect rr;
+ rr.setOval(oval);
+ return rr;
+ }
+
/**
* Set this RR to match the supplied oval. All x radii will equal half the
* width and all y radii will equal half the height.
diff --git a/include/core/SkScalar.h b/include/core/SkScalar.h
index 71575a4920..4efa8417af 100644
--- a/include/core/SkScalar.h
+++ b/include/core/SkScalar.h
@@ -224,7 +224,7 @@ static inline bool SkScalarNearlyZero(SkScalar x,
}
static inline bool SkScalarNearlyEqual(SkScalar x, SkScalar y,
- SkScalar tolerance = SK_ScalarNearlyZero) {
+ SkScalar tolerance = SK_ScalarNearlyZero) {
SkASSERT(tolerance >= 0);
return SkScalarAbs(x-y) <= tolerance;
}