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 "SkArenaAlloc.h"
9 #include "SkColorShader.h"
10 #include "SkColorSpace.h"
11 #include "SkColorSpacePriv.h"
12 #include "SkColorSpaceXformSteps.h"
13 #include "SkRasterPipeline.h"
14 #include "SkReadBuffer.h"
15 #include "SkUtils.h"
16
SkColorShader(SkColor c)17 SkColorShader::SkColorShader(SkColor c) : fColor(c) {}
18
isOpaque() const19 bool SkColorShader::isOpaque() const {
20 return SkColorGetA(fColor) == 255;
21 }
22
CreateProc(SkReadBuffer & buffer)23 sk_sp<SkFlattenable> SkColorShader::CreateProc(SkReadBuffer& buffer) {
24 return sk_make_sp<SkColorShader>(buffer.readColor());
25 }
26
flatten(SkWriteBuffer & buffer) const27 void SkColorShader::flatten(SkWriteBuffer& buffer) const {
28 buffer.writeColor(fColor);
29 }
30
asAGradient(GradientInfo * info) const31 SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const {
32 if (info) {
33 if (info->fColors && info->fColorCount >= 1) {
34 info->fColors[0] = fColor;
35 }
36 info->fColorCount = 1;
37 info->fTileMode = SkShader::kRepeat_TileMode;
38 }
39 return kColor_GradientType;
40 }
41
SkColor4Shader(const SkColor4f & color,sk_sp<SkColorSpace> space)42 SkColor4Shader::SkColor4Shader(const SkColor4f& color, sk_sp<SkColorSpace> space)
43 : fColorSpace(std::move(space))
44 , fColor(color)
45 {}
46
CreateProc(SkReadBuffer & buffer)47 sk_sp<SkFlattenable> SkColor4Shader::CreateProc(SkReadBuffer& buffer) {
48 SkColor4f color;
49 sk_sp<SkColorSpace> colorSpace;
50 buffer.readColor4f(&color);
51 if (buffer.readBool()) {
52 sk_sp<SkData> data = buffer.readByteArrayAsData();
53 colorSpace = data ? SkColorSpace::Deserialize(data->data(), data->size()) : nullptr;
54 }
55 return SkShader::MakeColorShader(color, std::move(colorSpace));
56 }
57
flatten(SkWriteBuffer & buffer) const58 void SkColor4Shader::flatten(SkWriteBuffer& buffer) const {
59 buffer.writeColor4f(fColor);
60 sk_sp<SkData> colorSpaceData = fColorSpace ? fColorSpace->serialize() : nullptr;
61 if (colorSpaceData) {
62 buffer.writeBool(true);
63 buffer.writeDataAsByteArray(colorSpaceData.get());
64 } else {
65 buffer.writeBool(false);
66 }
67 }
68
69
onMakeColorSpace(SkColorSpaceXformer * xformer) const70 sk_sp<SkShader> SkColor4Shader::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
71 SkColor4f color = fColor;
72 SkColorSpaceXformSteps(fColorSpace.get(), kUnpremul_SkAlphaType,
73 xformer->dst().get(), kUnpremul_SkAlphaType).apply(color.vec());
74 return SkShader::MakeColorShader(color.toSkColor());
75 }
76
MakeColorShader(const SkColor4f & color,sk_sp<SkColorSpace> space)77 sk_sp<SkShader> SkShader::MakeColorShader(const SkColor4f& color, sk_sp<SkColorSpace> space) {
78 if (!SkScalarsAreFinite(color.vec(), 4)) {
79 return nullptr;
80 }
81 return sk_make_sp<SkColor4Shader>(color, std::move(space));
82 }
83
onAppendStages(const StageRec & rec) const84 bool SkColorShader::onAppendStages(const StageRec& rec) const {
85 SkColor4f color = SkColor4f::FromColor(fColor);
86 SkColorSpaceXformSteps(sk_srgb_singleton(), kUnpremul_SkAlphaType,
87 rec.fDstCS, kUnpremul_SkAlphaType).apply(color.vec());
88 rec.fPipeline->append_constant_color(rec.fAlloc, color.premul().vec());
89 return true;
90 }
91
onAppendStages(const StageRec & rec) const92 bool SkColor4Shader::onAppendStages(const StageRec& rec) const {
93 SkColor4f color = fColor;
94 SkColorSpaceXformSteps(fColorSpace.get(), kUnpremul_SkAlphaType,
95 rec.fDstCS, kUnpremul_SkAlphaType).apply(color.vec());
96 rec.fPipeline->append_constant_color(rec.fAlloc, color.premul().vec());
97 return true;
98 }
99
100 #if SK_SUPPORT_GPU
101
102 #include "GrColorSpaceInfo.h"
103 #include "GrColorSpaceXform.h"
104 #include "SkGr.h"
105 #include "effects/GrConstColorProcessor.h"
106
asFragmentProcessor(const GrFPArgs & args) const107 std::unique_ptr<GrFragmentProcessor> SkColorShader::asFragmentProcessor(
108 const GrFPArgs& args) const {
109 SkPMColor4f color = SkColorToPMColor4f(fColor, *args.fDstColorSpaceInfo);
110 return GrConstColorProcessor::Make(color, GrConstColorProcessor::InputMode::kModulateA);
111 }
112
asFragmentProcessor(const GrFPArgs & args) const113 std::unique_ptr<GrFragmentProcessor> SkColor4Shader::asFragmentProcessor(
114 const GrFPArgs& args) const {
115 SkColorSpaceXformSteps steps{ fColorSpace.get(), kUnpremul_SkAlphaType,
116 args.fDstColorSpaceInfo->colorSpace(), kUnpremul_SkAlphaType };
117 SkColor4f color = fColor;
118 steps.apply(color.vec());
119 return GrConstColorProcessor::Make(color.premul(),
120 GrConstColorProcessor::InputMode::kModulateA);
121 }
122
123 #endif
124