| 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 |