• 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->colorSpaceInfo(),
105                                                     skPaint, viewMatrix, &grPaint));
106 
107                     GrConstColorProcessor::InputMode mode = (GrConstColorProcessor::InputMode) m;
108                     GrColor4f color = GrColor4f::FromGrColor(kColors[procColor]);
109                     auto fp = GrConstColorProcessor::Make(color, mode);
110 
111                     grPaint.addColorFragmentProcessor(std::move(fp));
112                     renderTargetContext->priv().testingOnly_addDrawOp(
113                             GrRectOpFactory::MakeNonAAFill(std::move(grPaint), viewMatrix,
114                                                            renderRect, GrAAType::kNone));
115 
116                     // Draw labels for the input to the processor and the processor to the right of
117                     // the test rect. The input label appears above the processor label.
118                     SkPaint labelPaint;
119                     sk_tool_utils::set_portable_typeface(&labelPaint);
120                     labelPaint.setAntiAlias(true);
121                     labelPaint.setTextSize(10.f);
122                     SkString inputLabel;
123                     inputLabel.set("Input: ");
124                     if (paintType >= SK_ARRAY_COUNT(kPaintColors)) {
125                         inputLabel.append("gradient");
126                     } else {
127                         inputLabel.appendf("0x%08x", kPaintColors[paintType]);
128                     }
129                     SkString procLabel;
130                     procLabel.printf("Proc: [0x%08x, %s]", kColors[procColor], kModeStrs[m]);
131 
132                     SkRect inputLabelBounds;
133                     // get the bounds of the text in order to position it
134                     labelPaint.measureText(inputLabel.c_str(), inputLabel.size(),
135                                            &inputLabelBounds);
136                     canvas->drawString(inputLabel,
137                                      renderRect.fRight + kPad,
138                                      -inputLabelBounds.fTop, labelPaint);
139                     // update the bounds to reflect the offset we used to draw it.
140                     inputLabelBounds.offset(renderRect.fRight + kPad, -inputLabelBounds.fTop);
141 
142                     SkRect procLabelBounds;
143                     labelPaint.measureText(procLabel.c_str(), procLabel.size(),
144                                            &procLabelBounds);
145                     canvas->drawString(procLabel,
146                                      renderRect.fRight + kPad,
147                                      inputLabelBounds.fBottom + 2.f - procLabelBounds.fTop,
148                                      labelPaint);
149                     procLabelBounds.offset(renderRect.fRight + kPad,
150                                            inputLabelBounds.fBottom + 2.f - procLabelBounds.fTop);
151 
152                     labelPaint.setStrokeWidth(0);
153                     labelPaint.setStyle(SkPaint::kStroke_Style);
154                     canvas->drawRect(renderRect, labelPaint);
155 
156                     canvas->restore();
157 
158                     // update x and y for the next test case.
159                     SkScalar height = renderRect.height();
160                     SkScalar width = SkTMax(inputLabelBounds.fRight, procLabelBounds.fRight);
161                     maxW = SkTMax(maxW, width);
162                     y += height + kPad;
163                     if (y + height > kHeight) {
164                         y = kPad;
165                         x += maxW + kPad;
166                         maxW = 0;
167                     }
168                 }
169             }
170         }
171     }
172 
173 private:
174     // Use this as a way of generating and input FP
175     sk_sp<SkShader> fShader;
176 
177     static constexpr SkScalar       kPad = 10.f;
178     static constexpr SkScalar       kRectSize = 20.f;
179     static constexpr int            kWidth  = 820;
180     static constexpr int            kHeight = 500;
181 
182     typedef GM INHERITED;
183 };
184 
185 DEF_GM(return new ConstColorProcessor;)
186 }
187 
188 #endif
189