| Index: src/utils/SkDeferredCanvas.cpp
|
| diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp
|
| index d5cf97bd04df38287faa639f08bd9f7aa4a7c245..7d0a8e8593b5e51a2a4421318751cd7c2f9740b0 100644
|
| --- a/src/utils/SkDeferredCanvas.cpp
|
| +++ b/src/utils/SkDeferredCanvas.cpp
|
| @@ -32,12 +32,31 @@ enum PlaybackMode {
|
| kSilent_PlaybackMode,
|
| };
|
|
|
| -static bool should_draw_immediately(const SkBitmap* bitmap, const SkPaint* paint,
|
| - size_t bitmapSizeThreshold) {
|
| +static uint64_t image_area(const SkImage* image) {
|
| + return sk_64_mul(image->width(), image->height());
|
| +}
|
| +
|
| +// HACK -- see crbug.com/485243
|
| +//
|
| +// Work around case where Blink gives us an image, but will "mutate" it (by changing its contents
|
| +// directly using webgl). Until that is fixed at the call-site, we treat gpu-backed-images as
|
| +// mutable for now (at least for the purposes of deferred canvas)
|
| +//
|
| +static bool should_draw_gpu_image_immediately(const SkImage* image) {
|
| + return image->getTexture() != NULL;
|
| +}
|
| +
|
| +static bool should_draw_immediately(const SkBitmap* bitmap, const SkImage* image,
|
| + const SkPaint* paint, size_t bitmapSizeThreshold) {
|
| if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) ||
|
| - (bitmap->getSize() > bitmapSizeThreshold))) {
|
| + (bitmap->getSize() > bitmapSizeThreshold))) {
|
| return true;
|
| }
|
| + if (image) {
|
| + if (should_draw_gpu_image_immediately(image) || image_area(image) > bitmapSizeThreshold) {
|
| + return true;
|
| + }
|
| + }
|
| if (paint) {
|
| SkShader* shader = paint->getShader();
|
| // Here we detect the case where the shader is an SkBitmapProcShader
|
| @@ -202,6 +221,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);}
|
| @@ -481,11 +505,15 @@ class AutoImmediateDrawIfNeeded {
|
| public:
|
| AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap,
|
| const SkPaint* paint) {
|
| - this->init(canvas, bitmap, paint);
|
| + this->init(canvas, bitmap, NULL, paint);
|
| + }
|
| + AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkImage* image,
|
| + const SkPaint* paint) {
|
| + this->init(canvas, NULL, image, paint);
|
| }
|
|
|
| AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) {
|
| - this->init(canvas, NULL, paint);
|
| + this->init(canvas, NULL, NULL, paint);
|
| }
|
|
|
| ~AutoImmediateDrawIfNeeded() {
|
| @@ -494,9 +522,10 @@ public:
|
| }
|
| }
|
| private:
|
| - void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* paint) {
|
| + void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkImage* image,
|
| + const SkPaint* paint) {
|
| if (canvas.isDeferredDrawing() &&
|
| - should_draw_immediately(bitmap, paint, canvas.getBitmapSizeThreshold())) {
|
| + should_draw_immediately(bitmap, image, paint, canvas.getBitmapSizeThreshold())) {
|
| canvas.setDeferredDrawing(false);
|
| fCanvas = &canvas;
|
| } else {
|
| @@ -836,6 +865,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) {
|
|
|