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