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 |
11 #include "SkBitmapDevice.h" | 11 #include "SkBitmapDevice.h" |
12 #include "SkChunkAlloc.h" | 12 #include "SkChunkAlloc.h" |
13 #include "SkColorFilter.h" | 13 #include "SkColorFilter.h" |
14 #include "SkDrawFilter.h" | 14 #include "SkDrawFilter.h" |
15 #include "SkGPipe.h" | 15 #include "SkGPipe.h" |
| 16 #include "SkImage_Base.h" |
16 #include "SkPaint.h" | 17 #include "SkPaint.h" |
17 #include "SkPaintPriv.h" | 18 #include "SkPaintPriv.h" |
18 #include "SkRRect.h" | 19 #include "SkRRect.h" |
19 #include "SkShader.h" | 20 #include "SkShader.h" |
20 #include "SkSurface.h" | 21 #include "SkSurface.h" |
21 | 22 |
22 enum { | 23 enum { |
23 // Deferred canvas will auto-flush when recording reaches this limit | 24 // Deferred canvas will auto-flush when recording reaches this limit |
24 kDefaultMaxRecordingStorageBytes = 64*1024*1024, | 25 kDefaultMaxRecordingStorageBytes = 64*1024*1024, |
25 kDeferredCanvasBitmapSizeThreshold = ~0U, // Disables this feature | 26 kDeferredCanvasBitmapSizeThreshold = ~0U, // Disables this feature |
26 | 27 |
27 kNoSaveLayerIndex = -1, | 28 kNoSaveLayerIndex = -1, |
28 }; | 29 }; |
29 | 30 |
30 enum PlaybackMode { | 31 enum PlaybackMode { |
31 kNormal_PlaybackMode, | 32 kNormal_PlaybackMode, |
32 kSilent_PlaybackMode, | 33 kSilent_PlaybackMode, |
33 }; | 34 }; |
34 | 35 |
35 static bool should_draw_immediately(const SkBitmap* bitmap, const SkPaint* paint
, | 36 static bool should_draw_immediately(const SkPaint* paint) { |
36 size_t bitmapSizeThreshold) { | |
37 if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) || | |
38 (bitmap->getSize() > bitmapSizeThreshold))) { | |
39 return true; | |
40 } | |
41 if (paint) { | 37 if (paint) { |
42 SkShader* shader = paint->getShader(); | 38 SkShader* shader = paint->getShader(); |
43 // Here we detect the case where the shader is an SkBitmapProcShader | 39 // Here we detect the case where the shader is an SkBitmapProcShader |
44 // with a gpu texture attached. Checking this without RTTI | 40 // with a gpu texture attached. Checking this without RTTI |
45 // requires making the assumption that only gradient shaders | 41 // requires making the assumption that only gradient shaders |
46 // and SkBitmapProcShader implement asABitmap(). The following | 42 // and SkBitmapProcShader implement asABitmap(). The following |
47 // code may need to be revised if that assumption is ever broken. | 43 // code may need to be revised if that assumption is ever broken. |
48 if (shader && !shader->asAGradient(NULL)) { | 44 if (shader && !shader->asAGradient(NULL)) { |
49 SkBitmap bm; | 45 SkBitmap bm; |
50 if (shader->asABitmap(&bm, NULL, NULL) && | 46 if (shader->asABitmap(&bm, NULL, NULL) && |
51 bm.getTexture()) { | 47 bm.getTexture()) { |
52 return true; | 48 return true; |
53 } | 49 } |
54 } | 50 } |
55 } | 51 } |
56 return false; | 52 return false; |
57 } | 53 } |
58 | 54 |
| 55 static bool should_draw_immediately(const SkBitmap* bitmap, const SkPaint* paint
, |
| 56 size_t bitmapSizeThreshold) { |
| 57 if ((bitmap->getTexture() && !bitmap->isImmutable()) || |
| 58 (bitmap->getSize() > bitmapSizeThreshold)) { |
| 59 return true; |
| 60 } |
| 61 return should_draw_immediately(paint); |
| 62 } |
| 63 |
| 64 static bool should_draw_immediately(const SkImage* image, const SkPaint* paint, |
| 65 size_t bitmapSizeThreshold) { |
| 66 SkASSERT(image); |
| 67 if (as_IB(image)->getSize() > bitmapSizeThreshold) { |
| 68 return true; |
| 69 } |
| 70 return should_draw_immediately(paint); |
| 71 } |
| 72 |
| 73 |
59 //----------------------------------------------------------------------------- | 74 //----------------------------------------------------------------------------- |
60 // DeferredPipeController | 75 // DeferredPipeController |
61 //----------------------------------------------------------------------------- | 76 //----------------------------------------------------------------------------- |
62 | 77 |
63 class DeferredPipeController : public SkGPipeController { | 78 class DeferredPipeController : public SkGPipeController { |
64 public: | 79 public: |
65 DeferredPipeController(); | 80 DeferredPipeController(); |
66 void setPlaybackCanvas(SkCanvas*); | 81 void setPlaybackCanvas(SkCanvas*); |
67 virtual ~DeferredPipeController(); | 82 virtual ~DeferredPipeController(); |
68 void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE; | 83 void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE; |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap, | 210 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap, |
196 const SkMatrix& matrix, const SkPaint& paint) SK_OVE
RRIDE | 211 const SkMatrix& matrix, const SkPaint& paint) SK_OVE
RRIDE |
197 {SkASSERT(0);} | 212 {SkASSERT(0);} |
198 virtual void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*, | 213 virtual void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*, |
199 const SkRect&, const SkPaint&, | 214 const SkRect&, const SkPaint&, |
200 SkCanvas::DrawBitmapRectFlags) SK_OVERRIDE | 215 SkCanvas::DrawBitmapRectFlags) SK_OVERRIDE |
201 {SkASSERT(0);} | 216 {SkASSERT(0);} |
202 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, | 217 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, |
203 int x, int y, const SkPaint& paint) SK_OVERRIDE | 218 int x, int y, const SkPaint& paint) SK_OVERRIDE |
204 {SkASSERT(0);} | 219 {SkASSERT(0);} |
| 220 virtual void drawSprite(const SkDraw&, const SkImage& image, |
| 221 int x, int y, const SkPaint& paint) SK_OVERRIDE |
| 222 {SkASSERT(0);} |
205 virtual void drawText(const SkDraw&, const void* text, size_t len, | 223 virtual void drawText(const SkDraw&, const void* text, size_t len, |
206 SkScalar x, SkScalar y, const SkPaint& paint) SK_OVE
RRIDE | 224 SkScalar x, SkScalar y, const SkPaint& paint) SK_OVE
RRIDE |
207 {SkASSERT(0);} | 225 {SkASSERT(0);} |
208 virtual void drawPosText(const SkDraw&, const void* text, size_t len, | 226 virtual void drawPosText(const SkDraw&, const void* text, size_t len, |
209 const SkScalar pos[], int scalarsPerPos, | 227 const SkScalar pos[], int scalarsPerPos, |
210 const SkPoint& offset, const SkPaint& paint) SK_OVE
RRIDE | 228 const SkPoint& offset, const SkPaint& paint) SK_OVE
RRIDE |
211 {SkASSERT(0);} | 229 {SkASSERT(0);} |
212 virtual void drawTextOnPath(const SkDraw&, const void* text, | 230 virtual void drawTextOnPath(const SkDraw&, const void* text, |
213 size_t len, const SkPath& path, | 231 size_t len, const SkPath& path, |
214 const SkMatrix* matrix, | 232 const SkMatrix* matrix, |
(...skipping 15 matching lines...) Expand all Loading... |
230 | 248 |
231 void lockPixels() SK_OVERRIDE {} | 249 void lockPixels() SK_OVERRIDE {} |
232 void unlockPixels() SK_OVERRIDE {} | 250 void unlockPixels() SK_OVERRIDE {} |
233 | 251 |
234 bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE { | 252 bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE { |
235 return false; | 253 return false; |
236 } | 254 } |
237 bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE { | 255 bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE { |
238 return false; | 256 return false; |
239 } | 257 } |
240 virtual bool filterImage(const SkImageFilter*, const SkBitmap&, | 258 virtual bool filterImage(const SkImageFilter*, const SkImage*, |
241 const SkImageFilter::Context&, SkBitmap*, SkIPoint*
) SK_OVERRIDE { | 259 const SkImageFilter::Context&, |
| 260 SkAutoTUnref<const SkImage>&, SkIPoint*) SK_OVERRID
E { |
242 return false; | 261 return false; |
243 } | 262 } |
244 | 263 |
245 private: | 264 private: |
246 void flush() SK_OVERRIDE; | 265 void flush() SK_OVERRIDE; |
247 void replaceBitmapBackend(const SkBitmap&) SK_OVERRIDE {} | 266 void replaceBitmapBackend(const SkBitmap&) SK_OVERRIDE {} |
248 | 267 |
249 void beginRecording(); | 268 void beginRecording(); |
250 void init(); | 269 void init(); |
251 void aboutToDraw(); | 270 void aboutToDraw(); |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 | 492 |
474 bool SkDeferredDevice::onReadPixels(const SkImageInfo& info, void* pixels, size_
t rowBytes, | 493 bool SkDeferredDevice::onReadPixels(const SkImageInfo& info, void* pixels, size_
t rowBytes, |
475 int x, int y) { | 494 int x, int y) { |
476 this->flushPendingCommands(kNormal_PlaybackMode); | 495 this->flushPendingCommands(kNormal_PlaybackMode); |
477 return fImmediateCanvas->readPixels(info, pixels, rowBytes, x, y); | 496 return fImmediateCanvas->readPixels(info, pixels, rowBytes, x, y); |
478 } | 497 } |
479 | 498 |
480 class AutoImmediateDrawIfNeeded { | 499 class AutoImmediateDrawIfNeeded { |
481 public: | 500 public: |
482 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap, | 501 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap, |
483 const SkPaint* paint) { | 502 const SkPaint* paint) |
484 this->init(canvas, bitmap, paint); | 503 : fCanvas(NULL) { |
| 504 if (canvas.isDeferredDrawing() && |
| 505 should_draw_immediately(bitmap, paint, canvas.getBitmapSizeThreshold
())) { |
| 506 fCanvas = &canvas; |
| 507 } |
| 508 this->init(); |
485 } | 509 } |
486 | 510 |
487 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) { | 511 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkImage* image, |
488 this->init(canvas, NULL, paint); | 512 const SkPaint* paint) |
| 513 : fCanvas(NULL) { |
| 514 if (canvas.isDeferredDrawing() && |
| 515 should_draw_immediately(image, paint, canvas.getBitmapSizeThreshold(
))) { |
| 516 fCanvas = &canvas; |
| 517 } |
| 518 this->init(); |
| 519 } |
| 520 |
| 521 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) |
| 522 : fCanvas(NULL) { |
| 523 if (canvas.isDeferredDrawing() && should_draw_immediately(paint)) { |
| 524 fCanvas = &canvas; |
| 525 } |
| 526 this->init(); |
489 } | 527 } |
490 | 528 |
491 ~AutoImmediateDrawIfNeeded() { | 529 ~AutoImmediateDrawIfNeeded() { |
492 if (fCanvas) { | 530 if (fCanvas) { |
493 fCanvas->setDeferredDrawing(true); | 531 fCanvas->setDeferredDrawing(true); |
494 } | 532 } |
495 } | 533 } |
496 private: | 534 private: |
497 void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* p
aint) { | 535 void init() { |
498 if (canvas.isDeferredDrawing() && | 536 if (fCanvas) { |
499 should_draw_immediately(bitmap, paint, canvas.getBitmapSizeThreshold
())) { | 537 fCanvas->setDeferredDrawing(false); |
500 canvas.setDeferredDrawing(false); | |
501 fCanvas = &canvas; | |
502 } else { | |
503 fCanvas = NULL; | |
504 } | 538 } |
505 } | 539 } |
506 | 540 |
507 SkDeferredCanvas* fCanvas; | 541 SkDeferredCanvas* fCanvas; |
508 }; | 542 }; |
509 | 543 |
510 SkDeferredCanvas* SkDeferredCanvas::Create(SkSurface* surface) { | 544 SkDeferredCanvas* SkDeferredCanvas::Create(SkSurface* surface) { |
511 SkAutoTUnref<SkDeferredDevice> deferredDevice(SkNEW_ARGS(SkDeferredDevice, (
surface))); | 545 SkAutoTUnref<SkDeferredDevice> deferredDevice(SkNEW_ARGS(SkDeferredDevice, (
surface))); |
512 return SkNEW_ARGS(SkDeferredCanvas, (deferredDevice)); | 546 return SkNEW_ARGS(SkDeferredCanvas, (deferredDevice)); |
513 } | 547 } |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
857 this->isFullFrame(&bitmapRect, paint) && | 891 this->isFullFrame(&bitmapRect, paint) && |
858 isPaintOpaque(paint, &bitmap)) { | 892 isPaintOpaque(paint, &bitmap)) { |
859 this->getDeferredDevice()->skipPendingCommands(); | 893 this->getDeferredDevice()->skipPendingCommands(); |
860 } | 894 } |
861 | 895 |
862 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint); | 896 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint); |
863 this->drawingCanvas()->drawSprite(bitmap, left, top, paint); | 897 this->drawingCanvas()->drawSprite(bitmap, left, top, paint); |
864 this->recordedDrawCommand(); | 898 this->recordedDrawCommand(); |
865 } | 899 } |
866 | 900 |
| 901 void SkDeferredCanvas::onDrawSprite(const SkImage& image, int left, int top, |
| 902 const SkPaint* paint) { |
| 903 SkRect imageRect = SkRect::MakeXYWH( |
| 904 SkIntToScalar(left), |
| 905 SkIntToScalar(top), |
| 906 SkIntToScalar(image.width()), |
| 907 SkIntToScalar(image.height())); |
| 908 if (fDeferredDrawing && |
| 909 this->isFullFrame(&imageRect, paint) && |
| 910 isPaintOpaque(paint, &image)) { |
| 911 this->getDeferredDevice()->skipPendingCommands(); |
| 912 } |
| 913 |
| 914 AutoImmediateDrawIfNeeded autoDraw(*this, &image, paint); |
| 915 this->drawingCanvas()->drawSprite(image, left, top, paint); |
| 916 this->recordedDrawCommand(); |
| 917 } |
| 918 |
867 void SkDeferredCanvas::onDrawText(const void* text, size_t byteLength, SkScalar
x, SkScalar y, | 919 void SkDeferredCanvas::onDrawText(const void* text, size_t byteLength, SkScalar
x, SkScalar y, |
868 const SkPaint& paint) { | 920 const SkPaint& paint) { |
869 AutoImmediateDrawIfNeeded autoDraw(*this, &paint); | 921 AutoImmediateDrawIfNeeded autoDraw(*this, &paint); |
870 this->drawingCanvas()->drawText(text, byteLength, x, y, paint); | 922 this->drawingCanvas()->drawText(text, byteLength, x, y, paint); |
871 this->recordedDrawCommand(); | 923 this->recordedDrawCommand(); |
872 } | 924 } |
873 | 925 |
874 void SkDeferredCanvas::onDrawPosText(const void* text, size_t byteLength, const
SkPoint pos[], | 926 void SkDeferredCanvas::onDrawPosText(const void* text, size_t byteLength, const
SkPoint pos[], |
875 const SkPaint& paint) { | 927 const SkPaint& paint) { |
876 AutoImmediateDrawIfNeeded autoDraw(*this, &paint); | 928 AutoImmediateDrawIfNeeded autoDraw(*this, &paint); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { | 980 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { |
929 this->drawingCanvas()->setDrawFilter(filter); | 981 this->drawingCanvas()->setDrawFilter(filter); |
930 this->INHERITED::setDrawFilter(filter); | 982 this->INHERITED::setDrawFilter(filter); |
931 this->recordedDrawCommand(); | 983 this->recordedDrawCommand(); |
932 return filter; | 984 return filter; |
933 } | 985 } |
934 | 986 |
935 SkCanvas* SkDeferredCanvas::canvasForDrawIter() { | 987 SkCanvas* SkDeferredCanvas::canvasForDrawIter() { |
936 return this->drawingCanvas(); | 988 return this->drawingCanvas(); |
937 } | 989 } |
OLD | NEW |