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

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: 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 "SkOverdrawMode.h"
9 #include "SkXfermode.h"
10
11 #if SK_SUPPORT_GPU
12 #include "GrFragmentProcessor.h"
13 #include "GrInvariantOutput.h"
14 #include "GrXferProcessor.h"
15 #include "glsl/GrGLSLFragmentProcessor.h"
16 #include "glsl/GrGLSLFragmentShaderBuilder.h"
17 #include "glsl/GrGLSLXferProcessor.h"
18
19 ///////////////////////////////////////////////////////////////////////////////
20 // Fragment Processor
21 ///////////////////////////////////////////////////////////////////////////////
22
23 class GLOverdrawFP;
24
25 class GrOverdrawFP : public GrFragmentProcessor {
26 public:
27 static const GrFragmentProcessor* Create(const GrFragmentProcessor* dst) {
28 return new GrOverdrawFP(dst);
29 }
30
31 ~GrOverdrawFP() override { }
32
33 const char* name() const override { return "Overdraw"; }
34
35 SkString dumpInfo() const override {
36 SkString str;
37 return str;
38 }
39
40 private:
41 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
42
43 void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder* b) cons t override;
44
45 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
46
47 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
48 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput);
49 }
50
51 GrOverdrawFP(const GrFragmentProcessor* dst) {
52 this->initClassID<GrOverdrawFP>();
53
54 SkASSERT(dst);
55 SkDEBUGCODE(int dstIndex = )this->registerChildProcessor(dst);
56 SkASSERT(0 == dstIndex);
57 }
58
59 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
60 typedef GrFragmentProcessor INHERITED;
61 };
62
63 ///////////////////////////////////////////////////////////////////////////////
64
65 static void add_overdraw_code(GrGLSLFragmentBuilder* fragBuilder,
66 const char* dstColor,
67 const char* outputColor) {
68
69 fragBuilder->codeAppend("vec4 gTable[11] = vec4[11](");
70 fragBuilder->codeAppend("vec4(0, 0, 0, 0.0),");
71 fragBuilder->codeAppend("vec4(0.5, 0.617, 1.0, 1.0),");
72 fragBuilder->codeAppend("vec4(0.664, 0.723, 0.83, 1.0),");
73 fragBuilder->codeAppend("vec4(0.832, 0.762, 0.664, 1.0),");
74 fragBuilder->codeAppend("vec4(1, 0.75, 0.496, 1.0),");
75 fragBuilder->codeAppend("vec4(1, 0.723, 0.332, 1.0),");
76 fragBuilder->codeAppend("vec4(1, 0.645, 0.164, 1.0),");
77 fragBuilder->codeAppend("vec4(1, 0.527, 0, 1.0),");
78 fragBuilder->codeAppend("vec4(1, 0.371, 0, 1.0),");
79 fragBuilder->codeAppend("vec4(1, 0.195, 0, 1.0),");
80 fragBuilder->codeAppend("vec4(1, 0, 0, 1.0)");
81 fragBuilder->codeAppend(");");
82
83 fragBuilder->codeAppend("int idx;");
84 fragBuilder->codeAppendf("vec4 dst = %s;", dstColor);
85 fragBuilder->codeAppend("if (dst.r < 0.25) { idx = 0; }");
86 // cap 'idx' at 9 for upcoming increment
87 fragBuilder->codeAppend("else if (dst.g < 0.0977) { idx = 9; }");
88 fragBuilder->codeAppend("else if (dst.b > 0.08) { idx = 7 - int(6 * dst.b + 0.5); }");
89 fragBuilder->codeAppend("else { idx = 10 - int(5.7 * dst.g + 0.5); }");
90 fragBuilder->codeAppend("idx++;");
91 fragBuilder->codeAppendf("%s = gTable[idx];", outputColor);
92 }
93
94 class GLOverdrawFP : public GrGLSLFragmentProcessor {
95 public:
96 GLOverdrawFP(const GrOverdrawFP&) {}
97
98 ~GLOverdrawFP() override {}
99
100 void emitCode(EmitArgs& args) override {
101 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
102 SkString dstColor("dstColor");
103 this->emitChild(0, nullptr, &dstColor, args);
104
105 add_overdraw_code(fragBuilder, dstColor.c_str(), args.fOutputColor);
106 }
107
108 static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuil der*) { }
109
110 private:
111 typedef GrGLSLFragmentProcessor INHERITED;
112 };
113
114 ///////////////////////////////////////////////////////////////////////////////
115
116 GrGLSLFragmentProcessor* GrOverdrawFP::onCreateGLSLInstance() const {
117 return new GLOverdrawFP(*this);
118 }
119
120 void GrOverdrawFP::onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyB uilder* b) const {
121 GLOverdrawFP::GenKey(*this, caps, b);
122 }
123
124 const GrFragmentProcessor* GrOverdrawFP::TestCreate(GrProcessorTestData* d) {
125 SkAutoTUnref<const GrFragmentProcessor> dst(GrProcessorUnitTest::CreateChild FP(d));
126 return new GrOverdrawFP(dst);
127 }
128
129 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrOverdrawFP);
130
131 ///////////////////////////////////////////////////////////////////////////////
132 // Xfer Processor
133 ///////////////////////////////////////////////////////////////////////////////
134
135 class OverdrawXP : public GrXferProcessor {
136 public:
137 OverdrawXP(const DstTexture* dstTexture, bool hasMixedSamples)
138 : INHERITED(dstTexture, true, hasMixedSamples) {
139 this->initClassID<OverdrawXP>();
140 }
141
142 const char* name() const override { return "Overdraw"; }
143
144 GrGLSLXferProcessor* createGLSLInstance() const override;
145
146 private:
147 GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations& optimizations,
148 bool doesStencilWrite,
149 GrColor* overrideColor,
150 const GrCaps& caps) const overr ide {
151 return GrXferProcessor::kNone_OptFlags;
egdaniel 2016/01/20 14:28:34 I think this can return ignore color right?
robertphillips 2016/01/20 15:45:10 Done.
152 }
153
154 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
155
156 bool onIsEqual(const GrXferProcessor&) const override { return true; }
157
158 typedef GrXferProcessor INHERITED;
159 };
160
161 ///////////////////////////////////////////////////////////////////////////////
162
163 class GLOverdrawXP : public GrGLSLXferProcessor {
164 public:
165 GLOverdrawXP(const OverdrawXP&) { }
166
167 ~GLOverdrawXP() override {}
168
169 static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuil der*) { }
170
171 private:
172 void emitBlendCodeForDstRead(GrGLSLXPFragmentBuilder* fragBuilder,
173 GrGLSLUniformHandler* uniformHandler,
174 const char* srcColor,
175 const char* srcCoverage,
176 const char* dstColor,
177 const char* outColor,
178 const char* outColorSecondary,
179 const GrXferProcessor& proc) override {
180 add_overdraw_code(fragBuilder, dstColor, outColor);
181
182 // Apply coverage.
183 if (proc.dstReadUsesMixedSamples()) {
egdaniel 2016/01/20 14:28:34 Instead of copying and pasting this code into almo
robertphillips 2016/01/20 15:45:10 Done.
184 if (srcCoverage) {
185 fragBuilder->codeAppendf("%s *= %s;", outColor, srcCoverage);
186 fragBuilder->codeAppendf("%s = %s;", outColorSecondary, srcCover age);
187 } else {
188 fragBuilder->codeAppendf("%s = vec4(1.0);", outColorSecondary);
189 }
190 } else if (srcCoverage) {
191 fragBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;",
192 outColor, srcCoverage, outColor, srcCoverage, dstColor);
193 }
194 }
195
196 void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) over ride { };
197
198 typedef GrGLSLXferProcessor INHERITED;
199 };
200
201 ///////////////////////////////////////////////////////////////////////////////
202
203 void OverdrawXP::onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBui lder* b) const {
204 GLOverdrawXP::GenKey(*this, caps, b);
205 }
206
207 GrGLSLXferProcessor* OverdrawXP::createGLSLInstance() const { return new GLOverd rawXP(*this); }
208
209 ///////////////////////////////////////////////////////////////////////////////
210 class GrOverdrawXPFactory : public GrXPFactory {
211 public:
212 static GrXPFactory* Create() { return new GrOverdrawXPFactory(); }
213
214 void getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
215 GrXPFactory::InvariantBlendedColor* blendedCol or) const override {
216 blendedColor->fWillBlendWithDst = true;
217 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags;
218 }
219
220 private:
221 GrOverdrawXPFactory() {
222 this->initClassID<GrOverdrawXPFactory>();
223 }
224
225 GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
226 const GrPipelineOptimizations& optimi zations,
227 bool hasMixedSamples,
228 const DstTexture* dstTexture) const o verride {
229 return new OverdrawXP(dstTexture, hasMixedSamples);
230 }
231
232 bool willReadDstColor(const GrCaps& caps,
233 const GrPipelineOptimizations& optimizations,
234 bool hasMixedSamples) const override {
235 return true;
236 }
237
238 bool onIsEqual(const GrXPFactory& xpfBase) const override { return true; }
239
240 GR_DECLARE_XP_FACTORY_TEST;
241
242 typedef GrXPFactory INHERITED;
243 };
244
245 GR_DEFINE_XP_FACTORY_TEST(GrOverdrawXPFactory);
246
247 const GrXPFactory* GrOverdrawXPFactory::TestCreate(GrProcessorTestData* d) {
248 return GrOverdrawXPFactory::Create();
249 }
250 #endif
251
252 ///////////////////////////////////////////////////////////////////////////////
253 class SkOverdrawXfermode : public SkXfermode {
254 public:
255 static SkXfermode* Create() {
256 return new SkOverdrawXfermode;
257 }
258
259 SkPMColor xferColor(SkPMColor src, SkPMColor dst) const override {
260 // This table encodes the color progression of the overdraw visualizatio n
261 static const SkPMColor gTable[] = {
262 SkPackARGB32(0x00, 0x00, 0x00, 0x00),
263 SkPackARGB32(0xFF, 128, 158, 255),
264 SkPackARGB32(0xFF, 170, 185, 212),
265 SkPackARGB32(0xFF, 213, 195, 170),
266 SkPackARGB32(0xFF, 255, 192, 127),
267 SkPackARGB32(0xFF, 255, 185, 85),
268 SkPackARGB32(0xFF, 255, 165, 42),
269 SkPackARGB32(0xFF, 255, 135, 0),
270 SkPackARGB32(0xFF, 255, 95, 0),
271 SkPackARGB32(0xFF, 255, 50, 0),
272 SkPackARGB32(0xFF, 255, 0, 0)
273 };
274
275
276 int idx;
277 if (SkColorGetR(dst) < 64) { // 0
278 idx = 0;
279 } else if (SkColorGetG(dst) < 25) { // 10
280 idx = 9; // cap at 9 for upcoming increment
281 } else if ((SkColorGetB(dst)+21)/42 > 0) { // 1-6
282 idx = 7 - (SkColorGetB(dst)+21)/42;
283 } else { // 7-9
284 idx = 10 - (SkColorGetG(dst)+22)/45;
285 }
286 ++idx;
egdaniel 2016/01/20 14:28:34 Why is this +1 here? Why not either get right of t
robertphillips 2016/01/20 15:45:10 Done. Here and in the gpu implementation.
287 SkASSERT(idx < (int)SK_ARRAY_COUNT(gTable));
288
289 return gTable[idx];
290 }
291
292 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkOverdrawXfermode)
293
294 #if SK_SUPPORT_GPU
295 bool asFragmentProcessor(const GrFragmentProcessor** output,
296 const GrFragmentProcessor* dst) const override {
297 if (output) {
298 *output = GrOverdrawFP::Create(dst);
299 }
300 return true;
301 }
302
303 bool asXPFactory(GrXPFactory** xpf) const override {
304 if (xpf) {
305 *xpf = GrOverdrawXPFactory::Create();
306 }
307 return true;
308 }
309 #endif
310
311 #ifndef SK_IGNORE_TO_STRING
312 void toString(SkString* str) const override { str->set("SkOverdrawXfermode") ; }
313 #endif
314
315 private:
316 friend class SkOverdrawMode;
317
318 void flatten(SkWriteBuffer& buffer) const override { }
319
320 typedef SkXfermode INHERITED;
321 };
322
323 SkFlattenable* SkOverdrawXfermode::CreateProc(SkReadBuffer& buffer) {
324 return Create();
325 }
326
327 SkXfermode* SkOverdrawMode::Create() { return new SkOverdrawXfermode; }
328
329 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkOverdrawMode)
330 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkOverdrawXfermode)
331 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