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