| 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 |