1 /*
2  * Copyright 2012 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/gm.h"
9 #include "include/core/SkBitmap.h"
10 #include "include/core/SkBlurTypes.h"
11 #include "include/core/SkCanvas.h"
12 #include "include/core/SkColor.h"
13 #include "include/core/SkFont.h"
14 #include "include/core/SkMaskFilter.h"
15 #include "include/core/SkPaint.h"
16 #include "include/core/SkPath.h"
17 #include "include/core/SkRect.h"
18 #include "include/core/SkRefCnt.h"
19 #include "include/core/SkScalar.h"
20 #include "include/core/SkShader.h"
21 #include "include/core/SkSize.h"
22 #include "include/core/SkString.h"
23 #include "include/core/SkTileMode.h"
24 #include "include/core/SkTypeface.h"
25 #include "tools/ToolUtils.h"
26 
27 namespace skiagm {
28 
29 /**
30  * Stress test the GPU samplers by rendering a textured glyph with a mask and
31  * an AA clip
32  */
33 class SamplerStressGM : public GM {
34 public:
SamplerStressGM()35     SamplerStressGM()
36     : fTextureCreated(false)
37     , fMaskFilter(nullptr) {
38     }
39 
40 protected:
41 
onShortName()42     SkString onShortName() override {
43         return SkString("gpusamplerstress");
44     }
45 
onISize()46     SkISize onISize() override {
47         return SkISize::Make(640, 480);
48     }
49 
50     /**
51      * Create a red & green stripes on black texture
52      */
createTexture()53     void createTexture() {
54         if (fTextureCreated) {
55             return;
56         }
57 
58         constexpr int xSize = 16;
59         constexpr int ySize = 16;
60 
61         fTexture.allocN32Pixels(xSize, ySize);
62         SkPMColor* addr = fTexture.getAddr32(0, 0);
63 
64         for (int y = 0; y < ySize; ++y) {
65             for (int x = 0; x < xSize; ++x) {
66                 addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorBLACK);
67 
68                 if ((y % 5) == 0) {
69                     addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorRED);
70                 }
71                 if ((x % 7) == 0) {
72                     addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorGREEN);
73                 }
74             }
75         }
76 
77         fTextureCreated = true;
78     }
79 
createShader()80     void createShader() {
81         if (fShader) {
82             return;
83         }
84 
85         createTexture();
86 
87         fShader = fTexture.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
88                                       SkSamplingOptions());
89     }
90 
createMaskFilter()91     void createMaskFilter() {
92         if (fMaskFilter) {
93             return;
94         }
95 
96         const SkScalar sigma = 1;
97         fMaskFilter = SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, sigma);
98     }
99 
onDraw(SkCanvas * canvas)100     void onDraw(SkCanvas* canvas) override {
101         createShader();
102         createMaskFilter();
103 
104         canvas->save();
105 
106         // draw a letter "M" with a green & red striped texture and a
107         // stipple mask with a round rect soft clip
108         SkPaint paint;
109         paint.setAntiAlias(true);
110         paint.setShader(fShader);
111         paint.setMaskFilter(fMaskFilter);
112         SkFont font(ToolUtils::create_portable_typeface(), 72);
113 
114         SkRect temp;
115         temp.setLTRB(115, 75, 144, 110);
116 
117         SkPath path;
118         path.addRoundRect(temp, SkIntToScalar(5), SkIntToScalar(5));
119 
120         canvas->clipPath(path, true); // AA is on
121 
122         canvas->drawString("M", 100.0f, 100.0f, font, paint);
123 
124         canvas->restore();
125 
126         // Now draw stroked versions of the "M" and the round rect so we can
127         // see what is going on
128         SkPaint paint2;
129         paint2.setColor(SK_ColorBLACK);
130         paint2.setAntiAlias(true);
131         paint2.setStyle(SkPaint::kStroke_Style);
132         paint2.setStrokeWidth(1);
133         canvas->drawString("M", 100.0f, 100.0f, font, paint2);
134 
135         paint2.setColor(SK_ColorGRAY);
136 
137         canvas->drawPath(path, paint2);
138     }
139 
140 private:
141     SkBitmap        fTexture;
142     bool            fTextureCreated;
143     sk_sp<SkShader> fShader;
144     sk_sp<SkMaskFilter> fMaskFilter;
145 
146     using INHERITED = GM;
147 };
148 
149 //////////////////////////////////////////////////////////////////////////////
150 
151 DEF_GM( return new SamplerStressGM; )
152 
153 }  // namespace skiagm
154