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 14 matching lines...) Expand all Loading... |
25 kDeferredCanvasBitmapSizeThreshold = ~0U, // Disables this feature | 25 kDeferredCanvasBitmapSizeThreshold = ~0U, // Disables this feature |
26 | 26 |
27 kNoSaveLayerIndex = -1, | 27 kNoSaveLayerIndex = -1, |
28 }; | 28 }; |
29 | 29 |
30 enum PlaybackMode { | 30 enum PlaybackMode { |
31 kNormal_PlaybackMode, | 31 kNormal_PlaybackMode, |
32 kSilent_PlaybackMode, | 32 kSilent_PlaybackMode, |
33 }; | 33 }; |
34 | 34 |
35 static uint64_t image_area(const SkImage* image) { | 35 static bool should_draw_immediately(const SkBitmap* bitmap, const SkPaint* paint
, |
36 return sk_64_mul(image->width(), image->height()); | 36 size_t bitmapSizeThreshold) { |
37 } | |
38 | |
39 static bool should_draw_immediately(const SkBitmap* bitmap, const SkImage* image
, | |
40 const SkPaint* paint, size_t bitmapSizeThres
hold) { | |
41 if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) || | 37 if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) || |
42 (bitmap->getSize() > bitmapSizeThreshold))) { | 38 (bitmap->getSize() > bitmapSizeThreshold))) { |
43 return true; | |
44 } | |
45 if (image && (image_area(image) > bitmapSizeThreshold)) { | |
46 return true; | 39 return true; |
47 } | 40 } |
48 if (paint) { | 41 if (paint) { |
49 SkShader* shader = paint->getShader(); | 42 SkShader* shader = paint->getShader(); |
50 // Here we detect the case where the shader is an SkBitmapProcShader | 43 // Here we detect the case where the shader is an SkBitmapProcShader |
51 // with a gpu texture attached. Checking this without RTTI | 44 // with a gpu texture attached. Checking this without RTTI |
52 // requires making the assumption that only gradient shaders | 45 // requires making the assumption that only gradient shaders |
53 // and SkBitmapProcShader implement asABitmap(). The following | 46 // and SkBitmapProcShader implement asABitmap(). The following |
54 // code may need to be revised if that assumption is ever broken. | 47 // code may need to be revised if that assumption is ever broken. |
55 if (shader && !shader->asAGradient(NULL)) { | 48 if (shader && !shader->asAGradient(NULL)) { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 void drawBitmap(const SkDraw&, const SkBitmap& bitmap, | 195 void drawBitmap(const SkDraw&, const SkBitmap& bitmap, |
203 const SkMatrix& matrix, const SkPaint& paint) override | 196 const SkMatrix& matrix, const SkPaint& paint) override |
204 {SkASSERT(0);} | 197 {SkASSERT(0);} |
205 void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*, | 198 void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*, |
206 const SkRect&, const SkPaint&, | 199 const SkRect&, const SkPaint&, |
207 SkCanvas::DrawBitmapRectFlags) override | 200 SkCanvas::DrawBitmapRectFlags) override |
208 {SkASSERT(0);} | 201 {SkASSERT(0);} |
209 void drawSprite(const SkDraw&, const SkBitmap& bitmap, | 202 void drawSprite(const SkDraw&, const SkBitmap& bitmap, |
210 int x, int y, const SkPaint& paint) override | 203 int x, int y, const SkPaint& paint) override |
211 {SkASSERT(0);} | 204 {SkASSERT(0);} |
212 void drawImage(const SkDraw&, const SkImage*, SkScalar, SkScalar, const SkPa
int&) override | |
213 {SkASSERT(0);} | |
214 void drawImageRect(const SkDraw&, const SkImage*, const SkRect*, const SkRec
t&, | |
215 const SkPaint&) override | |
216 {SkASSERT(0);} | |
217 void drawText(const SkDraw&, const void* text, size_t len, | 205 void drawText(const SkDraw&, const void* text, size_t len, |
218 SkScalar x, SkScalar y, const SkPaint& paint) override | 206 SkScalar x, SkScalar y, const SkPaint& paint) override |
219 {SkASSERT(0);} | 207 {SkASSERT(0);} |
220 void drawPosText(const SkDraw&, const void* text, size_t len, | 208 void drawPosText(const SkDraw&, const void* text, size_t len, |
221 const SkScalar pos[], int scalarsPerPos, | 209 const SkScalar pos[], int scalarsPerPos, |
222 const SkPoint& offset, const SkPaint& paint) override | 210 const SkPoint& offset, const SkPaint& paint) override |
223 {SkASSERT(0);} | 211 {SkASSERT(0);} |
224 void drawTextOnPath(const SkDraw&, const void* text, | 212 void drawTextOnPath(const SkDraw&, const void* text, |
225 size_t len, const SkPath& path, | 213 size_t len, const SkPath& path, |
226 const SkMatrix* matrix, | 214 const SkMatrix* matrix, |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 bool SkDeferredDevice::onReadPixels(const SkImageInfo& info, void* pixels, size_
t rowBytes, | 474 bool SkDeferredDevice::onReadPixels(const SkImageInfo& info, void* pixels, size_
t rowBytes, |
487 int x, int y) { | 475 int x, int y) { |
488 this->flushPendingCommands(kNormal_PlaybackMode); | 476 this->flushPendingCommands(kNormal_PlaybackMode); |
489 return fImmediateCanvas->readPixels(info, pixels, rowBytes, x, y); | 477 return fImmediateCanvas->readPixels(info, pixels, rowBytes, x, y); |
490 } | 478 } |
491 | 479 |
492 class AutoImmediateDrawIfNeeded { | 480 class AutoImmediateDrawIfNeeded { |
493 public: | 481 public: |
494 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap, | 482 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap, |
495 const SkPaint* paint) { | 483 const SkPaint* paint) { |
496 this->init(canvas, bitmap, NULL, paint); | 484 this->init(canvas, bitmap, paint); |
497 } | |
498 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkImage* image, | |
499 const SkPaint* paint) { | |
500 this->init(canvas, NULL, image, paint); | |
501 } | 485 } |
502 | 486 |
503 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) { | 487 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) { |
504 this->init(canvas, NULL, NULL, paint); | 488 this->init(canvas, NULL, paint); |
505 } | 489 } |
506 | 490 |
507 ~AutoImmediateDrawIfNeeded() { | 491 ~AutoImmediateDrawIfNeeded() { |
508 if (fCanvas) { | 492 if (fCanvas) { |
509 fCanvas->setDeferredDrawing(true); | 493 fCanvas->setDeferredDrawing(true); |
510 } | 494 } |
511 } | 495 } |
512 private: | 496 private: |
513 void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkImage* i
mage, | 497 void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* p
aint) { |
514 const SkPaint* paint) { | |
515 if (canvas.isDeferredDrawing() && | 498 if (canvas.isDeferredDrawing() && |
516 should_draw_immediately(bitmap, image, paint, canvas.getBitmapSizeTh
reshold())) { | 499 should_draw_immediately(bitmap, paint, canvas.getBitmapSizeThreshold
())) { |
517 canvas.setDeferredDrawing(false); | 500 canvas.setDeferredDrawing(false); |
518 fCanvas = &canvas; | 501 fCanvas = &canvas; |
519 } else { | 502 } else { |
520 fCanvas = NULL; | 503 fCanvas = NULL; |
521 } | 504 } |
522 } | 505 } |
523 | 506 |
524 SkDeferredCanvas* fCanvas; | 507 SkDeferredCanvas* fCanvas; |
525 }; | 508 }; |
526 | 509 |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
846 this->isFullFrame(&dst, paint) && | 829 this->isFullFrame(&dst, paint) && |
847 isPaintOpaque(paint, &bitmap)) { | 830 isPaintOpaque(paint, &bitmap)) { |
848 this->getDeferredDevice()->skipPendingCommands(); | 831 this->getDeferredDevice()->skipPendingCommands(); |
849 } | 832 } |
850 | 833 |
851 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint); | 834 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint); |
852 this->drawingCanvas()->drawBitmapRectToRect(bitmap, src, dst, paint, flags); | 835 this->drawingCanvas()->drawBitmapRectToRect(bitmap, src, dst, paint, flags); |
853 this->recordedDrawCommand(); | 836 this->recordedDrawCommand(); |
854 } | 837 } |
855 | 838 |
856 | |
857 void SkDeferredCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, | |
858 const SkPaint* paint) { | |
859 SkRect bounds = SkRect::MakeXYWH(x, y, | |
860 SkIntToScalar(image->width()), SkIntToScala
r(image->height())); | |
861 if (fDeferredDrawing && | |
862 this->isFullFrame(&bounds, paint) && | |
863 isPaintOpaque(paint, image)) { | |
864 this->getDeferredDevice()->skipPendingCommands(); | |
865 } | |
866 | |
867 AutoImmediateDrawIfNeeded autoDraw(*this, image, paint); | |
868 this->drawingCanvas()->drawImage(image, x, y, paint); | |
869 this->recordedDrawCommand(); | |
870 } | |
871 void SkDeferredCanvas::onDrawImageRect(const SkImage* image, const SkRect* src,
const SkRect& dst, | |
872 const SkPaint* paint) { | |
873 if (fDeferredDrawing && | |
874 this->isFullFrame(&dst, paint) && | |
875 isPaintOpaque(paint, image)) { | |
876 this->getDeferredDevice()->skipPendingCommands(); | |
877 } | |
878 | |
879 AutoImmediateDrawIfNeeded autoDraw(*this, image, paint); | |
880 this->drawingCanvas()->drawImageRect(image, src, dst, paint); | |
881 this->recordedDrawCommand(); | |
882 } | |
883 | |
884 void SkDeferredCanvas::onDrawBitmapNine(const SkBitmap& bitmap, | 839 void SkDeferredCanvas::onDrawBitmapNine(const SkBitmap& bitmap, |
885 const SkIRect& center, const SkRect& dst
, | 840 const SkIRect& center, const SkRect& dst
, |
886 const SkPaint* paint) { | 841 const SkPaint* paint) { |
887 // TODO: reset recording canvas if paint+bitmap is opaque and clip rect | 842 // TODO: reset recording canvas if paint+bitmap is opaque and clip rect |
888 // covers canvas entirely and dst covers canvas entirely | 843 // covers canvas entirely and dst covers canvas entirely |
889 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint); | 844 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint); |
890 this->drawingCanvas()->drawBitmapNine(bitmap, center, dst, paint); | 845 this->drawingCanvas()->drawBitmapNine(bitmap, center, dst, paint); |
891 this->recordedDrawCommand(); | 846 this->recordedDrawCommand(); |
892 } | 847 } |
893 | 848 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
973 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { | 928 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { |
974 this->drawingCanvas()->setDrawFilter(filter); | 929 this->drawingCanvas()->setDrawFilter(filter); |
975 this->INHERITED::setDrawFilter(filter); | 930 this->INHERITED::setDrawFilter(filter); |
976 this->recordedDrawCommand(); | 931 this->recordedDrawCommand(); |
977 return filter; | 932 return filter; |
978 } | 933 } |
979 | 934 |
980 SkCanvas* SkDeferredCanvas::canvasForDrawIter() { | 935 SkCanvas* SkDeferredCanvas::canvasForDrawIter() { |
981 return this->drawingCanvas(); | 936 return this->drawingCanvas(); |
982 } | 937 } |
OLD | NEW |