• 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 "include/core/SkColorSpace.h"
9 #include "src/core/SkArenaAlloc.h"
10 #include "src/core/SkColorSpacePriv.h"
11 #include "src/core/SkColorSpaceXformSteps.h"
12 #include "src/core/SkRasterPipeline.h"
13 #include "src/core/SkReadBuffer.h"
14 #include "src/core/SkUtils.h"
15 #include "src/core/SkVM.h"
16 #include "src/shaders/SkColorShader.h"
17 
SkColorShader(SkColor c)18 SkColorShader::SkColorShader(SkColor c) : fColor(c) {}
19 
isOpaque() const20 bool SkColorShader::isOpaque() const {
21     return SkColorGetA(fColor) == 255;
22 }
23 
CreateProc(SkReadBuffer & buffer)24 sk_sp<SkFlattenable> SkColorShader::CreateProc(SkReadBuffer& buffer) {
25     return sk_make_sp<SkColorShader>(buffer.readColor());
26 }
27 
flatten(SkWriteBuffer & buffer) const28 void SkColorShader::flatten(SkWriteBuffer& buffer) const {
29     buffer.writeColor(fColor);
30 }
31 
asAGradient(GradientInfo * info) const32 SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const {
33     if (info) {
34         if (info->fColors && info->fColorCount >= 1) {
35             info->fColors[0] = fColor;
36         }
37         info->fColorCount = 1;
38         info->fTileMode = SkTileMode::kRepeat;
39     }
40     return kColor_GradientType;
41 }
42 
SkColor4Shader(const SkColor4f & color,sk_sp<SkColorSpace> space)43 SkColor4Shader::SkColor4Shader(const SkColor4f& color, sk_sp<SkColorSpace> space)
44     : fColorSpace(std::move(space))
45     , fColor({color.fR, color.fG, color.fB, SkTPin(color.fA, 0.0f, 1.0f)})
46 {}
47 
CreateProc(SkReadBuffer & buffer)48 sk_sp<SkFlattenable> SkColor4Shader::CreateProc(SkReadBuffer& buffer) {
49     SkColor4f color;
50     sk_sp<SkColorSpace> colorSpace;
51     buffer.readColor4f(&color);
52     if (buffer.readBool()) {
53         sk_sp<SkData> data = buffer.readByteArrayAsData();
54         colorSpace = data ? SkColorSpace::Deserialize(data->data(), data->size()) : nullptr;
55     }
56     return SkShaders::Color(color, std::move(colorSpace));
57 }
58 
flatten(SkWriteBuffer & buffer) const59 void SkColor4Shader::flatten(SkWriteBuffer& buffer) const {
60     buffer.writeColor4f(fColor);
61     sk_sp<SkData> colorSpaceData = fColorSpace ? fColorSpace->serialize() : nullptr;
62     if (colorSpaceData) {
63         buffer.writeBool(true);
64         buffer.writeDataAsByteArray(colorSpaceData.get());
65     } else {
66         buffer.writeBool(false);
67     }
68 }
69 
70 
Color(const SkColor4f & color,sk_sp<SkColorSpace> space)71 sk_sp<SkShader> SkShaders::Color(const SkColor4f& color, sk_sp<SkColorSpace> space) {
72     if (!SkScalarsAreFinite(color.vec(), 4)) {
73         return nullptr;
74     }
75     return sk_make_sp<SkColor4Shader>(color, std::move(space));
76 }
77 
onAppendStages(const SkStageRec & rec) const78 bool SkColorShader::onAppendStages(const SkStageRec& rec) const {
79     SkColor4f color = SkColor4f::FromColor(fColor);
80     SkColorSpaceXformSteps(sk_srgb_singleton(), kUnpremul_SkAlphaType,
81                            rec.fDstCS,          kUnpremul_SkAlphaType).apply(color.vec());
82     rec.fPipeline->append_constant_color(rec.fAlloc, color.premul().vec());
83     return true;
84 }
85 
onAppendStages(const SkStageRec & rec) const86 bool SkColor4Shader::onAppendStages(const SkStageRec& rec) const {
87     SkColor4f color = fColor;
88     SkColorSpaceXformSteps(fColorSpace.get(), kUnpremul_SkAlphaType,
89                            rec.fDstCS,        kUnpremul_SkAlphaType).apply(color.vec());
90     rec.fPipeline->append_constant_color(rec.fAlloc, color.premul().vec());
91     return true;
92 }
93 
onProgram(skvm::Builder * p,skvm::Coord,skvm::Coord,skvm::Color,const SkMatrixProvider &,const SkMatrix *,const SkColorInfo & dst,skvm::Uniforms * uniforms,SkArenaAlloc *) const94 skvm::Color SkColorShader::onProgram(skvm::Builder* p,
95                                      skvm::Coord /*device*/, skvm::Coord /*local*/,
96                                      skvm::Color /*paint*/, const SkMatrixProvider&,
97                                      const SkMatrix* /*localM*/, const SkColorInfo& dst,
98                                      skvm::Uniforms* uniforms, SkArenaAlloc*) const {
99     SkColor4f color = SkColor4f::FromColor(fColor);
100     SkColorSpaceXformSteps(sk_srgb_singleton(), kUnpremul_SkAlphaType,
101                               dst.colorSpace(),   kPremul_SkAlphaType).apply(color.vec());
102     return p->uniformColor(color, uniforms);
103 }
onProgram(skvm::Builder * p,skvm::Coord,skvm::Coord,skvm::Color,const SkMatrixProvider &,const SkMatrix *,const SkColorInfo & dst,skvm::Uniforms * uniforms,SkArenaAlloc *) const104 skvm::Color SkColor4Shader::onProgram(skvm::Builder* p,
105                                       skvm::Coord /*device*/, skvm::Coord /*local*/,
106                                       skvm::Color /*paint*/, const SkMatrixProvider&,
107                                       const SkMatrix* /*localM*/, const SkColorInfo& dst,
108                                       skvm::Uniforms* uniforms, SkArenaAlloc*) const {
109     SkColor4f color = fColor;
110     SkColorSpaceXformSteps(fColorSpace.get(), kUnpremul_SkAlphaType,
111                             dst.colorSpace(),   kPremul_SkAlphaType).apply(color.vec());
112     return p->uniformColor(color, uniforms);
113 }
114 
115 #if SK_SUPPORT_GPU
116 
117 #include "src/gpu/GrColorInfo.h"
118 #include "src/gpu/GrColorSpaceXform.h"
119 #include "src/gpu/GrFragmentProcessor.h"
120 #include "src/gpu/SkGr.h"
121 
asFragmentProcessor(const GrFPArgs & args) const122 std::unique_ptr<GrFragmentProcessor> SkColorShader::asFragmentProcessor(
123         const GrFPArgs& args) const {
124     return GrFragmentProcessor::MakeColor(SkColorToPMColor4f(fColor, *args.fDstColorInfo));
125 }
126 
asFragmentProcessor(const GrFPArgs & args) const127 std::unique_ptr<GrFragmentProcessor> SkColor4Shader::asFragmentProcessor(
128         const GrFPArgs& args) const {
129     SkColorSpaceXformSteps steps{ fColorSpace.get(),                kUnpremul_SkAlphaType,
130                                   args.fDstColorInfo->colorSpace(), kUnpremul_SkAlphaType };
131     SkColor4f color = fColor;
132     steps.apply(color.vec());
133     return GrFragmentProcessor::MakeColor(color.premul());
134 }
135 
136 #endif
137