diff options
author | sugoi@google.com <sugoi@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-11-21 15:47:04 +0000 |
---|---|---|
committer | sugoi@google.com <sugoi@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-11-21 15:47:04 +0000 |
commit | 7775fd5779e632d6f5724e0e5d39ed347cf965b0 (patch) | |
tree | 42c72bb45da8d29e3818dddc94cc66088379a4d9 /src | |
parent | f68154a3cf43eb22d45be11f3b09e25440c366a6 (diff) |
Deferred canvas can now be flushed if an image is beyond a certain size to avoid a costly image copy.
BUG=http://code.google.com/p/chromium/issues/detail?id=137924
TEST=TestDeferredCanvasBitmapSizeThreshold unit test
Review URL: https://codereview.appspot.com/6852071
git-svn-id: http://skia.googlecode.com/svn/trunk@6527 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r-- | src/utils/SkDeferredCanvas.cpp | 93 |
1 files changed, 59 insertions, 34 deletions
diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp index 207ec053a7..ffc935d5de 100644 --- a/src/utils/SkDeferredCanvas.cpp +++ b/src/utils/SkDeferredCanvas.cpp @@ -16,6 +16,10 @@ #include "SkPaint.h" #include "SkShader.h" +#ifndef SK_DEFERRED_CANVAS_BITMAP_SIZE_THRESHOLD +#define SK_DEFERRED_CANVAS_BITMAP_SIZE_THRESHOLD ~0 // Disables this feature +#endif + enum { // Deferred canvas will auto-flush when recording reaches this limit kDefaultMaxRecordingStorageBytes = 64*1024*1024, @@ -27,8 +31,10 @@ enum PlaybackMode { }; namespace { -bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint) { - if (bitmap && bitmap->getTexture() && !bitmap->isImmutable()) { +bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint, + size_t bitmapSizeThreshold) { + if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) || + (bitmap->getSize() > bitmapSizeThreshold))) { return true; } if (paint) { @@ -50,36 +56,6 @@ bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint) { } } -class AutoImmediateDrawIfNeeded { -public: - AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap, - const SkPaint* paint) { - this->init(canvas, bitmap, paint); - } - - AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) { - this->init(canvas, NULL, paint); - } - - ~AutoImmediateDrawIfNeeded() { - if (fCanvas) { - fCanvas->setDeferredDrawing(true); - } - } -private: - void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* paint) - { - if (canvas.isDeferredDrawing() && shouldDrawImmediately(bitmap, paint)) { - canvas.setDeferredDrawing(false); - fCanvas = &canvas; - } else { - fCanvas = NULL; - } - } - - SkDeferredCanvas* fCanvas; -}; - namespace { bool isPaintOpaque(const SkPaint* paint, @@ -244,6 +220,8 @@ public: bool hasPendingCommands(); size_t storageAllocatedForRecording() const; size_t freeMemoryIfPossible(size_t bytesToFree); + size_t getBitmapSizeThreshold() const; + void setBitmapSizeThreshold(size_t sizeThreshold); void flushPendingCommands(PlaybackMode); void skipPendingCommands(); void setMaxRecordingStorage(size_t); @@ -339,6 +317,7 @@ private: bool fFreshFrame; size_t fMaxRecordingStorageBytes; size_t fPreviousStorageAllocated; + size_t fBitmapSizeThreshold; }; DeferredDevice::DeferredDevice( @@ -347,7 +326,8 @@ DeferredDevice::DeferredDevice( immediateDevice->height(), immediateDevice->isOpaque()) , fRecordingCanvas(NULL) , fFreshFrame(true) - , fPreviousStorageAllocated(0){ + , fPreviousStorageAllocated(0) + , fBitmapSizeThreshold(SK_DEFERRED_CANVAS_BITMAP_SIZE_THRESHOLD){ fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes; fNotificationClient = notificationClient; @@ -424,6 +404,14 @@ size_t DeferredDevice::freeMemoryIfPossible(size_t bytesToFree) { return val; } +size_t DeferredDevice::getBitmapSizeThreshold() const { + return fBitmapSizeThreshold; +} + +void DeferredDevice::setBitmapSizeThreshold(size_t sizeThreshold) { + fBitmapSizeThreshold = sizeThreshold; +} + size_t DeferredDevice::storageAllocatedForRecording() const { return (fPipeController.storageAllocatedForRecording() + fPipeWriter.storageAllocatedForRecording()); @@ -492,7 +480,7 @@ void DeferredDevice::writePixels(const SkBitmap& bitmap, SkPaint paint; paint.setXfermodeMode(SkXfermode::kSrc_Mode); - if (shouldDrawImmediately(&bitmap, NULL)) { + if (shouldDrawImmediately(&bitmap, NULL, getBitmapSizeThreshold())) { this->flushPendingCommands(kNormal_PlaybackMode); fImmediateCanvas->drawSprite(bitmap, x, y, &paint); } else { @@ -527,6 +515,37 @@ bool DeferredDevice::onReadPixels( x, y, config8888); } +class AutoImmediateDrawIfNeeded { +public: + AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap, + const SkPaint* paint) { + this->init(canvas, bitmap, paint); + } + + AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) { + this->init(canvas, NULL, paint); + } + + ~AutoImmediateDrawIfNeeded() { + if (fCanvas) { + fCanvas->setDeferredDrawing(true); + } + } +private: + void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* paint) + { + DeferredDevice* device = static_cast<DeferredDevice*>(canvas.getDevice()); + if (canvas.isDeferredDrawing() && (NULL != device) && + shouldDrawImmediately(bitmap, paint, device->getBitmapSizeThreshold())) { + canvas.setDeferredDrawing(false); + fCanvas = &canvas; + } else { + fCanvas = NULL; + } + } + + SkDeferredCanvas* fCanvas; +}; SkDeferredCanvas::SkDeferredCanvas() { this->init(); @@ -554,6 +573,12 @@ size_t SkDeferredCanvas::freeMemoryIfPossible(size_t bytesToFree) { return this->getDeferredDevice()->freeMemoryIfPossible(bytesToFree); } +void SkDeferredCanvas::setBitmapSizeThreshold(size_t sizeThreshold) { + DeferredDevice* deferredDevice = this->getDeferredDevice(); + SkASSERT(deferredDevice); + deferredDevice->setBitmapSizeThreshold(sizeThreshold); +} + void SkDeferredCanvas::recordedDrawCommand() { if (fDeferredDrawing) { this->getDeferredDevice()->recordedDrawCommand(); |