Make skpaint->grpaint flow work for composing draws (verts and atlas)
[platform/upstream/libSkiaSharp.git] / gm / constcolorprocessor.cpp
1
2 /*
3  * Copyright 2015 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8
9 // This test only works with the GPU backend.
10
11 #include "gm.h"
12
13 #if SK_SUPPORT_GPU
14
15 #include "GrContext.h"
16 #include "GrTest.h"
17 #include "effects/GrConstColorProcessor.h"
18 #include "SkGrPriv.h"
19 #include "SkGradientShader.h"
20
21 namespace skiagm {
22 /**
23  * This GM directly exercises GrConstColorProcessor.
24  */
25 class ConstColorProcessor : public GM {
26 public:
27     ConstColorProcessor() {
28         this->setBGColor(sk_tool_utils::color_to_565(0xFFDDDDDD));
29     }
30
31 protected:
32     SkString onShortName() override {
33         return SkString("const_color_processor");
34     }
35
36     SkISize onISize() override {
37         return SkISize::Make(kWidth, kHeight);
38     }
39
40     void onOnceBeforeDraw() override {
41         SkColor colors[] = { 0xFFFF0000, 0x2000FF00, 0xFF0000FF};
42         SkPoint pts[] = { SkPoint::Make(0, 0), SkPoint::Make(kRectSize, kRectSize) };
43         fShader.reset(SkGradientShader::CreateLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
44                        SkShader::kClamp_TileMode));
45     }
46
47     void onDraw(SkCanvas* canvas) override {
48         GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
49         if (nullptr == rt) {
50             return;
51         }
52         GrContext* context = rt->getContext();
53         if (nullptr == context) {
54             skiagm::GM::DrawGpuOnlyMessage(canvas);
55             return;
56         }
57
58         static const GrColor kColors[] = {
59             0xFFFFFFFF,
60             0xFFFF00FF,
61             0x80000000,
62             0x00000000,
63         };
64
65         static const SkColor kPaintColors[] = {
66             0xFFFFFFFF,
67             0xFFFF0000,
68             0x80FF0000,
69             0x00000000,
70         };
71
72         static const char* kModeStrs[] {
73             "kIgnore",
74             "kModulateRGBA",
75             "kModulateA",
76         };
77         GR_STATIC_ASSERT(SK_ARRAY_COUNT(kModeStrs) == GrConstColorProcessor::kInputModeCnt);
78
79         SkScalar y = kPad;
80         SkScalar x = kPad;
81         SkScalar maxW = 0;
82         for (size_t paintType = 0; paintType < SK_ARRAY_COUNT(kPaintColors) + 1; ++paintType) {
83             for (size_t procColor = 0; procColor < SK_ARRAY_COUNT(kColors); ++procColor) {
84                 for (int m = 0; m < GrConstColorProcessor::kInputModeCnt; ++m) {
85                     // translate by x,y for the canvas draws and the test target draws.
86                     canvas->save();
87                     canvas->translate(x, y);
88                     const SkMatrix viewMatrix = SkMatrix::MakeTrans(x, y);
89
90                     // rect to draw
91                     SkRect renderRect = SkRect::MakeXYWH(0, 0, kRectSize, kRectSize);
92
93                     GrTestTarget tt;
94                     context->getTestTarget(&tt);
95                     if (nullptr == tt.target()) {
96                         SkDEBUGFAIL("Couldn't get Gr test target.");
97                         return;
98                     }
99
100                     GrPaint grPaint;
101                     SkPaint skPaint;
102                     if (paintType >= SK_ARRAY_COUNT(kPaintColors)) {
103                         skPaint.setShader(fShader);
104                     } else {
105                         skPaint.setColor(kPaintColors[paintType]);
106                     }
107                     SkAssertResult(SkPaintToGrPaint(context, skPaint, viewMatrix, &grPaint));
108
109                     GrConstColorProcessor::InputMode mode = (GrConstColorProcessor::InputMode) m;
110                     GrColor color = kColors[procColor];
111                     SkAutoTUnref<GrFragmentProcessor> fp(GrConstColorProcessor::Create(color, mode));
112
113                     GrClip clip;
114                     GrPipelineBuilder pipelineBuilder(grPaint, rt, clip);
115                     pipelineBuilder.addColorFragmentProcessor(fp);
116
117                     tt.target()->drawNonAARect(pipelineBuilder,
118                                                grPaint.getColor(),
119                                                viewMatrix,
120                                                renderRect);
121
122                     // Draw labels for the input to the processor and the processor to the right of
123                     // the test rect. The input label appears above the processor label.
124                     SkPaint labelPaint;
125                     sk_tool_utils::set_portable_typeface(&labelPaint);
126                     labelPaint.setAntiAlias(true);
127                     labelPaint.setTextSize(10.f);
128                     SkString inputLabel;
129                     inputLabel.set("Input: ");
130                     if (paintType >= SK_ARRAY_COUNT(kPaintColors)) {
131                         inputLabel.append("gradient");
132                     } else {
133                         inputLabel.appendf("0x%08x", kPaintColors[paintType]);
134                     }
135                     SkString procLabel;
136                     procLabel.printf("Proc: [0x%08x, %s]", kColors[procColor], kModeStrs[m]);
137
138                     SkRect inputLabelBounds;
139                     // get the bounds of the text in order to position it
140                     labelPaint.measureText(inputLabel.c_str(), inputLabel.size(),
141                                            &inputLabelBounds);
142                     canvas->drawText(inputLabel.c_str(), inputLabel.size(),
143                                      renderRect.fRight + kPad,
144                                      -inputLabelBounds.fTop, labelPaint);
145                     // update the bounds to reflect the offset we used to draw it.
146                     inputLabelBounds.offset(renderRect.fRight + kPad, -inputLabelBounds.fTop);
147
148                     SkRect procLabelBounds;
149                     labelPaint.measureText(procLabel.c_str(), procLabel.size(),
150                                            &procLabelBounds);
151                     canvas->drawText(procLabel.c_str(), procLabel.size(),
152                                      renderRect.fRight + kPad,
153                                      inputLabelBounds.fBottom + 2.f - procLabelBounds.fTop,
154                                      labelPaint);
155                     procLabelBounds.offset(renderRect.fRight + kPad,
156                                            inputLabelBounds.fBottom + 2.f - procLabelBounds.fTop);
157
158                     labelPaint.setStrokeWidth(0);
159                     labelPaint.setStyle(SkPaint::kStroke_Style);
160                     canvas->drawRect(renderRect, labelPaint);
161
162                     canvas->restore();
163
164                     // update x and y for the next test case.
165                     SkScalar height = renderRect.height();
166                     SkScalar width = SkTMax(inputLabelBounds.fRight, procLabelBounds.fRight);
167                     maxW = SkTMax(maxW, width);
168                     y += height + kPad;
169                     if (y + height > kHeight) {
170                         y = kPad;
171                         x += maxW + kPad;
172                         maxW = 0;
173                     }
174                 }
175             }
176         }
177     }
178
179 private:
180     // Use this as a way of generating and input FP
181     SkAutoTUnref<SkShader>      fShader;
182
183     static const SkScalar       kPad;
184     static const SkScalar       kRectSize;
185     static const int            kWidth  = 820;
186     static const int            kHeight = 500;
187
188     typedef GM INHERITED;
189 };
190
191 const SkScalar ConstColorProcessor::kPad = 10.f;
192 const SkScalar ConstColorProcessor::kRectSize = 20.f;
193
194 DEF_GM(return new ConstColorProcessor;)
195 }
196
197 #endif