diff options
author | robertphillips <robertphillips@google.com> | 2015-09-15 10:20:55 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-09-15 10:20:55 -0700 |
commit | 30c4cae7d3a26252e7e45adf6e5722b34adf6848 (patch) | |
tree | 51e48fb3326a2a4a76a762d932069357e3b7c56f /include | |
parent | de5973b05be6ecc80309cded8541f9c305135d15 (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.h | 10 | ||||
-rw-r--r-- | include/core/SkMaskFilter.h | 30 | ||||
-rw-r--r-- | include/core/SkRRect.h | 13 | ||||
-rw-r--r-- | include/core/SkScalar.h | 2 |
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; } |