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