| 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 |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |