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

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

Issue 197433002: support direct writing to top layer (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 6 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
« no previous file with comments | « src/core/SkDevice.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 if (fBlock) { 126 if (fBlock) {
127 fReader.playback(fBlock, fBytesWritten, flags); 127 fReader.playback(fBlock, fBytesWritten, flags);
128 fBlock = NULL; 128 fBlock = NULL;
129 } 129 }
130 130
131 // Release all allocated blocks 131 // Release all allocated blocks
132 fAllocator.reset(); 132 fAllocator.reset();
133 } 133 }
134 134
135 //----------------------------------------------------------------------------- 135 //-----------------------------------------------------------------------------
136 // DeferredDevice 136 // SkDeferredDevice
137 //----------------------------------------------------------------------------- 137 //-----------------------------------------------------------------------------
138 class DeferredDevice : public SkBaseDevice { 138 class SkDeferredDevice : public SkBaseDevice {
139 public: 139 public:
140 explicit DeferredDevice(SkSurface* surface); 140 explicit SkDeferredDevice(SkSurface* surface);
141 ~DeferredDevice(); 141 ~SkDeferredDevice();
142 142
143 void setNotificationClient(SkDeferredCanvas::NotificationClient* notificatio nClient); 143 void setNotificationClient(SkDeferredCanvas::NotificationClient* notificatio nClient);
144 SkCanvas* recordingCanvas(); 144 SkCanvas* recordingCanvas();
145 SkCanvas* immediateCanvas() const {return fImmediateCanvas;} 145 SkCanvas* immediateCanvas() const {return fImmediateCanvas;}
146 SkBaseDevice* immediateDevice() const {return fImmediateCanvas->getTopDevice ();} 146 SkBaseDevice* immediateDevice() const {return fImmediateCanvas->getTopDevice ();}
147 SkImage* newImageSnapshot(); 147 SkImage* newImageSnapshot();
148 void setSurface(SkSurface* surface); 148 void setSurface(SkSurface* surface);
149 bool isFreshFrame(); 149 bool isFreshFrame();
150 bool hasPendingCommands(); 150 bool hasPendingCommands();
151 size_t storageAllocatedForRecording() const; 151 size_t storageAllocatedForRecording() const;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 SkCanvas* fRecordingCanvas; 270 SkCanvas* fRecordingCanvas;
271 SkSurface* fSurface; 271 SkSurface* fSurface;
272 SkDeferredCanvas::NotificationClient* fNotificationClient; 272 SkDeferredCanvas::NotificationClient* fNotificationClient;
273 bool fFreshFrame; 273 bool fFreshFrame;
274 bool fCanDiscardCanvasContents; 274 bool fCanDiscardCanvasContents;
275 size_t fMaxRecordingStorageBytes; 275 size_t fMaxRecordingStorageBytes;
276 size_t fPreviousStorageAllocated; 276 size_t fPreviousStorageAllocated;
277 size_t fBitmapSizeThreshold; 277 size_t fBitmapSizeThreshold;
278 }; 278 };
279 279
280 DeferredDevice::DeferredDevice(SkSurface* surface) { 280 SkDeferredDevice::SkDeferredDevice(SkSurface* surface) {
281 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes; 281 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
282 fNotificationClient = NULL; 282 fNotificationClient = NULL;
283 fImmediateCanvas = NULL; 283 fImmediateCanvas = NULL;
284 fSurface = NULL; 284 fSurface = NULL;
285 this->setSurface(surface); 285 this->setSurface(surface);
286 this->init(); 286 this->init();
287 } 287 }
288 288
289 void DeferredDevice::setSurface(SkSurface* surface) { 289 void SkDeferredDevice::setSurface(SkSurface* surface) {
290 SkRefCnt_SafeAssign(fImmediateCanvas, surface->getCanvas()); 290 SkRefCnt_SafeAssign(fImmediateCanvas, surface->getCanvas());
291 SkRefCnt_SafeAssign(fSurface, surface); 291 SkRefCnt_SafeAssign(fSurface, surface);
292 fPipeController.setPlaybackCanvas(fImmediateCanvas); 292 fPipeController.setPlaybackCanvas(fImmediateCanvas);
293 } 293 }
294 294
295 void DeferredDevice::init() { 295 void SkDeferredDevice::init() {
296 fRecordingCanvas = NULL; 296 fRecordingCanvas = NULL;
297 fFreshFrame = true; 297 fFreshFrame = true;
298 fCanDiscardCanvasContents = false; 298 fCanDiscardCanvasContents = false;
299 fPreviousStorageAllocated = 0; 299 fPreviousStorageAllocated = 0;
300 fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold; 300 fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold;
301 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes; 301 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
302 fNotificationClient = NULL; 302 fNotificationClient = NULL;
303 this->beginRecording(); 303 this->beginRecording();
304 } 304 }
305 305
306 DeferredDevice::~DeferredDevice() { 306 SkDeferredDevice::~SkDeferredDevice() {
307 this->flushPendingCommands(kSilent_PlaybackMode); 307 this->flushPendingCommands(kSilent_PlaybackMode);
308 SkSafeUnref(fImmediateCanvas); 308 SkSafeUnref(fImmediateCanvas);
309 SkSafeUnref(fSurface); 309 SkSafeUnref(fSurface);
310 } 310 }
311 311
312 void DeferredDevice::setMaxRecordingStorage(size_t maxStorage) { 312 void SkDeferredDevice::setMaxRecordingStorage(size_t maxStorage) {
313 fMaxRecordingStorageBytes = maxStorage; 313 fMaxRecordingStorageBytes = maxStorage;
314 this->recordingCanvas(); // Accessing the recording canvas applies the new l imit. 314 this->recordingCanvas(); // Accessing the recording canvas applies the new l imit.
315 } 315 }
316 316
317 void DeferredDevice::beginRecording() { 317 void SkDeferredDevice::beginRecording() {
318 SkASSERT(NULL == fRecordingCanvas); 318 SkASSERT(NULL == fRecordingCanvas);
319 fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0, 319 fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0,
320 immediateDevice()->width(), immediateDevice()->height()); 320 immediateDevice()->width(), immediateDevice()->height());
321 } 321 }
322 322
323 void DeferredDevice::setNotificationClient( 323 void SkDeferredDevice::setNotificationClient(
324 SkDeferredCanvas::NotificationClient* notificationClient) { 324 SkDeferredCanvas::NotificationClient* notificationClient) {
325 fNotificationClient = notificationClient; 325 fNotificationClient = notificationClient;
326 } 326 }
327 327
328 void DeferredDevice::skipPendingCommands() { 328 void SkDeferredDevice::skipPendingCommands() {
329 if (!fRecordingCanvas->isDrawingToLayer()) { 329 if (!fRecordingCanvas->isDrawingToLayer()) {
330 fCanDiscardCanvasContents = true; 330 fCanDiscardCanvasContents = true;
331 if (fPipeController.hasPendingCommands()) { 331 if (fPipeController.hasPendingCommands()) {
332 fFreshFrame = true; 332 fFreshFrame = true;
333 flushPendingCommands(kSilent_PlaybackMode); 333 flushPendingCommands(kSilent_PlaybackMode);
334 if (fNotificationClient) { 334 if (fNotificationClient) {
335 fNotificationClient->skippedPendingDrawCommands(); 335 fNotificationClient->skippedPendingDrawCommands();
336 } 336 }
337 } 337 }
338 } 338 }
339 } 339 }
340 340
341 bool DeferredDevice::isFreshFrame() { 341 bool SkDeferredDevice::isFreshFrame() {
342 bool ret = fFreshFrame; 342 bool ret = fFreshFrame;
343 fFreshFrame = false; 343 fFreshFrame = false;
344 return ret; 344 return ret;
345 } 345 }
346 346
347 bool DeferredDevice::hasPendingCommands() { 347 bool SkDeferredDevice::hasPendingCommands() {
348 return fPipeController.hasPendingCommands(); 348 return fPipeController.hasPendingCommands();
349 } 349 }
350 350
351 void DeferredDevice::aboutToDraw() 351 void SkDeferredDevice::aboutToDraw()
352 { 352 {
353 if (NULL != fNotificationClient) { 353 if (NULL != fNotificationClient) {
354 fNotificationClient->prepareForDraw(); 354 fNotificationClient->prepareForDraw();
355 } 355 }
356 if (fCanDiscardCanvasContents) { 356 if (fCanDiscardCanvasContents) {
357 if (NULL != fSurface) { 357 if (NULL != fSurface) {
358 fSurface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeM ode); 358 fSurface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeM ode);
359 } 359 }
360 fCanDiscardCanvasContents = false; 360 fCanDiscardCanvasContents = false;
361 } 361 }
362 } 362 }
363 363
364 void DeferredDevice::flushPendingCommands(PlaybackMode playbackMode) { 364 void SkDeferredDevice::flushPendingCommands(PlaybackMode playbackMode) {
365 if (!fPipeController.hasPendingCommands()) { 365 if (!fPipeController.hasPendingCommands()) {
366 return; 366 return;
367 } 367 }
368 if (playbackMode == kNormal_PlaybackMode) { 368 if (playbackMode == kNormal_PlaybackMode) {
369 aboutToDraw(); 369 aboutToDraw();
370 } 370 }
371 fPipeWriter.flushRecording(true); 371 fPipeWriter.flushRecording(true);
372 fPipeController.playback(kSilent_PlaybackMode == playbackMode); 372 fPipeController.playback(kSilent_PlaybackMode == playbackMode);
373 if (playbackMode == kNormal_PlaybackMode && fNotificationClient) { 373 if (playbackMode == kNormal_PlaybackMode && fNotificationClient) {
374 fNotificationClient->flushedDrawCommands(); 374 fNotificationClient->flushedDrawCommands();
375 } 375 }
376 fPreviousStorageAllocated = storageAllocatedForRecording(); 376 fPreviousStorageAllocated = storageAllocatedForRecording();
377 } 377 }
378 378
379 void DeferredDevice::flush() { 379 void SkDeferredDevice::flush() {
380 this->flushPendingCommands(kNormal_PlaybackMode); 380 this->flushPendingCommands(kNormal_PlaybackMode);
381 fImmediateCanvas->flush(); 381 fImmediateCanvas->flush();
382 } 382 }
383 383
384 size_t DeferredDevice::freeMemoryIfPossible(size_t bytesToFree) { 384 size_t SkDeferredDevice::freeMemoryIfPossible(size_t bytesToFree) {
385 size_t val = fPipeWriter.freeMemoryIfPossible(bytesToFree); 385 size_t val = fPipeWriter.freeMemoryIfPossible(bytesToFree);
386 fPreviousStorageAllocated = storageAllocatedForRecording(); 386 fPreviousStorageAllocated = storageAllocatedForRecording();
387 return val; 387 return val;
388 } 388 }
389 389
390 size_t DeferredDevice::getBitmapSizeThreshold() const { 390 size_t SkDeferredDevice::getBitmapSizeThreshold() const {
391 return fBitmapSizeThreshold; 391 return fBitmapSizeThreshold;
392 } 392 }
393 393
394 void DeferredDevice::setBitmapSizeThreshold(size_t sizeThreshold) { 394 void SkDeferredDevice::setBitmapSizeThreshold(size_t sizeThreshold) {
395 fBitmapSizeThreshold = sizeThreshold; 395 fBitmapSizeThreshold = sizeThreshold;
396 } 396 }
397 397
398 size_t DeferredDevice::storageAllocatedForRecording() const { 398 size_t SkDeferredDevice::storageAllocatedForRecording() const {
399 return (fPipeController.storageAllocatedForRecording() 399 return (fPipeController.storageAllocatedForRecording()
400 + fPipeWriter.storageAllocatedForRecording()); 400 + fPipeWriter.storageAllocatedForRecording());
401 } 401 }
402 402
403 void DeferredDevice::recordedDrawCommand() { 403 void SkDeferredDevice::recordedDrawCommand() {
404 size_t storageAllocated = this->storageAllocatedForRecording(); 404 size_t storageAllocated = this->storageAllocatedForRecording();
405 405
406 if (storageAllocated > fMaxRecordingStorageBytes) { 406 if (storageAllocated > fMaxRecordingStorageBytes) {
407 // First, attempt to reduce cache without flushing 407 // First, attempt to reduce cache without flushing
408 size_t tryFree = storageAllocated - fMaxRecordingStorageBytes; 408 size_t tryFree = storageAllocated - fMaxRecordingStorageBytes;
409 if (this->freeMemoryIfPossible(tryFree) < tryFree) { 409 if (this->freeMemoryIfPossible(tryFree) < tryFree) {
410 // Flush is necessary to free more space. 410 // Flush is necessary to free more space.
411 this->flushPendingCommands(kNormal_PlaybackMode); 411 this->flushPendingCommands(kNormal_PlaybackMode);
412 // Free as much as possible to avoid oscillating around fMaxRecordin gStorageBytes 412 // Free as much as possible to avoid oscillating around fMaxRecordin gStorageBytes
413 // which could cause a high flushing frequency. 413 // which could cause a high flushing frequency.
414 this->freeMemoryIfPossible(~0U); 414 this->freeMemoryIfPossible(~0U);
415 } 415 }
416 storageAllocated = this->storageAllocatedForRecording(); 416 storageAllocated = this->storageAllocatedForRecording();
417 } 417 }
418 418
419 if (fNotificationClient && 419 if (fNotificationClient &&
420 storageAllocated != fPreviousStorageAllocated) { 420 storageAllocated != fPreviousStorageAllocated) {
421 fPreviousStorageAllocated = storageAllocated; 421 fPreviousStorageAllocated = storageAllocated;
422 fNotificationClient->storageAllocatedForRecordingChanged(storageAllocate d); 422 fNotificationClient->storageAllocatedForRecordingChanged(storageAllocate d);
423 } 423 }
424 } 424 }
425 425
426 SkCanvas* DeferredDevice::recordingCanvas() { 426 SkCanvas* SkDeferredDevice::recordingCanvas() {
427 return fRecordingCanvas; 427 return fRecordingCanvas;
428 } 428 }
429 429
430 SkImage* DeferredDevice::newImageSnapshot() { 430 SkImage* SkDeferredDevice::newImageSnapshot() {
431 this->flush(); 431 this->flush();
432 return fSurface ? fSurface->newImageSnapshot() : NULL; 432 return fSurface ? fSurface->newImageSnapshot() : NULL;
433 } 433 }
434 434
435 uint32_t DeferredDevice::getDeviceCapabilities() { 435 uint32_t SkDeferredDevice::getDeviceCapabilities() {
436 return immediateDevice()->getDeviceCapabilities(); 436 return immediateDevice()->getDeviceCapabilities();
437 } 437 }
438 438
439 int DeferredDevice::width() const { 439 int SkDeferredDevice::width() const {
440 return immediateDevice()->width(); 440 return immediateDevice()->width();
441 } 441 }
442 442
443 int DeferredDevice::height() const { 443 int SkDeferredDevice::height() const {
444 return immediateDevice()->height(); 444 return immediateDevice()->height();
445 } 445 }
446 446
447 SkBitmap::Config DeferredDevice::config() const { 447 SkBitmap::Config SkDeferredDevice::config() const {
448 return immediateDevice()->config(); 448 return immediateDevice()->config();
449 } 449 }
450 450
451 bool DeferredDevice::isOpaque() const { 451 bool SkDeferredDevice::isOpaque() const {
452 return immediateDevice()->isOpaque(); 452 return immediateDevice()->isOpaque();
453 } 453 }
454 454
455 SkImageInfo DeferredDevice::imageInfo() const { 455 SkImageInfo SkDeferredDevice::imageInfo() const {
456 return immediateDevice()->imageInfo(); 456 return immediateDevice()->imageInfo();
457 } 457 }
458 458
459 GrRenderTarget* DeferredDevice::accessRenderTarget() { 459 GrRenderTarget* SkDeferredDevice::accessRenderTarget() {
460 this->flushPendingCommands(kNormal_PlaybackMode); 460 this->flushPendingCommands(kNormal_PlaybackMode);
461 return immediateDevice()->accessRenderTarget(); 461 return immediateDevice()->accessRenderTarget();
462 } 462 }
463 463
464 void DeferredDevice::prepareForImmediatePixelWrite() { 464 void SkDeferredDevice::prepareForImmediatePixelWrite() {
465 // The purpose of the following code is to make sure commands are flushed, t hat 465 // The purpose of the following code is to make sure commands are flushed, t hat
466 // aboutToDraw() is called and that notifyContentWillChange is called, witho ut 466 // aboutToDraw() is called and that notifyContentWillChange is called, witho ut
467 // calling anything redundantly. 467 // calling anything redundantly.
468 if (fPipeController.hasPendingCommands()) { 468 if (fPipeController.hasPendingCommands()) {
469 this->flushPendingCommands(kNormal_PlaybackMode); 469 this->flushPendingCommands(kNormal_PlaybackMode);
470 } else { 470 } else {
471 bool mustNotifyDirectly = !fCanDiscardCanvasContents; 471 bool mustNotifyDirectly = !fCanDiscardCanvasContents;
472 this->aboutToDraw(); 472 this->aboutToDraw();
473 if (mustNotifyDirectly) { 473 if (mustNotifyDirectly) {
474 fSurface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMo de); 474 fSurface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMo de);
475 } 475 }
476 } 476 }
477 477
478 fImmediateCanvas->flush(); 478 fImmediateCanvas->flush();
479 } 479 }
480 480
481 #ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG 481 #ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
482 void DeferredDevice::writePixels(const SkBitmap& bitmap, int x, int y, 482 void SkDeferredDevice::writePixels(const SkBitmap& bitmap, int x, int y,
483 SkCanvas::Config8888 config8888) { 483 SkCanvas::Config8888 config8888) {
484 484
485 if (x <= 0 && y <= 0 && (x + bitmap.width()) >= width() && 485 if (x <= 0 && y <= 0 && (x + bitmap.width()) >= width() &&
486 (y + bitmap.height()) >= height()) { 486 (y + bitmap.height()) >= height()) {
487 this->skipPendingCommands(); 487 this->skipPendingCommands();
488 } 488 }
489 489
490 if (SkBitmap::kARGB_8888_Config == bitmap.config() && 490 if (SkBitmap::kARGB_8888_Config == bitmap.config() &&
491 SkCanvas::kNative_Premul_Config8888 != config8888 && 491 SkCanvas::kNative_Premul_Config8888 != config8888 &&
492 kPMColorAlias != config8888) { 492 kPMColorAlias != config8888) {
493 //Special case config: no deferral 493 //Special case config: no deferral
494 prepareForImmediatePixelWrite(); 494 prepareForImmediatePixelWrite();
495 immediateDevice()->writePixels(bitmap, x, y, config8888); 495 immediateDevice()->writePixels(bitmap, x, y, config8888);
496 return; 496 return;
497 } 497 }
498 498
499 SkPaint paint; 499 SkPaint paint;
500 paint.setXfermodeMode(SkXfermode::kSrc_Mode); 500 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
501 if (shouldDrawImmediately(&bitmap, NULL, getBitmapSizeThreshold())) { 501 if (shouldDrawImmediately(&bitmap, NULL, getBitmapSizeThreshold())) {
502 prepareForImmediatePixelWrite(); 502 prepareForImmediatePixelWrite();
503 fImmediateCanvas->drawSprite(bitmap, x, y, &paint); 503 fImmediateCanvas->drawSprite(bitmap, x, y, &paint);
504 } else { 504 } else {
505 this->recordingCanvas()->drawSprite(bitmap, x, y, &paint); 505 this->recordingCanvas()->drawSprite(bitmap, x, y, &paint);
506 this->recordedDrawCommand(); 506 this->recordedDrawCommand();
507 507
508 } 508 }
509 } 509 }
510 #endif 510 #endif
511 511
512 bool DeferredDevice::onWritePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, 512 bool SkDeferredDevice::onWritePixels(const SkImageInfo& info, const void* pixels , size_t rowBytes,
513 int x, int y) { 513 int x, int y) {
514 SkASSERT(x >= 0 && y >= 0); 514 SkASSERT(x >= 0 && y >= 0);
515 SkASSERT(x + info.width() <= width()); 515 SkASSERT(x + info.width() <= width());
516 SkASSERT(y + info.height() <= height()); 516 SkASSERT(y + info.height() <= height());
517 517
518 this->flushPendingCommands(kNormal_PlaybackMode); 518 this->flushPendingCommands(kNormal_PlaybackMode);
519 519
520 const SkImageInfo deviceInfo = this->imageInfo(); 520 const SkImageInfo deviceInfo = this->imageInfo();
521 if (info.width() == deviceInfo.width() && info.height() == deviceInfo.height ()) { 521 if (info.width() == deviceInfo.width() && info.height() == deviceInfo.height ()) {
522 this->skipPendingCommands(); 522 this->skipPendingCommands();
523 } 523 }
524 524
525 this->prepareForImmediatePixelWrite(); 525 this->prepareForImmediatePixelWrite();
526 return immediateDevice()->onWritePixels(info, pixels, rowBytes, x, y); 526 return immediateDevice()->onWritePixels(info, pixels, rowBytes, x, y);
527 } 527 }
528 528
529 const SkBitmap& DeferredDevice::onAccessBitmap() { 529 const SkBitmap& SkDeferredDevice::onAccessBitmap() {
530 this->flushPendingCommands(kNormal_PlaybackMode); 530 this->flushPendingCommands(kNormal_PlaybackMode);
531 return immediateDevice()->accessBitmap(false); 531 return immediateDevice()->accessBitmap(false);
532 } 532 }
533 533
534 SkBaseDevice* DeferredDevice::onCreateDevice(const SkImageInfo& info, Usage usag e) { 534 SkBaseDevice* SkDeferredDevice::onCreateDevice(const SkImageInfo& info, Usage us age) {
535 // Save layer usage not supported, and not required by SkDeferredCanvas. 535 // Save layer usage not supported, and not required by SkDeferredCanvas.
536 SkASSERT(usage != kSaveLayer_Usage); 536 SkASSERT(usage != kSaveLayer_Usage);
537 // Create a compatible non-deferred device. 537 // Create a compatible non-deferred device.
538 // We do not create a deferred device because we know the new device 538 // We do not create a deferred device because we know the new device
539 // will not be used with a deferred canvas (there is no API for that). 539 // will not be used with a deferred canvas (there is no API for that).
540 // And connecting a DeferredDevice to non-deferred canvas can result 540 // And connecting a SkDeferredDevice to non-deferred canvas can result
541 // in unpredictable behavior. 541 // in unpredictable behavior.
542 return immediateDevice()->createCompatibleDevice(info); 542 return immediateDevice()->createCompatibleDevice(info);
543 } 543 }
544 544
545 SkSurface* DeferredDevice::newSurface(const SkImageInfo& info) { 545 SkSurface* SkDeferredDevice::newSurface(const SkImageInfo& info) {
546 return this->immediateDevice()->newSurface(info); 546 return this->immediateDevice()->newSurface(info);
547 } 547 }
548 548
549 bool DeferredDevice::onReadPixels( 549 bool SkDeferredDevice::onReadPixels(
550 const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) { 550 const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) {
551 this->flushPendingCommands(kNormal_PlaybackMode); 551 this->flushPendingCommands(kNormal_PlaybackMode);
552 return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap), 552 return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap),
553 x, y, config8888); 553 x, y, config8888);
554 } 554 }
555 555
556 class AutoImmediateDrawIfNeeded { 556 class AutoImmediateDrawIfNeeded {
557 public: 557 public:
558 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap, 558 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap,
559 const SkPaint* paint) { 559 const SkPaint* paint) {
560 this->init(canvas, bitmap, paint); 560 this->init(canvas, bitmap, paint);
561 } 561 }
562 562
563 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) { 563 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) {
564 this->init(canvas, NULL, paint); 564 this->init(canvas, NULL, paint);
565 } 565 }
566 566
567 ~AutoImmediateDrawIfNeeded() { 567 ~AutoImmediateDrawIfNeeded() {
568 if (fCanvas) { 568 if (fCanvas) {
569 fCanvas->setDeferredDrawing(true); 569 fCanvas->setDeferredDrawing(true);
570 } 570 }
571 } 571 }
572 private: 572 private:
573 void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* p aint) 573 void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* p aint)
574 { 574 {
575 DeferredDevice* device = static_cast<DeferredDevice*>(canvas.getDevice() ); 575 SkDeferredDevice* device = static_cast<SkDeferredDevice*>(canvas.getDevi ce());
576 if (canvas.isDeferredDrawing() && (NULL != device) && 576 if (canvas.isDeferredDrawing() && (NULL != device) &&
577 shouldDrawImmediately(bitmap, paint, device->getBitmapSizeThreshold( ))) { 577 shouldDrawImmediately(bitmap, paint, device->getBitmapSizeThreshold( ))) {
578 canvas.setDeferredDrawing(false); 578 canvas.setDeferredDrawing(false);
579 fCanvas = &canvas; 579 fCanvas = &canvas;
580 } else { 580 } else {
581 fCanvas = NULL; 581 fCanvas = NULL;
582 } 582 }
583 } 583 }
584 584
585 SkDeferredCanvas* fCanvas; 585 SkDeferredCanvas* fCanvas;
586 }; 586 };
587 587
588 SkDeferredCanvas* SkDeferredCanvas::Create(SkSurface* surface) { 588 SkDeferredCanvas* SkDeferredCanvas::Create(SkSurface* surface) {
589 SkAutoTUnref<DeferredDevice> deferredDevice(SkNEW_ARGS(DeferredDevice, (surf ace))); 589 SkAutoTUnref<SkDeferredDevice> deferredDevice(SkNEW_ARGS(SkDeferredDevice, ( surface)));
590 return SkNEW_ARGS(SkDeferredCanvas, (deferredDevice)); 590 return SkNEW_ARGS(SkDeferredCanvas, (deferredDevice));
591 } 591 }
592 592
593 SkDeferredCanvas::SkDeferredCanvas(DeferredDevice* device) : SkCanvas (device) { 593 SkDeferredCanvas::SkDeferredCanvas(SkDeferredDevice* device) : SkCanvas (device) {
594 this->init(); 594 this->init();
595 } 595 }
596 596
597 void SkDeferredCanvas::init() { 597 void SkDeferredCanvas::init() {
598 fDeferredDrawing = true; // On by default 598 fDeferredDrawing = true; // On by default
599 } 599 }
600 600
601 void SkDeferredCanvas::setMaxRecordingStorage(size_t maxStorage) { 601 void SkDeferredCanvas::setMaxRecordingStorage(size_t maxStorage) {
602 this->validate(); 602 this->validate();
603 this->getDeferredDevice()->setMaxRecordingStorage(maxStorage); 603 this->getDeferredDevice()->setMaxRecordingStorage(maxStorage);
604 } 604 }
605 605
606 size_t SkDeferredCanvas::storageAllocatedForRecording() const { 606 size_t SkDeferredCanvas::storageAllocatedForRecording() const {
607 return this->getDeferredDevice()->storageAllocatedForRecording(); 607 return this->getDeferredDevice()->storageAllocatedForRecording();
608 } 608 }
609 609
610 size_t SkDeferredCanvas::freeMemoryIfPossible(size_t bytesToFree) { 610 size_t SkDeferredCanvas::freeMemoryIfPossible(size_t bytesToFree) {
611 return this->getDeferredDevice()->freeMemoryIfPossible(bytesToFree); 611 return this->getDeferredDevice()->freeMemoryIfPossible(bytesToFree);
612 } 612 }
613 613
614 void SkDeferredCanvas::setBitmapSizeThreshold(size_t sizeThreshold) { 614 void SkDeferredCanvas::setBitmapSizeThreshold(size_t sizeThreshold) {
615 DeferredDevice* deferredDevice = this->getDeferredDevice(); 615 SkDeferredDevice* deferredDevice = this->getDeferredDevice();
616 SkASSERT(deferredDevice); 616 SkASSERT(deferredDevice);
617 deferredDevice->setBitmapSizeThreshold(sizeThreshold); 617 deferredDevice->setBitmapSizeThreshold(sizeThreshold);
618 } 618 }
619 619
620 void SkDeferredCanvas::recordedDrawCommand() { 620 void SkDeferredCanvas::recordedDrawCommand() {
621 if (fDeferredDrawing) { 621 if (fDeferredDrawing) {
622 this->getDeferredDevice()->recordedDrawCommand(); 622 this->getDeferredDevice()->recordedDrawCommand();
623 } 623 }
624 } 624 }
625 625
626 void SkDeferredCanvas::validate() const { 626 void SkDeferredCanvas::validate() const {
627 SkASSERT(this->getDevice()); 627 SkASSERT(this->getDevice());
628 } 628 }
629 629
630 SkCanvas* SkDeferredCanvas::drawingCanvas() const { 630 SkCanvas* SkDeferredCanvas::drawingCanvas() const {
631 this->validate(); 631 this->validate();
632 return fDeferredDrawing ? this->getDeferredDevice()->recordingCanvas() : 632 return fDeferredDrawing ? this->getDeferredDevice()->recordingCanvas() :
633 this->getDeferredDevice()->immediateCanvas(); 633 this->getDeferredDevice()->immediateCanvas();
634 } 634 }
635 635
636 SkCanvas* SkDeferredCanvas::immediateCanvas() const { 636 SkCanvas* SkDeferredCanvas::immediateCanvas() const {
637 this->validate(); 637 this->validate();
638 return this->getDeferredDevice()->immediateCanvas(); 638 return this->getDeferredDevice()->immediateCanvas();
639 } 639 }
640 640
641 DeferredDevice* SkDeferredCanvas::getDeferredDevice() const { 641 SkDeferredDevice* SkDeferredCanvas::getDeferredDevice() const {
642 return static_cast<DeferredDevice*>(this->getDevice()); 642 return static_cast<SkDeferredDevice*>(this->getDevice());
643 } 643 }
644 644
645 void SkDeferredCanvas::setDeferredDrawing(bool val) { 645 void SkDeferredCanvas::setDeferredDrawing(bool val) {
646 this->validate(); // Must set device before calling this method 646 this->validate(); // Must set device before calling this method
647 if (val != fDeferredDrawing) { 647 if (val != fDeferredDrawing) {
648 if (fDeferredDrawing) { 648 if (fDeferredDrawing) {
649 // Going live. 649 // Going live.
650 this->getDeferredDevice()->flushPendingCommands(kNormal_PlaybackMode ); 650 this->getDeferredDevice()->flushPendingCommands(kNormal_PlaybackMode );
651 } 651 }
652 fDeferredDrawing = val; 652 fDeferredDrawing = val;
(...skipping 15 matching lines...) Expand all
668 void SkDeferredCanvas::silentFlush() { 668 void SkDeferredCanvas::silentFlush() {
669 if (fDeferredDrawing) { 669 if (fDeferredDrawing) {
670 this->getDeferredDevice()->flushPendingCommands(kSilent_PlaybackMode); 670 this->getDeferredDevice()->flushPendingCommands(kSilent_PlaybackMode);
671 } 671 }
672 } 672 }
673 673
674 SkDeferredCanvas::~SkDeferredCanvas() { 674 SkDeferredCanvas::~SkDeferredCanvas() {
675 } 675 }
676 676
677 SkSurface* SkDeferredCanvas::setSurface(SkSurface* surface) { 677 SkSurface* SkDeferredCanvas::setSurface(SkSurface* surface) {
678 DeferredDevice* deferredDevice = this->getDeferredDevice(); 678 SkDeferredDevice* deferredDevice = this->getDeferredDevice();
679 SkASSERT(NULL != deferredDevice); 679 SkASSERT(NULL != deferredDevice);
680 // By swapping the surface into the existing device, we preserve 680 // By swapping the surface into the existing device, we preserve
681 // all pending commands, which can help to seamlessly recover from 681 // all pending commands, which can help to seamlessly recover from
682 // a lost accelerated graphics context. 682 // a lost accelerated graphics context.
683 deferredDevice->setSurface(surface); 683 deferredDevice->setSurface(surface);
684 return surface; 684 return surface;
685 } 685 }
686 686
687 SkDeferredCanvas::NotificationClient* SkDeferredCanvas::setNotificationClient( 687 SkDeferredCanvas::NotificationClient* SkDeferredCanvas::setNotificationClient(
688 NotificationClient* notificationClient) { 688 NotificationClient* notificationClient) {
689 689
690 DeferredDevice* deferredDevice = this->getDeferredDevice(); 690 SkDeferredDevice* deferredDevice = this->getDeferredDevice();
691 SkASSERT(deferredDevice); 691 SkASSERT(deferredDevice);
692 if (deferredDevice) { 692 if (deferredDevice) {
693 deferredDevice->setNotificationClient(notificationClient); 693 deferredDevice->setNotificationClient(notificationClient);
694 } 694 }
695 return notificationClient; 695 return notificationClient;
696 } 696 }
697 697
698 SkImage* SkDeferredCanvas::newImageSnapshot() { 698 SkImage* SkDeferredCanvas::newImageSnapshot() {
699 DeferredDevice* deferredDevice = this->getDeferredDevice(); 699 SkDeferredDevice* deferredDevice = this->getDeferredDevice();
700 SkASSERT(deferredDevice); 700 SkASSERT(deferredDevice);
701 return deferredDevice ? deferredDevice->newImageSnapshot() : NULL; 701 return deferredDevice ? deferredDevice->newImageSnapshot() : NULL;
702 } 702 }
703 703
704 bool SkDeferredCanvas::isFullFrame(const SkRect* rect, 704 bool SkDeferredCanvas::isFullFrame(const SkRect* rect,
705 const SkPaint* paint) const { 705 const SkPaint* paint) const {
706 SkCanvas* canvas = this->drawingCanvas(); 706 SkCanvas* canvas = this->drawingCanvas();
707 SkISize canvasSize = this->getDeviceSize(); 707 SkISize canvasSize = this->getDeviceSize();
708 if (rect) { 708 if (rect) {
709 if (!canvas->getTotalMatrix().rectStaysRect()) { 709 if (!canvas->getTotalMatrix().rectStaysRect()) {
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { 1035 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) {
1036 this->drawingCanvas()->setDrawFilter(filter); 1036 this->drawingCanvas()->setDrawFilter(filter);
1037 this->INHERITED::setDrawFilter(filter); 1037 this->INHERITED::setDrawFilter(filter);
1038 this->recordedDrawCommand(); 1038 this->recordedDrawCommand();
1039 return filter; 1039 return filter;
1040 } 1040 }
1041 1041
1042 SkCanvas* SkDeferredCanvas::canvasForDrawIter() { 1042 SkCanvas* SkDeferredCanvas::canvasForDrawIter() {
1043 return this->drawingCanvas(); 1043 return this->drawingCanvas();
1044 } 1044 }
OLDNEW
« no previous file with comments | « src/core/SkDevice.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698