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