blob: 7d95e3a7f112a5242608eeb92913ca1ec89a3a03 [file] [log] [blame]
Matt Sarett030cbd52016-11-22 15:48:50 -05001/*
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 "SkOverdrawColorFilter.h"
9
10void SkOverdrawColorFilter::filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const {
11 for (int x = 0; x < count; x++) {
12 uint8_t alpha = SkGetPackedA32(src[x]);
13 if (alpha >= kNumColors) {
14 alpha = kNumColors - 1;
15 }
16
17 dst[x] = fColors[alpha];
18 }
19}
20
21void SkOverdrawColorFilter::toString(SkString* str) const {
22 str->append("SkOverdrawColorFilter (");
23 for (int i = 0; i < kNumColors; i++) {
24 str->appendf("%d: %x\n", i, fColors[i]);
25 }
26 str->append(")");
27}
28
29void SkOverdrawColorFilter::flatten(SkWriteBuffer& buffer) const {
30 buffer.writeByteArray(fColors, kNumColors * sizeof(SkPMColor));
31}
32
33sk_sp<SkFlattenable> SkOverdrawColorFilter::CreateProc(SkReadBuffer& buffer) {
34 SkPMColor colors[kNumColors];
35 size_t size = buffer.getArrayCount();
36 if (!buffer.validate(size == sizeof(colors))) {
37 return nullptr;
38 }
39 if (!buffer.readByteArray(colors, sizeof(colors))) {
40 return nullptr;
41 }
42
43 return SkOverdrawColorFilter::Make(colors);
44}
45
46SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkOverdrawColorFilter)
47 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkOverdrawColorFilter)
48SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
49
50#if SK_SUPPORT_GPU
51
52#include "GrFragmentProcessor.h"
53#include "GrInvariantOutput.h"
54#include "glsl/GrGLSLFragmentProcessor.h"
55#include "glsl/GrGLSLFragmentShaderBuilder.h"
56
57class OverdrawFragmentProcessor : public GrFragmentProcessor {
58public:
59 static sk_sp<GrFragmentProcessor> Make(const SkPMColor* colors);
60
61 const char* name() const override { return "Overdraw"; }
62
63private:
64 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
Brian Salomon94efbf52016-11-29 13:43:05 -050065 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
Matt Sarett030cbd52016-11-22 15:48:50 -050066 bool onIsEqual(const GrFragmentProcessor&) const override;
67 void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
68
69 OverdrawFragmentProcessor(const GrColor4f* colors);
70
71 GrColor4f fColors[SkOverdrawColorFilter::kNumColors];
72
73 typedef GrFragmentProcessor INHERITED;
74};
75
76class GLOverdrawFragmentProcessor : public GrGLSLFragmentProcessor {
77public:
78 GLOverdrawFragmentProcessor(const GrColor4f* colors);
79
80 void emitCode(EmitArgs&) override;
81
82protected:
83 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override {}
84
85private:
86 GrColor4f fColors[SkOverdrawColorFilter::kNumColors];
87
88 typedef GrGLSLFragmentProcessor INHERITED;
89};
90
91sk_sp<GrFragmentProcessor> SkOverdrawColorFilter::asFragmentProcessor(GrContext*,
92 SkColorSpace*) const {
93 return OverdrawFragmentProcessor::Make(fColors);
94}
95
96sk_sp<GrFragmentProcessor> OverdrawFragmentProcessor::Make(const SkPMColor* colors) {
97 GrColor4f grColors[SkOverdrawColorFilter::kNumColors];
98 for (int i = 0; i < SkOverdrawColorFilter::kNumColors; i++) {
99 grColors[i] = GrColor4f::FromGrColor(GrColorPackRGBA(SkGetPackedR32(colors[i]),
100 SkGetPackedG32(colors[i]),
101 SkGetPackedB32(colors[i]),
102 SkGetPackedA32(colors[i])));
103 }
104
105 return sk_sp<OverdrawFragmentProcessor>(new OverdrawFragmentProcessor(grColors));
106}
107
108OverdrawFragmentProcessor::OverdrawFragmentProcessor(const GrColor4f* colors) {
109 this->initClassID<OverdrawFragmentProcessor>();
110 memcpy(fColors, colors, SkOverdrawColorFilter::kNumColors * sizeof(GrColor4f));
111}
112
113GrGLSLFragmentProcessor* OverdrawFragmentProcessor::onCreateGLSLInstance() const {
114 return new GLOverdrawFragmentProcessor(fColors);
115}
116
117bool OverdrawFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const {
118 const OverdrawFragmentProcessor& that = other.cast<OverdrawFragmentProcessor>();
119 return 0 == memcmp(fColors, that.fColors,
120 sizeof(GrColor4f) * SkOverdrawColorFilter::kNumColors);
121}
122
123void OverdrawFragmentProcessor::onComputeInvariantOutput(GrInvariantOutput* inout) const {
124 inout->invalidateComponents(kRGBA_GrColorComponentFlags, GrInvariantOutput::kWill_ReadInput);
125}
126
127GLOverdrawFragmentProcessor::GLOverdrawFragmentProcessor(const GrColor4f* colors) {
128 memcpy(fColors, colors, SkOverdrawColorFilter::kNumColors * sizeof(GrColor4f));
129}
130
131void GLOverdrawFragmentProcessor::emitCode(EmitArgs& args) {
132 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
133 if (nullptr == args.fInputColor) {
134 fragBuilder->codeAppendf("%s.rgba = vec4(%f, %f, %f, %f);", args.fOutputColor,
135 fColors[5].fRGBA[0],
136 fColors[5].fRGBA[1],
137 fColors[5].fRGBA[2],
138 fColors[5].fRGBA[3]);
139 } else {
140 fragBuilder->codeAppendf("float alpha = 255.0 * %s.a;", args.fInputColor);
141 fragBuilder->codeAppendf("if (alpha < 0.5) {");
142 fragBuilder->codeAppendf(" %s.rgba = vec4(%f, %f, %f, %f);", args.fOutputColor,
143 fColors[0].fRGBA[0],
144 fColors[0].fRGBA[1],
145 fColors[0].fRGBA[2],
146 fColors[0].fRGBA[3]);
147 fragBuilder->codeAppendf("} else if (alpha < 1.5) {");
148 fragBuilder->codeAppendf(" %s.rgba = vec4(%f, %f, %f, %f);", args.fOutputColor,
149 fColors[1].fRGBA[0],
150 fColors[1].fRGBA[1],
151 fColors[1].fRGBA[2],
152 fColors[1].fRGBA[3]);
153 fragBuilder->codeAppendf("} else if (alpha < 2.5) {");
154 fragBuilder->codeAppendf(" %s.rgba = vec4(%f, %f, %f, %f);", args.fOutputColor,
155 fColors[2].fRGBA[0],
156 fColors[2].fRGBA[1],
157 fColors[2].fRGBA[2],
158 fColors[2].fRGBA[3]);
159 fragBuilder->codeAppendf("} else if (alpha < 3.5) {");
160 fragBuilder->codeAppendf(" %s.rgba = vec4(%f, %f, %f, %f);", args.fOutputColor,
161 fColors[3].fRGBA[0],
162 fColors[3].fRGBA[1],
163 fColors[3].fRGBA[2],
164 fColors[3].fRGBA[3]);
165 fragBuilder->codeAppendf("} else if (alpha < 4.5) {");
166 fragBuilder->codeAppendf(" %s.rgba = vec4(%f, %f, %f, %f);", args.fOutputColor,
167 fColors[4].fRGBA[0],
168 fColors[4].fRGBA[1],
169 fColors[4].fRGBA[2],
170 fColors[4].fRGBA[3]);
171 fragBuilder->codeAppendf("} else {");
172 fragBuilder->codeAppendf(" %s.rgba = vec4(%f, %f, %f, %f);", args.fOutputColor,
173 fColors[5].fRGBA[0],
174 fColors[5].fRGBA[1],
175 fColors[5].fRGBA[2],
176 fColors[5].fRGBA[3]);
177 fragBuilder->codeAppendf("}");
178 }
179}
180
181#endif