Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Side by Side Diff: src/utils/debugger/SkOverdrawMode.cpp

Issue 1607253002: Add gpu implementation of OverdrawXfermode (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Update FP & XP Factory counts Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/utils/debugger/SkOverdrawMode.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "SkColorPriv.h"
9 #include "SkOverdrawMode.h"
10 #include "SkString.h"
11 #include "SkXfermode.h"
12
13 #if SK_SUPPORT_GPU
14 #include "GrFragmentProcessor.h"
15 #include "GrInvariantOutput.h"
16 #include "GrXferProcessor.h"
17 #include "glsl/GrGLSLFragmentProcessor.h"
18 #include "glsl/GrGLSLFragmentShaderBuilder.h"
19 #include "glsl/GrGLSLXferProcessor.h"
20
21 ///////////////////////////////////////////////////////////////////////////////
22 // Fragment Processor
23 ///////////////////////////////////////////////////////////////////////////////
24
25 class GLOverdrawFP;
26
27 class GrOverdrawFP : public GrFragmentProcessor {
28 public:
29 static const GrFragmentProcessor* Create(const GrFragmentProcessor* dst) {
30 return new GrOverdrawFP(dst);
31 }
32
33 ~GrOverdrawFP() override { }
34
35 const char* name() const override { return "Overdraw"; }
36
37 SkString dumpInfo() const override {
38 SkString str;
39 return str;
40 }
41
42 private:
43 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
44
45 void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder* b) cons t override;
46
47 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
48
49 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
50 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput);
51 }
52
53 GrOverdrawFP(const GrFragmentProcessor* dst) {
54 this->initClassID<GrOverdrawFP>();
55
56 SkASSERT(dst);
57 SkDEBUGCODE(int dstIndex = )this->registerChildProcessor(dst);
58 SkASSERT(0 == dstIndex);
59 }
60
61 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
62 typedef GrFragmentProcessor INHERITED;
63 };
64
65 ///////////////////////////////////////////////////////////////////////////////
66
67 static void add_overdraw_code(GrGLSLFragmentBuilder* fragBuilder,
68 const char* dstColor,
69 const char* outputColor) {
70
71 static const GrGLSLShaderVar gColorTableArgs[] = {
72 // TODO: once kInt_GrSLType lands - switch this over
73 GrGLSLShaderVar("index", kFloat_GrSLType),
74 };
75 SkString colorTableFuncName;
76
77 // The 'colorTable' function exists to work around older GLSL's prohibition
78 // of initialized arrays. It takes an integer index and just returns the
79 // corresponding color.
80 fragBuilder->emitFunction(kVec4f_GrSLType,
81 "colorTable",
82 SK_ARRAY_COUNT(gColorTableArgs),
83 gColorTableArgs,
84 "if (index < 1.5) { return vec4(0.5, 0.617, 1.0, 1.0); }"
85 "if (index < 2.5) { return vec4(0.664, 0.723, 0.83, 1.0); }"
86 "if (index < 3.5) { return vec4(0.832, 0.762, 0.664 , 1.0); }"
87 "if (index < 4.5) { return vec4(1, 0.75, 0.496 , 1.0); }"
88 "if (index < 5.5) { return vec4(1, 0.723, 0.332 , 1.0); }"
89 "if (index < 6.5) { return vec4(1, 0.645, 0.164 , 1.0); }"
90 "if (index < 7.5) { return vec4(1, 0.527, 0, 1.0); }"
91 "if (index < 8.5) { return vec4(1, 0.371, 0, 1.0); }"
92 "if (index < 9.5) { return vec4(1, 0.195, 0, 1.0); }"
93 "return vec4(1, 0, 0, 1.0);",
94 &colorTableFuncName);
95
96 fragBuilder->codeAppend("int nextIdx;");
97 fragBuilder->codeAppendf("vec4 dst = %s;", dstColor);
98 fragBuilder->codeAppend("if (dst.r < 0.25) { nextIdx = 1; }");
99 // cap 'idx' at 10
100 fragBuilder->codeAppend("else if (dst.g < 0.0977) { nextIdx = 10; }");
101 fragBuilder->codeAppend("else if (dst.b > 0.08) { nextIdx = 8 - int(6.0 * ds t.b + 0.5); }");
102 fragBuilder->codeAppend("else { nextIdx = 11 - int(5.7 * dst.g + 0.5); }");
103 fragBuilder->codeAppendf("%s = %s(float(nextIdx));", outputColor, colorTable FuncName.c_str());
104 }
105
106 class GLOverdrawFP : public GrGLSLFragmentProcessor {
107 public:
108 GLOverdrawFP(const GrOverdrawFP&) {}
109
110 ~GLOverdrawFP() override {}
111
112 void emitCode(EmitArgs& args) override {
113 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
114 SkString dstColor("dstColor");
115 this->emitChild(0, nullptr, &dstColor, args);
116
117 add_overdraw_code(fragBuilder, dstColor.c_str(), args.fOutputColor);
118 }
119
120 static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuil der*) { }
121
122 private:
123 typedef GrGLSLFragmentProcessor INHERITED;
124 };
125
126 ///////////////////////////////////////////////////////////////////////////////
127
128 GrGLSLFragmentProcessor* GrOverdrawFP::onCreateGLSLInstance() const {
129 return new GLOverdrawFP(*this);
130 }
131
132 void GrOverdrawFP::onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyB uilder* b) const {
133 GLOverdrawFP::GenKey(*this, caps, b);
134 }
135
136 const GrFragmentProcessor* GrOverdrawFP::TestCreate(GrProcessorTestData* d) {
137 SkAutoTUnref<const GrFragmentProcessor> dst(GrProcessorUnitTest::CreateChild FP(d));
138 return new GrOverdrawFP(dst);
139 }
140
141 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrOverdrawFP);
142
143 ///////////////////////////////////////////////////////////////////////////////
144 // Xfer Processor
145 ///////////////////////////////////////////////////////////////////////////////
146
147 class OverdrawXP : public GrXferProcessor {
148 public:
149 OverdrawXP(const DstTexture* dstTexture, bool hasMixedSamples)
150 : INHERITED(dstTexture, true, hasMixedSamples) {
151 this->initClassID<OverdrawXP>();
152 }
153
154 const char* name() const override { return "Overdraw"; }
155
156 GrGLSLXferProcessor* createGLSLInstance() const override;
157
158 private:
159 GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations& optimizations,
160 bool doesStencilWrite,
161 GrColor* overrideColor,
162 const GrCaps& caps) const overr ide {
163 // We never look at the color input
164 return GrXferProcessor::kIgnoreColor_OptFlag;
165 }
166
167 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
168
169 bool onIsEqual(const GrXferProcessor&) const override { return true; }
170
171 typedef GrXferProcessor INHERITED;
172 };
173
174 ///////////////////////////////////////////////////////////////////////////////
175
176 class GLOverdrawXP : public GrGLSLXferProcessor {
177 public:
178 GLOverdrawXP(const OverdrawXP&) { }
179
180 ~GLOverdrawXP() override {}
181
182 static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuil der*) { }
183
184 private:
185 void emitBlendCodeForDstRead(GrGLSLXPFragmentBuilder* fragBuilder,
186 GrGLSLUniformHandler* uniformHandler,
187 const char* srcColor,
188 const char* srcCoverage,
189 const char* dstColor,
190 const char* outColor,
191 const char* outColorSecondary,
192 const GrXferProcessor& proc) override {
193 add_overdraw_code(fragBuilder, dstColor, outColor);
194
195 // Apply coverage.
196 INHERITED::DefaultCoverageModulation(fragBuilder, srcCoverage, dstColor, outColor,
197 outColorSecondary, proc);
198 }
199
200 void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) over ride { };
201
202 typedef GrGLSLXferProcessor INHERITED;
203 };
204
205 ///////////////////////////////////////////////////////////////////////////////
206
207 void OverdrawXP::onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBui lder* b) const {
208 GLOverdrawXP::GenKey(*this, caps, b);
209 }
210
211 GrGLSLXferProcessor* OverdrawXP::createGLSLInstance() const { return new GLOverd rawXP(*this); }
212
213 ///////////////////////////////////////////////////////////////////////////////
214 class GrOverdrawXPFactory : public GrXPFactory {
215 public:
216 static GrXPFactory* Create() { return new GrOverdrawXPFactory(); }
217
218 void getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
219 GrXPFactory::InvariantBlendedColor* blendedCol or) const override {
220 blendedColor->fWillBlendWithDst = true;
221 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags;
222 }
223
224 private:
225 GrOverdrawXPFactory() {
226 this->initClassID<GrOverdrawXPFactory>();
227 }
228
229 GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
230 const GrPipelineOptimizations& optimi zations,
231 bool hasMixedSamples,
232 const DstTexture* dstTexture) const o verride {
233 return new OverdrawXP(dstTexture, hasMixedSamples);
234 }
235
236 bool willReadDstColor(const GrCaps& caps,
237 const GrPipelineOptimizations& optimizations,
238 bool hasMixedSamples) const override {
239 return true;
240 }
241
242 bool onIsEqual(const GrXPFactory& xpfBase) const override { return true; }
243
244 GR_DECLARE_XP_FACTORY_TEST;
245
246 typedef GrXPFactory INHERITED;
247 };
248
249 GR_DEFINE_XP_FACTORY_TEST(GrOverdrawXPFactory);
250
251 const GrXPFactory* GrOverdrawXPFactory::TestCreate(GrProcessorTestData* d) {
252 return GrOverdrawXPFactory::Create();
253 }
254 #endif
255
256 ///////////////////////////////////////////////////////////////////////////////
257 class SkOverdrawXfermode : public SkXfermode {
258 public:
259 static SkXfermode* Create() {
260 return new SkOverdrawXfermode;
261 }
262
263 SkPMColor xferColor(SkPMColor src, SkPMColor dst) const override {
264 // This table encodes the color progression of the overdraw visualizatio n
265 static const SkPMColor gTable[] = {
266 SkPackARGB32(0x00, 0x00, 0x00, 0x00),
267 SkPackARGB32(0xFF, 128, 158, 255),
268 SkPackARGB32(0xFF, 170, 185, 212),
269 SkPackARGB32(0xFF, 213, 195, 170),
270 SkPackARGB32(0xFF, 255, 192, 127),
271 SkPackARGB32(0xFF, 255, 185, 85),
272 SkPackARGB32(0xFF, 255, 165, 42),
273 SkPackARGB32(0xFF, 255, 135, 0),
274 SkPackARGB32(0xFF, 255, 95, 0),
275 SkPackARGB32(0xFF, 255, 50, 0),
276 SkPackARGB32(0xFF, 255, 0, 0)
277 };
278
279
280 int nextIdx;
281 if (SkColorGetR(dst) < 64) { // dst color is the 0th color so the next c olor is 1
282 nextIdx = 1;
283 } else if (SkColorGetG(dst) < 25) { // dst color is the 10th color so ca p there
284 nextIdx = 10;
285 } else if ((SkColorGetB(dst)+21)/42 > 0) { // dst color is one of 1-6
286 nextIdx = 8 - (SkColorGetB(dst)+21)/42;
287 } else { // dst color is between 7 and 9
288 nextIdx = 11 - (SkColorGetG(dst)+22)/45;
289 }
290 SkASSERT(nextIdx < (int)SK_ARRAY_COUNT(gTable));
291
292 return gTable[nextIdx];
293 }
294
295 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkOverdrawXfermode)
296
297 #if SK_SUPPORT_GPU
298 bool asFragmentProcessor(const GrFragmentProcessor** output,
299 const GrFragmentProcessor* dst) const override {
300 if (output) {
301 *output = GrOverdrawFP::Create(dst);
302 }
303 return true;
304 }
305
306 bool asXPFactory(GrXPFactory** xpf) const override {
307 if (xpf) {
308 *xpf = GrOverdrawXPFactory::Create();
309 }
310 return true;
311 }
312 #endif
313
314 #ifndef SK_IGNORE_TO_STRING
315 void toString(SkString* str) const override { str->set("SkOverdrawXfermode") ; }
316 #endif
317
318 private:
319 friend class SkOverdrawMode;
320
321 void flatten(SkWriteBuffer& buffer) const override { }
322
323 typedef SkXfermode INHERITED;
324 };
325
326 SkFlattenable* SkOverdrawXfermode::CreateProc(SkReadBuffer& buffer) {
327 return Create();
328 }
329
330 SkXfermode* SkOverdrawMode::Create() { return new SkOverdrawXfermode; }
331
332 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkOverdrawMode)
333 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkOverdrawXfermode)
334 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« no previous file with comments | « src/utils/debugger/SkOverdrawMode.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698