Move all non-AA fill rect ops off of GrLegacyMeshDrawOp.
[platform/upstream/libSkiaSharp.git] / gm / blurcircles2.cpp
1 /*
2 * Copyright 2016 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 "gm.h"
9 #include "SkAnimTimer.h"
10 #include "SkBlurMask.h"
11 #include "SkBlurMaskFilter.h"
12 #include "SkCanvas.h"
13 #include "SkPaint.h"
14 #include "SkPath.h"
15 #include "SkString.h"
16 #include "SkRandom.h"
17
18 /**
19  * In GM mode this draws an array of circles with different radii and different blur radii. Below
20  * each circle an almost-circle path is drawn with the same blur filter for comparison.
21  *
22  * In Sample mode this draws a single circle and almost-circle with animating radius and blur
23  * radius.
24  *
25  * Bench mode draws the same as GM mode but without the comparison almost-circle paths. It also
26  * slightly perturbs the blur and circle radii to stress caching of blurred profiles in GPU mode.
27  */
28 class BlurCircles2GM : public skiagm::GM {
29 public:
30     BlurCircles2GM() {
31         fAnimRadius = SkAnimTimer::PingPong(0, kRadiusPingPoingPeriod, kRadiusPingPoingShift,
32                                             kMinRadius, kMaxRadius);
33         fAnimBlurRadius = SkAnimTimer::PingPong(0, kBlurRadiusPingPoingPeriod,
34                                                 kBlurRadiusPingPoingShift, kMinBlurRadius,
35                                                 kMaxBlurRadius);
36     }
37
38 protected:
39     bool runAsBench() const override { return true; }
40
41     SkString onShortName() override { return SkString("blurcircles2"); }
42
43     SkISize onISize() override {
44         return SkISize::Make(730, 1350);
45     }
46
47     void onDraw(SkCanvas* canvas) override {
48         constexpr SkScalar kMaxR = kMaxRadius + kMaxBlurRadius;
49
50         auto almostCircleMaker = [] (SkScalar radius, SkPath* dst) {
51             dst->reset();
52             dst->addArc(SkRect::MakeXYWH(-radius, -radius, 2 * radius, 2 * radius), 0, 355);
53             dst->setIsVolatile(true);
54             dst->close();
55         };
56
57         auto blurMaker = [] (SkScalar radius) ->sk_sp<SkMaskFilter> {
58             return SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
59                                           SkBlurMask::ConvertRadiusToSigma(radius),
60                                           SkBlurMaskFilter::kHighQuality_BlurFlag);
61         };
62
63         SkPaint paint;
64         paint.setColor(SK_ColorBLACK);
65
66         if (this->getMode() == kSample_Mode) {
67             paint.setMaskFilter(blurMaker(fAnimBlurRadius));
68             SkISize size = canvas->getBaseLayerSize();
69             SkPath almostCircle;
70             almostCircleMaker(fAnimRadius, &almostCircle);
71             canvas->save();
72                 canvas->translate(size.fWidth / 2.f, size.fHeight / 4.f);
73                 canvas->drawCircle(0, 0, fAnimRadius, paint);
74                 canvas->translate(0, 2 * kMaxR);
75                 canvas->drawPath(almostCircle, paint);
76             canvas->restore();
77         } else {
78             bool benchMode = this->getMode() == kBench_Mode;
79             canvas->save();
80             constexpr SkScalar kPad = 5;
81             constexpr SkScalar kRadiusSteps = 5;
82             constexpr SkScalar kBlurRadiusSteps = 5;
83             canvas->translate(kPad + kMinRadius + kMaxBlurRadius,
84                               kPad + kMinRadius + kMaxBlurRadius);
85             constexpr SkScalar kDeltaRadius = (kMaxRadius - kMinRadius) / kRadiusSteps;
86             constexpr SkScalar kDeltaBlurRadius = (kMaxBlurRadius - kMinBlurRadius) /
87                                                          kBlurRadiusSteps;
88             SkScalar lineWidth = 0;
89             if (!benchMode) {
90                 for (int r = 0; r < kRadiusSteps - 1; ++r) {
91                     const SkScalar radius = r * kDeltaRadius + kMinRadius;
92                     lineWidth += 2 * (radius + kMaxBlurRadius) + kPad;
93                 }
94             }
95             for (int br = 0; br < kBlurRadiusSteps; ++br) {
96                 SkScalar blurRadius = br * kDeltaBlurRadius + kMinBlurRadius;
97                 if (benchMode) {
98                     blurRadius += fRandom.nextSScalar1() * kDeltaBlurRadius;
99                 }
100                 const SkScalar maxRowR = blurRadius + kMaxRadius;
101                 paint.setMaskFilter(blurMaker(blurRadius));
102                 canvas->save();
103                 for (int r = 0; r < kRadiusSteps; ++r) {
104                     SkScalar radius = r * kDeltaRadius + kMinRadius;
105                     if (benchMode) {
106                         radius += fRandom.nextSScalar1() * kDeltaRadius;
107                     }
108                     SkPath almostCircle;
109                     if (!benchMode) {
110                         almostCircleMaker(radius, &almostCircle);
111                     }
112                     canvas->save();
113                         canvas->drawCircle(0, 0, radius, paint);
114                         canvas->translate(0, 2 * maxRowR + kPad);
115                     if (!benchMode) {
116                         canvas->drawPath(almostCircle, paint);
117                     }
118                     canvas->restore();
119                     const SkScalar maxColR = radius + kMaxBlurRadius;
120                     canvas->translate(maxColR * 2 + kPad, 0);
121                 }
122                 canvas->restore();
123                 if (!benchMode) {
124                     SkPaint blackPaint;
125                     blackPaint.setColor(SK_ColorBLACK);
126                     const SkScalar lineY = 3 * maxRowR + 1.5f * kPad;
127                     if (br != kBlurRadiusSteps - 1) {
128                         canvas->drawLine(0, lineY, lineWidth, lineY, blackPaint);
129                     }
130                 }
131                 canvas->translate(0, maxRowR * 4 + 2 * kPad);
132             }
133             canvas->restore();
134         }
135     }
136
137     bool onAnimate(const SkAnimTimer& timer) override {
138         fAnimRadius = timer.pingPong(kRadiusPingPoingPeriod, kRadiusPingPoingShift, kMinRadius,
139                                      kMaxRadius);
140         fAnimBlurRadius = timer.pingPong(kBlurRadiusPingPoingPeriod, kBlurRadiusPingPoingShift,
141                                          kMinBlurRadius, kMaxBlurRadius);
142         return true;
143     }
144
145 private:
146     static constexpr SkScalar kMinRadius = 15;
147     static constexpr SkScalar kMaxRadius = 45;
148     static constexpr SkScalar kRadiusPingPoingPeriod = 8;
149     static constexpr SkScalar kRadiusPingPoingShift = 3;
150
151     static constexpr SkScalar kMinBlurRadius = 5;
152     static constexpr SkScalar kMaxBlurRadius = 45;
153     static constexpr SkScalar kBlurRadiusPingPoingPeriod = 3;
154     static constexpr SkScalar kBlurRadiusPingPoingShift = 1.5;
155
156     SkScalar    fAnimRadius;
157     SkScalar    fAnimBlurRadius;
158
159     SkRandom    fRandom;
160
161     typedef skiagm::GM INHERITED;
162 };
163
164 DEF_GM(return new BlurCircles2GM();)