/src/skia/src/shaders/SkColorShader.cpp
Line | Count | Source (jump to first uncovered line) |
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 | 12.1k | SkColorShader::SkColorShader(SkColor c) : fColor(c) {} |
19 | | |
20 | 6.24k | bool SkColorShader::isOpaque() const { |
21 | 6.24k | return SkColorGetA(fColor) == 255; |
22 | 6.24k | } |
23 | | |
24 | 0 | sk_sp<SkFlattenable> SkColorShader::CreateProc(SkReadBuffer& buffer) { |
25 | 0 | return sk_make_sp<SkColorShader>(buffer.readColor()); |
26 | 0 | } |
27 | | |
28 | 0 | void SkColorShader::flatten(SkWriteBuffer& buffer) const { |
29 | 0 | buffer.writeColor(fColor); |
30 | 0 | } |
31 | | |
32 | 36 | SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const { |
33 | 36 | if (info) { |
34 | 18 | if (info->fColors && info->fColorCount >= 1) { |
35 | 0 | info->fColors[0] = fColor; |
36 | 0 | } |
37 | 18 | info->fColorCount = 1; |
38 | 18 | info->fTileMode = SkTileMode::kRepeat; |
39 | 18 | } |
40 | 36 | return kColor_GradientType; |
41 | 36 | } |
42 | | |
43 | | SkColor4Shader::SkColor4Shader(const SkColor4f& color, sk_sp<SkColorSpace> space) |
44 | | : fColorSpace(std::move(space)) |
45 | | , fColor(color) |
46 | 2.73k | {} |
47 | | |
48 | 0 | sk_sp<SkFlattenable> SkColor4Shader::CreateProc(SkReadBuffer& buffer) { |
49 | 0 | SkColor4f color; |
50 | 0 | sk_sp<SkColorSpace> colorSpace; |
51 | 0 | buffer.readColor4f(&color); |
52 | 0 | if (buffer.readBool()) { |
53 | 0 | sk_sp<SkData> data = buffer.readByteArrayAsData(); |
54 | 0 | colorSpace = data ? SkColorSpace::Deserialize(data->data(), data->size()) : nullptr; |
55 | 0 | } |
56 | 0 | return SkShaders::Color(color, std::move(colorSpace)); |
57 | 0 | } |
58 | | |
59 | 0 | void SkColor4Shader::flatten(SkWriteBuffer& buffer) const { |
60 | 0 | buffer.writeColor4f(fColor); |
61 | 0 | sk_sp<SkData> colorSpaceData = fColorSpace ? fColorSpace->serialize() : nullptr; |
62 | 0 | if (colorSpaceData) { |
63 | 0 | buffer.writeBool(true); |
64 | 0 | buffer.writeDataAsByteArray(colorSpaceData.get()); |
65 | 0 | } else { |
66 | 0 | buffer.writeBool(false); |
67 | 0 | } |
68 | 0 | } |
69 | | |
70 | | |
71 | 3.63k | sk_sp<SkShader> SkShaders::Color(const SkColor4f& color, sk_sp<SkColorSpace> space) { |
72 | 3.63k | if (!SkScalarsAreFinite(color.vec(), 4)) { |
73 | 896 | return nullptr; |
74 | 896 | } |
75 | 2.73k | return sk_make_sp<SkColor4Shader>(color, std::move(space)); |
76 | 2.73k | } |
77 | | |
78 | 6.47k | bool SkColorShader::onAppendStages(const SkStageRec& rec) const { |
79 | 6.47k | SkColor4f color = SkColor4f::FromColor(fColor); |
80 | 6.47k | SkColorSpaceXformSteps(sk_srgb_singleton(), kUnpremul_SkAlphaType, |
81 | 6.47k | rec.fDstCS, kUnpremul_SkAlphaType).apply(color.vec()); |
82 | 6.47k | rec.fPipeline->append_constant_color(rec.fAlloc, color.premul().vec()); |
83 | 6.47k | return true; |
84 | 6.47k | } |
85 | | |
86 | 45 | bool SkColor4Shader::onAppendStages(const SkStageRec& rec) const { |
87 | 45 | SkColor4f color = fColor; |
88 | 45 | SkColorSpaceXformSteps(fColorSpace.get(), kUnpremul_SkAlphaType, |
89 | 45 | rec.fDstCS, kUnpremul_SkAlphaType).apply(color.vec()); |
90 | 45 | rec.fPipeline->append_constant_color(rec.fAlloc, color.premul().vec()); |
91 | 45 | return true; |
92 | 45 | } |
93 | | |
94 | | 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 | 0 | skvm::Uniforms* uniforms, SkArenaAlloc*) const { |
99 | 0 | SkColor4f color = SkColor4f::FromColor(fColor); |
100 | 0 | SkColorSpaceXformSteps(sk_srgb_singleton(), kUnpremul_SkAlphaType, |
101 | 0 | dst.colorSpace(), kPremul_SkAlphaType).apply(color.vec()); |
102 | 0 | return p->uniformColor(color, uniforms); |
103 | 0 | } |
104 | | 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 | 0 | skvm::Uniforms* uniforms, SkArenaAlloc*) const { |
109 | 0 | SkColor4f color = fColor; |
110 | 0 | SkColorSpaceXformSteps(fColorSpace.get(), kUnpremul_SkAlphaType, |
111 | 0 | dst.colorSpace(), kPremul_SkAlphaType).apply(color.vec()); |
112 | 0 | return p->uniformColor(color, uniforms); |
113 | 0 | } |
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 | | |
122 | | std::unique_ptr<GrFragmentProcessor> SkColorShader::asFragmentProcessor( |
123 | 137 | const GrFPArgs& args) const { |
124 | 137 | return GrFragmentProcessor::ModulateAlpha(/*child=*/nullptr, |
125 | 137 | SkColorToPMColor4f(fColor, *args.fDstColorInfo)); |
126 | 137 | } |
127 | | |
128 | | std::unique_ptr<GrFragmentProcessor> SkColor4Shader::asFragmentProcessor( |
129 | 45 | const GrFPArgs& args) const { |
130 | 45 | SkColorSpaceXformSteps steps{ fColorSpace.get(), kUnpremul_SkAlphaType, |
131 | 45 | args.fDstColorInfo->colorSpace(), kUnpremul_SkAlphaType }; |
132 | 45 | SkColor4f color = fColor; |
133 | 45 | steps.apply(color.vec()); |
134 | 45 | return GrFragmentProcessor::ModulateAlpha(/*child=*/nullptr, color.premul()); |
135 | 45 | } |
136 | | |
137 | | #endif |