OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkCanvasPriv.h" | 8 #include "SkCanvasPriv.h" |
9 #include "SkClipStack.h" | 9 #include "SkClipStack.h" |
10 #include "SkDebugCanvas.h" | 10 #include "SkDebugCanvas.h" |
11 #include "SkDrawCommand.h" | 11 #include "SkDrawCommand.h" |
12 #include "SkDevice.h" | 12 #include "SkDevice.h" |
13 #include "SkPaintFilterCanvas.h" | 13 #include "SkPaintFilterCanvas.h" |
14 #include "SkOverdrawMode.h" | 14 #include "SkOverdrawMode.h" |
15 | 15 |
| 16 #if SK_SUPPORT_GPU |
| 17 #include "GrAuditTrail.h" |
| 18 #include "GrContext.h" |
| 19 #include "GrRenderTarget.h" |
| 20 #endif |
| 21 |
16 #define SKDEBUGCANVAS_VERSION 1 | 22 #define SKDEBUGCANVAS_VERSION 1 |
17 #define SKDEBUGCANVAS_ATTRIBUTE_VERSION "version" | 23 #define SKDEBUGCANVAS_ATTRIBUTE_VERSION "version" |
18 #define SKDEBUGCANVAS_ATTRIBUTE_COMMANDS "commands" | 24 #define SKDEBUGCANVAS_ATTRIBUTE_COMMANDS "commands" |
19 | 25 |
20 class DebugPaintFilterCanvas : public SkPaintFilterCanvas { | 26 class DebugPaintFilterCanvas : public SkPaintFilterCanvas { |
21 public: | 27 public: |
22 DebugPaintFilterCanvas(int width, | 28 DebugPaintFilterCanvas(int width, |
23 int height, | 29 int height, |
24 bool overdrawViz, | 30 bool overdrawViz, |
25 bool overrideFilterQuality, | 31 bool overrideFilterQuality, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 }; | 67 }; |
62 | 68 |
63 SkDebugCanvas::SkDebugCanvas(int width, int height) | 69 SkDebugCanvas::SkDebugCanvas(int width, int height) |
64 : INHERITED(width, height) | 70 : INHERITED(width, height) |
65 , fPicture(nullptr) | 71 , fPicture(nullptr) |
66 , fFilter(false) | 72 , fFilter(false) |
67 , fMegaVizMode(false) | 73 , fMegaVizMode(false) |
68 , fOverdrawViz(false) | 74 , fOverdrawViz(false) |
69 , fOverrideFilterQuality(false) | 75 , fOverrideFilterQuality(false) |
70 , fFilterQuality(kNone_SkFilterQuality) | 76 , fFilterQuality(kNone_SkFilterQuality) |
71 , fClipVizColor(SK_ColorTRANSPARENT) { | 77 , fClipVizColor(SK_ColorTRANSPARENT) |
| 78 , fDrawGpuBatchBounds(true) { |
72 fUserMatrix.reset(); | 79 fUserMatrix.reset(); |
73 | 80 |
74 // SkPicturePlayback uses the base-class' quickReject calls to cull clipped | 81 // SkPicturePlayback uses the base-class' quickReject calls to cull clipped |
75 // operations. This can lead to problems in the debugger which expects all | 82 // operations. This can lead to problems in the debugger which expects all |
76 // the operations in the captured skp to appear in the debug canvas. To | 83 // the operations in the captured skp to appear in the debug canvas. To |
77 // circumvent this we create a wide open clip here (an empty clip rect | 84 // circumvent this we create a wide open clip here (an empty clip rect |
78 // is not sufficient). | 85 // is not sufficient). |
79 // Internally, the SkRect passed to clipRect is converted to an SkIRect and | 86 // Internally, the SkRect passed to clipRect is converted to an SkIRect and |
80 // rounded out. The following code creates a nearly maximal rect that will | 87 // rounded out. The following code creates a nearly maximal rect that will |
81 // not get collapsed by the coming conversions (Due to precision loss the | 88 // not get collapsed by the coming conversions (Due to precision loss the |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 canvas->clear(SK_ColorWHITE); | 209 canvas->clear(SK_ColorWHITE); |
203 canvas->resetMatrix(); | 210 canvas->resetMatrix(); |
204 if (!windowRect.isEmpty()) { | 211 if (!windowRect.isEmpty()) { |
205 canvas->clipRect(windowRect, SkRegion::kReplace_Op); | 212 canvas->clipRect(windowRect, SkRegion::kReplace_Op); |
206 } | 213 } |
207 this->applyUserTransform(canvas); | 214 this->applyUserTransform(canvas); |
208 | 215 |
209 if (fPaintFilterCanvas) { | 216 if (fPaintFilterCanvas) { |
210 fPaintFilterCanvas->addCanvas(canvas); | 217 fPaintFilterCanvas->addCanvas(canvas); |
211 canvas = fPaintFilterCanvas.get(); | 218 canvas = fPaintFilterCanvas.get(); |
| 219 |
212 } | 220 } |
213 | 221 |
214 if (fMegaVizMode) { | 222 if (fMegaVizMode) { |
215 this->markActiveCommands(index); | 223 this->markActiveCommands(index); |
216 } | 224 } |
| 225 |
| 226 // If we have a GPU backend we can also visualize the batching information |
| 227 #if SK_SUPPORT_GPU |
| 228 GrAuditTrail* at = nullptr; |
| 229 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget(); |
| 230 if (rt && fDrawGpuBatchBounds) { |
| 231 GrContext* ctx = rt->getContext(); |
| 232 if (ctx) { |
| 233 at = ctx->getAuditTrail(); |
| 234 } |
| 235 } |
| 236 #endif |
217 | 237 |
218 for (int i = 0; i <= index; i++) { | 238 for (int i = 0; i <= index; i++) { |
219 if (i == index && fFilter) { | 239 if (i == index && fFilter) { |
220 canvas->clear(0xAAFFFFFF); | 240 canvas->clear(0xAAFFFFFF); |
221 } | 241 } |
| 242 |
| 243 #if SK_SUPPORT_GPU |
| 244 GrAuditTrail::AutoCollectBatches* acb = nullptr; |
| 245 if (at) { |
| 246 acb = new GrAuditTrail::AutoCollectBatches(at, i); |
| 247 } |
| 248 #endif |
222 | 249 |
223 if (fCommandVector[i]->isVisible()) { | 250 if (fCommandVector[i]->isVisible()) { |
224 if (fMegaVizMode && fCommandVector[i]->active()) { | 251 if (fMegaVizMode && fCommandVector[i]->active()) { |
225 // "active" commands execute their visualization behaviors: | 252 // "active" commands execute their visualization behaviors: |
226 // All active saveLayers get replaced with saves so all draw
s go to the | 253 // All active saveLayers get replaced with saves so all draw
s go to the |
227 // visible canvas. | 254 // visible canvas. |
228 // All active culls draw their cull box | 255 // All active culls draw their cull box |
229 fCommandVector[i]->vizExecute(canvas); | 256 fCommandVector[i]->vizExecute(canvas); |
230 } else { | 257 } else { |
231 fCommandVector[i]->setUserMatrix(fUserMatrix); | 258 fCommandVector[i]->setUserMatrix(fUserMatrix); |
232 fCommandVector[i]->execute(canvas); | 259 fCommandVector[i]->execute(canvas); |
233 } | 260 } |
234 } | 261 } |
| 262 #if SK_SUPPORT_GPU |
| 263 if (at && acb) { |
| 264 delete acb; |
| 265 } |
| 266 #endif |
235 } | 267 } |
236 | 268 |
237 if (SkColorGetA(fClipVizColor) != 0) { | 269 if (SkColorGetA(fClipVizColor) != 0) { |
238 canvas->save(); | 270 canvas->save(); |
239 #define LARGE_COORD 1000000000 | 271 #define LARGE_COORD 1000000000 |
240 canvas->clipRect(SkRect::MakeLTRB(-LARGE_COORD, -LARGE_COORD, LARGE_COOR
D, LARGE_COORD), | 272 canvas->clipRect(SkRect::MakeLTRB(-LARGE_COORD, -LARGE_COORD, LARGE_COOR
D, LARGE_COORD), |
241 SkRegion::kReverseDifference_Op); | 273 SkRegion::kReverseDifference_Op); |
242 SkPaint clipPaint; | 274 SkPaint clipPaint; |
243 clipPaint.setColor(fClipVizColor); | 275 clipPaint.setColor(fClipVizColor); |
244 canvas->drawPaint(clipPaint); | 276 canvas->drawPaint(clipPaint); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 fMatrix = canvas->getTotalMatrix(); | 319 fMatrix = canvas->getTotalMatrix(); |
288 if (!canvas->getClipDeviceBounds(&fClip)) { | 320 if (!canvas->getClipDeviceBounds(&fClip)) { |
289 fClip.setEmpty(); | 321 fClip.setEmpty(); |
290 } | 322 } |
291 | 323 |
292 canvas->restoreToCount(saveCount); | 324 canvas->restoreToCount(saveCount); |
293 | 325 |
294 if (fPaintFilterCanvas) { | 326 if (fPaintFilterCanvas) { |
295 fPaintFilterCanvas->removeAll(); | 327 fPaintFilterCanvas->removeAll(); |
296 } | 328 } |
| 329 |
| 330 #if SK_SUPPORT_GPU |
| 331 // draw any batches if required and issue a full reset onto GrAuditTrail |
| 332 if (at) { |
| 333 GrAuditTrail::AutoEnable ae(at); |
| 334 SkTArray<GrAuditTrail::BatchInfo> childrenBounds; |
| 335 at->getBoundsByClientID(&childrenBounds, index); |
| 336 SkPaint paint; |
| 337 paint.setStyle(SkPaint::kStroke_Style); |
| 338 paint.setStrokeWidth(1); |
| 339 for (int i = 0; i < childrenBounds.count(); i++) { |
| 340 paint.setColor(SK_ColorBLACK); |
| 341 canvas->drawRect(childrenBounds[i].fBounds, paint); |
| 342 for (int j = 0; j < childrenBounds[i].fBatches.count(); j++) { |
| 343 const GrAuditTrail::BatchInfo::Batch& batch = childrenBounds[i].
fBatches[j]; |
| 344 if (batch.fClientID != index) { |
| 345 paint.setColor(SK_ColorBLUE); |
| 346 } else { |
| 347 paint.setColor(SK_ColorRED); |
| 348 } |
| 349 canvas->drawRect(batch.fBounds, paint); |
| 350 } |
| 351 } |
| 352 |
| 353 at->fullReset(); |
| 354 } |
| 355 |
| 356 #endif |
297 } | 357 } |
298 | 358 |
299 void SkDebugCanvas::deleteDrawCommandAt(int index) { | 359 void SkDebugCanvas::deleteDrawCommandAt(int index) { |
300 SkASSERT(index < fCommandVector.count()); | 360 SkASSERT(index < fCommandVector.count()); |
301 delete fCommandVector[index]; | 361 delete fCommandVector[index]; |
302 fCommandVector.remove(index); | 362 fCommandVector.remove(index); |
303 } | 363 } |
304 | 364 |
305 SkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) { | 365 SkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) { |
306 SkASSERT(index < fCommandVector.count()); | 366 SkASSERT(index < fCommandVector.count()); |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 } | 705 } |
646 | 706 |
647 bool SkDebugCanvas::lastClipStackData(const SkPath& devPath) { | 707 bool SkDebugCanvas::lastClipStackData(const SkPath& devPath) { |
648 if (fCalledAddStackData) { | 708 if (fCalledAddStackData) { |
649 fClipStackData.appendf("<br>"); | 709 fClipStackData.appendf("<br>"); |
650 addPathData(devPath, "pathOut"); | 710 addPathData(devPath, "pathOut"); |
651 return true; | 711 return true; |
652 } | 712 } |
653 return false; | 713 return false; |
654 } | 714 } |
OLD | NEW |