OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2013 Google Inc. | 3 * Copyright 2013 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 #include "SkDeferredCanvas.h" | 9 #include "SkDeferredCanvas.h" |
10 | 10 |
11 #include "SkChunkAlloc.h" | 11 #include "SkChunkAlloc.h" |
12 #include "SkColorFilter.h" | 12 #include "SkColorFilter.h" |
13 #include "SkDevice.h" | 13 #include "SkDevice.h" |
14 #include "SkDrawFilter.h" | 14 #include "SkDrawFilter.h" |
15 #include "SkGPipe.h" | 15 #include "SkGPipe.h" |
16 #include "SkPaint.h" | 16 #include "SkPaint.h" |
17 #include "SkPaintPriv.h" | 17 #include "SkPaintPriv.h" |
18 #include "SkRRect.h" | 18 #include "SkRRect.h" |
19 #include "SkShader.h" | 19 #include "SkShader.h" |
| 20 #include "SkSurface.h" |
20 | 21 |
21 enum { | 22 enum { |
22 // Deferred canvas will auto-flush when recording reaches this limit | 23 // Deferred canvas will auto-flush when recording reaches this limit |
23 kDefaultMaxRecordingStorageBytes = 64*1024*1024, | 24 kDefaultMaxRecordingStorageBytes = 64*1024*1024, |
24 kDeferredCanvasBitmapSizeThreshold = ~0U, // Disables this feature | 25 kDeferredCanvasBitmapSizeThreshold = ~0U, // Disables this feature |
25 }; | 26 }; |
26 | 27 |
27 enum PlaybackMode { | 28 enum PlaybackMode { |
28 kNormal_PlaybackMode, | 29 kNormal_PlaybackMode, |
29 kSilent_PlaybackMode, | 30 kSilent_PlaybackMode, |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 | 132 |
132 // Release all allocated blocks | 133 // Release all allocated blocks |
133 fAllocator.reset(); | 134 fAllocator.reset(); |
134 } | 135 } |
135 | 136 |
136 //----------------------------------------------------------------------------- | 137 //----------------------------------------------------------------------------- |
137 // DeferredDevice | 138 // DeferredDevice |
138 //----------------------------------------------------------------------------- | 139 //----------------------------------------------------------------------------- |
139 class DeferredDevice : public SkDevice { | 140 class DeferredDevice : public SkDevice { |
140 public: | 141 public: |
141 DeferredDevice(SkDevice* immediateDevice, | 142 explicit DeferredDevice(SkDevice* immediateDevice); |
142 SkDeferredCanvas::NotificationClient* notificationClient = NULL); | 143 explicit DeferredDevice(SkSurface* surface); |
143 ~DeferredDevice(); | 144 ~DeferredDevice(); |
144 | 145 |
145 void setNotificationClient(SkDeferredCanvas::NotificationClient* notificatio
nClient); | 146 void setNotificationClient(SkDeferredCanvas::NotificationClient* notificatio
nClient); |
146 SkCanvas* recordingCanvas(); | 147 SkCanvas* recordingCanvas(); |
147 SkCanvas* immediateCanvas() const {return fImmediateCanvas;} | 148 SkCanvas* immediateCanvas() const {return fImmediateCanvas;} |
148 SkDevice* immediateDevice() const {return fImmediateDevice;} | 149 SkDevice* immediateDevice() const {return fImmediateDevice;} |
| 150 SkImage* newImageShapshot(); |
149 bool isFreshFrame(); | 151 bool isFreshFrame(); |
150 bool hasPendingCommands(); | 152 bool hasPendingCommands(); |
151 size_t storageAllocatedForRecording() const; | 153 size_t storageAllocatedForRecording() const; |
152 size_t freeMemoryIfPossible(size_t bytesToFree); | 154 size_t freeMemoryIfPossible(size_t bytesToFree); |
153 size_t getBitmapSizeThreshold() const; | 155 size_t getBitmapSizeThreshold() const; |
154 void setBitmapSizeThreshold(size_t sizeThreshold); | 156 void setBitmapSizeThreshold(size_t sizeThreshold); |
155 void flushPendingCommands(PlaybackMode); | 157 void flushPendingCommands(PlaybackMode); |
156 void skipPendingCommands(); | 158 void skipPendingCommands(); |
157 void setMaxRecordingStorage(size_t); | 159 void setMaxRecordingStorage(size_t); |
158 void recordedDrawCommand(); | 160 void recordedDrawCommand(); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 SkXfermode* xmode, const uint16_t indices[], | 232 SkXfermode* xmode, const uint16_t indices[], |
231 int indexCount, const SkPaint& paint) | 233 int indexCount, const SkPaint& paint) |
232 {SkASSERT(0);} | 234 {SkASSERT(0);} |
233 virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y, | 235 virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y, |
234 const SkPaint&) | 236 const SkPaint&) |
235 {SkASSERT(0);} | 237 {SkASSERT(0);} |
236 private: | 238 private: |
237 virtual void flush(); | 239 virtual void flush(); |
238 | 240 |
239 void beginRecording(); | 241 void beginRecording(); |
| 242 void init(); |
240 | 243 |
241 DeferredPipeController fPipeController; | 244 DeferredPipeController fPipeController; |
242 SkGPipeWriter fPipeWriter; | 245 SkGPipeWriter fPipeWriter; |
243 SkDevice* fImmediateDevice; | 246 SkDevice* fImmediateDevice; |
244 SkCanvas* fImmediateCanvas; | 247 SkCanvas* fImmediateCanvas; |
245 SkCanvas* fRecordingCanvas; | 248 SkCanvas* fRecordingCanvas; |
| 249 SkSurface* fSurface; |
246 SkDeferredCanvas::NotificationClient* fNotificationClient; | 250 SkDeferredCanvas::NotificationClient* fNotificationClient; |
247 bool fFreshFrame; | 251 bool fFreshFrame; |
248 size_t fMaxRecordingStorageBytes; | 252 size_t fMaxRecordingStorageBytes; |
249 size_t fPreviousStorageAllocated; | 253 size_t fPreviousStorageAllocated; |
250 size_t fBitmapSizeThreshold; | 254 size_t fBitmapSizeThreshold; |
251 }; | 255 }; |
252 | 256 |
253 DeferredDevice::DeferredDevice( | 257 DeferredDevice::DeferredDevice(SkDevice* immediateDevice) |
254 SkDevice* immediateDevice, SkDeferredCanvas::NotificationClient* notificatio
nClient) : | 258 : SkDevice(SkBitmap::kNo_Config, |
255 SkDevice(SkBitmap::kNo_Config, | 259 immediateDevice->width(), immediateDevice->height(), |
256 immediateDevice->width(), immediateDevice->height(), | 260 immediateDevice->isOpaque(), |
257 immediateDevice->isOpaque(), | 261 immediateDevice->getDeviceProperties()) { |
258 immediateDevice->getDeviceProperties()) | 262 fSurface = NULL; |
259 , fRecordingCanvas(NULL) | 263 fImmediateDevice = immediateDevice; // ref counted via fImmediateCanvas |
260 , fFreshFrame(true) | 264 fImmediateCanvas = SkNEW_ARGS(SkCanvas, (fImmediateDevice)); |
261 , fPreviousStorageAllocated(0) | 265 this->init(); |
262 , fBitmapSizeThreshold(kDeferredCanvasBitmapSizeThreshold){ | 266 } |
263 | 267 |
| 268 DeferredDevice::DeferredDevice(SkSurface* surface) |
| 269 : SkDevice(SkBitmap::kNo_Config, |
| 270 surface->getCanvas()->getDevice()->width(), |
| 271 surface->getCanvas()->getDevice()->height(), |
| 272 surface->getCanvas()->getDevice()->isOpaque(), |
| 273 surface->getCanvas()->getDevice()->getDeviceProperties()) { |
264 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes; | 274 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes; |
265 fNotificationClient = notificationClient; | 275 fNotificationClient = NULL; |
266 fImmediateDevice = immediateDevice; // ref counted via fImmediateCanvas | 276 fImmediateCanvas = surface->getCanvas(); |
267 fImmediateCanvas = SkNEW_ARGS(SkCanvas, (fImmediateDevice)); | 277 SkSafeRef(fImmediateCanvas); |
| 278 fSurface = surface; |
| 279 SkSafeRef(fSurface); |
| 280 fImmediateDevice = fImmediateCanvas->getDevice(); // ref counted via fImmed
iateCanvas |
| 281 this->init(); |
| 282 } |
| 283 |
| 284 void DeferredDevice::init() { |
| 285 fRecordingCanvas = NULL; |
| 286 fFreshFrame = true; |
| 287 fPreviousStorageAllocated = 0; |
| 288 fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold; |
| 289 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes; |
| 290 fNotificationClient = NULL; |
268 fPipeController.setPlaybackCanvas(fImmediateCanvas); | 291 fPipeController.setPlaybackCanvas(fImmediateCanvas); |
269 this->beginRecording(); | 292 this->beginRecording(); |
270 } | 293 } |
271 | 294 |
272 DeferredDevice::~DeferredDevice() { | 295 DeferredDevice::~DeferredDevice() { |
273 this->flushPendingCommands(kSilent_PlaybackMode); | 296 this->flushPendingCommands(kSilent_PlaybackMode); |
274 SkSafeUnref(fImmediateCanvas); | 297 SkSafeUnref(fImmediateCanvas); |
| 298 SkSafeUnref(fSurface); |
275 } | 299 } |
276 | 300 |
277 void DeferredDevice::setMaxRecordingStorage(size_t maxStorage) { | 301 void DeferredDevice::setMaxRecordingStorage(size_t maxStorage) { |
278 fMaxRecordingStorageBytes = maxStorage; | 302 fMaxRecordingStorageBytes = maxStorage; |
279 this->recordingCanvas(); // Accessing the recording canvas applies the new l
imit. | 303 this->recordingCanvas(); // Accessing the recording canvas applies the new l
imit. |
280 } | 304 } |
281 | 305 |
282 void DeferredDevice::beginRecording() { | 306 void DeferredDevice::beginRecording() { |
283 SkASSERT(NULL == fRecordingCanvas); | 307 SkASSERT(NULL == fRecordingCanvas); |
284 fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0, | 308 fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0, |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 storageAllocated != fPreviousStorageAllocated) { | 393 storageAllocated != fPreviousStorageAllocated) { |
370 fPreviousStorageAllocated = storageAllocated; | 394 fPreviousStorageAllocated = storageAllocated; |
371 fNotificationClient->storageAllocatedForRecordingChanged(storageAllocate
d); | 395 fNotificationClient->storageAllocatedForRecordingChanged(storageAllocate
d); |
372 } | 396 } |
373 } | 397 } |
374 | 398 |
375 SkCanvas* DeferredDevice::recordingCanvas() { | 399 SkCanvas* DeferredDevice::recordingCanvas() { |
376 return fRecordingCanvas; | 400 return fRecordingCanvas; |
377 } | 401 } |
378 | 402 |
| 403 SkImage* DeferredDevice::newImageShapshot() { |
| 404 this->flush(); |
| 405 return fSurface ? fSurface->newImageShapshot() : NULL; |
| 406 } |
| 407 |
379 uint32_t DeferredDevice::getDeviceCapabilities() { | 408 uint32_t DeferredDevice::getDeviceCapabilities() { |
380 return fImmediateDevice->getDeviceCapabilities(); | 409 return fImmediateDevice->getDeviceCapabilities(); |
381 } | 410 } |
382 | 411 |
383 int DeferredDevice::width() const { | 412 int DeferredDevice::width() const { |
384 return fImmediateDevice->width(); | 413 return fImmediateDevice->width(); |
385 } | 414 } |
386 | 415 |
387 int DeferredDevice::height() const { | 416 int DeferredDevice::height() const { |
388 return fImmediateDevice->height(); | 417 return fImmediateDevice->height(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 SkDevice* DeferredDevice::onCreateCompatibleDevice( | 459 SkDevice* DeferredDevice::onCreateCompatibleDevice( |
431 SkBitmap::Config config, int width, int height, bool isOpaque, | 460 SkBitmap::Config config, int width, int height, bool isOpaque, |
432 Usage usage) { | 461 Usage usage) { |
433 | 462 |
434 // Save layer usage not supported, and not required by SkDeferredCanvas. | 463 // Save layer usage not supported, and not required by SkDeferredCanvas. |
435 SkASSERT(usage != kSaveLayer_Usage); | 464 SkASSERT(usage != kSaveLayer_Usage); |
436 // Create a compatible non-deferred device. | 465 // Create a compatible non-deferred device. |
437 SkAutoTUnref<SkDevice> compatibleDevice | 466 SkAutoTUnref<SkDevice> compatibleDevice |
438 (fImmediateDevice->createCompatibleDevice(config, width, height, | 467 (fImmediateDevice->createCompatibleDevice(config, width, height, |
439 isOpaque)); | 468 isOpaque)); |
440 return SkNEW_ARGS(DeferredDevice, (compatibleDevice, fNotificationClient)); | 469 DeferredDevice* device = SkNEW_ARGS(DeferredDevice, (compatibleDevice)); |
| 470 device->setNotificationClient(fNotificationClient); |
| 471 return device; |
441 } | 472 } |
442 | 473 |
443 bool DeferredDevice::onReadPixels( | 474 bool DeferredDevice::onReadPixels( |
444 const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) { | 475 const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) { |
445 this->flushPendingCommands(kNormal_PlaybackMode); | 476 this->flushPendingCommands(kNormal_PlaybackMode); |
446 return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap), | 477 return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap), |
447 x, y, config8888); | 478 x, y, config8888); |
448 } | 479 } |
449 | 480 |
450 class AutoImmediateDrawIfNeeded { | 481 class AutoImmediateDrawIfNeeded { |
(...skipping 30 matching lines...) Expand all Loading... |
481 | 512 |
482 SkDeferredCanvas::SkDeferredCanvas() { | 513 SkDeferredCanvas::SkDeferredCanvas() { |
483 this->init(); | 514 this->init(); |
484 } | 515 } |
485 | 516 |
486 SkDeferredCanvas::SkDeferredCanvas(SkDevice* device) { | 517 SkDeferredCanvas::SkDeferredCanvas(SkDevice* device) { |
487 this->init(); | 518 this->init(); |
488 this->setDevice(device); | 519 this->setDevice(device); |
489 } | 520 } |
490 | 521 |
| 522 SkDeferredCanvas::SkDeferredCanvas(SkSurface* surface) { |
| 523 this->init(); |
| 524 this->INHERITED::setDevice(SkNEW_ARGS(DeferredDevice, (surface)))->unref(); |
| 525 } |
| 526 |
491 void SkDeferredCanvas::init() { | 527 void SkDeferredCanvas::init() { |
492 fDeferredDrawing = true; // On by default | 528 fDeferredDrawing = true; // On by default |
493 } | 529 } |
494 | 530 |
495 void SkDeferredCanvas::setMaxRecordingStorage(size_t maxStorage) { | 531 void SkDeferredCanvas::setMaxRecordingStorage(size_t maxStorage) { |
496 this->validate(); | 532 this->validate(); |
497 this->getDeferredDevice()->setMaxRecordingStorage(maxStorage); | 533 this->getDeferredDevice()->setMaxRecordingStorage(maxStorage); |
498 } | 534 } |
499 | 535 |
500 size_t SkDeferredCanvas::storageAllocatedForRecording() const { | 536 size_t SkDeferredCanvas::storageAllocatedForRecording() const { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 NotificationClient* notificationClient) { | 613 NotificationClient* notificationClient) { |
578 | 614 |
579 DeferredDevice* deferredDevice = this->getDeferredDevice(); | 615 DeferredDevice* deferredDevice = this->getDeferredDevice(); |
580 SkASSERT(deferredDevice); | 616 SkASSERT(deferredDevice); |
581 if (deferredDevice) { | 617 if (deferredDevice) { |
582 deferredDevice->setNotificationClient(notificationClient); | 618 deferredDevice->setNotificationClient(notificationClient); |
583 } | 619 } |
584 return notificationClient; | 620 return notificationClient; |
585 } | 621 } |
586 | 622 |
| 623 SkImage* SkDeferredCanvas::newImageShapshot() { |
| 624 DeferredDevice* deferredDevice = this->getDeferredDevice(); |
| 625 SkASSERT(deferredDevice); |
| 626 return deferredDevice ? deferredDevice->newImageShapshot() : NULL; |
| 627 } |
| 628 |
587 bool SkDeferredCanvas::isFullFrame(const SkRect* rect, | 629 bool SkDeferredCanvas::isFullFrame(const SkRect* rect, |
588 const SkPaint* paint) const { | 630 const SkPaint* paint) const { |
589 SkCanvas* canvas = this->drawingCanvas(); | 631 SkCanvas* canvas = this->drawingCanvas(); |
590 SkISize canvasSize = this->getDeviceSize(); | 632 SkISize canvasSize = this->getDeviceSize(); |
591 if (rect) { | 633 if (rect) { |
592 if (!canvas->getTotalMatrix().rectStaysRect()) { | 634 if (!canvas->getTotalMatrix().rectStaysRect()) { |
593 return false; // conservative | 635 return false; // conservative |
594 } | 636 } |
595 | 637 |
596 SkRect transformedRect; | 638 SkRect transformedRect; |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
915 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { | 957 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { |
916 this->drawingCanvas()->setDrawFilter(filter); | 958 this->drawingCanvas()->setDrawFilter(filter); |
917 this->INHERITED::setDrawFilter(filter); | 959 this->INHERITED::setDrawFilter(filter); |
918 this->recordedDrawCommand(); | 960 this->recordedDrawCommand(); |
919 return filter; | 961 return filter; |
920 } | 962 } |
921 | 963 |
922 SkCanvas* SkDeferredCanvas::canvasForDrawIter() { | 964 SkCanvas* SkDeferredCanvas::canvasForDrawIter() { |
923 return this->drawingCanvas(); | 965 return this->drawingCanvas(); |
924 } | 966 } |
OLD | NEW |