diff options
-rw-r--r-- | bench/BlurRoundRectBench.cpp | 116 | ||||
-rw-r--r-- | gm/blurroundrect.cpp | 191 |
2 files changed, 114 insertions, 193 deletions
diff --git a/bench/BlurRoundRectBench.cpp b/bench/BlurRoundRectBench.cpp index 4fe4902255..c57688a142 100644 --- a/bench/BlurRoundRectBench.cpp +++ b/bench/BlurRoundRectBench.cpp @@ -19,30 +19,15 @@ #include "SkString.h" #include "SkXfermode.h" +// Large blurred RR appear frequently on web pages. This benchmark measures our +// performance in this case. class BlurRoundRectBench : public SkBenchmark { public: - BlurRoundRectBench(int width, int height, - // X and Y radii for the upper left corner - int ulX, int ulY, - // X and Y radii for the upper right corner - int urX, int urY, - // X and Y radii for the lower right corner - int lrX, int lrY, - // X and Y radii for the lower left corner - int llX, int llY) - : fName("blurroundrect") - , fWidth(width) - , fHeight(height) { - fName.appendf("_WH[%ix%i]_UL[%ix%i]_UR[%ix%i]_LR[%ix%i]_LL[%ix%i]", - width, height, - ulX, ulY, - urX, urY, - lrX, lrY, - llX, llY); - fRadii[0].set(SkIntToScalar(ulX), SkIntToScalar(ulY)); - fRadii[1].set(SkIntToScalar(urX), SkIntToScalar(urY)); - fRadii[2].set(SkIntToScalar(lrX), SkIntToScalar(lrY)); - fRadii[3].set(SkIntToScalar(llX), SkIntToScalar(llY)); + BlurRoundRectBench(int width, int height, int cornerRadius) + : fName("blurroundrect") { + fName.appendf("_WH[%ix%i]_cr[%i]", width, height, cornerRadius); + SkRect r = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); + fRRect.setRectXY(r, SkIntToScalar(cornerRadius), SkIntToScalar(cornerRadius)); } virtual const char* onGetName() SK_OVERRIDE { @@ -50,60 +35,59 @@ public: } virtual SkIPoint onGetSize() SK_OVERRIDE { - return SkIPoint::Make(fWidth, fHeight); + return SkIPoint::Make(SkScalarCeilToInt(fRRect.rect().width()), + SkScalarCeilToInt(fRRect.rect().height())); } virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { - for (int i = 0; i < this->getLoops(); i++) { - SkLayerDrawLooper* looper = new SkLayerDrawLooper; - { - SkLayerDrawLooper::LayerInfo info; - info.fFlagsMask = 0; - info.fPaintBits = 40; - info.fColorMode = SkXfermode::kSrc_Mode; - info.fOffset = SkPoint::Make(SkIntToScalar(-1), SkIntToScalar(0)); - info.fPostTranslate = false; - SkPaint* paint = looper->addLayerOnTop(info); - SkMaskFilter* maskFilter = SkBlurMaskFilter::Create(SK_ScalarHalf, - SkBlurMaskFilter::kNormal_BlurStyle, - SkBlurMaskFilter::kHighQuality_BlurFlag); - paint->setMaskFilter(maskFilter)->unref(); - SkColorFilter* colorFilter = SkColorFilter::CreateModeFilter(SK_ColorLTGRAY, - SkXfermode::kSrcIn_Mode); - paint->setColorFilter(colorFilter)->unref(); - paint->setColor(SK_ColorGRAY); - } - { - SkLayerDrawLooper::LayerInfo info; - looper->addLayerOnTop(info); - } - SkPaint paint; - SkRect rect = SkRect::MakeWH(SkIntToScalar(fWidth), SkIntToScalar(fHeight)); - canvas->drawRect(rect, paint); + SkLayerDrawLooper* looper = new SkLayerDrawLooper; + { + SkLayerDrawLooper::LayerInfo info; + info.fFlagsMask = 0; + info.fPaintBits = SkLayerDrawLooper::kMaskFilter_Bit + | SkLayerDrawLooper::kColorFilter_Bit; + info.fColorMode = SkXfermode::kSrc_Mode; + info.fOffset = SkPoint::Make(SkIntToScalar(-1), SkIntToScalar(0)); + info.fPostTranslate = false; + SkPaint* paint = looper->addLayerOnTop(info); + SkMaskFilter* maskFilter = SkBlurMaskFilter::Create(SK_ScalarHalf, + SkBlurMaskFilter::kNormal_BlurStyle, + SkBlurMaskFilter::kHighQuality_BlurFlag); + paint->setMaskFilter(maskFilter)->unref(); + SkColorFilter* colorFilter = SkColorFilter::CreateModeFilter(SK_ColorLTGRAY, + SkXfermode::kSrcIn_Mode); + paint->setColorFilter(colorFilter)->unref(); + paint->setColor(SK_ColorGRAY); + } + { + SkLayerDrawLooper::LayerInfo info; + looper->addLayerOnTop(info); + } + SkPaint dullPaint; + dullPaint.setAntiAlias(true); - paint.setLooper(looper)->unref(); - paint.setAntiAlias(true); - paint.setColor(SK_ColorCYAN); + SkPaint loopedPaint; + loopedPaint.setLooper(looper)->unref(); + loopedPaint.setAntiAlias(true); + loopedPaint.setColor(SK_ColorCYAN); - SkRRect rrect; - rrect.setRectRadii(rect, fRadii); - canvas->drawRRect(rrect, paint); + for (int i = 0; i < this->getLoops(); i++) { + canvas->drawRect(fRRect.rect(), dullPaint); + canvas->drawRRect(fRRect, loopedPaint); } } private: - SkString fName; - const int fWidth; - const int fHeight; - SkVector fRadii[4]; - typedef SkBenchmark INHERITED; + SkString fName; + SkRRect fRRect; + + typedef SkBenchmark INHERITED; }; // Create one with dimensions/rounded corners based on the skp -DEF_BENCH(return new BlurRoundRectBench(600, 5514, 6, 6, 6, 6, 6, 6, 6, 6);) +DEF_BENCH(return new BlurRoundRectBench(600, 5514, 6);) // Same radii, much smaller rectangle -DEF_BENCH(return new BlurRoundRectBench(100, 100, 6, 6, 6, 6, 6, 6, 6, 6);) -// Rounded rect with two opposite corners with large radii, the other two -// small. -DEF_BENCH(return new BlurRoundRectBench(100, 100, 30, 30, 10, 10, 30, 30, 10, 10);) -DEF_BENCH(return new BlurRoundRectBench(100, 100, 90, 90, 90, 90, 90, 90, 90, 90);) +DEF_BENCH(return new BlurRoundRectBench(100, 100, 6);) +// Other radii options +DEF_BENCH(return new BlurRoundRectBench(100, 100, 30);) +DEF_BENCH(return new BlurRoundRectBench(100, 100, 90);) diff --git a/gm/blurroundrect.cpp b/gm/blurroundrect.cpp index 5a2fa01db7..575606c4cb 100644 --- a/gm/blurroundrect.cpp +++ b/gm/blurroundrect.cpp @@ -19,36 +19,27 @@ #include "SkString.h" #include "SkXfermode.h" +// This GM mimics a blurred RR seen in the wild. class BlurRoundRectGM : public skiagm::GM { public: - BlurRoundRectGM(int width, int height, - // X and Y radii for the upper left corner - int ulX, int ulY, - // X and Y radii for the upper right corner - int urX, int urY, - // X and Y radii for the lower right corner - int lrX, int lrY, - // X and Y radii for the lower left corner - int llX, int llY, - int scaleX, int scaleY) + BlurRoundRectGM(int width, int height, int radius) : fName("blurroundrect") - , fWidth(width) - , fHeight(height) - , fScaleX(SkIntToScalar(scaleX)) - , fScaleY(SkIntToScalar(scaleY)) { - fName.appendf("-WH[%ix%i]-UL[%ix%i]-UR[%ix%i]-LR[%ix%i]-LL[%ix%i]-scale[%ix%i]", - width, height, - ulX, ulY, - urX, urY, - lrX, lrY, - llX, llY, - scaleX, scaleY); + { + SkRect r = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); + fRRect.setRectXY(r, SkIntToScalar(radius), SkIntToScalar(radius)); + fName.appendf("-WH[%ix%i]-corner[%i]", width, height, radius); + } + + BlurRoundRectGM(int width, int height) + : fName("blurroundrect") { + fName.appendf("-WH[%ix%i]-unevenCorners", + width, height); SkVector radii[4]; - radii[0].set(SkIntToScalar(ulX), SkIntToScalar(ulY)); - radii[1].set(SkIntToScalar(urX), SkIntToScalar(urY)); - radii[2].set(SkIntToScalar(lrX), SkIntToScalar(lrY)); - radii[3].set(SkIntToScalar(llX), SkIntToScalar(llY)); - SkRect r = SkRect::MakeWH(SkIntToScalar(fWidth), SkIntToScalar(fHeight)); + radii[0].set(SkIntToScalar(30), SkIntToScalar(30)); + radii[1].set(SkIntToScalar(10), SkIntToScalar(10)); + radii[2].set(SkIntToScalar(30), SkIntToScalar(30)); + radii[3].set(SkIntToScalar(10), SkIntToScalar(10)); + SkRect r = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); fRRect.setRectRadii(r, radii); } @@ -57,63 +48,17 @@ public: } virtual SkISize onISize() SK_OVERRIDE { - SkISize size = this->getUnscaledSize(); - return SkISize::Make(SkScalarCeilToInt(SkScalarMul(size.fWidth, fScaleX)), - SkScalarCeilToInt(SkScalarMul(size.fHeight, fScaleY))); - } - - virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { - canvas->scale(fScaleX, fScaleY); - } - - const SkRRect& getRRect() const { - return fRRect; - } - - // The subclass will implement this to inform us how big they - // draw before scaling. - virtual SkISize getUnscaledSize() const = 0; - - // So subclasses can modify the name. - SkString* getName() { - return &fName; - } - -private: - SkString fName; - const int fWidth; - const int fHeight; - const SkScalar fScaleX; - const SkScalar fScaleY; - SkRRect fRRect; - typedef skiagm::GM INHERITED; -}; - -class SKPBlurRoundRectGM : public BlurRoundRectGM { -public: - SKPBlurRoundRectGM(int width, int height, - int ulX, int ulY, - int urX, int urY, - int lrX, int lrY, - int llX, int llY, - int scaleX, int scaleY) - : INHERITED(width, height, ulX, ulY, urX, urY, lrX, lrY, llX, llY, scaleX, scaleY) { - this->getName()->prepend("skp-"); - } - -protected: - virtual SkISize getUnscaledSize() const SK_OVERRIDE { - return SkISize::Make(SkScalarCeilToInt(this->getRRect().rect().width()), - SkScalarCeilToInt(this->getRRect().rect().height())); + return SkISize::Make(SkScalarCeilToInt(fRRect.rect().width()), + SkScalarCeilToInt(fRRect.rect().height())); } virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { - this->INHERITED::onDraw(canvas); SkLayerDrawLooper* looper = new SkLayerDrawLooper; { SkLayerDrawLooper::LayerInfo info; info.fFlagsMask = 0; - info.fPaintBits = 40; + info.fPaintBits = SkLayerDrawLooper::kMaskFilter_Bit + | SkLayerDrawLooper::kColorFilter_Bit; info.fColorMode = SkXfermode::kSrc_Mode; info.fOffset = SkPoint::Make(SkIntToScalar(-1), SkIntToScalar(0)); info.fPostTranslate = false; @@ -132,80 +77,72 @@ protected: looper->addLayerOnTop(info); } SkPaint paint; - canvas->drawRect(this->getRRect().rect(), paint); + canvas->drawRect(fRRect.rect(), paint); paint.setLooper(looper)->unref(); paint.setColor(SK_ColorCYAN); paint.setAntiAlias(true); - canvas->drawRRect(this->getRRect(), paint); + canvas->drawRRect(fRRect, paint); } private: - typedef BlurRoundRectGM INHERITED; + SkString fName; + SkRRect fRRect; + + typedef skiagm::GM INHERITED; }; -class SimpleBlurRoundRectGM : public BlurRoundRectGM { +// Simpler blurred RR test cases where all the radii are the same. +class SimpleBlurRoundRectGM : public skiagm::GM { public: - SimpleBlurRoundRectGM(int width, int height, - int blurRadius, int cornerRadius, - int scaleX = 1, int scaleY = 1) - : INHERITED(width, height, cornerRadius, cornerRadius, - cornerRadius, cornerRadius, cornerRadius, - cornerRadius, cornerRadius, cornerRadius, scaleX, scaleY) - , fBlurRadius(blurRadius) { - // For now at least, change the name to reflect only the - // variables that are changing. - this->getName()->printf("blurround-blur[%i]-corner[%i]-scale[%ix%i]", fBlurRadius, cornerRadius, scaleX, scaleY); + SimpleBlurRoundRectGM() + : fName("simpleblurroundrect") { } protected: - virtual SkISize getUnscaledSize() const SK_OVERRIDE { - return SkISize::Make(SkScalarCeilToInt(this->getRRect().rect().width() + 20), - SkScalarCeilToInt(this->getRRect().rect().height() + 20)); + virtual SkString onShortName() SK_OVERRIDE { + return fName; + } + + virtual SkISize onISize() SK_OVERRIDE { + return SkISize::Make(SkIntToScalar(750), SkIntToScalar(750)); } virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { - // Handle the scaling. - this->INHERITED::onDraw(canvas); - canvas->translate(SkIntToScalar(10), SkIntToScalar(10)); - SkMaskFilter* filter = SkBlurMaskFilter::Create(SkIntToScalar(fBlurRadius), - SkBlurMaskFilter::kNormal_BlurStyle); - SkPaint paint; - paint.setColor(SK_ColorBLUE); - paint.setMaskFilter(filter)->unref(); - canvas->drawRRect(this->getRRect(), paint); + canvas->scale(SkFloatToScalar(1.5f), SkFloatToScalar(1.5f)); + + const int blurRadii[] = { 1, 3, 6, 10 }; + const int cornerRadii[] = { 1, 3, 6, 10 }; + const SkRect r = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100)); + for (size_t i = 0; i < SK_ARRAY_COUNT(blurRadii); ++i) { + SkAutoCanvasRestore autoRestore(canvas, true); + canvas->translate(0, (r.height() + SkIntToScalar(20)) * i); + for (size_t j = 0; j < SK_ARRAY_COUNT(cornerRadii); ++j) { + SkMaskFilter* filter = SkBlurMaskFilter::Create(SkIntToScalar(blurRadii[i]), + SkBlurMaskFilter::kNormal_BlurStyle); + SkPaint paint; + paint.setColor(SK_ColorBLUE); + paint.setMaskFilter(filter)->unref(); + + SkRRect rrect; + rrect.setRectXY(r, SkIntToScalar(cornerRadii[j]), SkIntToScalar(cornerRadii[j])); + canvas->drawRRect(rrect, paint); + canvas->translate(r.width() + SkIntToScalar(10), 0); + } + } } private: - const int fBlurRadius; + const SkString fName; - typedef BlurRoundRectGM INHERITED; + typedef skiagm::GM INHERITED; }; // Create one with dimensions/rounded corners based on the skp -DEF_GM(return new SKPBlurRoundRectGM(600, 5514, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1);) -// Same radii, much smaller rectangle -DEF_GM(return new SKPBlurRoundRectGM(100, 100, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2);) +DEF_GM(return new BlurRoundRectGM(600, 5514, 6);) // Rounded rect with two opposite corners with large radii, the other two // small. -DEF_GM(return new SKPBlurRoundRectGM(100, 100, 30, 30, 10, 10, 30, 30, 10, 10, 3, 4);) -DEF_GM(return new SKPBlurRoundRectGM(100, 100, 90, 90, 90, 90, 90, 90, 90, 90, 2, 3);) - -// Try a few blur values with a small corner radius -DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 1, 1)); -DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 3, 1, 2, 2)); -DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 6, 1)); -DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 10, 1, 3, 3)); - -// Now a few blur values with a larger corner radius -DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 1, 3, 2, 2)); -DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 3, 3)); -DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 6, 3, 3, 3)); -DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 10, 3)); - -// Even larger corner radius -DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 1, 6, 2, 4)); -DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 3, 6)); -DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 6, 6)); -DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 10, 6, 1, 3)); +DEF_GM(return new BlurRoundRectGM(100, 100);) + +DEF_GM(return new SimpleBlurRoundRectGM();) |