blob: 8c91a722eccd07a11b94efda440c6ff41f6e9aa8 [file] [log] [blame]
bsalomonc9c3e622015-04-02 11:12:09 -07001/*
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"
robertphillips391395d2016-03-02 09:26:36 -080015#include "GrDrawContextPriv.h"
joshualitt04194f32016-01-13 10:08:27 -080016#include "GrPipelineBuilder.h"
bsalomonf1b7a1d2015-09-28 06:26:28 -070017#include "SkGrPriv.h"
bsalomonc9c3e622015-04-02 11:12:09 -070018#include "SkGradientShader.h"
joshualitt04194f32016-01-13 10:08:27 -080019#include "batches/GrDrawBatch.h"
20#include "batches/GrRectBatchFactory.h"
21#include "effects/GrConstColorProcessor.h"
bsalomonc9c3e622015-04-02 11:12:09 -070022
23namespace skiagm {
24/**
25 * This GM directly exercises GrConstColorProcessor.
26 */
27class ConstColorProcessor : public GM {
28public:
29 ConstColorProcessor() {
caryclark65cdba62015-06-15 06:51:08 -070030 this->setBGColor(sk_tool_utils::color_to_565(0xFFDDDDDD));
bsalomonc9c3e622015-04-02 11:12:09 -070031 }
32
33protected:
34 SkString onShortName() override {
35 return SkString("const_color_processor");
36 }
37
38 SkISize onISize() override {
39 return SkISize::Make(kWidth, kHeight);
40 }
41
42 void onOnceBeforeDraw() override {
43 SkColor colors[] = { 0xFFFF0000, 0x2000FF00, 0xFF0000FF};
44 SkPoint pts[] = { SkPoint::Make(0, 0), SkPoint::Make(kRectSize, kRectSize) };
reed2ad1aa62016-03-09 09:50:50 -080045 fShader = SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
46 SkShader::kClamp_TileMode);
bsalomonc9c3e622015-04-02 11:12:09 -070047 }
48
49 void onDraw(SkCanvas* canvas) override {
50 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
halcanary96fcdcc2015-08-27 07:41:13 -070051 if (nullptr == rt) {
bsalomonc9c3e622015-04-02 11:12:09 -070052 return;
53 }
54 GrContext* context = rt->getContext();
halcanary96fcdcc2015-08-27 07:41:13 -070055 if (nullptr == context) {
halcanary2a243382015-09-09 08:16:41 -070056 skiagm::GM::DrawGpuOnlyMessage(canvas);
bsalomonc9c3e622015-04-02 11:12:09 -070057 return;
58 }
59
joshualitt04194f32016-01-13 10:08:27 -080060 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(rt));
61 if (!drawContext) {
62 return;
63 }
64
bsalomonc9c3e622015-04-02 11:12:09 -070065 static const GrColor kColors[] = {
66 0xFFFFFFFF,
67 0xFFFF00FF,
68 0x80000000,
69 0x00000000,
70 };
71
72 static const SkColor kPaintColors[] = {
73 0xFFFFFFFF,
74 0xFFFF0000,
75 0x80FF0000,
76 0x00000000,
77 };
78
79 static const char* kModeStrs[] {
80 "kIgnore",
81 "kModulateRGBA",
82 "kModulateA",
83 };
84 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kModeStrs) == GrConstColorProcessor::kInputModeCnt);
85
86 SkScalar y = kPad;
87 SkScalar x = kPad;
88 SkScalar maxW = 0;
89 for (size_t paintType = 0; paintType < SK_ARRAY_COUNT(kPaintColors) + 1; ++paintType) {
90 for (size_t procColor = 0; procColor < SK_ARRAY_COUNT(kColors); ++procColor) {
91 for (int m = 0; m < GrConstColorProcessor::kInputModeCnt; ++m) {
92 // translate by x,y for the canvas draws and the test target draws.
93 canvas->save();
94 canvas->translate(x, y);
95 const SkMatrix viewMatrix = SkMatrix::MakeTrans(x, y);
96
97 // rect to draw
98 SkRect renderRect = SkRect::MakeXYWH(0, 0, kRectSize, kRectSize);
99
bsalomonc9c3e622015-04-02 11:12:09 -0700100 GrPaint grPaint;
101 SkPaint skPaint;
102 if (paintType >= SK_ARRAY_COUNT(kPaintColors)) {
103 skPaint.setShader(fShader);
104 } else {
105 skPaint.setColor(kPaintColors[paintType]);
106 }
bsalomonf1b7a1d2015-09-28 06:26:28 -0700107 SkAssertResult(SkPaintToGrPaint(context, skPaint, viewMatrix, &grPaint));
bsalomonc9c3e622015-04-02 11:12:09 -0700108
109 GrConstColorProcessor::InputMode mode = (GrConstColorProcessor::InputMode) m;
110 GrColor color = kColors[procColor];
111 SkAutoTUnref<GrFragmentProcessor> fp(GrConstColorProcessor::Create(color, mode));
112
bsalomonc9c3e622015-04-02 11:12:09 -0700113 GrClip clip;
joshualitt7b670db2015-07-09 13:25:02 -0700114 GrPipelineBuilder pipelineBuilder(grPaint, rt, clip);
bsalomonac856c92015-08-27 06:30:17 -0700115 pipelineBuilder.addColorFragmentProcessor(fp);
bsalomonc9c3e622015-04-02 11:12:09 -0700116
joshualitt04194f32016-01-13 10:08:27 -0800117 SkAutoTUnref<GrDrawBatch> batch(
118 GrRectBatchFactory::CreateNonAAFill(grPaint.getColor(), viewMatrix,
119 renderRect, nullptr, nullptr));
robertphillips391395d2016-03-02 09:26:36 -0800120 drawContext->drawContextPriv().testingOnly_drawBatch(pipelineBuilder, batch);
bsalomonc9c3e622015-04-02 11:12:09 -0700121
122 // Draw labels for the input to the processor and the processor to the right of
123 // the test rect. The input label appears above the processor label.
124 SkPaint labelPaint;
caryclark1818acb2015-07-24 12:09:25 -0700125 sk_tool_utils::set_portable_typeface(&labelPaint);
bsalomonc9c3e622015-04-02 11:12:09 -0700126 labelPaint.setAntiAlias(true);
127 labelPaint.setTextSize(10.f);
128 SkString inputLabel;
129 inputLabel.set("Input: ");
130 if (paintType >= SK_ARRAY_COUNT(kPaintColors)) {
131 inputLabel.append("gradient");
132 } else {
133 inputLabel.appendf("0x%08x", kPaintColors[paintType]);
134 }
135 SkString procLabel;
136 procLabel.printf("Proc: [0x%08x, %s]", kColors[procColor], kModeStrs[m]);
137
138 SkRect inputLabelBounds;
139 // get the bounds of the text in order to position it
140 labelPaint.measureText(inputLabel.c_str(), inputLabel.size(),
141 &inputLabelBounds);
142 canvas->drawText(inputLabel.c_str(), inputLabel.size(),
143 renderRect.fRight + kPad,
144 -inputLabelBounds.fTop, labelPaint);
145 // update the bounds to reflect the offset we used to draw it.
146 inputLabelBounds.offset(renderRect.fRight + kPad, -inputLabelBounds.fTop);
147
148 SkRect procLabelBounds;
149 labelPaint.measureText(procLabel.c_str(), procLabel.size(),
150 &procLabelBounds);
151 canvas->drawText(procLabel.c_str(), procLabel.size(),
152 renderRect.fRight + kPad,
153 inputLabelBounds.fBottom + 2.f - procLabelBounds.fTop,
154 labelPaint);
155 procLabelBounds.offset(renderRect.fRight + kPad,
156 inputLabelBounds.fBottom + 2.f - procLabelBounds.fTop);
157
158 labelPaint.setStrokeWidth(0);
159 labelPaint.setStyle(SkPaint::kStroke_Style);
160 canvas->drawRect(renderRect, labelPaint);
161
162 canvas->restore();
163
164 // update x and y for the next test case.
165 SkScalar height = renderRect.height();
166 SkScalar width = SkTMax(inputLabelBounds.fRight, procLabelBounds.fRight);
167 maxW = SkTMax(maxW, width);
168 y += height + kPad;
169 if (y + height > kHeight) {
170 y = kPad;
171 x += maxW + kPad;
172 maxW = 0;
173 }
174 }
175 }
176 }
177 }
178
179private:
180 // Use this as a way of generating and input FP
reed2ad1aa62016-03-09 09:50:50 -0800181 sk_sp<SkShader> fShader;
bsalomonc9c3e622015-04-02 11:12:09 -0700182
183 static const SkScalar kPad;
184 static const SkScalar kRectSize;
185 static const int kWidth = 820;
186 static const int kHeight = 500;
187
188 typedef GM INHERITED;
189};
190
191const SkScalar ConstColorProcessor::kPad = 10.f;
192const SkScalar ConstColorProcessor::kRectSize = 20.f;
193
halcanary385fe4d2015-08-26 13:07:48 -0700194DEF_GM(return new ConstColorProcessor;)
bsalomonc9c3e622015-04-02 11:12:09 -0700195}
196
197#endif