• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 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 #include "src/shaders/SkColorShader.h"
9 
10 #include "include/core/SkColorSpace.h"
11 #include "src/core/SkArenaAlloc.h"
12 #include "src/core/SkColorSpacePriv.h"
13 #include "src/core/SkColorSpaceXformSteps.h"
14 #include "src/core/SkKeyHelpers.h"
15 #include "src/core/SkRasterPipeline.h"
16 #include "src/core/SkReadBuffer.h"
17 #include "src/core/SkUtils.h"
18 #include "src/core/SkVM.h"
19 
SkColorShader(SkColor c)20 SkColorShader::SkColorShader(SkColor c) : fColor(c) {}
21 
isOpaque() const22 bool SkColorShader::isOpaque() const {
23     return SkColorGetA(fColor) == 255;
24 }
25 
CreateProc(SkReadBuffer & buffer)26 sk_sp<SkFlattenable> SkColorShader::CreateProc(SkReadBuffer& buffer) {
27     return sk_make_sp<SkColorShader>(buffer.readColor());
28 }
29 
flatten(SkWriteBuffer & buffer) const30 void SkColorShader::flatten(SkWriteBuffer& buffer) const {
31     buffer.writeColor(fColor);
32 }
33 
asAGradient(GradientInfo * info) const34 SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const {
35     if (info) {
36         if (info->fColors && info->fColorCount >= 1) {
37             info->fColors[0] = fColor;
38         }
39         info->fColorCount = 1;
40         info->fTileMode = SkTileMode::kRepeat;
41     }
42     return kColor_GradientType;
43 }
44 
SkColor4Shader(const SkColor4f & color,sk_sp<SkColorSpace> space)45 SkColor4Shader::SkColor4Shader(const SkColor4f& color, sk_sp<SkColorSpace> space)
46     : fColorSpace(std::move(space))
47     , fColor({color.fR, color.fG, color.fB, SkTPin(color.fA, 0.0f, 1.0f)})
48 {}
49 
CreateProc(SkReadBuffer & buffer)50 sk_sp<SkFlattenable> SkColor4Shader::CreateProc(SkReadBuffer& buffer) {
51     SkColor4f color;
52     sk_sp<SkColorSpace> colorSpace;
53     buffer.readColor4f(&color);
54     if (buffer.readBool()) {
55         sk_sp<SkData> data = buffer.readByteArrayAsData();
56         colorSpace = data ? SkColorSpace::Deserialize(data->data(), data->size()) : nullptr;
57     }
58     return SkShaders::Color(color, std::move(colorSpace));
59 }
60 
flatten(SkWriteBuffer & buffer) const61 void SkColor4Shader::flatten(SkWriteBuffer& buffer) const {
62     buffer.writeColor4f(fColor);
63     sk_sp<SkData> colorSpaceData = fColorSpace ? fColorSpace->serialize() : nullptr;
64     if (colorSpaceData) {
65         buffer.writeBool(true);
66         buffer.writeDataAsByteArray(colorSpaceData.get());
67     } else {
68         buffer.writeBool(false);
69     }
70 }
71 
72 
Color(const SkColor4f & color,sk_sp<SkColorSpace> space)73 sk_sp<SkShader> SkShaders::Color(const SkColor4f& color, sk_sp<SkColorSpace> space) {
74     if (!SkScalarsAreFinite(color.vec(), 4)) {
75         return nullptr;
76     }
77     return sk_make_sp<SkColor4Shader>(color, std::move(space));
78 }
79 
onAppendStages(const SkStageRec & rec) const80 bool SkColorShader::onAppendStages(const SkStageRec& rec) const {
81     SkColor4f color = SkColor4f::FromColor(fColor);
82     SkColorSpaceXformSteps(sk_srgb_singleton(), kUnpremul_SkAlphaType,
83                            rec.fDstCS,          kUnpremul_SkAlphaType).apply(color.vec());
84     rec.fPipeline->append_constant_color(rec.fAlloc, color.premul().vec());
85     return true;
86 }
87 
onAppendStages(const SkStageRec & rec) const88 bool SkColor4Shader::onAppendStages(const SkStageRec& rec) const {
89     SkColor4f color = fColor;
90     SkColorSpaceXformSteps(fColorSpace.get(), kUnpremul_SkAlphaType,
91                            rec.fDstCS,        kUnpremul_SkAlphaType).apply(color.vec());
92     rec.fPipeline->append_constant_color(rec.fAlloc, color.premul().vec());
93     return true;
94 }
95 
onProgram(skvm::Builder * p,skvm::Coord,skvm::Coord,skvm::Color,const SkMatrixProvider &,const SkMatrix *,const SkColorInfo & dst,skvm::Uniforms * uniforms,SkArenaAlloc *) const96 skvm::Color SkColorShader::onProgram(skvm::Builder* p,
97                                      skvm::Coord /*device*/, skvm::Coord /*local*/,
98                                      skvm::Color /*paint*/, const SkMatrixProvider&,
99                                      const SkMatrix* /*localM*/, const SkColorInfo& dst,
100                                      skvm::Uniforms* uniforms, SkArenaAlloc*) const {
101     SkColor4f color = SkColor4f::FromColor(fColor);
102     SkColorSpaceXformSteps(sk_srgb_singleton(), kUnpremul_SkAlphaType,
103                               dst.colorSpace(),   kPremul_SkAlphaType).apply(color.vec());
104     return p->uniformColor(color, uniforms);
105 }
onProgram(skvm::Builder * p,skvm::Coord,skvm::Coord,skvm::Color,const SkMatrixProvider &,const SkMatrix *,const SkColorInfo & dst,skvm::Uniforms * uniforms,SkArenaAlloc *) const106 skvm::Color SkColor4Shader::onProgram(skvm::Builder* p,
107                                       skvm::Coord /*device*/, skvm::Coord /*local*/,
108                                       skvm::Color /*paint*/, const SkMatrixProvider&,
109                                       const SkMatrix* /*localM*/, const SkColorInfo& dst,
110                                       skvm::Uniforms* uniforms, SkArenaAlloc*) const {
111     SkColor4f color = fColor;
112     SkColorSpaceXformSteps(fColorSpace.get(), kUnpremul_SkAlphaType,
113                             dst.colorSpace(),   kPremul_SkAlphaType).apply(color.vec());
114     return p->uniformColor(color, uniforms);
115 }
116 
117 #if SK_SUPPORT_GPU
118 
119 #include "src/gpu/GrColorInfo.h"
120 #include "src/gpu/GrColorSpaceXform.h"
121 #include "src/gpu/GrFragmentProcessor.h"
122 #include "src/gpu/SkGr.h"
123 
asFragmentProcessor(const GrFPArgs & args) const124 std::unique_ptr<GrFragmentProcessor> SkColorShader::asFragmentProcessor(
125         const GrFPArgs& args) const {
126     return GrFragmentProcessor::MakeColor(SkColorToPMColor4f(fColor, *args.fDstColorInfo));
127 }
128 
asFragmentProcessor(const GrFPArgs & args) const129 std::unique_ptr<GrFragmentProcessor> SkColor4Shader::asFragmentProcessor(
130         const GrFPArgs& args) const {
131     SkColorSpaceXformSteps steps{ fColorSpace.get(),                kUnpremul_SkAlphaType,
132                                   args.fDstColorInfo->colorSpace(), kUnpremul_SkAlphaType };
133     SkColor4f color = fColor;
134     steps.apply(color.vec());
135     return GrFragmentProcessor::MakeColor(color.premul());
136 }
137 
138 #endif
139 
addToKey(SkShaderCodeDictionary * dict,SkBackend backend,SkPaintParamsKeyBuilder * builder,SkUniformBlock * uniformBlock) const140 void SkColorShader::addToKey(SkShaderCodeDictionary* dict,
141                              SkBackend backend,
142                              SkPaintParamsKeyBuilder* builder,
143                              SkUniformBlock* uniformBlock) const {
144     SolidColorShaderBlock::AddToKey(dict, backend, builder, uniformBlock,
145                                     SkColor4f::FromColor(fColor));
146 }
147 
addToKey(SkShaderCodeDictionary * dict,SkBackend backend,SkPaintParamsKeyBuilder * builder,SkUniformBlock * uniformBlock) const148 void SkColor4Shader::addToKey(SkShaderCodeDictionary* dict,
149                               SkBackend backend,
150                               SkPaintParamsKeyBuilder* builder,
151                               SkUniformBlock* uniformBlock) const {
152     SolidColorShaderBlock::AddToKey(dict, backend, builder, uniformBlock, fColor);
153 }
154