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

Side by Side Diff: src/utils/SkDeferredCanvas.cpp

Issue 12567025: Integrating SkSurface with SkDeferredCanvas (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 9 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 | Annotate | Revision Log
OLDNEW
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
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
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;
252 bool fNextFlushOverwritesContents;
248 size_t fMaxRecordingStorageBytes; 253 size_t fMaxRecordingStorageBytes;
249 size_t fPreviousStorageAllocated; 254 size_t fPreviousStorageAllocated;
250 size_t fBitmapSizeThreshold; 255 size_t fBitmapSizeThreshold;
251 }; 256 };
252 257
253 DeferredDevice::DeferredDevice( 258 DeferredDevice::DeferredDevice(SkDevice* immediateDevice)
254 SkDevice* immediateDevice, SkDeferredCanvas::NotificationClient* notificatio nClient) : 259 : SkDevice(SkBitmap::kNo_Config,
255 SkDevice(SkBitmap::kNo_Config, 260 immediateDevice->width(), immediateDevice->height(),
256 immediateDevice->width(), immediateDevice->height(), 261 immediateDevice->isOpaque(),
257 immediateDevice->isOpaque(), 262 immediateDevice->getDeviceProperties()) {
258 immediateDevice->getDeviceProperties()) 263 fSurface = NULL;
259 , fRecordingCanvas(NULL) 264 fImmediateDevice = immediateDevice; // ref counted via fImmediateCanvas
260 , fFreshFrame(true) 265 fImmediateCanvas = SkNEW_ARGS(SkCanvas, (fImmediateDevice));
261 , fPreviousStorageAllocated(0) 266 this->init();
262 , fBitmapSizeThreshold(kDeferredCanvasBitmapSizeThreshold){ 267 }
263 268
269 DeferredDevice::DeferredDevice(SkSurface* surface)
270 : SkDevice(SkBitmap::kNo_Config,
271 surface->getCanvas()->getDevice()->width(),
272 surface->getCanvas()->getDevice()->height(),
273 surface->getCanvas()->getDevice()->isOpaque(),
274 surface->getCanvas()->getDevice()->getDeviceProperties()) {
264 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes; 275 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
265 fNotificationClient = notificationClient; 276 fNotificationClient = NULL;
266 fImmediateDevice = immediateDevice; // ref counted via fImmediateCanvas 277 fImmediateCanvas = surface->getCanvas();
267 fImmediateCanvas = SkNEW_ARGS(SkCanvas, (fImmediateDevice)); 278 SkSafeRef(fImmediateCanvas);
279 fSurface = surface;
280 SkSafeRef(fSurface);
281 fImmediateDevice = fImmediateCanvas->getDevice(); // ref counted via fImmed iateCanvas
282 this->init();
283 }
284
285 void DeferredDevice::init() {
286 fRecordingCanvas = NULL;
287 fFreshFrame = true;
288 fPreviousStorageAllocated = 0;
289 fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold;
290 fNextFlushOverwritesContents = false;
291 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
292 fNotificationClient = NULL;
268 fPipeController.setPlaybackCanvas(fImmediateCanvas); 293 fPipeController.setPlaybackCanvas(fImmediateCanvas);
269 this->beginRecording(); 294 this->beginRecording();
270 } 295 }
271 296
272 DeferredDevice::~DeferredDevice() { 297 DeferredDevice::~DeferredDevice() {
273 this->flushPendingCommands(kSilent_PlaybackMode); 298 this->flushPendingCommands(kSilent_PlaybackMode);
274 SkSafeUnref(fImmediateCanvas); 299 SkSafeUnref(fImmediateCanvas);
300 SkSafeUnref(fSurface);
275 } 301 }
276 302
277 void DeferredDevice::setMaxRecordingStorage(size_t maxStorage) { 303 void DeferredDevice::setMaxRecordingStorage(size_t maxStorage) {
278 fMaxRecordingStorageBytes = maxStorage; 304 fMaxRecordingStorageBytes = maxStorage;
279 this->recordingCanvas(); // Accessing the recording canvas applies the new l imit. 305 this->recordingCanvas(); // Accessing the recording canvas applies the new l imit.
280 } 306 }
281 307
282 void DeferredDevice::beginRecording() { 308 void DeferredDevice::beginRecording() {
283 SkASSERT(NULL == fRecordingCanvas); 309 SkASSERT(NULL == fRecordingCanvas);
284 fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0, 310 fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0,
285 fImmediateDevice->width(), fImmediateDevice->height()); 311 fImmediateDevice->width(), fImmediateDevice->height());
286 } 312 }
287 313
288 void DeferredDevice::setNotificationClient( 314 void DeferredDevice::setNotificationClient(
289 SkDeferredCanvas::NotificationClient* notificationClient) { 315 SkDeferredCanvas::NotificationClient* notificationClient) {
290 fNotificationClient = notificationClient; 316 fNotificationClient = notificationClient;
291 } 317 }
292 318
293 void DeferredDevice::skipPendingCommands() { 319 void DeferredDevice::skipPendingCommands() {
294 if (!fRecordingCanvas->isDrawingToLayer() && fPipeController.hasPendingComma nds()) { 320 if (!fRecordingCanvas->isDrawingToLayer() && fPipeController.hasPendingComma nds()) {
295 fFreshFrame = true; 321 fFreshFrame = true;
296 flushPendingCommands(kSilent_PlaybackMode); 322 flushPendingCommands(kSilent_PlaybackMode);
297 if (fNotificationClient) { 323 if (fNotificationClient) {
298 fNotificationClient->skippedPendingDrawCommands(); 324 fNotificationClient->skippedPendingDrawCommands();
299 } 325 }
300 } 326 }
327 fNextFlushOverwritesContents = true;
301 } 328 }
302 329
303 bool DeferredDevice::isFreshFrame() { 330 bool DeferredDevice::isFreshFrame() {
304 bool ret = fFreshFrame; 331 bool ret = fFreshFrame;
305 fFreshFrame = false; 332 fFreshFrame = false;
306 return ret; 333 return ret;
307 } 334 }
308 335
309 bool DeferredDevice::hasPendingCommands() { 336 bool DeferredDevice::hasPendingCommands() {
310 return fPipeController.hasPendingCommands(); 337 return fPipeController.hasPendingCommands();
311 } 338 }
312 339
313 void DeferredDevice::flushPendingCommands(PlaybackMode playbackMode) { 340 void DeferredDevice::flushPendingCommands(PlaybackMode playbackMode) {
314 if (!fPipeController.hasPendingCommands()) { 341 if (!fPipeController.hasPendingCommands()) {
315 return; 342 return;
316 } 343 }
317 if (playbackMode == kNormal_PlaybackMode && fNotificationClient) { 344 if (playbackMode == kNormal_PlaybackMode) {
318 fNotificationClient->prepareForDraw(); 345 if (NULL != fNotificationClient) {
346 fNotificationClient->prepareForDraw();
347 }
348 if (NULL != fSurface) {
349 // Preempt SkCanvas::predrawNotify because we know something it does n't
350 fSurface->notifyContentChanged(fNextFlushOverwritesContents);
351 }
319 } 352 }
320 fPipeWriter.flushRecording(true); 353 fPipeWriter.flushRecording(true);
321 fPipeController.playback(kSilent_PlaybackMode == playbackMode); 354 fPipeController.playback(kSilent_PlaybackMode == playbackMode);
322 if (playbackMode == kNormal_PlaybackMode && fNotificationClient) { 355 if (playbackMode == kNormal_PlaybackMode && fNotificationClient) {
323 fNotificationClient->flushedDrawCommands(); 356 fNotificationClient->flushedDrawCommands();
324 } 357 }
325 fPreviousStorageAllocated = storageAllocatedForRecording(); 358 fPreviousStorageAllocated = storageAllocatedForRecording();
359 fNextFlushOverwritesContents = false;
326 } 360 }
327 361
328 void DeferredDevice::flush() { 362 void DeferredDevice::flush() {
329 this->flushPendingCommands(kNormal_PlaybackMode); 363 this->flushPendingCommands(kNormal_PlaybackMode);
330 fImmediateCanvas->flush(); 364 fImmediateCanvas->flush();
331 } 365 }
332 366
333 size_t DeferredDevice::freeMemoryIfPossible(size_t bytesToFree) { 367 size_t DeferredDevice::freeMemoryIfPossible(size_t bytesToFree) {
334 size_t val = fPipeWriter.freeMemoryIfPossible(bytesToFree); 368 size_t val = fPipeWriter.freeMemoryIfPossible(bytesToFree);
335 fPreviousStorageAllocated = storageAllocatedForRecording(); 369 fPreviousStorageAllocated = storageAllocatedForRecording();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 storageAllocated != fPreviousStorageAllocated) { 403 storageAllocated != fPreviousStorageAllocated) {
370 fPreviousStorageAllocated = storageAllocated; 404 fPreviousStorageAllocated = storageAllocated;
371 fNotificationClient->storageAllocatedForRecordingChanged(storageAllocate d); 405 fNotificationClient->storageAllocatedForRecordingChanged(storageAllocate d);
372 } 406 }
373 } 407 }
374 408
375 SkCanvas* DeferredDevice::recordingCanvas() { 409 SkCanvas* DeferredDevice::recordingCanvas() {
376 return fRecordingCanvas; 410 return fRecordingCanvas;
377 } 411 }
378 412
413 SkImage* DeferredDevice::newImageShapshot() {
414 this->flush();
415 return fSurface ? fSurface->newImageShapshot() : NULL;
416 }
417
379 uint32_t DeferredDevice::getDeviceCapabilities() { 418 uint32_t DeferredDevice::getDeviceCapabilities() {
380 return fImmediateDevice->getDeviceCapabilities(); 419 return fImmediateDevice->getDeviceCapabilities();
381 } 420 }
382 421
383 int DeferredDevice::width() const { 422 int DeferredDevice::width() const {
384 return fImmediateDevice->width(); 423 return fImmediateDevice->width();
385 } 424 }
386 425
387 int DeferredDevice::height() const { 426 int DeferredDevice::height() const {
388 return fImmediateDevice->height(); 427 return fImmediateDevice->height();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 SkDevice* DeferredDevice::onCreateCompatibleDevice( 469 SkDevice* DeferredDevice::onCreateCompatibleDevice(
431 SkBitmap::Config config, int width, int height, bool isOpaque, 470 SkBitmap::Config config, int width, int height, bool isOpaque,
432 Usage usage) { 471 Usage usage) {
433 472
434 // Save layer usage not supported, and not required by SkDeferredCanvas. 473 // Save layer usage not supported, and not required by SkDeferredCanvas.
435 SkASSERT(usage != kSaveLayer_Usage); 474 SkASSERT(usage != kSaveLayer_Usage);
436 // Create a compatible non-deferred device. 475 // Create a compatible non-deferred device.
437 SkAutoTUnref<SkDevice> compatibleDevice 476 SkAutoTUnref<SkDevice> compatibleDevice
438 (fImmediateDevice->createCompatibleDevice(config, width, height, 477 (fImmediateDevice->createCompatibleDevice(config, width, height,
439 isOpaque)); 478 isOpaque));
440 return SkNEW_ARGS(DeferredDevice, (compatibleDevice, fNotificationClient)); 479 DeferredDevice* device = SkNEW_ARGS(DeferredDevice, (compatibleDevice));
480 device->setNotificationClient(fNotificationClient);
481 return device;
441 } 482 }
442 483
443 bool DeferredDevice::onReadPixels( 484 bool DeferredDevice::onReadPixels(
444 const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) { 485 const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) {
445 this->flushPendingCommands(kNormal_PlaybackMode); 486 this->flushPendingCommands(kNormal_PlaybackMode);
446 return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap), 487 return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap),
447 x, y, config8888); 488 x, y, config8888);
448 } 489 }
449 490
450 class AutoImmediateDrawIfNeeded { 491 class AutoImmediateDrawIfNeeded {
(...skipping 30 matching lines...) Expand all
481 522
482 SkDeferredCanvas::SkDeferredCanvas() { 523 SkDeferredCanvas::SkDeferredCanvas() {
483 this->init(); 524 this->init();
484 } 525 }
485 526
486 SkDeferredCanvas::SkDeferredCanvas(SkDevice* device) { 527 SkDeferredCanvas::SkDeferredCanvas(SkDevice* device) {
487 this->init(); 528 this->init();
488 this->setDevice(device); 529 this->setDevice(device);
489 } 530 }
490 531
532 SkDeferredCanvas::SkDeferredCanvas(SkSurface* surface) {
533 this->init();
534 this->INHERITED::setDevice(SkNEW_ARGS(DeferredDevice, (surface)))->unref();
535 }
536
491 void SkDeferredCanvas::init() { 537 void SkDeferredCanvas::init() {
492 fDeferredDrawing = true; // On by default 538 fDeferredDrawing = true; // On by default
493 } 539 }
494 540
495 void SkDeferredCanvas::setMaxRecordingStorage(size_t maxStorage) { 541 void SkDeferredCanvas::setMaxRecordingStorage(size_t maxStorage) {
496 this->validate(); 542 this->validate();
497 this->getDeferredDevice()->setMaxRecordingStorage(maxStorage); 543 this->getDeferredDevice()->setMaxRecordingStorage(maxStorage);
498 } 544 }
499 545
500 size_t SkDeferredCanvas::storageAllocatedForRecording() const { 546 size_t SkDeferredCanvas::storageAllocatedForRecording() const {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 NotificationClient* notificationClient) { 623 NotificationClient* notificationClient) {
578 624
579 DeferredDevice* deferredDevice = this->getDeferredDevice(); 625 DeferredDevice* deferredDevice = this->getDeferredDevice();
580 SkASSERT(deferredDevice); 626 SkASSERT(deferredDevice);
581 if (deferredDevice) { 627 if (deferredDevice) {
582 deferredDevice->setNotificationClient(notificationClient); 628 deferredDevice->setNotificationClient(notificationClient);
583 } 629 }
584 return notificationClient; 630 return notificationClient;
585 } 631 }
586 632
633 SkImage* SkDeferredCanvas::newImageShapshot() {
634 DeferredDevice* deferredDevice = this->getDeferredDevice();
635 SkASSERT(deferredDevice);
636 return deferredDevice ? deferredDevice->newImageShapshot() : NULL;
637 }
638
587 bool SkDeferredCanvas::isFullFrame(const SkRect* rect, 639 bool SkDeferredCanvas::isFullFrame(const SkRect* rect,
588 const SkPaint* paint) const { 640 const SkPaint* paint) const {
589 SkCanvas* canvas = this->drawingCanvas(); 641 SkCanvas* canvas = this->drawingCanvas();
590 SkISize canvasSize = this->getDeviceSize(); 642 SkISize canvasSize = this->getDeviceSize();
591 if (rect) { 643 if (rect) {
592 if (!canvas->getTotalMatrix().rectStaysRect()) { 644 if (!canvas->getTotalMatrix().rectStaysRect()) {
593 return false; // conservative 645 return false; // conservative
594 } 646 }
595 647
596 SkRect transformedRect; 648 SkRect transformedRect;
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
915 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { 967 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) {
916 this->drawingCanvas()->setDrawFilter(filter); 968 this->drawingCanvas()->setDrawFilter(filter);
917 this->INHERITED::setDrawFilter(filter); 969 this->INHERITED::setDrawFilter(filter);
918 this->recordedDrawCommand(); 970 this->recordedDrawCommand();
919 return filter; 971 return filter;
920 } 972 }
921 973
922 SkCanvas* SkDeferredCanvas::canvasForDrawIter() { 974 SkCanvas* SkDeferredCanvas::canvasForDrawIter() {
923 return this->drawingCanvas(); 975 return this->drawingCanvas();
924 } 976 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698