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 | |
18 | SkColorShader::SkColorShader(SkColor c) : fColor(c) {} |
19 | |
20 | bool SkColorShader::isOpaque() const { |
21 | return SkColorGetA(fColor) == 255; |
22 | } |
23 | |
24 | sk_sp<SkFlattenable> SkColorShader::CreateProc(SkReadBuffer& buffer) { |
25 | return sk_make_sp<SkColorShader>(buffer.readColor()); |
26 | } |
27 | |
28 | void SkColorShader::flatten(SkWriteBuffer& buffer) const { |
29 | buffer.writeColor(fColor); |
30 | } |
31 | |
32 | 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 | |
43 | SkColor4Shader::SkColor4Shader(const SkColor4f& color, sk_sp<SkColorSpace> space) |
44 | : fColorSpace(std::move(space)) |
45 | , fColor(color) |
46 | {} |
47 | |
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 | |
59 | 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 | |
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 | |
78 | 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 | |
86 | 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 | |
94 | skvm::Color SkColorShader::onProgram(skvm::Builder* p, |
95 | skvm::F32 /*x*/, skvm::F32 /*y*/, skvm::Color /*paint*/, |
96 | const SkMatrix& /*ctm*/, const SkMatrix* /*localM*/, |
97 | SkFilterQuality /*quality*/, const SkColorInfo& dst, |
98 | skvm::Uniforms* uniforms, SkArenaAlloc*) const { |
99 | return p->uniformPremul(SkColor4f::FromColor(fColor), sk_srgb_singleton(), |
100 | uniforms, dst.colorSpace()); |
101 | } |
102 | skvm::Color SkColor4Shader::onProgram(skvm::Builder* p, |
103 | skvm::F32 /*x*/, skvm::F32 /*y*/, skvm::Color /*paint*/, |
104 | const SkMatrix& /*ctm*/, const SkMatrix* /*localM*/, |
105 | SkFilterQuality /*quality*/, const SkColorInfo& dst, |
106 | skvm::Uniforms* uniforms, SkArenaAlloc*) const { |
107 | return p->uniformPremul(fColor, fColorSpace.get(), |
108 | uniforms, dst.colorSpace()); |
109 | } |
110 | |
111 | #if SK_SUPPORT_GPU |
112 | |
113 | #include "src/gpu/GrColorInfo.h" |
114 | #include "src/gpu/GrColorSpaceXform.h" |
115 | #include "src/gpu/SkGr.h" |
116 | #include "src/gpu/effects/generated/GrConstColorProcessor.h" |
117 | |
118 | std::unique_ptr<GrFragmentProcessor> SkColorShader::asFragmentProcessor( |
119 | const GrFPArgs& args) const { |
120 | SkPMColor4f color = SkColorToPMColor4f(fColor, *args.fDstColorInfo); |
121 | return GrConstColorProcessor::Make(color, GrConstColorProcessor::InputMode::kModulateA); |
122 | } |
123 | |
124 | std::unique_ptr<GrFragmentProcessor> SkColor4Shader::asFragmentProcessor( |
125 | const GrFPArgs& args) const { |
126 | SkColorSpaceXformSteps steps{ fColorSpace.get(), kUnpremul_SkAlphaType, |
127 | args.fDstColorInfo->colorSpace(), kUnpremul_SkAlphaType }; |
128 | SkColor4f color = fColor; |
129 | steps.apply(color.vec()); |
130 | return GrConstColorProcessor::Make(color.premul(), |
131 | GrConstColorProcessor::InputMode::kModulateA); |
132 | } |
133 | |
134 | #endif |
135 | |