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 |