1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2015 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// This test only works with the GPU backend.
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "gm.h"
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "sk_tool_utils.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrContext.h"
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrRenderTargetContextPriv.h"
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGr.h"
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGradientShader.h"
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "effects/GrConstColorProcessor.h"
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "ops/GrDrawOp.h"
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "ops/GrRectOpFactory.h"
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotnamespace skiagm {
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/**
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * This GM directly exercises GrConstColorProcessor.
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass ConstColorProcessor : public GM {
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ConstColorProcessor() {
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->setBGColor(sk_tool_utils::color_to_565(0xFFDDDDDD));
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString onShortName() override {
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkString("const_color_processor");
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkISize onISize() override {
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkISize::Make(kWidth, kHeight);
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onOnceBeforeDraw() override {
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkColor colors[] = { 0xFFFF0000, 0x2000FF00, 0xFF0000FF};
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPoint pts[] = { SkPoint::Make(0, 0), SkPoint::Make(kRectSize, kRectSize) };
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fShader = SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                               SkShader::kClamp_TileMode);
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onDraw(SkCanvas* canvas) override {
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrRenderTargetContext* renderTargetContext =
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->internal_private_accessTopLayerRenderTargetContext();
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!renderTargetContext) {
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            skiagm::GM::DrawGpuOnlyMessage(canvas);
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return;
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrContext* context = canvas->getGrContext();
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!context) {
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return;
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        constexpr GrColor kColors[] = {
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            0xFFFFFFFF,
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            0xFFFF00FF,
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            0x80000000,
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            0x00000000,
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        constexpr SkColor kPaintColors[] = {
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            0xFFFFFFFF,
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            0xFFFF0000,
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            0x80FF0000,
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            0x00000000,
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* kModeStrs[] {
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            "kIgnore",
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            "kModulateRGBA",
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            "kModulateA",
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GR_STATIC_ASSERT(SK_ARRAY_COUNT(kModeStrs) == GrConstColorProcessor::kInputModeCnt);
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar y = kPad;
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar x = kPad;
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar maxW = 0;
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (size_t paintType = 0; paintType < SK_ARRAY_COUNT(kPaintColors) + 1; ++paintType) {
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (size_t procColor = 0; procColor < SK_ARRAY_COUNT(kColors); ++procColor) {
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                for (int m = 0; m < GrConstColorProcessor::kInputModeCnt; ++m) {
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    // translate by x,y for the canvas draws and the test target draws.
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    canvas->save();
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    canvas->translate(x, y);
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    const SkMatrix viewMatrix = SkMatrix::MakeTrans(x, y);
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    // rect to draw
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkRect renderRect = SkRect::MakeXYWH(0, 0, kRectSize, kRectSize);
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    GrPaint grPaint;
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkPaint skPaint;
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (paintType >= SK_ARRAY_COUNT(kPaintColors)) {
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        skPaint.setShader(fShader);
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    } else {
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        skPaint.setColor(kPaintColors[paintType]);
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkAssertResult(SkPaintToGrPaint(context, renderTargetContext->colorSpaceInfo(),
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                    skPaint, viewMatrix, &grPaint));
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    GrConstColorProcessor::InputMode mode = (GrConstColorProcessor::InputMode) m;
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    GrColor4f color = GrColor4f::FromGrColor(kColors[procColor]);
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    auto fp = GrConstColorProcessor::Make(color, mode);
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    grPaint.addColorFragmentProcessor(std::move(fp));
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    renderTargetContext->priv().testingOnly_addDrawOp(
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            GrRectOpFactory::MakeNonAAFill(std::move(grPaint), viewMatrix,
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                           renderRect, GrAAType::kNone));
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    // Draw labels for the input to the processor and the processor to the right of
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    // the test rect. The input label appears above the processor label.
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkPaint labelPaint;
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    sk_tool_utils::set_portable_typeface(&labelPaint);
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    labelPaint.setAntiAlias(true);
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    labelPaint.setTextSize(10.f);
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkString inputLabel;
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    inputLabel.set("Input: ");
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (paintType >= SK_ARRAY_COUNT(kPaintColors)) {
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        inputLabel.append("gradient");
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    } else {
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        inputLabel.appendf("0x%08x", kPaintColors[paintType]);
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkString procLabel;
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    procLabel.printf("Proc: [0x%08x, %s]", kColors[procColor], kModeStrs[m]);
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkRect inputLabelBounds;
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    // get the bounds of the text in order to position it
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    labelPaint.measureText(inputLabel.c_str(), inputLabel.size(),
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                           &inputLabelBounds);
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    canvas->drawString(inputLabel,
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                     renderRect.fRight + kPad,
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                     -inputLabelBounds.fTop, labelPaint);
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    // update the bounds to reflect the offset we used to draw it.
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    inputLabelBounds.offset(renderRect.fRight + kPad, -inputLabelBounds.fTop);
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkRect procLabelBounds;
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    labelPaint.measureText(procLabel.c_str(), procLabel.size(),
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                           &procLabelBounds);
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    canvas->drawString(procLabel,
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                     renderRect.fRight + kPad,
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                     inputLabelBounds.fBottom + 2.f - procLabelBounds.fTop,
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                     labelPaint);
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    procLabelBounds.offset(renderRect.fRight + kPad,
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                           inputLabelBounds.fBottom + 2.f - procLabelBounds.fTop);
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    labelPaint.setStrokeWidth(0);
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    labelPaint.setStyle(SkPaint::kStroke_Style);
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    canvas->drawRect(renderRect, labelPaint);
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    canvas->restore();
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    // update x and y for the next test case.
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkScalar height = renderRect.height();
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkScalar width = SkTMax(inputLabelBounds.fRight, procLabelBounds.fRight);
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    maxW = SkTMax(maxW, width);
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    y += height + kPad;
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (y + height > kHeight) {
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        y = kPad;
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        x += maxW + kPad;
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        maxW = 0;
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Use this as a way of generating and input FP
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkShader> fShader;
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr SkScalar       kPad = 10.f;
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr SkScalar       kRectSize = 20.f;
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr int            kWidth  = 820;
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr int            kHeight = 500;
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef GM INHERITED;
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM(return new ConstColorProcessor;)
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
189