SkDeferredCanvas.cpp revision 5ee449af7448c202cfc6e9a359d8f996392885b2
1 2/* 3 * Copyright 2013 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9#include "SkDeferredCanvas.h" 10 11#include "SkChunkAlloc.h" 12#include "SkColorFilter.h" 13#include "SkDevice.h" 14#include "SkDrawFilter.h" 15#include "SkGPipe.h" 16#include "SkPaint.h" 17#include "SkPaintPriv.h" 18#include "SkRRect.h" 19#include "SkShader.h" 20#include "SkSurface.h" 21 22enum { 23 // Deferred canvas will auto-flush when recording reaches this limit 24 kDefaultMaxRecordingStorageBytes = 64*1024*1024, 25 kDeferredCanvasBitmapSizeThreshold = ~0U, // Disables this feature 26}; 27 28enum PlaybackMode { 29 kNormal_PlaybackMode, 30 kSilent_PlaybackMode, 31}; 32 33namespace { 34bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint, 35 size_t bitmapSizeThreshold) { 36 if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) || 37 (bitmap->getSize() > bitmapSizeThreshold))) { 38 return true; 39 } 40 if (paint) { 41 SkShader* shader = paint->getShader(); 42 // Here we detect the case where the shader is an SkBitmapProcShader 43 // with a gpu texture attached. Checking this without RTTI 44 // requires making the assumption that only gradient shaders 45 // and SkBitmapProcShader implement asABitmap(). The following 46 // code may need to be revised if that assumption is ever broken. 47 if (shader && !shader->asAGradient(NULL)) { 48 SkBitmap bm; 49 if (shader->asABitmap(&bm, NULL, NULL) && 50 NULL != bm.getTexture()) { 51 return true; 52 } 53 } 54 } 55 return false; 56} 57} 58 59//----------------------------------------------------------------------------- 60// DeferredPipeController 61//----------------------------------------------------------------------------- 62 63class DeferredPipeController : public SkGPipeController { 64public: 65 DeferredPipeController(); 66 void setPlaybackCanvas(SkCanvas*); 67 virtual ~DeferredPipeController(); 68 virtual void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE; 69 virtual void notifyWritten(size_t bytes) SK_OVERRIDE; 70 void playback(bool silent); 71 bool hasPendingCommands() const { return fAllocator.blockCount() != 0; } 72 size_t storageAllocatedForRecording() const { return fAllocator.totalCapacity(); } 73private: 74 enum { 75 kMinBlockSize = 4096 76 }; 77 struct PipeBlock { 78 PipeBlock(void* block, size_t size) { fBlock = block, fSize = size; } 79 void* fBlock; 80 size_t fSize; 81 }; 82 void* fBlock; 83 size_t fBytesWritten; 84 SkChunkAlloc fAllocator; 85 SkTDArray<PipeBlock> fBlockList; 86 SkGPipeReader fReader; 87}; 88 89DeferredPipeController::DeferredPipeController() : 90 fAllocator(kMinBlockSize) { 91 fBlock = NULL; 92 fBytesWritten = 0; 93} 94 95DeferredPipeController::~DeferredPipeController() { 96 fAllocator.reset(); 97} 98 99void DeferredPipeController::setPlaybackCanvas(SkCanvas* canvas) { 100 fReader.setCanvas(canvas); 101} 102 103void* DeferredPipeController::requestBlock(size_t minRequest, size_t *actual) { 104 if (fBlock) { 105 // Save the previous block for later 106 PipeBlock previousBloc(fBlock, fBytesWritten); 107 fBlockList.push(previousBloc); 108 } 109 int32_t blockSize = SkMax32(minRequest, kMinBlockSize); 110 fBlock = fAllocator.allocThrow(blockSize); 111 fBytesWritten = 0; 112 *actual = blockSize; 113 return fBlock; 114} 115 116void DeferredPipeController::notifyWritten(size_t bytes) { 117 fBytesWritten += bytes; 118} 119 120void DeferredPipeController::playback(bool silent) { 121 uint32_t flags = silent ? SkGPipeReader::kSilent_PlaybackFlag : 0; 122 for (int currentBlock = 0; currentBlock < fBlockList.count(); currentBlock++ ) { 123 fReader.playback(fBlockList[currentBlock].fBlock, fBlockList[currentBlock].fSize, 124 flags); 125 } 126 fBlockList.reset(); 127 128 if (fBlock) { 129 fReader.playback(fBlock, fBytesWritten, flags); 130 fBlock = NULL; 131 } 132 133 // Release all allocated blocks 134 fAllocator.reset(); 135} 136 137//----------------------------------------------------------------------------- 138// DeferredDevice 139//----------------------------------------------------------------------------- 140class DeferredDevice : public SkDevice { 141public: 142 explicit DeferredDevice(SkDevice* immediateDevice); 143 explicit DeferredDevice(SkSurface* surface); 144 ~DeferredDevice(); 145 146 void setNotificationClient(SkDeferredCanvas::NotificationClient* notificationClient); 147 SkCanvas* recordingCanvas(); 148 SkCanvas* immediateCanvas() const {return fImmediateCanvas;} 149 SkDevice* immediateDevice() const {return fImmediateDevice;} 150 SkImage* newImageSnapshot(); 151 bool isFreshFrame(); 152 bool hasPendingCommands(); 153 size_t storageAllocatedForRecording() const; 154 size_t freeMemoryIfPossible(size_t bytesToFree); 155 size_t getBitmapSizeThreshold() const; 156 void setBitmapSizeThreshold(size_t sizeThreshold); 157 void flushPendingCommands(PlaybackMode); 158 void skipPendingCommands(); 159 void setMaxRecordingStorage(size_t); 160 void recordedDrawCommand(); 161 162 virtual uint32_t getDeviceCapabilities() SK_OVERRIDE; 163 virtual int width() const SK_OVERRIDE; 164 virtual int height() const SK_OVERRIDE; 165 virtual SkGpuRenderTarget* accessRenderTarget() SK_OVERRIDE; 166 167 virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config, 168 int width, int height, 169 bool isOpaque, 170 Usage usage) SK_OVERRIDE; 171 172 virtual void writePixels(const SkBitmap& bitmap, int x, int y, 173 SkCanvas::Config8888 config8888) SK_OVERRIDE; 174 175protected: 176 virtual const SkBitmap& onAccessBitmap(SkBitmap*) SK_OVERRIDE; 177 virtual bool onReadPixels(const SkBitmap& bitmap, 178 int x, int y, 179 SkCanvas::Config8888 config8888) SK_OVERRIDE; 180 181 // The following methods are no-ops on a deferred device 182 virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) 183 SK_OVERRIDE 184 {return false;} 185 186 // None of the following drawing methods should ever get called on the 187 // deferred device 188 virtual void clear(SkColor color) 189 {SkASSERT(0);} 190 virtual void drawPaint(const SkDraw&, const SkPaint& paint) 191 {SkASSERT(0);} 192 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, 193 size_t count, const SkPoint[], 194 const SkPaint& paint) 195 {SkASSERT(0);} 196 virtual void drawRect(const SkDraw&, const SkRect& r, 197 const SkPaint& paint) 198 {SkASSERT(0);} 199 virtual void drawPath(const SkDraw&, const SkPath& path, 200 const SkPaint& paint, 201 const SkMatrix* prePathMatrix = NULL, 202 bool pathIsMutable = false) 203 {SkASSERT(0);} 204 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap, 205 const SkIRect* srcRectOrNull, 206 const SkMatrix& matrix, const SkPaint& paint) 207 {SkASSERT(0);} 208 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, 209 int x, int y, const SkPaint& paint) 210 {SkASSERT(0);} 211 virtual void drawText(const SkDraw&, const void* text, size_t len, 212 SkScalar x, SkScalar y, const SkPaint& paint) 213 {SkASSERT(0);} 214 virtual void drawPosText(const SkDraw&, const void* text, size_t len, 215 const SkScalar pos[], SkScalar constY, 216 int scalarsPerPos, const SkPaint& paint) 217 {SkASSERT(0);} 218 virtual void drawTextOnPath(const SkDraw&, const void* text, 219 size_t len, const SkPath& path, 220 const SkMatrix* matrix, 221 const SkPaint& paint) 222 {SkASSERT(0);} 223 virtual void drawPosTextOnPath(const SkDraw& draw, const void* text, 224 size_t len, const SkPoint pos[], 225 const SkPaint& paint, 226 const SkPath& path, 227 const SkMatrix* matrix) 228 {SkASSERT(0);} 229 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, 230 int vertexCount, const SkPoint verts[], 231 const SkPoint texs[], const SkColor colors[], 232 SkXfermode* xmode, const uint16_t indices[], 233 int indexCount, const SkPaint& paint) 234 {SkASSERT(0);} 235 virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y, 236 const SkPaint&) 237 {SkASSERT(0);} 238private: 239 virtual void flush(); 240 241 void beginRecording(); 242 void init(); 243 244 DeferredPipeController fPipeController; 245 SkGPipeWriter fPipeWriter; 246 SkDevice* fImmediateDevice; 247 SkCanvas* fImmediateCanvas; 248 SkCanvas* fRecordingCanvas; 249 SkSurface* fSurface; 250 SkDeferredCanvas::NotificationClient* fNotificationClient; 251 bool fFreshFrame; 252 size_t fMaxRecordingStorageBytes; 253 size_t fPreviousStorageAllocated; 254 size_t fBitmapSizeThreshold; 255}; 256 257DeferredDevice::DeferredDevice(SkDevice* immediateDevice) 258 : SkDevice(SkBitmap::kNo_Config, 259 immediateDevice->width(), immediateDevice->height(), 260 immediateDevice->isOpaque(), 261 immediateDevice->getDeviceProperties()) { 262 fSurface = NULL; 263 fImmediateDevice = immediateDevice; // ref counted via fImmediateCanvas 264 fImmediateCanvas = SkNEW_ARGS(SkCanvas, (fImmediateDevice)); 265 this->init(); 266} 267 268DeferredDevice::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()) { 274 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes; 275 fNotificationClient = NULL; 276 fImmediateCanvas = surface->getCanvas(); 277 SkSafeRef(fImmediateCanvas); 278 fSurface = surface; 279 SkSafeRef(fSurface); 280 fImmediateDevice = fImmediateCanvas->getDevice(); // ref counted via fImmediateCanvas 281 this->init(); 282} 283 284void DeferredDevice::init() { 285 fRecordingCanvas = NULL; 286 fFreshFrame = true; 287 fPreviousStorageAllocated = 0; 288 fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold; 289 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes; 290 fNotificationClient = NULL; 291 fPipeController.setPlaybackCanvas(fImmediateCanvas); 292 this->beginRecording(); 293} 294 295DeferredDevice::~DeferredDevice() { 296 this->flushPendingCommands(kSilent_PlaybackMode); 297 SkSafeUnref(fImmediateCanvas); 298 SkSafeUnref(fSurface); 299} 300 301void DeferredDevice::setMaxRecordingStorage(size_t maxStorage) { 302 fMaxRecordingStorageBytes = maxStorage; 303 this->recordingCanvas(); // Accessing the recording canvas applies the new limit. 304} 305 306void DeferredDevice::beginRecording() { 307 SkASSERT(NULL == fRecordingCanvas); 308 fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0, 309 fImmediateDevice->width(), fImmediateDevice->height()); 310} 311 312void DeferredDevice::setNotificationClient( 313 SkDeferredCanvas::NotificationClient* notificationClient) { 314 fNotificationClient = notificationClient; 315} 316 317void DeferredDevice::skipPendingCommands() { 318 if (!fRecordingCanvas->isDrawingToLayer() && fPipeController.hasPendingCommands()) { 319 fFreshFrame = true; 320 flushPendingCommands(kSilent_PlaybackMode); 321 if (fNotificationClient) { 322 fNotificationClient->skippedPendingDrawCommands(); 323 } 324 } 325} 326 327bool DeferredDevice::isFreshFrame() { 328 bool ret = fFreshFrame; 329 fFreshFrame = false; 330 return ret; 331} 332 333bool DeferredDevice::hasPendingCommands() { 334 return fPipeController.hasPendingCommands(); 335} 336 337void DeferredDevice::flushPendingCommands(PlaybackMode playbackMode) { 338 if (!fPipeController.hasPendingCommands()) { 339 return; 340 } 341 if (playbackMode == kNormal_PlaybackMode && fNotificationClient) { 342 fNotificationClient->prepareForDraw(); 343 } 344 fPipeWriter.flushRecording(true); 345 fPipeController.playback(kSilent_PlaybackMode == playbackMode); 346 if (playbackMode == kNormal_PlaybackMode && fNotificationClient) { 347 fNotificationClient->flushedDrawCommands(); 348 } 349 fPreviousStorageAllocated = storageAllocatedForRecording(); 350} 351 352void DeferredDevice::flush() { 353 this->flushPendingCommands(kNormal_PlaybackMode); 354 fImmediateCanvas->flush(); 355} 356 357size_t DeferredDevice::freeMemoryIfPossible(size_t bytesToFree) { 358 size_t val = fPipeWriter.freeMemoryIfPossible(bytesToFree); 359 fPreviousStorageAllocated = storageAllocatedForRecording(); 360 return val; 361} 362 363size_t DeferredDevice::getBitmapSizeThreshold() const { 364 return fBitmapSizeThreshold; 365} 366 367void DeferredDevice::setBitmapSizeThreshold(size_t sizeThreshold) { 368 fBitmapSizeThreshold = sizeThreshold; 369} 370 371size_t DeferredDevice::storageAllocatedForRecording() const { 372 return (fPipeController.storageAllocatedForRecording() 373 + fPipeWriter.storageAllocatedForRecording()); 374} 375 376void DeferredDevice::recordedDrawCommand() { 377 size_t storageAllocated = this->storageAllocatedForRecording(); 378 379 if (storageAllocated > fMaxRecordingStorageBytes) { 380 // First, attempt to reduce cache without flushing 381 size_t tryFree = storageAllocated - fMaxRecordingStorageBytes; 382 if (this->freeMemoryIfPossible(tryFree) < tryFree) { 383 // Flush is necessary to free more space. 384 this->flushPendingCommands(kNormal_PlaybackMode); 385 // Free as much as possible to avoid oscillating around fMaxRecordingStorageBytes 386 // which could cause a high flushing frequency. 387 this->freeMemoryIfPossible(~0U); 388 } 389 storageAllocated = this->storageAllocatedForRecording(); 390 } 391 392 if (fNotificationClient && 393 storageAllocated != fPreviousStorageAllocated) { 394 fPreviousStorageAllocated = storageAllocated; 395 fNotificationClient->storageAllocatedForRecordingChanged(storageAllocated); 396 } 397} 398 399SkCanvas* DeferredDevice::recordingCanvas() { 400 return fRecordingCanvas; 401} 402 403SkImage* DeferredDevice::newImageSnapshot() { 404 this->flush(); 405 return fSurface ? fSurface->newImageSnapshot() : NULL; 406} 407 408uint32_t DeferredDevice::getDeviceCapabilities() { 409 return fImmediateDevice->getDeviceCapabilities(); 410} 411 412int DeferredDevice::width() const { 413 return fImmediateDevice->width(); 414} 415 416int DeferredDevice::height() const { 417 return fImmediateDevice->height(); 418} 419 420SkGpuRenderTarget* DeferredDevice::accessRenderTarget() { 421 this->flushPendingCommands(kNormal_PlaybackMode); 422 return fImmediateDevice->accessRenderTarget(); 423} 424 425void DeferredDevice::writePixels(const SkBitmap& bitmap, 426 int x, int y, SkCanvas::Config8888 config8888) { 427 428 if (x <= 0 && y <= 0 && (x + bitmap.width()) >= width() && 429 (y + bitmap.height()) >= height()) { 430 this->skipPendingCommands(); 431 } 432 433 if (SkBitmap::kARGB_8888_Config == bitmap.config() && 434 SkCanvas::kNative_Premul_Config8888 != config8888 && 435 kPMColorAlias != config8888) { 436 //Special case config: no deferral 437 this->flushPendingCommands(kNormal_PlaybackMode); 438 fImmediateDevice->writePixels(bitmap, x, y, config8888); 439 return; 440 } 441 442 SkPaint paint; 443 paint.setXfermodeMode(SkXfermode::kSrc_Mode); 444 if (shouldDrawImmediately(&bitmap, NULL, getBitmapSizeThreshold())) { 445 this->flushPendingCommands(kNormal_PlaybackMode); 446 fImmediateCanvas->drawSprite(bitmap, x, y, &paint); 447 } else { 448 this->recordingCanvas()->drawSprite(bitmap, x, y, &paint); 449 this->recordedDrawCommand(); 450 451 } 452} 453 454const SkBitmap& DeferredDevice::onAccessBitmap(SkBitmap*) { 455 this->flushPendingCommands(kNormal_PlaybackMode); 456 return fImmediateDevice->accessBitmap(false); 457} 458 459SkDevice* DeferredDevice::onCreateCompatibleDevice( 460 SkBitmap::Config config, int width, int height, bool isOpaque, 461 Usage usage) { 462 463 // Save layer usage not supported, and not required by SkDeferredCanvas. 464 SkASSERT(usage != kSaveLayer_Usage); 465 // Create a compatible non-deferred device. 466 SkAutoTUnref<SkDevice> compatibleDevice 467 (fImmediateDevice->createCompatibleDevice(config, width, height, 468 isOpaque)); 469 DeferredDevice* device = SkNEW_ARGS(DeferredDevice, (compatibleDevice)); 470 device->setNotificationClient(fNotificationClient); 471 return device; 472} 473 474bool DeferredDevice::onReadPixels( 475 const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) { 476 this->flushPendingCommands(kNormal_PlaybackMode); 477 return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap), 478 x, y, config8888); 479} 480 481class AutoImmediateDrawIfNeeded { 482public: 483 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap, 484 const SkPaint* paint) { 485 this->init(canvas, bitmap, paint); 486 } 487 488 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) { 489 this->init(canvas, NULL, paint); 490 } 491 492 ~AutoImmediateDrawIfNeeded() { 493 if (fCanvas) { 494 fCanvas->setDeferredDrawing(true); 495 } 496 } 497private: 498 void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* paint) 499 { 500 DeferredDevice* device = static_cast<DeferredDevice*>(canvas.getDevice()); 501 if (canvas.isDeferredDrawing() && (NULL != device) && 502 shouldDrawImmediately(bitmap, paint, device->getBitmapSizeThreshold())) { 503 canvas.setDeferredDrawing(false); 504 fCanvas = &canvas; 505 } else { 506 fCanvas = NULL; 507 } 508 } 509 510 SkDeferredCanvas* fCanvas; 511}; 512 513SkDeferredCanvas::SkDeferredCanvas() { 514 this->init(); 515} 516 517SkDeferredCanvas::SkDeferredCanvas(SkDevice* device) { 518 this->init(); 519 this->setDevice(device); 520} 521 522SkDeferredCanvas::SkDeferredCanvas(SkSurface* surface) { 523 this->init(); 524 this->INHERITED::setDevice(SkNEW_ARGS(DeferredDevice, (surface)))->unref(); 525} 526 527void SkDeferredCanvas::init() { 528 fDeferredDrawing = true; // On by default 529} 530 531void SkDeferredCanvas::setMaxRecordingStorage(size_t maxStorage) { 532 this->validate(); 533 this->getDeferredDevice()->setMaxRecordingStorage(maxStorage); 534} 535 536size_t SkDeferredCanvas::storageAllocatedForRecording() const { 537 return this->getDeferredDevice()->storageAllocatedForRecording(); 538} 539 540size_t SkDeferredCanvas::freeMemoryIfPossible(size_t bytesToFree) { 541 return this->getDeferredDevice()->freeMemoryIfPossible(bytesToFree); 542} 543 544void SkDeferredCanvas::setBitmapSizeThreshold(size_t sizeThreshold) { 545 DeferredDevice* deferredDevice = this->getDeferredDevice(); 546 SkASSERT(deferredDevice); 547 deferredDevice->setBitmapSizeThreshold(sizeThreshold); 548} 549 550void SkDeferredCanvas::recordedDrawCommand() { 551 if (fDeferredDrawing) { 552 this->getDeferredDevice()->recordedDrawCommand(); 553 } 554} 555 556void SkDeferredCanvas::validate() const { 557 SkASSERT(this->getDevice()); 558} 559 560SkCanvas* SkDeferredCanvas::drawingCanvas() const { 561 this->validate(); 562 return fDeferredDrawing ? this->getDeferredDevice()->recordingCanvas() : 563 this->getDeferredDevice()->immediateCanvas(); 564} 565 566SkCanvas* SkDeferredCanvas::immediateCanvas() const { 567 this->validate(); 568 return this->getDeferredDevice()->immediateCanvas(); 569} 570 571DeferredDevice* SkDeferredCanvas::getDeferredDevice() const { 572 return static_cast<DeferredDevice*>(this->getDevice()); 573} 574 575void SkDeferredCanvas::setDeferredDrawing(bool val) { 576 this->validate(); // Must set device before calling this method 577 if (val != fDeferredDrawing) { 578 if (fDeferredDrawing) { 579 // Going live. 580 this->getDeferredDevice()->flushPendingCommands(kNormal_PlaybackMode); 581 } 582 fDeferredDrawing = val; 583 } 584} 585 586bool SkDeferredCanvas::isDeferredDrawing() const { 587 return fDeferredDrawing; 588} 589 590bool SkDeferredCanvas::isFreshFrame() const { 591 return this->getDeferredDevice()->isFreshFrame(); 592} 593 594bool SkDeferredCanvas::hasPendingCommands() const { 595 return this->getDeferredDevice()->hasPendingCommands(); 596} 597 598void SkDeferredCanvas::silentFlush() { 599 if (fDeferredDrawing) { 600 this->getDeferredDevice()->flushPendingCommands(kSilent_PlaybackMode); 601 } 602} 603 604SkDeferredCanvas::~SkDeferredCanvas() { 605} 606 607SkDevice* SkDeferredCanvas::setDevice(SkDevice* device) { 608 this->INHERITED::setDevice(SkNEW_ARGS(DeferredDevice, (device)))->unref(); 609 return device; 610} 611 612SkDeferredCanvas::NotificationClient* SkDeferredCanvas::setNotificationClient( 613 NotificationClient* notificationClient) { 614 615 DeferredDevice* deferredDevice = this->getDeferredDevice(); 616 SkASSERT(deferredDevice); 617 if (deferredDevice) { 618 deferredDevice->setNotificationClient(notificationClient); 619 } 620 return notificationClient; 621} 622 623SkImage* SkDeferredCanvas::newImageSnapshot() { 624 DeferredDevice* deferredDevice = this->getDeferredDevice(); 625 SkASSERT(deferredDevice); 626 return deferredDevice ? deferredDevice->newImageSnapshot() : NULL; 627} 628 629bool SkDeferredCanvas::isFullFrame(const SkRect* rect, 630 const SkPaint* paint) const { 631 SkCanvas* canvas = this->drawingCanvas(); 632 SkISize canvasSize = this->getDeviceSize(); 633 if (rect) { 634 if (!canvas->getTotalMatrix().rectStaysRect()) { 635 return false; // conservative 636 } 637 638 SkRect transformedRect; 639 canvas->getTotalMatrix().mapRect(&transformedRect, *rect); 640 641 if (paint) { 642 SkPaint::Style paintStyle = paint->getStyle(); 643 if (!(paintStyle == SkPaint::kFill_Style || 644 paintStyle == SkPaint::kStrokeAndFill_Style)) { 645 return false; 646 } 647 if (paint->getMaskFilter() || paint->getLooper() 648 || paint->getPathEffect() || paint->getImageFilter()) { 649 return false; // conservative 650 } 651 } 652 653 // The following test holds with AA enabled, and is conservative 654 // by a 0.5 pixel margin with AA disabled 655 if (transformedRect.fLeft > SkIntToScalar(0) || 656 transformedRect.fTop > SkIntToScalar(0) || 657 transformedRect.fRight < SkIntToScalar(canvasSize.fWidth) || 658 transformedRect.fBottom < SkIntToScalar(canvasSize.fHeight)) { 659 return false; 660 } 661 } 662 663 return this->getClipStack()->quickContains(SkRect::MakeXYWH(0, 0, 664 SkIntToScalar(canvasSize.fWidth), SkIntToScalar(canvasSize.fHeight))); 665} 666 667int SkDeferredCanvas::save(SaveFlags flags) { 668 this->drawingCanvas()->save(flags); 669 int val = this->INHERITED::save(flags); 670 this->recordedDrawCommand(); 671 672 return val; 673} 674 675int SkDeferredCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, 676 SaveFlags flags) { 677 this->drawingCanvas()->saveLayer(bounds, paint, flags); 678 int count = this->INHERITED::save(flags); 679 this->clipRectBounds(bounds, flags, NULL); 680 this->recordedDrawCommand(); 681 682 return count; 683} 684 685void SkDeferredCanvas::restore() { 686 this->drawingCanvas()->restore(); 687 this->INHERITED::restore(); 688 this->recordedDrawCommand(); 689} 690 691bool SkDeferredCanvas::isDrawingToLayer() const { 692 return this->drawingCanvas()->isDrawingToLayer(); 693} 694 695bool SkDeferredCanvas::translate(SkScalar dx, SkScalar dy) { 696 this->drawingCanvas()->translate(dx, dy); 697 bool val = this->INHERITED::translate(dx, dy); 698 this->recordedDrawCommand(); 699 return val; 700} 701 702bool SkDeferredCanvas::scale(SkScalar sx, SkScalar sy) { 703 this->drawingCanvas()->scale(sx, sy); 704 bool val = this->INHERITED::scale(sx, sy); 705 this->recordedDrawCommand(); 706 return val; 707} 708 709bool SkDeferredCanvas::rotate(SkScalar degrees) { 710 this->drawingCanvas()->rotate(degrees); 711 bool val = this->INHERITED::rotate(degrees); 712 this->recordedDrawCommand(); 713 return val; 714} 715 716bool SkDeferredCanvas::skew(SkScalar sx, SkScalar sy) { 717 this->drawingCanvas()->skew(sx, sy); 718 bool val = this->INHERITED::skew(sx, sy); 719 this->recordedDrawCommand(); 720 return val; 721} 722 723bool SkDeferredCanvas::concat(const SkMatrix& matrix) { 724 this->drawingCanvas()->concat(matrix); 725 bool val = this->INHERITED::concat(matrix); 726 this->recordedDrawCommand(); 727 return val; 728} 729 730void SkDeferredCanvas::setMatrix(const SkMatrix& matrix) { 731 this->drawingCanvas()->setMatrix(matrix); 732 this->INHERITED::setMatrix(matrix); 733 this->recordedDrawCommand(); 734} 735 736bool SkDeferredCanvas::clipRect(const SkRect& rect, 737 SkRegion::Op op, 738 bool doAntiAlias) { 739 this->drawingCanvas()->clipRect(rect, op, doAntiAlias); 740 bool val = this->INHERITED::clipRect(rect, op, doAntiAlias); 741 this->recordedDrawCommand(); 742 return val; 743} 744 745bool SkDeferredCanvas::clipRRect(const SkRRect& rrect, 746 SkRegion::Op op, 747 bool doAntiAlias) { 748 this->drawingCanvas()->clipRRect(rrect, op, doAntiAlias); 749 bool val = this->INHERITED::clipRRect(rrect, op, doAntiAlias); 750 this->recordedDrawCommand(); 751 return val; 752} 753 754bool SkDeferredCanvas::clipPath(const SkPath& path, 755 SkRegion::Op op, 756 bool doAntiAlias) { 757 this->drawingCanvas()->clipPath(path, op, doAntiAlias); 758 bool val = this->INHERITED::clipPath(path, op, doAntiAlias); 759 this->recordedDrawCommand(); 760 return val; 761} 762 763bool SkDeferredCanvas::clipRegion(const SkRegion& deviceRgn, 764 SkRegion::Op op) { 765 this->drawingCanvas()->clipRegion(deviceRgn, op); 766 bool val = this->INHERITED::clipRegion(deviceRgn, op); 767 this->recordedDrawCommand(); 768 return val; 769} 770 771void SkDeferredCanvas::clear(SkColor color) { 772 // purge pending commands 773 if (fDeferredDrawing) { 774 this->getDeferredDevice()->skipPendingCommands(); 775 } 776 777 this->drawingCanvas()->clear(color); 778 this->recordedDrawCommand(); 779} 780 781void SkDeferredCanvas::drawPaint(const SkPaint& paint) { 782 if (fDeferredDrawing && this->isFullFrame(NULL, &paint) && 783 isPaintOpaque(&paint)) { 784 this->getDeferredDevice()->skipPendingCommands(); 785 } 786 AutoImmediateDrawIfNeeded autoDraw(*this, &paint); 787 this->drawingCanvas()->drawPaint(paint); 788 this->recordedDrawCommand(); 789} 790 791void SkDeferredCanvas::drawPoints(PointMode mode, size_t count, 792 const SkPoint pts[], const SkPaint& paint) { 793 AutoImmediateDrawIfNeeded autoDraw(*this, &paint); 794 this->drawingCanvas()->drawPoints(mode, count, pts, paint); 795 this->recordedDrawCommand(); 796} 797 798void SkDeferredCanvas::drawOval(const SkRect& rect, const SkPaint& paint) { 799 AutoImmediateDrawIfNeeded autoDraw(*this, &paint); 800 this->drawingCanvas()->drawOval(rect, paint); 801 this->recordedDrawCommand(); 802} 803 804void SkDeferredCanvas::drawRect(const SkRect& rect, const SkPaint& paint) { 805 if (fDeferredDrawing && this->isFullFrame(&rect, &paint) && 806 isPaintOpaque(&paint)) { 807 this->getDeferredDevice()->skipPendingCommands(); 808 } 809 810 AutoImmediateDrawIfNeeded autoDraw(*this, &paint); 811 this->drawingCanvas()->drawRect(rect, paint); 812 this->recordedDrawCommand(); 813} 814 815void SkDeferredCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 816 if (rrect.isRect()) { 817 this->SkDeferredCanvas::drawRect(rrect.getBounds(), paint); 818 } else if (rrect.isOval()) { 819 this->SkDeferredCanvas::drawOval(rrect.getBounds(), paint); 820 } else { 821 AutoImmediateDrawIfNeeded autoDraw(*this, &paint); 822 this->drawingCanvas()->drawRRect(rrect, paint); 823 this->recordedDrawCommand(); 824 } 825} 826 827void SkDeferredCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 828 AutoImmediateDrawIfNeeded autoDraw(*this, &paint); 829 this->drawingCanvas()->drawPath(path, paint); 830 this->recordedDrawCommand(); 831} 832 833void SkDeferredCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left, 834 SkScalar top, const SkPaint* paint) { 835 SkRect bitmapRect = SkRect::MakeXYWH(left, top, 836 SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height())); 837 if (fDeferredDrawing && 838 this->isFullFrame(&bitmapRect, paint) && 839 isPaintOpaque(paint, &bitmap)) { 840 this->getDeferredDevice()->skipPendingCommands(); 841 } 842 843 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint); 844 this->drawingCanvas()->drawBitmap(bitmap, left, top, paint); 845 this->recordedDrawCommand(); 846} 847 848void SkDeferredCanvas::drawBitmapRectToRect(const SkBitmap& bitmap, 849 const SkRect* src, 850 const SkRect& dst, 851 const SkPaint* paint) { 852 if (fDeferredDrawing && 853 this->isFullFrame(&dst, paint) && 854 isPaintOpaque(paint, &bitmap)) { 855 this->getDeferredDevice()->skipPendingCommands(); 856 } 857 858 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint); 859 this->drawingCanvas()->drawBitmapRectToRect(bitmap, src, dst, paint); 860 this->recordedDrawCommand(); 861} 862 863 864void SkDeferredCanvas::drawBitmapMatrix(const SkBitmap& bitmap, 865 const SkMatrix& m, 866 const SkPaint* paint) { 867 // TODO: reset recording canvas if paint+bitmap is opaque and clip rect 868 // covers canvas entirely and transformed bitmap covers canvas entirely 869 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint); 870 this->drawingCanvas()->drawBitmapMatrix(bitmap, m, paint); 871 this->recordedDrawCommand(); 872} 873 874void SkDeferredCanvas::drawBitmapNine(const SkBitmap& bitmap, 875 const SkIRect& center, const SkRect& dst, 876 const SkPaint* paint) { 877 // TODO: reset recording canvas if paint+bitmap is opaque and clip rect 878 // covers canvas entirely and dst covers canvas entirely 879 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint); 880 this->drawingCanvas()->drawBitmapNine(bitmap, center, dst, paint); 881 this->recordedDrawCommand(); 882} 883 884void SkDeferredCanvas::drawSprite(const SkBitmap& bitmap, int left, int top, 885 const SkPaint* paint) { 886 SkRect bitmapRect = SkRect::MakeXYWH( 887 SkIntToScalar(left), 888 SkIntToScalar(top), 889 SkIntToScalar(bitmap.width()), 890 SkIntToScalar(bitmap.height())); 891 if (fDeferredDrawing && 892 this->isFullFrame(&bitmapRect, paint) && 893 isPaintOpaque(paint, &bitmap)) { 894 this->getDeferredDevice()->skipPendingCommands(); 895 } 896 897 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint); 898 this->drawingCanvas()->drawSprite(bitmap, left, top, paint); 899 this->recordedDrawCommand(); 900} 901 902void SkDeferredCanvas::drawText(const void* text, size_t byteLength, 903 SkScalar x, SkScalar y, const SkPaint& paint) { 904 AutoImmediateDrawIfNeeded autoDraw(*this, &paint); 905 this->drawingCanvas()->drawText(text, byteLength, x, y, paint); 906 this->recordedDrawCommand(); 907} 908 909void SkDeferredCanvas::drawPosText(const void* text, size_t byteLength, 910 const SkPoint pos[], const SkPaint& paint) { 911 AutoImmediateDrawIfNeeded autoDraw(*this, &paint); 912 this->drawingCanvas()->drawPosText(text, byteLength, pos, paint); 913 this->recordedDrawCommand(); 914} 915 916void SkDeferredCanvas::drawPosTextH(const void* text, size_t byteLength, 917 const SkScalar xpos[], SkScalar constY, 918 const SkPaint& paint) { 919 AutoImmediateDrawIfNeeded autoDraw(*this, &paint); 920 this->drawingCanvas()->drawPosTextH(text, byteLength, xpos, constY, paint); 921 this->recordedDrawCommand(); 922} 923 924void SkDeferredCanvas::drawTextOnPath(const void* text, size_t byteLength, 925 const SkPath& path, 926 const SkMatrix* matrix, 927 const SkPaint& paint) { 928 AutoImmediateDrawIfNeeded autoDraw(*this, &paint); 929 this->drawingCanvas()->drawTextOnPath(text, byteLength, path, matrix, paint); 930 this->recordedDrawCommand(); 931} 932 933void SkDeferredCanvas::drawPicture(SkPicture& picture) { 934 this->drawingCanvas()->drawPicture(picture); 935 this->recordedDrawCommand(); 936} 937 938void SkDeferredCanvas::drawVertices(VertexMode vmode, int vertexCount, 939 const SkPoint vertices[], 940 const SkPoint texs[], 941 const SkColor colors[], SkXfermode* xmode, 942 const uint16_t indices[], int indexCount, 943 const SkPaint& paint) { 944 AutoImmediateDrawIfNeeded autoDraw(*this, &paint); 945 this->drawingCanvas()->drawVertices(vmode, vertexCount, vertices, texs, colors, xmode, 946 indices, indexCount, paint); 947 this->recordedDrawCommand(); 948} 949 950SkBounder* SkDeferredCanvas::setBounder(SkBounder* bounder) { 951 this->drawingCanvas()->setBounder(bounder); 952 this->INHERITED::setBounder(bounder); 953 this->recordedDrawCommand(); 954 return bounder; 955} 956 957SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { 958 this->drawingCanvas()->setDrawFilter(filter); 959 this->INHERITED::setDrawFilter(filter); 960 this->recordedDrawCommand(); 961 return filter; 962} 963 964SkCanvas* SkDeferredCanvas::canvasForDrawIter() { 965 return this->drawingCanvas(); 966} 967