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

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

Issue 1032173002: Add a paint filter utility canvas (SkPaintFilterCanvas) (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: rebased Created 5 years, 8 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/SkDebugCanvas.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
1 1
2 /* 2 /*
3 * Copyright 2012 Google Inc. 3 * Copyright 2012 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 9
10 #include "SkColorPriv.h" 10 #include "SkColorPriv.h"
11 #include "SkDebugCanvas.h" 11 #include "SkDebugCanvas.h"
12 #include "SkDrawCommand.h" 12 #include "SkDrawCommand.h"
13 #include "SkDrawFilter.h"
14 #include "SkDevice.h" 13 #include "SkDevice.h"
14 #include "SkPaintFilterCanvas.h"
15 #include "SkXfermode.h" 15 #include "SkXfermode.h"
16 16
17 namespace {
18
19 class OverdrawXfermode : public SkXfermode {
20 public:
21 SkPMColor xferColor(SkPMColor src, SkPMColor dst) const override {
22 // This table encodes the color progression of the overdraw visualizatio n
23 static const SkPMColor gTable[] = {
24 SkPackARGB32(0x00, 0x00, 0x00, 0x00),
25 SkPackARGB32(0xFF, 128, 158, 255),
26 SkPackARGB32(0xFF, 170, 185, 212),
27 SkPackARGB32(0xFF, 213, 195, 170),
28 SkPackARGB32(0xFF, 255, 192, 127),
29 SkPackARGB32(0xFF, 255, 185, 85),
30 SkPackARGB32(0xFF, 255, 165, 42),
31 SkPackARGB32(0xFF, 255, 135, 0),
32 SkPackARGB32(0xFF, 255, 95, 0),
33 SkPackARGB32(0xFF, 255, 50, 0),
34 SkPackARGB32(0xFF, 255, 0, 0)
35 };
36
37
38 int idx;
39 if (SkColorGetR(dst) < 64) { // 0
40 idx = 0;
41 } else if (SkColorGetG(dst) < 25) { // 10
42 idx = 9; // cap at 9 for upcoming increment
43 } else if ((SkColorGetB(dst)+21)/42 > 0) { // 1-6
44 idx = 7 - (SkColorGetB(dst)+21)/42;
45 } else { // 7-9
46 idx = 10 - (SkColorGetG(dst)+22)/45;
47 }
48 ++idx;
49 SkASSERT(idx < (int)SK_ARRAY_COUNT(gTable));
50
51 return gTable[idx];
52 }
53
54 Factory getFactory() const override { return NULL; }
55 #ifndef SK_IGNORE_TO_STRING
56 virtual void toString(SkString* str) const override { str->set("OverdrawXfer mode"); }
57 #endif
58 };
59
60 class DebugPaintFilterCanvas : public SkPaintFilterCanvas {
61 public:
62 DebugPaintFilterCanvas(int width, int height, bool overdrawViz, bool overrid eFilterQuality,
63 SkFilterQuality quality)
64 : INHERITED(width, height)
65 , fOverdrawXfermode(overdrawViz ? SkNEW(OverdrawXfermode) : NULL)
66 , fOverrideFilterQuality(overrideFilterQuality)
67 , fFilterQuality(quality) { }
68
69 protected:
70 void onFilterPaint(SkPaint* paint, Type) const override {
71 if (NULL != fOverdrawXfermode.get()) {
72 paint->setAntiAlias(false);
73 paint->setXfermode(fOverdrawXfermode.get());
74 }
75
76 if (fOverrideFilterQuality) {
77 paint->setFilterQuality(fFilterQuality);
78 }
79 }
80
81 void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, const S kPaint* paint) {
82 // We need to replay the picture onto this canvas in order to filter its internal paints.
83 this->SkCanvas::onDrawPicture(picture, matrix, paint);
84 }
85
86 private:
87 SkAutoTUnref<SkXfermode> fOverdrawXfermode;
88
89 bool fOverrideFilterQuality;
90 SkFilterQuality fFilterQuality;
91
92 typedef SkPaintFilterCanvas INHERITED;
93 };
94
95 }
96
17 SkDebugCanvas::SkDebugCanvas(int width, int height) 97 SkDebugCanvas::SkDebugCanvas(int width, int height)
18 : INHERITED(width, height) 98 : INHERITED(width, height)
19 , fPicture(NULL) 99 , fPicture(NULL)
20 , fFilter(false) 100 , fFilter(false)
21 , fMegaVizMode(false) 101 , fMegaVizMode(false)
22 , fOverdrawViz(false) 102 , fOverdrawViz(false)
23 , fOverdrawFilter(NULL) 103 , fOverrideFilterQuality(false)
24 , fOverrideTexFiltering(false) 104 , fFilterQuality(kNone_SkFilterQuality) {
25 , fTexOverrideFilter(NULL) {
26 fUserMatrix.reset(); 105 fUserMatrix.reset();
27 106
28 // SkPicturePlayback uses the base-class' quickReject calls to cull clipped 107 // SkPicturePlayback uses the base-class' quickReject calls to cull clipped
29 // operations. This can lead to problems in the debugger which expects all 108 // operations. This can lead to problems in the debugger which expects all
30 // the operations in the captured skp to appear in the debug canvas. To 109 // the operations in the captured skp to appear in the debug canvas. To
31 // circumvent this we create a wide open clip here (an empty clip rect 110 // circumvent this we create a wide open clip here (an empty clip rect
32 // is not sufficient). 111 // is not sufficient).
33 // Internally, the SkRect passed to clipRect is converted to an SkIRect and 112 // Internally, the SkRect passed to clipRect is converted to an SkIRect and
34 // rounded out. The following code creates a nearly maximal rect that will 113 // rounded out. The following code creates a nearly maximal rect that will
35 // not get collapsed by the coming conversions (Due to precision loss the 114 // not get collapsed by the coming conversions (Due to precision loss the
36 // inset has to be surprisingly large). 115 // inset has to be surprisingly large).
37 SkIRect largeIRect = SkIRect::MakeLargest(); 116 SkIRect largeIRect = SkIRect::MakeLargest();
38 largeIRect.inset(1024, 1024); 117 largeIRect.inset(1024, 1024);
39 SkRect large = SkRect::Make(largeIRect); 118 SkRect large = SkRect::Make(largeIRect);
40 #ifdef SK_DEBUG 119 #ifdef SK_DEBUG
41 SkASSERT(!large.roundOut().isEmpty()); 120 SkASSERT(!large.roundOut().isEmpty());
42 #endif 121 #endif
43 // call the base class' version to avoid adding a draw command 122 // call the base class' version to avoid adding a draw command
44 this->INHERITED::onClipRect(large, SkRegion::kReplace_Op, kHard_ClipEdgeStyl e); 123 this->INHERITED::onClipRect(large, SkRegion::kReplace_Op, kHard_ClipEdgeStyl e);
45 } 124 }
46 125
47 SkDebugCanvas::~SkDebugCanvas() { 126 SkDebugCanvas::~SkDebugCanvas() {
48 fCommandVector.deleteAll(); 127 fCommandVector.deleteAll();
49 SkSafeUnref(fOverdrawFilter);
50 SkSafeUnref(fTexOverrideFilter);
51 } 128 }
52 129
53 void SkDebugCanvas::addDrawCommand(SkDrawCommand* command) { 130 void SkDebugCanvas::addDrawCommand(SkDrawCommand* command) {
54 command->setOffset(this->getOpID()); 131 command->setOffset(this->getOpID());
55 fCommandVector.push(command); 132 fCommandVector.push(command);
56 } 133 }
57 134
58 void SkDebugCanvas::draw(SkCanvas* canvas) { 135 void SkDebugCanvas::draw(SkCanvas* canvas) {
59 if (!fCommandVector.isEmpty()) { 136 if (!fCommandVector.isEmpty()) {
60 this->drawTo(canvas, fCommandVector.count() - 1); 137 this->drawTo(canvas, fCommandVector.count() - 1);
(...skipping 20 matching lines...) Expand all
81 fCommandVector[i]->execute(&canvas); 158 fCommandVector[i]->execute(&canvas);
82 } 159 }
83 if (prev != bitmap.getColor(0,0)) { 160 if (prev != bitmap.getColor(0,0)) {
84 layer = i; 161 layer = i;
85 } 162 }
86 prev = bitmap.getColor(0,0); 163 prev = bitmap.getColor(0,0);
87 } 164 }
88 return layer; 165 return layer;
89 } 166 }
90 167
91 class OverdrawXfermode : public SkXfermode {
92 public:
93 SkPMColor xferColor(SkPMColor src, SkPMColor dst) const override {
94 // This table encodes the color progression of the overdraw visualizatio n
95 static const SkPMColor gTable[] = {
96 SkPackARGB32(0x00, 0x00, 0x00, 0x00),
97 SkPackARGB32(0xFF, 128, 158, 255),
98 SkPackARGB32(0xFF, 170, 185, 212),
99 SkPackARGB32(0xFF, 213, 195, 170),
100 SkPackARGB32(0xFF, 255, 192, 127),
101 SkPackARGB32(0xFF, 255, 185, 85),
102 SkPackARGB32(0xFF, 255, 165, 42),
103 SkPackARGB32(0xFF, 255, 135, 0),
104 SkPackARGB32(0xFF, 255, 95, 0),
105 SkPackARGB32(0xFF, 255, 50, 0),
106 SkPackARGB32(0xFF, 255, 0, 0)
107 };
108
109
110 int idx;
111 if (SkColorGetR(dst) < 64) { // 0
112 idx = 0;
113 } else if (SkColorGetG(dst) < 25) { // 10
114 idx = 9; // cap at 9 for upcoming increment
115 } else if ((SkColorGetB(dst)+21)/42 > 0) { // 1-6
116 idx = 7 - (SkColorGetB(dst)+21)/42;
117 } else { // 7-9
118 idx = 10 - (SkColorGetG(dst)+22)/45;
119 }
120 ++idx;
121 SkASSERT(idx < (int)SK_ARRAY_COUNT(gTable));
122
123 return gTable[idx];
124 }
125
126 Factory getFactory() const override { return NULL; }
127 #ifndef SK_IGNORE_TO_STRING
128 virtual void toString(SkString* str) const override { str->set("OverdrawXfer mode"); }
129 #endif
130 };
131
132 class SkOverdrawFilter : public SkDrawFilter {
133 public:
134 SkOverdrawFilter() {
135 fXferMode = SkNEW(OverdrawXfermode);
136 }
137
138 virtual ~SkOverdrawFilter() {
139 delete fXferMode;
140 }
141
142 bool filter(SkPaint* p, Type) override {
143 p->setXfermode(fXferMode);
144 p->setAntiAlias(false);
145 return true;
146 }
147
148 protected:
149 SkXfermode* fXferMode;
150
151 private:
152 typedef SkDrawFilter INHERITED;
153 };
154
155 // SkTexOverrideFilter modifies every paint to use the specified
156 // texture filtering mode
157 class SkTexOverrideFilter : public SkDrawFilter {
158 public:
159 SkTexOverrideFilter() : fFilterQuality(kNone_SkFilterQuality) {
160 }
161
162 void setFilterQuality(SkFilterQuality filterQuality) {
163 fFilterQuality = filterQuality;
164 }
165
166 bool filter(SkPaint* p, Type) override {
167 p->setFilterQuality(fFilterQuality);
168 return true;
169 }
170
171 protected:
172 SkFilterQuality fFilterQuality;
173
174 private:
175 typedef SkDrawFilter INHERITED;
176 };
177
178 class SkDebugClipVisitor : public SkCanvas::ClipVisitor { 168 class SkDebugClipVisitor : public SkCanvas::ClipVisitor {
179 public: 169 public:
180 SkDebugClipVisitor(SkCanvas* canvas) : fCanvas(canvas) {} 170 SkDebugClipVisitor(SkCanvas* canvas) : fCanvas(canvas) {}
181 171
182 void clipRect(const SkRect& r, SkRegion::Op, bool doAA) override { 172 void clipRect(const SkRect& r, SkRegion::Op, bool doAA) override {
183 SkPaint p; 173 SkPaint p;
184 p.setColor(SK_ColorRED); 174 p.setColor(SK_ColorRED);
185 p.setStyle(SkPaint::kStroke_Style); 175 p.setStyle(SkPaint::kStroke_Style);
186 p.setAntiAlias(doAA); 176 p.setAntiAlias(doAA);
187 fCanvas->drawRect(r, p); 177 fCanvas->drawRect(r, p);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 233
244 bool pathOpsMode = getAllowSimplifyClip(); 234 bool pathOpsMode = getAllowSimplifyClip();
245 canvas->setAllowSimplifyClip(pathOpsMode); 235 canvas->setAllowSimplifyClip(pathOpsMode);
246 canvas->clear(SK_ColorTRANSPARENT); 236 canvas->clear(SK_ColorTRANSPARENT);
247 canvas->resetMatrix(); 237 canvas->resetMatrix();
248 if (!windowRect.isEmpty()) { 238 if (!windowRect.isEmpty()) {
249 canvas->clipRect(windowRect, SkRegion::kReplace_Op); 239 canvas->clipRect(windowRect, SkRegion::kReplace_Op);
250 } 240 }
251 this->applyUserTransform(canvas); 241 this->applyUserTransform(canvas);
252 242
253 // The setting of the draw filter has to go here (rather than in 243 if (fPaintFilterCanvas) {
254 // SkRasterWidget) due to the canvas restores this class performs. 244 fPaintFilterCanvas->addCanvas(canvas);
255 // Since the draw filter is stored in the layer stack if we 245 canvas = fPaintFilterCanvas.get();
256 // call setDrawFilter on anything but the root layer odd things happen.
257 if (fOverdrawViz) {
258 if (NULL == fOverdrawFilter) {
259 fOverdrawFilter = new SkOverdrawFilter;
260 }
261
262 if (fOverdrawFilter != canvas->getDrawFilter()) {
263 canvas->setDrawFilter(fOverdrawFilter);
264 }
265 } else if (fOverrideTexFiltering) {
266 if (NULL == fTexOverrideFilter) {
267 fTexOverrideFilter = new SkTexOverrideFilter;
268 }
269
270 if (fTexOverrideFilter != canvas->getDrawFilter()) {
271 canvas->setDrawFilter(fTexOverrideFilter);
272 }
273 } else {
274 canvas->setDrawFilter(NULL);
275 } 246 }
276 247
277 if (fMegaVizMode) { 248 if (fMegaVizMode) {
278 this->markActiveCommands(index); 249 this->markActiveCommands(index);
279 } 250 }
280 251
281 for (int i = 0; i <= index; i++) { 252 for (int i = 0; i <= index; i++) {
282 if (i == index && fFilter) { 253 if (i == index && fFilter) {
283 canvas->clear(0xAAFFFFFF); 254 canvas->clear(0xAAFFFFFF);
284 } 255 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 } 306 }
336 } 307 }
337 this->lastClipStackData(devPath); 308 this->lastClipStackData(devPath);
338 } 309 }
339 fMatrix = canvas->getTotalMatrix(); 310 fMatrix = canvas->getTotalMatrix();
340 if (!canvas->getClipDeviceBounds(&fClip)) { 311 if (!canvas->getClipDeviceBounds(&fClip)) {
341 fClip.setEmpty(); 312 fClip.setEmpty();
342 } 313 }
343 314
344 canvas->restoreToCount(saveCount); 315 canvas->restoreToCount(saveCount);
316
317 if (fPaintFilterCanvas) {
318 fPaintFilterCanvas->removeAll();
319 }
345 } 320 }
346 321
347 void SkDebugCanvas::deleteDrawCommandAt(int index) { 322 void SkDebugCanvas::deleteDrawCommandAt(int index) {
348 SkASSERT(index < fCommandVector.count()); 323 SkASSERT(index < fCommandVector.count());
349 delete fCommandVector[index]; 324 delete fCommandVector[index];
350 fCommandVector.remove(index); 325 fCommandVector.remove(index);
351 } 326 }
352 327
353 SkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) { 328 SkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) {
354 SkASSERT(index < fCommandVector.count()); 329 SkASSERT(index < fCommandVector.count());
(...skipping 17 matching lines...) Expand all
372 } 347 }
373 348
374 const SkTDArray <SkDrawCommand*>& SkDebugCanvas::getDrawCommands() const { 349 const SkTDArray <SkDrawCommand*>& SkDebugCanvas::getDrawCommands() const {
375 return fCommandVector; 350 return fCommandVector;
376 } 351 }
377 352
378 SkTDArray <SkDrawCommand*>& SkDebugCanvas::getDrawCommands() { 353 SkTDArray <SkDrawCommand*>& SkDebugCanvas::getDrawCommands() {
379 return fCommandVector; 354 return fCommandVector;
380 } 355 }
381 356
382 void SkDebugCanvas::overrideTexFiltering(bool overrideTexFiltering, SkFilterQual ity quality) { 357 void SkDebugCanvas::updatePaintFilterCanvas() {
383 if (NULL == fTexOverrideFilter) { 358 if (!fOverdrawViz && !fOverrideFilterQuality) {
384 fTexOverrideFilter = new SkTexOverrideFilter; 359 fPaintFilterCanvas.reset(NULL);
360 return;
385 } 361 }
386 362
387 fOverrideTexFiltering = overrideTexFiltering; 363 const SkImageInfo info = this->imageInfo();
388 fTexOverrideFilter->setFilterQuality(quality); 364 fPaintFilterCanvas.reset(SkNEW_ARGS(DebugPaintFilterCanvas, (info.width(),
365 info.height(),
366 fOverdrawViz,
367 fOverrideFilter Quality,
368 fFilterQuality) ));
369 }
370
371 void SkDebugCanvas::setOverdrawViz(bool overdrawViz) {
372 if (fOverdrawViz == overdrawViz) {
373 return;
374 }
375
376 fOverdrawViz = overdrawViz;
377 this->updatePaintFilterCanvas();
378 }
379
380 void SkDebugCanvas::overrideTexFiltering(bool overrideTexFiltering, SkFilterQual ity quality) {
381 if (fOverrideFilterQuality == overrideTexFiltering && fFilterQuality == qual ity) {
382 return;
383 }
384
385 fOverrideFilterQuality = overrideTexFiltering;
386 fFilterQuality = quality;
387 this->updatePaintFilterCanvas();
389 } 388 }
390 389
391 void SkDebugCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyl e edgeStyle) { 390 void SkDebugCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyl e edgeStyle) {
392 this->addDrawCommand(new SkClipPathCommand(path, op, kSoft_ClipEdgeStyle == edgeStyle)); 391 this->addDrawCommand(new SkClipPathCommand(path, op, kSoft_ClipEdgeStyle == edgeStyle));
393 } 392 }
394 393
395 void SkDebugCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyl e edgeStyle) { 394 void SkDebugCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyl e edgeStyle) {
396 this->addDrawCommand(new SkClipRectCommand(rect, op, kSoft_ClipEdgeStyle == edgeStyle)); 395 this->addDrawCommand(new SkClipRectCommand(rect, op, kSoft_ClipEdgeStyle == edgeStyle));
397 } 396 }
398 397
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 } 672 }
674 673
675 bool SkDebugCanvas::lastClipStackData(const SkPath& devPath) { 674 bool SkDebugCanvas::lastClipStackData(const SkPath& devPath) {
676 if (fCalledAddStackData) { 675 if (fCalledAddStackData) {
677 fClipStackData.appendf("<br>"); 676 fClipStackData.appendf("<br>");
678 addPathData(devPath, "pathOut"); 677 addPathData(devPath, "pathOut");
679 return true; 678 return true;
680 } 679 }
681 return false; 680 return false;
682 } 681 }
OLDNEW
« no previous file with comments | « src/utils/debugger/SkDebugCanvas.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698