1/*
2* Copyright 2013 Google Inc.
3*
4* Use of this source code is governed by a BSD-style license that can be
5* found in the LICENSE file.
6*/
7
8#include "SkBenchmark.h"
9#include "SkBlurMask.h"
10#include "SkBlurMaskFilter.h"
11#include "SkCanvas.h"
12#include "SkColorFilter.h"
13#include "SkLayerDrawLooper.h"
14#include "SkPaint.h"
15#include "SkPath.h"
16#include "SkPoint.h"
17#include "SkRect.h"
18#include "SkRRect.h"
19#include "SkString.h"
20#include "SkXfermode.h"
21
22// Large blurred RR appear frequently on web pages. This benchmark measures our
23// performance in this case.
24class BlurRoundRectBench : public SkBenchmark {
25public:
26    BlurRoundRectBench(int width, int height, int cornerRadius)
27        : fName("blurroundrect") {
28        fName.appendf("_WH[%ix%i]_cr[%i]", width, height, cornerRadius);
29        SkRect r = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
30        fRRect.setRectXY(r, SkIntToScalar(cornerRadius), SkIntToScalar(cornerRadius));
31    }
32
33    virtual const char* onGetName() SK_OVERRIDE {
34        return fName.c_str();
35    }
36
37    virtual SkIPoint onGetSize() SK_OVERRIDE {
38        return SkIPoint::Make(SkScalarCeilToInt(fRRect.rect().width()),
39                              SkScalarCeilToInt(fRRect.rect().height()));
40    }
41
42    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
43        SkLayerDrawLooper* looper = new SkLayerDrawLooper;
44        {
45            SkLayerDrawLooper::LayerInfo info;
46            info.fFlagsMask = 0;
47            info.fPaintBits = SkLayerDrawLooper::kMaskFilter_Bit
48                              | SkLayerDrawLooper::kColorFilter_Bit;
49            info.fColorMode = SkXfermode::kSrc_Mode;
50            info.fOffset = SkPoint::Make(SkIntToScalar(-1), SkIntToScalar(0));
51            info.fPostTranslate = false;
52            SkPaint* paint = looper->addLayerOnTop(info);
53            SkMaskFilter* maskFilter = SkBlurMaskFilter::Create(
54                    SkBlurMaskFilter::kNormal_BlurStyle,
55                    SkBlurMask::ConvertRadiusToSigma(SK_ScalarHalf),
56                    SkBlurMaskFilter::kHighQuality_BlurFlag);
57            paint->setMaskFilter(maskFilter)->unref();
58            SkColorFilter* colorFilter = SkColorFilter::CreateModeFilter(SK_ColorLTGRAY,
59                    SkXfermode::kSrcIn_Mode);
60            paint->setColorFilter(colorFilter)->unref();
61            paint->setColor(SK_ColorGRAY);
62        }
63        {
64            SkLayerDrawLooper::LayerInfo info;
65            looper->addLayerOnTop(info);
66        }
67        SkPaint dullPaint;
68        dullPaint.setAntiAlias(true);
69
70        SkPaint loopedPaint;
71        loopedPaint.setLooper(looper)->unref();
72        loopedPaint.setAntiAlias(true);
73        loopedPaint.setColor(SK_ColorCYAN);
74
75        for (int i = 0; i < loops; i++) {
76            canvas->drawRect(fRRect.rect(), dullPaint);
77            canvas->drawRRect(fRRect, loopedPaint);
78        }
79    }
80
81private:
82    SkString    fName;
83    SkRRect     fRRect;
84
85    typedef     SkBenchmark INHERITED;
86};
87
88// Create one with dimensions/rounded corners based on the skp
89DEF_BENCH(return new BlurRoundRectBench(600, 5514, 6);)
90// Same radii, much smaller rectangle
91DEF_BENCH(return new BlurRoundRectBench(100, 100, 6);)
92// Other radii options
93DEF_BENCH(return new BlurRoundRectBench(100, 100, 30);)
94DEF_BENCH(return new BlurRoundRectBench(100, 100, 90);)
95