| 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 12 matching lines...) Expand all Loading... |
| 23 // Deferred canvas will auto-flush when recording reaches this limit | 23 // Deferred canvas will auto-flush when recording reaches this limit |
| 24 kDefaultMaxRecordingStorageBytes = 64*1024*1024, | 24 kDefaultMaxRecordingStorageBytes = 64*1024*1024, |
| 25 kDeferredCanvasBitmapSizeThreshold = ~0U, // Disables this feature | 25 kDeferredCanvasBitmapSizeThreshold = ~0U, // Disables this feature |
| 26 }; | 26 }; |
| 27 | 27 |
| 28 enum PlaybackMode { | 28 enum PlaybackMode { |
| 29 kNormal_PlaybackMode, | 29 kNormal_PlaybackMode, |
| 30 kSilent_PlaybackMode, | 30 kSilent_PlaybackMode, |
| 31 }; | 31 }; |
| 32 | 32 |
| 33 namespace { | 33 static bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint, |
| 34 bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint, | |
| 35 size_t bitmapSizeThreshold) { | 34 size_t bitmapSizeThreshold) { |
| 36 if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) || | 35 if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) || |
| 37 (bitmap->getSize() > bitmapSizeThreshold))) { | 36 (bitmap->getSize() > bitmapSizeThreshold))) { |
| 38 return true; | 37 return true; |
| 39 } | 38 } |
| 40 if (paint) { | 39 if (paint) { |
| 41 SkShader* shader = paint->getShader(); | 40 SkShader* shader = paint->getShader(); |
| 42 // Here we detect the case where the shader is an SkBitmapProcShader | 41 // Here we detect the case where the shader is an SkBitmapProcShader |
| 43 // with a gpu texture attached. Checking this without RTTI | 42 // with a gpu texture attached. Checking this without RTTI |
| 44 // requires making the assumption that only gradient shaders | 43 // requires making the assumption that only gradient shaders |
| 45 // and SkBitmapProcShader implement asABitmap(). The following | 44 // and SkBitmapProcShader implement asABitmap(). The following |
| 46 // code may need to be revised if that assumption is ever broken. | 45 // code may need to be revised if that assumption is ever broken. |
| 47 if (shader && !shader->asAGradient(NULL)) { | 46 if (shader && !shader->asAGradient(NULL)) { |
| 48 SkBitmap bm; | 47 SkBitmap bm; |
| 49 if (shader->asABitmap(&bm, NULL, NULL) && | 48 if (shader->asABitmap(&bm, NULL, NULL) && |
| 50 NULL != bm.getTexture()) { | 49 NULL != bm.getTexture()) { |
| 51 return true; | 50 return true; |
| 52 } | 51 } |
| 53 } | 52 } |
| 54 } | 53 } |
| 55 return false; | 54 return false; |
| 56 } | 55 } |
| 57 } | |
| 58 | 56 |
| 59 //----------------------------------------------------------------------------- | 57 //----------------------------------------------------------------------------- |
| 60 // DeferredPipeController | 58 // DeferredPipeController |
| 61 //----------------------------------------------------------------------------- | 59 //----------------------------------------------------------------------------- |
| 62 | 60 |
| 63 class DeferredPipeController : public SkGPipeController { | 61 class DeferredPipeController : public SkGPipeController { |
| 64 public: | 62 public: |
| 65 DeferredPipeController(); | 63 DeferredPipeController(); |
| 66 void setPlaybackCanvas(SkCanvas*); | 64 void setPlaybackCanvas(SkCanvas*); |
| 67 virtual ~DeferredPipeController(); | 65 virtual ~DeferredPipeController(); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 virtual int width() const SK_OVERRIDE; | 161 virtual int width() const SK_OVERRIDE; |
| 164 virtual int height() const SK_OVERRIDE; | 162 virtual int height() const SK_OVERRIDE; |
| 165 virtual SkBitmap::Config config() const SK_OVERRIDE; | 163 virtual SkBitmap::Config config() const SK_OVERRIDE; |
| 166 virtual bool isOpaque() const SK_OVERRIDE; | 164 virtual bool isOpaque() const SK_OVERRIDE; |
| 167 virtual SkImageInfo imageInfo() const SK_OVERRIDE; | 165 virtual SkImageInfo imageInfo() const SK_OVERRIDE; |
| 168 | 166 |
| 169 virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE; | 167 virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE; |
| 170 | 168 |
| 171 virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE; | 169 virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE; |
| 172 | 170 |
| 171 #ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG |
| 173 virtual void writePixels(const SkBitmap& bitmap, int x, int y, | 172 virtual void writePixels(const SkBitmap& bitmap, int x, int y, |
| 174 SkCanvas::Config8888 config8888) SK_OVERRIDE; | 173 SkCanvas::Config8888 config8888) SK_OVERRIDE; |
| 175 | 174 #endif |
| 176 virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE; | 175 virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE; |
| 177 | 176 |
| 178 protected: | 177 protected: |
| 179 virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE; | 178 virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE; |
| 180 virtual bool onReadPixels(const SkBitmap& bitmap, | 179 virtual bool onReadPixels(const SkBitmap& bitmap, |
| 181 int x, int y, | 180 int x, int y, |
| 182 SkCanvas::Config8888 config8888) SK_OVERRIDE; | 181 SkCanvas::Config8888 config8888) SK_OVERRIDE; |
| 182 virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, i
nt y) SK_OVERRIDE; |
| 183 | 183 |
| 184 // The following methods are no-ops on a deferred device | 184 // The following methods are no-ops on a deferred device |
| 185 virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE { | 185 virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE { |
| 186 return false; | 186 return false; |
| 187 } | 187 } |
| 188 | 188 |
| 189 // None of the following drawing methods should ever get called on the | 189 // None of the following drawing methods should ever get called on the |
| 190 // deferred device | 190 // deferred device |
| 191 virtual void clear(SkColor color) SK_OVERRIDE | 191 virtual void clear(SkColor color) SK_OVERRIDE |
| 192 {SkASSERT(0);} | 192 {SkASSERT(0);} |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 void DeferredDevice::writePixels(const SkBitmap& bitmap, | 481 #ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG |
| 482 int x, int y, SkCanvas::Config8888 config8888) { | 482 void DeferredDevice::writePixels(const SkBitmap& bitmap, int x, int y, |
| 483 SkCanvas::Config8888 config8888) { |
| 483 | 484 |
| 484 if (x <= 0 && y <= 0 && (x + bitmap.width()) >= width() && | 485 if (x <= 0 && y <= 0 && (x + bitmap.width()) >= width() && |
| 485 (y + bitmap.height()) >= height()) { | 486 (y + bitmap.height()) >= height()) { |
| 486 this->skipPendingCommands(); | 487 this->skipPendingCommands(); |
| 487 } | 488 } |
| 488 | 489 |
| 489 if (SkBitmap::kARGB_8888_Config == bitmap.config() && | 490 if (SkBitmap::kARGB_8888_Config == bitmap.config() && |
| 490 SkCanvas::kNative_Premul_Config8888 != config8888 && | 491 SkCanvas::kNative_Premul_Config8888 != config8888 && |
| 491 kPMColorAlias != config8888) { | 492 kPMColorAlias != config8888) { |
| 492 //Special case config: no deferral | 493 //Special case config: no deferral |
| 493 prepareForImmediatePixelWrite(); | 494 prepareForImmediatePixelWrite(); |
| 494 immediateDevice()->writePixels(bitmap, x, y, config8888); | 495 immediateDevice()->writePixels(bitmap, x, y, config8888); |
| 495 return; | 496 return; |
| 496 } | 497 } |
| 497 | 498 |
| 498 SkPaint paint; | 499 SkPaint paint; |
| 499 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 500 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
| 500 if (shouldDrawImmediately(&bitmap, NULL, getBitmapSizeThreshold())) { | 501 if (shouldDrawImmediately(&bitmap, NULL, getBitmapSizeThreshold())) { |
| 501 prepareForImmediatePixelWrite(); | 502 prepareForImmediatePixelWrite(); |
| 502 fImmediateCanvas->drawSprite(bitmap, x, y, &paint); | 503 fImmediateCanvas->drawSprite(bitmap, x, y, &paint); |
| 503 } else { | 504 } else { |
| 504 this->recordingCanvas()->drawSprite(bitmap, x, y, &paint); | 505 this->recordingCanvas()->drawSprite(bitmap, x, y, &paint); |
| 505 this->recordedDrawCommand(); | 506 this->recordedDrawCommand(); |
| 506 | 507 |
| 507 } | 508 } |
| 508 } | 509 } |
| 510 #endif |
| 511 |
| 512 bool DeferredDevice::onWritePixels(const SkImageInfo& info, const void* pixels,
size_t rowBytes, |
| 513 int x, int y) { |
| 514 SkASSERT(x >= 0 && y >= 0); |
| 515 SkASSERT(x + info.width() <= width()); |
| 516 SkASSERT(y + info.height() <= height()); |
| 517 |
| 518 this->flushPendingCommands(kNormal_PlaybackMode); |
| 519 |
| 520 const SkImageInfo deviceInfo = this->imageInfo(); |
| 521 if (info.width() == deviceInfo.width() && info.height() == deviceInfo.height
()) { |
| 522 this->skipPendingCommands(); |
| 523 } |
| 524 |
| 525 this->prepareForImmediatePixelWrite(); |
| 526 return immediateDevice()->onWritePixels(info, pixels, rowBytes, x, y); |
| 527 } |
| 509 | 528 |
| 510 const SkBitmap& DeferredDevice::onAccessBitmap() { | 529 const SkBitmap& DeferredDevice::onAccessBitmap() { |
| 511 this->flushPendingCommands(kNormal_PlaybackMode); | 530 this->flushPendingCommands(kNormal_PlaybackMode); |
| 512 return immediateDevice()->accessBitmap(false); | 531 return immediateDevice()->accessBitmap(false); |
| 513 } | 532 } |
| 514 | 533 |
| 515 SkBaseDevice* DeferredDevice::onCreateDevice(const SkImageInfo& info, Usage usag
e) { | 534 SkBaseDevice* DeferredDevice::onCreateDevice(const SkImageInfo& info, Usage usag
e) { |
| 516 // Save layer usage not supported, and not required by SkDeferredCanvas. | 535 // Save layer usage not supported, and not required by SkDeferredCanvas. |
| 517 SkASSERT(usage != kSaveLayer_Usage); | 536 SkASSERT(usage != kSaveLayer_Usage); |
| 518 // Create a compatible non-deferred device. | 537 // Create a compatible non-deferred device. |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1016 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { | 1035 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { |
| 1017 this->drawingCanvas()->setDrawFilter(filter); | 1036 this->drawingCanvas()->setDrawFilter(filter); |
| 1018 this->INHERITED::setDrawFilter(filter); | 1037 this->INHERITED::setDrawFilter(filter); |
| 1019 this->recordedDrawCommand(); | 1038 this->recordedDrawCommand(); |
| 1020 return filter; | 1039 return filter; |
| 1021 } | 1040 } |
| 1022 | 1041 |
| 1023 SkCanvas* SkDeferredCanvas::canvasForDrawIter() { | 1042 SkCanvas* SkDeferredCanvas::canvasForDrawIter() { |
| 1024 return this->drawingCanvas(); | 1043 return this->drawingCanvas(); |
| 1025 } | 1044 } |
| OLD | NEW |