1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2016 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#include "SkArenaAlloc.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorShader.h"
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorSpace.h"
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPM4fPriv.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRasterPipeline.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkReadBuffer.h"
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkUtils.h"
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkColorShader::SkColorShader(SkColor c) : fColor(c) {}
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SkColorShader::isOpaque() const {
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkColorGetA(fColor) == 255;
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkFlattenable> SkColorShader::CreateProc(SkReadBuffer& buffer) {
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return sk_make_sp<SkColorShader>(buffer.readColor());
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkColorShader::flatten(SkWriteBuffer& buffer) const {
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    buffer.writeColor(fColor);
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotuint32_t SkColorShader::ColorShaderContext::getFlags() const {
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return fFlags;
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkShaderBase::Context* SkColorShader::onMakeContext(const ContextRec& rec,
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                    SkArenaAlloc* alloc) const {
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return alloc->make<ColorShaderContext>(*this, rec);
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shader,
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                      const ContextRec& rec)
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    : INHERITED(shader, rec)
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot{
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkColor color = shader.fColor;
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(rec.fPaint->getAlpha()));
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unsigned r = SkColorGetR(color);
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unsigned g = SkColorGetG(color);
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unsigned b = SkColorGetB(color);
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (a != 255) {
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r = SkMulDiv255Round(r, a);
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        g = SkMulDiv255Round(g, a);
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        b = SkMulDiv255Round(b, a);
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fPMColor = SkPackARGB32(a, r, g, b);
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkColor4f c4 = SkColor4f::FromColor(shader.fColor);
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    c4.fA *= rec.fPaint->getAlpha() / 255.0f;
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fPM4f = c4.premul();
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fFlags = kConstInY32_Flag;
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (255 == a) {
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fFlags |= kOpaqueAlpha_Flag;
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkColorShader::ColorShaderContext::shadeSpan(int x, int y, SkPMColor span[], int count) {
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_memset32(span, fPMColor, count);
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkColorShader::ColorShaderContext::shadeSpan4f(int x, int y, SkPM4f span[], int count) {
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < count; ++i) {
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        span[i] = fPM4f;
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const {
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (info) {
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (info->fColors && info->fColorCount >= 1) {
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            info->fColors[0] = fColor;
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        info->fColorCount = 1;
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        info->fTileMode = SkShader::kRepeat_TileMode;
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return kColor_GradientType;
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGr.h"
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "effects/GrConstColorProcessor.h"
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstd::unique_ptr<GrFragmentProcessor> SkColorShader::asFragmentProcessor(
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const GrFPArgs& args) const {
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrColor4f color = SkColorToPremulGrColor4f(fColor, *args.fDstColorSpaceInfo);
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return GrConstColorProcessor::Make(color, GrConstColorProcessor::InputMode::kModulateA);
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SK_IGNORE_TO_STRING
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkColorShader::toString(SkString* str) const {
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    str->append("SkColorShader: (");
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    str->append("Color: ");
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    str->appendHex(fColor);
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->INHERITED::toString(str);
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    str->append(")");
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot///////////////////////////////////////////////////////////////////////////////////////////////////
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot///////////////////////////////////////////////////////////////////////////////////////////////////
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic unsigned unit_to_byte(float unit) {
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(unit >= 0 && unit <= 1);
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return (unsigned)(unit * 255 + 0.5);
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic SkColor unit_to_skcolor(const SkColor4f& unit, SkColorSpace* cs) {
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkColorSetARGB(unit_to_byte(unit.fA), unit_to_byte(unit.fR),
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                          unit_to_byte(unit.fG), unit_to_byte(unit.fB));
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkColor4Shader::SkColor4Shader(const SkColor4f& color, sk_sp<SkColorSpace> space)
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    : fColorSpace(std::move(space))
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fColor4(color)
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fCachedByteColor(unit_to_skcolor(color.pin(), space.get()))
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot{}
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkFlattenable> SkColor4Shader::CreateProc(SkReadBuffer& buffer) {
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkColor4f color;
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    buffer.readColor4f(&color);
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (buffer.readBool()) {
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // TODO how do we unflatten colorspaces
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkShader::MakeColorShader(color, nullptr);
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkColor4Shader::flatten(SkWriteBuffer& buffer) const {
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    buffer.writeColor4f(fColor4);
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    buffer.writeBool(false);    // TODO how do we flatten colorspaces?
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotuint32_t SkColor4Shader::Color4Context::getFlags() const {
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return fFlags;
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkShaderBase::Context* SkColor4Shader::onMakeContext(const ContextRec& rec,
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                     SkArenaAlloc* alloc) const {
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return alloc->make<Color4Context>(*this, rec);
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkColor4Shader::Color4Context::Color4Context(const SkColor4Shader& shader,
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                      const ContextRec& rec)
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot: INHERITED(shader, rec)
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot{
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkColor color = shader.fCachedByteColor;
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(rec.fPaint->getAlpha()));
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unsigned r = SkColorGetR(color);
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unsigned g = SkColorGetG(color);
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unsigned b = SkColorGetB(color);
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (a != 255) {
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r = SkMulDiv255Round(r, a);
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        g = SkMulDiv255Round(g, a);
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        b = SkMulDiv255Round(b, a);
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fPMColor = SkPackARGB32(a, r, g, b);
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkColor4f c4 = shader.fColor4;
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    c4.fA *= rec.fPaint->getAlpha() * (1 / 255.0f);
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fPM4f = c4.premul();
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fFlags = kConstInY32_Flag;
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (255 == a) {
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fFlags |= kOpaqueAlpha_Flag;
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkColor4Shader::Color4Context::shadeSpan(int x, int y, SkPMColor span[], int count) {
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_memset32(span, fPMColor, count);
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkColor4Shader::Color4Context::shadeSpan4f(int x, int y, SkPM4f span[], int count) {
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < count; ++i) {
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        span[i] = fPM4f;
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// TODO: do we need an updated version of this method for color4+colorspace?
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkShader::GradientType SkColor4Shader::asAGradient(GradientInfo* info) const {
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (info) {
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (info->fColors && info->fColorCount >= 1) {
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            info->fColors[0] = fCachedByteColor;
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        info->fColorCount = 1;
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        info->fTileMode = SkShader::kRepeat_TileMode;
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return kColor_GradientType;
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrColorSpaceInfo.h"
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrColorSpaceXform.h"
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGr.h"
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "effects/GrConstColorProcessor.h"
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstd::unique_ptr<GrFragmentProcessor> SkColor4Shader::asFragmentProcessor(
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const GrFPArgs& args) const {
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Construct an xform assuming float inputs. The color space can have a transfer function on
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // it, which will be applied below.
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    auto colorSpaceXform = GrColorSpaceXform::Make(fColorSpace.get(), kRGBA_float_GrPixelConfig,
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                   args.fDstColorSpaceInfo->colorSpace());
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrColor4f color = GrColor4f::FromSkColor4f(fColor4);
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (colorSpaceXform) {
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        color = colorSpaceXform->clampedXform(color);
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return GrConstColorProcessor::Make(color.premul(),
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       GrConstColorProcessor::InputMode::kModulateA);
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SK_IGNORE_TO_STRING
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkColor4Shader::toString(SkString* str) const {
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    str->append("SkColor4Shader: (");
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    str->append("RGBA:");
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < 4; ++i) {
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        str->appendf(" %g", fColor4.vec()[i]);
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    str->append(" )");
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkShader> SkColor4Shader::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkShader::MakeColorShader(xformer->apply(fCachedByteColor));
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkShader> SkShader::MakeColorShader(const SkColor4f& color, sk_sp<SkColorSpace> space) {
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!SkScalarsAreFinite(color.vec(), 4)) {
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return nullptr;
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return sk_make_sp<SkColor4Shader>(color, std::move(space));
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot///////////////////////////////////////////////////////////////////////////////////////////////////
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SkColorShader::onAppendStages(const StageRec& rec) const {
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rec.fPipeline->append_constant_color(rec.fAlloc, SkPM4f_from_SkColor(fColor, rec.fDstCS));
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return true;
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SkColor4Shader::onAppendStages(const StageRec& rec) const {
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rec.fPipeline->append_constant_color(
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                     rec.fAlloc, to_colorspace(fColor4, fColorSpace.get(), rec.fDstCS).premul());
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return true;
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
263