Chromium Code Reviews| Index: src/utils/SkDeferredCanvas.cpp |
| diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp |
| index d5cf97bd04df38287faa639f08bd9f7aa4a7c245..5b74d172df675b4936789433b9fbfca64c14d7ff 100644 |
| --- a/src/utils/SkDeferredCanvas.cpp |
| +++ b/src/utils/SkDeferredCanvas.cpp |
| @@ -35,7 +35,34 @@ enum PlaybackMode { |
| static bool should_draw_immediately(const SkBitmap* bitmap, const SkPaint* paint, |
| size_t bitmapSizeThreshold) { |
| if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) || |
| - (bitmap->getSize() > bitmapSizeThreshold))) { |
| + (bitmap->getSize() > bitmapSizeThreshold))) { |
| + return true; |
| + } |
| + if (paint) { |
| + SkShader* shader = paint->getShader(); |
| + // Here we detect the case where the shader is an SkBitmapProcShader |
|
mtklein
2015/05/05 18:50:01
Let's pull out a static function for this bit?
reed1
2015/05/05 19:45:15
Done.
|
| + // with a gpu texture attached. Checking this without RTTI |
| + // requires making the assumption that only gradient shaders |
| + // and SkBitmapProcShader implement asABitmap(). The following |
| + // code may need to be revised if that assumption is ever broken. |
| + if (shader && !shader->asAGradient(NULL)) { |
| + SkBitmap bm; |
| + if (shader->asABitmap(&bm, NULL, NULL) && |
| + bm.getTexture()) { |
| + return true; |
| + } |
| + } |
| + } |
| + return false; |
| +} |
| + |
| +static uint64_t image_area(const SkImage* image) { |
| + return sk_64_mul(image->width(), image->height()); |
| +} |
| + |
| +static bool should_draw_immediately(const SkImage* image, const SkPaint* paint, |
| + size_t imageSizeThreshold) { |
| + if (image && (image_area(image) > imageSizeThreshold)) { |
| return true; |
| } |
| if (paint) { |
| @@ -202,6 +229,11 @@ protected: |
| void drawSprite(const SkDraw&, const SkBitmap& bitmap, |
| int x, int y, const SkPaint& paint) override |
| {SkASSERT(0);} |
| + void drawImage(const SkDraw&, const SkImage*, SkScalar, SkScalar, const SkPaint&) override |
| + {SkASSERT(0);} |
| + void drawImageRect(const SkDraw&, const SkImage*, const SkRect*, const SkRect&, |
| + const SkPaint&) override |
| + {SkASSERT(0);} |
| void drawText(const SkDraw&, const void* text, size_t len, |
| SkScalar x, SkScalar y, const SkPaint& paint) override |
| {SkASSERT(0);} |
| @@ -483,6 +515,16 @@ public: |
| const SkPaint* paint) { |
| this->init(canvas, bitmap, paint); |
| } |
| + AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkImage* image, |
|
mtklein
2015/05/05 18:50:01
This seems weirdly asymmetrical. Let's make init
reed1
2015/05/05 19:45:15
Done.
|
| + const SkPaint* paint) { |
| + if (canvas.isDeferredDrawing() && |
| + should_draw_immediately(image, paint, canvas.getBitmapSizeThreshold())) { |
| + canvas.setDeferredDrawing(false); |
| + fCanvas = &canvas; |
| + } else { |
| + fCanvas = NULL; |
| + } |
| + } |
| AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) { |
| this->init(canvas, NULL, paint); |
| @@ -836,6 +878,34 @@ void SkDeferredCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* sr |
| this->recordedDrawCommand(); |
| } |
| + |
| +void SkDeferredCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, |
| + const SkPaint* paint) { |
| + SkRect bounds = SkRect::MakeXYWH(x, y, |
| + SkIntToScalar(image->width()), SkIntToScalar(image->height())); |
| + if (fDeferredDrawing && |
| + this->isFullFrame(&bounds, paint) && |
| + isPaintOpaque(paint, image)) { |
| + this->getDeferredDevice()->skipPendingCommands(); |
| + } |
| + |
| + AutoImmediateDrawIfNeeded autoDraw(*this, image, paint); |
| + this->drawingCanvas()->drawImage(image, x, y, paint); |
| + this->recordedDrawCommand(); |
| +} |
| +void SkDeferredCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, |
| + const SkPaint* paint) { |
| + if (fDeferredDrawing && |
| + this->isFullFrame(&dst, paint) && |
| + isPaintOpaque(paint, image)) { |
| + this->getDeferredDevice()->skipPendingCommands(); |
| + } |
| + |
| + AutoImmediateDrawIfNeeded autoDraw(*this, image, paint); |
| + this->drawingCanvas()->drawImageRect(image, src, dst, paint); |
| + this->recordedDrawCommand(); |
| +} |
| + |
| void SkDeferredCanvas::onDrawBitmapNine(const SkBitmap& bitmap, |
| const SkIRect& center, const SkRect& dst, |
| const SkPaint* paint) { |