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 bool should_draw_immediately(const SkBitmap* bitmap, const SkPaint* paint
, | 35 static uint64_t image_area(const SkImage* image) { |
36 size_t bitmapSizeThreshold) { | 36 return sk_64_mul(image->width(), image->height()); |
| 37 } |
| 38 |
| 39 // HACK -- see crbug.com/485243 |
| 40 // |
| 41 // Work around case where Blink gives us an image, but will "mutate" it (by chan
ging its contents |
| 42 // directly using webgl). Until that is fixed at the call-site, we treat gpu-bac
ked-images as |
| 43 // mutable for now (at least for the purposes of deferred canvas) |
| 44 // |
| 45 static bool should_draw_gpu_image_immediately(const SkImage* image) { |
| 46 return image->getTexture() != NULL; |
| 47 } |
| 48 |
| 49 static bool should_draw_immediately(const SkBitmap* bitmap, const SkImage* image
, |
| 50 const SkPaint* paint, size_t bitmapSizeThres
hold) { |
37 if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) || | 51 if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) || |
38 (bitmap->getSize() > bitmapSizeThreshold))) { | 52 (bitmap->getSize() > bitmapSizeThreshold))) { |
39 return true; | 53 return true; |
40 } | 54 } |
| 55 if (image) { |
| 56 if (should_draw_gpu_image_immediately(image) || image_area(image) > bitm
apSizeThreshold) { |
| 57 return true; |
| 58 } |
| 59 } |
41 if (paint) { | 60 if (paint) { |
42 SkShader* shader = paint->getShader(); | 61 SkShader* shader = paint->getShader(); |
43 // Here we detect the case where the shader is an SkBitmapProcShader | 62 // Here we detect the case where the shader is an SkBitmapProcShader |
44 // with a gpu texture attached. Checking this without RTTI | 63 // with a gpu texture attached. Checking this without RTTI |
45 // requires making the assumption that only gradient shaders | 64 // requires making the assumption that only gradient shaders |
46 // and SkBitmapProcShader implement asABitmap(). The following | 65 // and SkBitmapProcShader implement asABitmap(). The following |
47 // code may need to be revised if that assumption is ever broken. | 66 // code may need to be revised if that assumption is ever broken. |
48 if (shader && !shader->asAGradient(NULL)) { | 67 if (shader && !shader->asAGradient(NULL)) { |
49 SkBitmap bm; | 68 SkBitmap bm; |
50 if (shader->asABitmap(&bm, NULL, NULL) && | 69 if (shader->asABitmap(&bm, NULL, NULL) && |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 void drawBitmap(const SkDraw&, const SkBitmap& bitmap, | 214 void drawBitmap(const SkDraw&, const SkBitmap& bitmap, |
196 const SkMatrix& matrix, const SkPaint& paint) override | 215 const SkMatrix& matrix, const SkPaint& paint) override |
197 {SkASSERT(0);} | 216 {SkASSERT(0);} |
198 void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*, | 217 void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*, |
199 const SkRect&, const SkPaint&, | 218 const SkRect&, const SkPaint&, |
200 SkCanvas::DrawBitmapRectFlags) override | 219 SkCanvas::DrawBitmapRectFlags) override |
201 {SkASSERT(0);} | 220 {SkASSERT(0);} |
202 void drawSprite(const SkDraw&, const SkBitmap& bitmap, | 221 void drawSprite(const SkDraw&, const SkBitmap& bitmap, |
203 int x, int y, const SkPaint& paint) override | 222 int x, int y, const SkPaint& paint) override |
204 {SkASSERT(0);} | 223 {SkASSERT(0);} |
| 224 void drawImage(const SkDraw&, const SkImage*, SkScalar, SkScalar, const SkPa
int&) override |
| 225 {SkASSERT(0);} |
| 226 void drawImageRect(const SkDraw&, const SkImage*, const SkRect*, const SkRec
t&, |
| 227 const SkPaint&) override |
| 228 {SkASSERT(0);} |
205 void drawText(const SkDraw&, const void* text, size_t len, | 229 void drawText(const SkDraw&, const void* text, size_t len, |
206 SkScalar x, SkScalar y, const SkPaint& paint) override | 230 SkScalar x, SkScalar y, const SkPaint& paint) override |
207 {SkASSERT(0);} | 231 {SkASSERT(0);} |
208 void drawPosText(const SkDraw&, const void* text, size_t len, | 232 void drawPosText(const SkDraw&, const void* text, size_t len, |
209 const SkScalar pos[], int scalarsPerPos, | 233 const SkScalar pos[], int scalarsPerPos, |
210 const SkPoint& offset, const SkPaint& paint) override | 234 const SkPoint& offset, const SkPaint& paint) override |
211 {SkASSERT(0);} | 235 {SkASSERT(0);} |
212 void drawTextOnPath(const SkDraw&, const void* text, | 236 void drawTextOnPath(const SkDraw&, const void* text, |
213 size_t len, const SkPath& path, | 237 size_t len, const SkPath& path, |
214 const SkMatrix* matrix, | 238 const SkMatrix* matrix, |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 bool SkDeferredDevice::onReadPixels(const SkImageInfo& info, void* pixels, size_
t rowBytes, | 498 bool SkDeferredDevice::onReadPixels(const SkImageInfo& info, void* pixels, size_
t rowBytes, |
475 int x, int y) { | 499 int x, int y) { |
476 this->flushPendingCommands(kNormal_PlaybackMode); | 500 this->flushPendingCommands(kNormal_PlaybackMode); |
477 return fImmediateCanvas->readPixels(info, pixels, rowBytes, x, y); | 501 return fImmediateCanvas->readPixels(info, pixels, rowBytes, x, y); |
478 } | 502 } |
479 | 503 |
480 class AutoImmediateDrawIfNeeded { | 504 class AutoImmediateDrawIfNeeded { |
481 public: | 505 public: |
482 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap, | 506 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap, |
483 const SkPaint* paint) { | 507 const SkPaint* paint) { |
484 this->init(canvas, bitmap, paint); | 508 this->init(canvas, bitmap, NULL, paint); |
| 509 } |
| 510 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkImage* image, |
| 511 const SkPaint* paint) { |
| 512 this->init(canvas, NULL, image, paint); |
485 } | 513 } |
486 | 514 |
487 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) { | 515 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) { |
488 this->init(canvas, NULL, paint); | 516 this->init(canvas, NULL, NULL, paint); |
489 } | 517 } |
490 | 518 |
491 ~AutoImmediateDrawIfNeeded() { | 519 ~AutoImmediateDrawIfNeeded() { |
492 if (fCanvas) { | 520 if (fCanvas) { |
493 fCanvas->setDeferredDrawing(true); | 521 fCanvas->setDeferredDrawing(true); |
494 } | 522 } |
495 } | 523 } |
496 private: | 524 private: |
497 void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* p
aint) { | 525 void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkImage* i
mage, |
| 526 const SkPaint* paint) { |
498 if (canvas.isDeferredDrawing() && | 527 if (canvas.isDeferredDrawing() && |
499 should_draw_immediately(bitmap, paint, canvas.getBitmapSizeThreshold
())) { | 528 should_draw_immediately(bitmap, image, paint, canvas.getBitmapSizeTh
reshold())) { |
500 canvas.setDeferredDrawing(false); | 529 canvas.setDeferredDrawing(false); |
501 fCanvas = &canvas; | 530 fCanvas = &canvas; |
502 } else { | 531 } else { |
503 fCanvas = NULL; | 532 fCanvas = NULL; |
504 } | 533 } |
505 } | 534 } |
506 | 535 |
507 SkDeferredCanvas* fCanvas; | 536 SkDeferredCanvas* fCanvas; |
508 }; | 537 }; |
509 | 538 |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
829 this->isFullFrame(&dst, paint) && | 858 this->isFullFrame(&dst, paint) && |
830 isPaintOpaque(paint, &bitmap)) { | 859 isPaintOpaque(paint, &bitmap)) { |
831 this->getDeferredDevice()->skipPendingCommands(); | 860 this->getDeferredDevice()->skipPendingCommands(); |
832 } | 861 } |
833 | 862 |
834 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint); | 863 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint); |
835 this->drawingCanvas()->drawBitmapRectToRect(bitmap, src, dst, paint, flags); | 864 this->drawingCanvas()->drawBitmapRectToRect(bitmap, src, dst, paint, flags); |
836 this->recordedDrawCommand(); | 865 this->recordedDrawCommand(); |
837 } | 866 } |
838 | 867 |
| 868 |
| 869 void SkDeferredCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, |
| 870 const SkPaint* paint) { |
| 871 SkRect bounds = SkRect::MakeXYWH(x, y, |
| 872 SkIntToScalar(image->width()), SkIntToScala
r(image->height())); |
| 873 if (fDeferredDrawing && |
| 874 this->isFullFrame(&bounds, paint) && |
| 875 isPaintOpaque(paint, image)) { |
| 876 this->getDeferredDevice()->skipPendingCommands(); |
| 877 } |
| 878 |
| 879 AutoImmediateDrawIfNeeded autoDraw(*this, image, paint); |
| 880 this->drawingCanvas()->drawImage(image, x, y, paint); |
| 881 this->recordedDrawCommand(); |
| 882 } |
| 883 void SkDeferredCanvas::onDrawImageRect(const SkImage* image, const SkRect* src,
const SkRect& dst, |
| 884 const SkPaint* paint) { |
| 885 if (fDeferredDrawing && |
| 886 this->isFullFrame(&dst, paint) && |
| 887 isPaintOpaque(paint, image)) { |
| 888 this->getDeferredDevice()->skipPendingCommands(); |
| 889 } |
| 890 |
| 891 AutoImmediateDrawIfNeeded autoDraw(*this, image, paint); |
| 892 this->drawingCanvas()->drawImageRect(image, src, dst, paint); |
| 893 this->recordedDrawCommand(); |
| 894 } |
| 895 |
839 void SkDeferredCanvas::onDrawBitmapNine(const SkBitmap& bitmap, | 896 void SkDeferredCanvas::onDrawBitmapNine(const SkBitmap& bitmap, |
840 const SkIRect& center, const SkRect& dst
, | 897 const SkIRect& center, const SkRect& dst
, |
841 const SkPaint* paint) { | 898 const SkPaint* paint) { |
842 // TODO: reset recording canvas if paint+bitmap is opaque and clip rect | 899 // TODO: reset recording canvas if paint+bitmap is opaque and clip rect |
843 // covers canvas entirely and dst covers canvas entirely | 900 // covers canvas entirely and dst covers canvas entirely |
844 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint); | 901 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint); |
845 this->drawingCanvas()->drawBitmapNine(bitmap, center, dst, paint); | 902 this->drawingCanvas()->drawBitmapNine(bitmap, center, dst, paint); |
846 this->recordedDrawCommand(); | 903 this->recordedDrawCommand(); |
847 } | 904 } |
848 | 905 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { | 985 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { |
929 this->drawingCanvas()->setDrawFilter(filter); | 986 this->drawingCanvas()->setDrawFilter(filter); |
930 this->INHERITED::setDrawFilter(filter); | 987 this->INHERITED::setDrawFilter(filter); |
931 this->recordedDrawCommand(); | 988 this->recordedDrawCommand(); |
932 return filter; | 989 return filter; |
933 } | 990 } |
934 | 991 |
935 SkCanvas* SkDeferredCanvas::canvasForDrawIter() { | 992 SkCanvas* SkDeferredCanvas::canvasForDrawIter() { |
936 return this->drawingCanvas(); | 993 return this->drawingCanvas(); |
937 } | 994 } |
OLD | NEW |