blob: d0168092e4025e1681d80021b57a8306a833e75d [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "gm/gm.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040011#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"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050027#include "include/effects/SkGradientShader.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040028#include "include/gpu/GrConfig.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050029#include "include/gpu/GrContext.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040030#include "include/private/GrTypesPriv.h"
31#include "include/private/SkColorData.h"
Brian Osman449b1152020-04-15 16:43:00 -040032#include "src/core/SkMatrixProvider.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040033#include "src/gpu/GrColor.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040034#include "src/gpu/GrFragmentProcessor.h"
35#include "src/gpu/GrPaint.h"
36#include "src/gpu/GrRenderTargetContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050037#include "src/gpu/GrRenderTargetContextPriv.h"
38#include "src/gpu/SkGr.h"
39#include "src/gpu/effects/generated/GrConstColorProcessor.h"
40#include "src/gpu/ops/GrDrawOp.h"
41#include "src/gpu/ops/GrFillRectOp.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040042#include "tools/ToolUtils.h"
43
44#include <utility>
bsalomonc9c3e622015-04-02 11:12:09 -070045
46namespace skiagm {
47/**
48 * This GM directly exercises GrConstColorProcessor.
49 */
Chris Dalton3a778372019-02-07 15:23:36 -070050class ConstColorProcessor : public GpuGM {
bsalomonc9c3e622015-04-02 11:12:09 -070051public:
52 ConstColorProcessor() {
Mike Kleind46dce32018-08-16 10:17:03 -040053 this->setBGColor(0xFFDDDDDD);
bsalomonc9c3e622015-04-02 11:12:09 -070054 }
55
56protected:
57 SkString onShortName() override {
58 return SkString("const_color_processor");
59 }
60
61 SkISize onISize() override {
62 return SkISize::Make(kWidth, kHeight);
63 }
64
65 void onOnceBeforeDraw() override {
66 SkColor colors[] = { 0xFFFF0000, 0x2000FF00, 0xFF0000FF};
67 SkPoint pts[] = { SkPoint::Make(0, 0), SkPoint::Make(kRectSize, kRectSize) };
reed2ad1aa62016-03-09 09:50:50 -080068 fShader = SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
Mike Reedfae8fce2019-04-03 10:27:45 -040069 SkTileMode::kClamp);
bsalomonc9c3e622015-04-02 11:12:09 -070070 }
71
Robert Phillips95c250c2020-06-29 15:36:12 -040072 void onDraw(GrRecordingContext* context, GrRenderTargetContext* renderTargetContext,
Chris Dalton3a778372019-02-07 15:23:36 -070073 SkCanvas* canvas) override {
mtkleindbfd7ab2016-09-01 11:24:54 -070074 constexpr GrColor kColors[] = {
bsalomonc9c3e622015-04-02 11:12:09 -070075 0xFFFFFFFF,
76 0xFFFF00FF,
77 0x80000000,
78 0x00000000,
79 };
80
mtkleindbfd7ab2016-09-01 11:24:54 -070081 constexpr SkColor kPaintColors[] = {
bsalomonc9c3e622015-04-02 11:12:09 -070082 0xFFFFFFFF,
83 0xFFFF0000,
84 0x80FF0000,
85 0x00000000,
86 };
87
mtkleindbfd7ab2016-09-01 11:24:54 -070088 const char* kModeStrs[] {
bsalomonc9c3e622015-04-02 11:12:09 -070089 "kIgnore",
90 "kModulateRGBA",
91 "kModulateA",
92 };
Brian Salomon4dea72a2019-12-18 10:43:10 -050093 static_assert(SK_ARRAY_COUNT(kModeStrs) == GrConstColorProcessor::kInputModeCnt);
bsalomonc9c3e622015-04-02 11:12:09 -070094
95 SkScalar y = kPad;
96 SkScalar x = kPad;
97 SkScalar maxW = 0;
98 for (size_t paintType = 0; paintType < SK_ARRAY_COUNT(kPaintColors) + 1; ++paintType) {
99 for (size_t procColor = 0; procColor < SK_ARRAY_COUNT(kColors); ++procColor) {
100 for (int m = 0; m < GrConstColorProcessor::kInputModeCnt; ++m) {
101 // translate by x,y for the canvas draws and the test target draws.
102 canvas->save();
103 canvas->translate(x, y);
Mike Reed1f607332020-05-21 12:11:27 -0400104 const SkMatrix viewMatrix = SkMatrix::Translate(x, y);
Brian Osman449b1152020-04-15 16:43:00 -0400105 SkSimpleMatrixProvider matrixProvider(viewMatrix);
bsalomonc9c3e622015-04-02 11:12:09 -0700106
107 // rect to draw
108 SkRect renderRect = SkRect::MakeXYWH(0, 0, kRectSize, kRectSize);
109
bsalomonc9c3e622015-04-02 11:12:09 -0700110 GrPaint grPaint;
111 SkPaint skPaint;
112 if (paintType >= SK_ARRAY_COUNT(kPaintColors)) {
113 skPaint.setShader(fShader);
114 } else {
115 skPaint.setColor(kPaintColors[paintType]);
116 }
Brian Salomon4bc0c1f2019-09-30 15:12:27 -0400117 SkAssertResult(SkPaintToGrPaint(context, renderTargetContext->colorInfo(),
Brian Osman449b1152020-04-15 16:43:00 -0400118 skPaint, matrixProvider, &grPaint));
bsalomonc9c3e622015-04-02 11:12:09 -0700119
120 GrConstColorProcessor::InputMode mode = (GrConstColorProcessor::InputMode) m;
Brian Osmancb3d0872018-10-16 15:19:28 -0400121 SkPMColor4f color = SkPMColor4f::FromBytes_RGBA(kColors[procColor]);
John Stilese3a39f72020-06-15 13:58:48 -0400122 auto fp = GrConstColorProcessor::Make(/*inputFP=*/nullptr, color, mode);
bsalomonc9c3e622015-04-02 11:12:09 -0700123
robertphillips28a838e2016-06-23 14:07:00 -0700124 grPaint.addColorFragmentProcessor(std::move(fp));
Brian Salomonac70f842017-05-08 10:43:33 -0400125 renderTargetContext->priv().testingOnly_addDrawOp(
Michael Ludwigaa1b6b32019-05-29 14:43:13 -0400126 GrFillRectOp::MakeNonAARect(context, std::move(grPaint),
127 viewMatrix, renderRect));
bsalomonc9c3e622015-04-02 11:12:09 -0700128
129 // Draw labels for the input to the processor and the processor to the right of
130 // the test rect. The input label appears above the processor label.
Mike Reed94cca602018-12-02 16:04:27 -0500131 SkFont labelFont;
Mike Kleinea3f0142019-03-20 11:12:10 -0500132 labelFont.setTypeface(ToolUtils::create_portable_typeface());
Mike Reed94cca602018-12-02 16:04:27 -0500133 labelFont.setEdging(SkFont::Edging::kAntiAlias);
134 labelFont.setSize(10.f);
bsalomonc9c3e622015-04-02 11:12:09 -0700135 SkPaint labelPaint;
bsalomonc9c3e622015-04-02 11:12:09 -0700136 labelPaint.setAntiAlias(true);
bsalomonc9c3e622015-04-02 11:12:09 -0700137 SkString inputLabel;
138 inputLabel.set("Input: ");
139 if (paintType >= SK_ARRAY_COUNT(kPaintColors)) {
140 inputLabel.append("gradient");
141 } else {
142 inputLabel.appendf("0x%08x", kPaintColors[paintType]);
143 }
144 SkString procLabel;
145 procLabel.printf("Proc: [0x%08x, %s]", kColors[procColor], kModeStrs[m]);
146
147 SkRect inputLabelBounds;
148 // get the bounds of the text in order to position it
Mike Reed94cca602018-12-02 16:04:27 -0500149 labelFont.measureText(inputLabel.c_str(), inputLabel.size(),
Ben Wagner51e15a62019-05-07 15:38:46 -0400150 SkTextEncoding::kUTF8, &inputLabelBounds);
Hal Canary89a644b2019-01-07 09:36:09 -0500151 canvas->drawString(inputLabel, renderRect.fRight + kPad, -inputLabelBounds.fTop,
152 labelFont, labelPaint);
bsalomonc9c3e622015-04-02 11:12:09 -0700153 // update the bounds to reflect the offset we used to draw it.
154 inputLabelBounds.offset(renderRect.fRight + kPad, -inputLabelBounds.fTop);
155
156 SkRect procLabelBounds;
Mike Reed94cca602018-12-02 16:04:27 -0500157 labelFont.measureText(procLabel.c_str(), procLabel.size(),
Ben Wagner51e15a62019-05-07 15:38:46 -0400158 SkTextEncoding::kUTF8, &procLabelBounds);
Hal Canary89a644b2019-01-07 09:36:09 -0500159 canvas->drawString(procLabel, renderRect.fRight + kPad,
160 inputLabelBounds.fBottom + 2.f - procLabelBounds.fTop,
161 labelFont, labelPaint);
bsalomonc9c3e622015-04-02 11:12:09 -0700162 procLabelBounds.offset(renderRect.fRight + kPad,
163 inputLabelBounds.fBottom + 2.f - procLabelBounds.fTop);
164
165 labelPaint.setStrokeWidth(0);
166 labelPaint.setStyle(SkPaint::kStroke_Style);
167 canvas->drawRect(renderRect, labelPaint);
168
169 canvas->restore();
170
171 // update x and y for the next test case.
172 SkScalar height = renderRect.height();
Brian Osman788b9162020-02-07 10:36:46 -0500173 SkScalar width = std::max(inputLabelBounds.fRight, procLabelBounds.fRight);
174 maxW = std::max(maxW, width);
bsalomonc9c3e622015-04-02 11:12:09 -0700175 y += height + kPad;
176 if (y + height > kHeight) {
177 y = kPad;
178 x += maxW + kPad;
179 maxW = 0;
180 }
181 }
182 }
183 }
184 }
185
186private:
187 // Use this as a way of generating and input FP
reed2ad1aa62016-03-09 09:50:50 -0800188 sk_sp<SkShader> fShader;
bsalomonc9c3e622015-04-02 11:12:09 -0700189
mtkleindbfd7ab2016-09-01 11:24:54 -0700190 static constexpr SkScalar kPad = 10.f;
191 static constexpr SkScalar kRectSize = 20.f;
192 static constexpr int kWidth = 820;
193 static constexpr int kHeight = 500;
bsalomonc9c3e622015-04-02 11:12:09 -0700194
195 typedef GM INHERITED;
196};
197
halcanary385fe4d2015-08-26 13:07:48 -0700198DEF_GM(return new ConstColorProcessor;)
bsalomonc9c3e622015-04-02 11:12:09 -0700199}