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