OLD | NEW |
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" | 13 #include "SkDrawFilter.h" |
14 #include "SkDevice.h" | 14 #include "SkDevice.h" |
15 #include "SkXfermode.h" | 15 #include "SkXfermode.h" |
16 | 16 |
17 SkDebugCanvas::SkDebugCanvas(int width, int height) | 17 SkDebugCanvas::SkDebugCanvas(int width, int height) |
18 : INHERITED(width, height) | 18 : INHERITED(width, height) |
19 , fPicture(NULL) | 19 , fPicture(NULL) |
20 , fFilter(false) | 20 , fFilter(false) |
21 , fMegaVizMode(false) | 21 , fMegaVizMode(false) |
22 , fIndex(0) | |
23 , fOverdrawViz(false) | 22 , fOverdrawViz(false) |
24 , fOverdrawFilter(NULL) | 23 , fOverdrawFilter(NULL) |
25 , fOverrideTexFiltering(false) | 24 , fOverrideTexFiltering(false) |
26 , fTexOverrideFilter(NULL) | 25 , fTexOverrideFilter(NULL) { |
27 , fOutstandingSaveCount(0) { | |
28 fUserMatrix.reset(); | 26 fUserMatrix.reset(); |
29 fDrawNeedsReset = false; | |
30 | 27 |
31 // SkPicturePlayback uses the base-class' quickReject calls to cull clipped | 28 // SkPicturePlayback uses the base-class' quickReject calls to cull clipped |
32 // operations. This can lead to problems in the debugger which expects all | 29 // operations. This can lead to problems in the debugger which expects all |
33 // the operations in the captured skp to appear in the debug canvas. To | 30 // the operations in the captured skp to appear in the debug canvas. To |
34 // circumvent this we create a wide open clip here (an empty clip rect | 31 // circumvent this we create a wide open clip here (an empty clip rect |
35 // is not sufficient). | 32 // is not sufficient). |
36 // Internally, the SkRect passed to clipRect is converted to an SkIRect and | 33 // Internally, the SkRect passed to clipRect is converted to an SkIRect and |
37 // rounded out. The following code creates a nearly maximal rect that will | 34 // rounded out. The following code creates a nearly maximal rect that will |
38 // not get collapsed by the coming conversions (Due to precision loss the | 35 // not get collapsed by the coming conversions (Due to precision loss the |
39 // inset has to be surprisingly large). | 36 // inset has to be surprisingly large). |
(...skipping 12 matching lines...) Expand all Loading... |
52 SkSafeUnref(fOverdrawFilter); | 49 SkSafeUnref(fOverdrawFilter); |
53 SkSafeUnref(fTexOverrideFilter); | 50 SkSafeUnref(fTexOverrideFilter); |
54 } | 51 } |
55 | 52 |
56 void SkDebugCanvas::addDrawCommand(SkDrawCommand* command) { | 53 void SkDebugCanvas::addDrawCommand(SkDrawCommand* command) { |
57 command->setOffset(this->getOpID()); | 54 command->setOffset(this->getOpID()); |
58 fCommandVector.push(command); | 55 fCommandVector.push(command); |
59 } | 56 } |
60 | 57 |
61 void SkDebugCanvas::draw(SkCanvas* canvas) { | 58 void SkDebugCanvas::draw(SkCanvas* canvas) { |
62 fDrawNeedsReset = true; | |
63 | |
64 if (!fCommandVector.isEmpty()) { | 59 if (!fCommandVector.isEmpty()) { |
65 this->drawTo(canvas, fCommandVector.count() - 1); | 60 this->drawTo(canvas, fCommandVector.count() - 1); |
66 } | 61 } |
67 } | 62 } |
68 | 63 |
69 void SkDebugCanvas::applyUserTransform(SkCanvas* canvas) { | 64 void SkDebugCanvas::applyUserTransform(SkCanvas* canvas) { |
70 canvas->concat(fUserMatrix); | 65 canvas->concat(fUserMatrix); |
71 } | 66 } |
72 | 67 |
73 int SkDebugCanvas::getCommandAtPoint(int x, int y, int index) { | 68 int SkDebugCanvas::getCommandAtPoint(int x, int y, int index) { |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 | 219 |
225 for (int i = 0; i < fActiveLayers.count(); ++i) { | 220 for (int i = 0; i < fActiveLayers.count(); ++i) { |
226 fActiveLayers[i]->setActive(true); | 221 fActiveLayers[i]->setActive(true); |
227 } | 222 } |
228 | 223 |
229 } | 224 } |
230 | 225 |
231 void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) { | 226 void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) { |
232 SkASSERT(!fCommandVector.isEmpty()); | 227 SkASSERT(!fCommandVector.isEmpty()); |
233 SkASSERT(index < fCommandVector.count()); | 228 SkASSERT(index < fCommandVector.count()); |
234 int i = 0; | 229 |
| 230 int saveCount = canvas->save(); |
| 231 |
235 SkRect windowRect = SkRect::MakeWH(SkIntToScalar(canvas->getBaseLayerSize().
width()), | 232 SkRect windowRect = SkRect::MakeWH(SkIntToScalar(canvas->getBaseLayerSize().
width()), |
236 SkIntToScalar(canvas->getBaseLayerSize().
height())); | 233 SkIntToScalar(canvas->getBaseLayerSize().
height())); |
237 | 234 |
238 bool pathOpsMode = getAllowSimplifyClip(); | 235 bool pathOpsMode = getAllowSimplifyClip(); |
239 canvas->setAllowSimplifyClip(pathOpsMode); | 236 canvas->setAllowSimplifyClip(pathOpsMode); |
240 // This only works assuming the canvas and device are the same ones that | 237 canvas->clear(SK_ColorTRANSPARENT); |
241 // were previously drawn into because they need to preserve all saves | 238 canvas->resetMatrix(); |
242 // and restores. | 239 if (!windowRect.isEmpty()) { |
243 // The visibility filter also requires a full re-draw - otherwise we can | 240 canvas->clipRect(windowRect, SkRegion::kReplace_Op); |
244 // end up drawing the filter repeatedly. | |
245 if (fIndex < index && !fFilter && !fMegaVizMode && !pathOpsMode && !fDrawNee
dsReset) { | |
246 i = fIndex + 1; | |
247 } else { | |
248 for (int j = 0; j < fOutstandingSaveCount; j++) { | |
249 canvas->restore(); | |
250 } | |
251 canvas->clear(SK_ColorTRANSPARENT); | |
252 canvas->resetMatrix(); | |
253 if (!windowRect.isEmpty()) { | |
254 canvas->clipRect(windowRect, SkRegion::kReplace_Op); | |
255 } | |
256 this->applyUserTransform(canvas); | |
257 fDrawNeedsReset = false; | |
258 fOutstandingSaveCount = 0; | |
259 } | 241 } |
| 242 this->applyUserTransform(canvas); |
260 | 243 |
261 // The setting of the draw filter has to go here (rather than in | 244 // The setting of the draw filter has to go here (rather than in |
262 // SkRasterWidget) due to the canvas restores this class performs. | 245 // SkRasterWidget) due to the canvas restores this class performs. |
263 // Since the draw filter is stored in the layer stack if we | 246 // Since the draw filter is stored in the layer stack if we |
264 // call setDrawFilter on anything but the root layer odd things happen. | 247 // call setDrawFilter on anything but the root layer odd things happen. |
265 if (fOverdrawViz) { | 248 if (fOverdrawViz) { |
266 if (NULL == fOverdrawFilter) { | 249 if (NULL == fOverdrawFilter) { |
267 fOverdrawFilter = new SkOverdrawFilter; | 250 fOverdrawFilter = new SkOverdrawFilter; |
268 } | 251 } |
269 | 252 |
270 if (fOverdrawFilter != canvas->getDrawFilter()) { | 253 if (fOverdrawFilter != canvas->getDrawFilter()) { |
271 canvas->setDrawFilter(fOverdrawFilter); | 254 canvas->setDrawFilter(fOverdrawFilter); |
272 } | 255 } |
273 } else if (fOverrideTexFiltering) { | 256 } else if (fOverrideTexFiltering) { |
274 if (NULL == fTexOverrideFilter) { | 257 if (NULL == fTexOverrideFilter) { |
275 fTexOverrideFilter = new SkTexOverrideFilter; | 258 fTexOverrideFilter = new SkTexOverrideFilter; |
276 } | 259 } |
277 | 260 |
278 if (fTexOverrideFilter != canvas->getDrawFilter()) { | 261 if (fTexOverrideFilter != canvas->getDrawFilter()) { |
279 canvas->setDrawFilter(fTexOverrideFilter); | 262 canvas->setDrawFilter(fTexOverrideFilter); |
280 } | 263 } |
281 } else { | 264 } else { |
282 canvas->setDrawFilter(NULL); | 265 canvas->setDrawFilter(NULL); |
283 } | 266 } |
284 | 267 |
285 if (fMegaVizMode) { | 268 if (fMegaVizMode) { |
286 this->markActiveCommands(index); | 269 this->markActiveCommands(index); |
287 } | 270 } |
288 | 271 |
289 for (; i <= index; i++) { | 272 for (int i = 0; i <= index; i++) { |
290 if (i == index && fFilter) { | 273 if (i == index && fFilter) { |
291 canvas->clear(0xAAFFFFFF); | 274 canvas->clear(0xAAFFFFFF); |
292 } | 275 } |
293 | 276 |
294 if (fCommandVector[i]->isVisible()) { | 277 if (fCommandVector[i]->isVisible()) { |
295 if (fMegaVizMode && fCommandVector[i]->active()) { | 278 if (fMegaVizMode && fCommandVector[i]->active()) { |
296 // "active" commands execute their visualization behaviors: | 279 // "active" commands execute their visualization behaviors: |
297 // All active saveLayers get replaced with saves so all draw
s go to the | 280 // All active saveLayers get replaced with saves so all draw
s go to the |
298 // visible canvas. | 281 // visible canvas. |
299 // All active culls draw their cull box | 282 // All active culls draw their cull box |
300 fCommandVector[i]->vizExecute(canvas); | 283 fCommandVector[i]->vizExecute(canvas); |
301 } else { | 284 } else { |
302 fCommandVector[i]->setUserMatrix(fUserMatrix); | 285 fCommandVector[i]->setUserMatrix(fUserMatrix); |
303 fCommandVector[i]->execute(canvas); | 286 fCommandVector[i]->execute(canvas); |
304 } | 287 } |
305 | |
306 fCommandVector[i]->trackSaveState(&fOutstandingSaveCount); | |
307 } | 288 } |
308 } | 289 } |
309 | 290 |
310 if (fMegaVizMode) { | 291 if (fMegaVizMode) { |
311 canvas->save(); | 292 canvas->save(); |
312 // nuke the CTM | 293 // nuke the CTM |
313 canvas->resetMatrix(); | 294 canvas->resetMatrix(); |
314 // turn off clipping | 295 // turn off clipping |
315 if (!windowRect.isEmpty()) { | 296 if (!windowRect.isEmpty()) { |
316 SkRect r = windowRect; | 297 SkRect r = windowRect; |
(...skipping 26 matching lines...) Expand all Loading... |
343 } else { | 324 } else { |
344 Op(devPath, operand, (SkPathOp) elementOp, &devPath); | 325 Op(devPath, operand, (SkPathOp) elementOp, &devPath); |
345 } | 326 } |
346 } | 327 } |
347 this->lastClipStackData(devPath); | 328 this->lastClipStackData(devPath); |
348 } | 329 } |
349 fMatrix = canvas->getTotalMatrix(); | 330 fMatrix = canvas->getTotalMatrix(); |
350 if (!canvas->getClipDeviceBounds(&fClip)) { | 331 if (!canvas->getClipDeviceBounds(&fClip)) { |
351 fClip.setEmpty(); | 332 fClip.setEmpty(); |
352 } | 333 } |
353 fIndex = index; | 334 |
| 335 canvas->restoreToCount(saveCount); |
354 } | 336 } |
355 | 337 |
356 void SkDebugCanvas::deleteDrawCommandAt(int index) { | 338 void SkDebugCanvas::deleteDrawCommandAt(int index) { |
357 SkASSERT(index < fCommandVector.count()); | 339 SkASSERT(index < fCommandVector.count()); |
358 delete fCommandVector[index]; | 340 delete fCommandVector[index]; |
359 fCommandVector.remove(index); | 341 fCommandVector.remove(index); |
360 } | 342 } |
361 | 343 |
362 SkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) { | 344 SkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) { |
363 SkASSERT(index < fCommandVector.count()); | 345 SkASSERT(index < fCommandVector.count()); |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 } | 671 } |
690 | 672 |
691 bool SkDebugCanvas::lastClipStackData(const SkPath& devPath) { | 673 bool SkDebugCanvas::lastClipStackData(const SkPath& devPath) { |
692 if (fCalledAddStackData) { | 674 if (fCalledAddStackData) { |
693 fClipStackData.appendf("<br>"); | 675 fClipStackData.appendf("<br>"); |
694 addPathData(devPath, "pathOut"); | 676 addPathData(devPath, "pathOut"); |
695 return true; | 677 return true; |
696 } | 678 } |
697 return false; | 679 return false; |
698 } | 680 } |
OLD | NEW |