/*
- * Copyright 2011 Google Inc.
+ * Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
};
namespace {
-bool shouldDrawImmediately(const SkBitmap& bitmap) {
- return bitmap.getTexture() && !bitmap.isImmutable();
+bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint) {
+ if (bitmap && bitmap->getTexture() && !bitmap->isImmutable()) {
+ return true;
+ }
+ if (paint) {
+ SkShader* shader = paint->getShader();
+ // Here we detect the case where the shader is an SkBitmapProcShader
+ // 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) &&
+ NULL != bm.getTexture()) {
+ return true;
+ }
+ }
+ }
+ return false;
}
}
class AutoImmediateDrawIfNeeded {
public:
- AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap& bitmap) {
- if (canvas.isDeferredDrawing() && shouldDrawImmediately(bitmap)) {
- canvas.setDeferredDrawing(false);
- fCanvas = &canvas;
- } else {
- fCanvas = NULL;
- }
+ AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap,
+ const SkPaint* paint) {
+ this->init(canvas, bitmap, paint);
+ }
+
+ AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) {
+ this->init(canvas, NULL, paint);
}
~AutoImmediateDrawIfNeeded() {
}
}
private:
+ void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* paint)
+ {
+ if (canvas.isDeferredDrawing() && shouldDrawImmediately(bitmap, paint)) {
+ canvas.setDeferredDrawing(false);
+ fCanvas = &canvas;
+ } else {
+ fCanvas = NULL;
+ }
+ }
+
SkDeferredCanvas* fCanvas;
};
isPaintOpaque(&paint)) {
getDeferredDevice()->contentsCleared();
}
-
+ AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
drawingCanvas()->drawPaint(paint);
}
void SkDeferredCanvas::drawPoints(PointMode mode, size_t count,
const SkPoint pts[], const SkPaint& paint) {
+ AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
drawingCanvas()->drawPoints(mode, count, pts, paint);
}
getDeferredDevice()->contentsCleared();
}
+ AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
drawingCanvas()->drawRect(rect, paint);
}
void SkDeferredCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
+ AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
drawingCanvas()->drawPath(path, paint);
}
getDeferredDevice()->contentsCleared();
}
- AutoImmediateDrawIfNeeded autoDraw(*this, bitmap);
+ AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
drawingCanvas()->drawBitmap(bitmap, left, top, paint);
}
getDeferredDevice()->contentsCleared();
}
- AutoImmediateDrawIfNeeded autoDraw(*this, bitmap);
+ AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
drawingCanvas()->drawBitmapRect(bitmap, src,
dst, paint);
}
const SkPaint* paint) {
// TODO: reset recording canvas if paint+bitmap is opaque and clip rect
// covers canvas entirely and transformed bitmap covers canvas entirely
- AutoImmediateDrawIfNeeded autoDraw(*this, bitmap);
+ AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
drawingCanvas()->drawBitmapMatrix(bitmap, m, paint);
}
const SkPaint* paint) {
// TODO: reset recording canvas if paint+bitmap is opaque and clip rect
// covers canvas entirely and dst covers canvas entirely
- AutoImmediateDrawIfNeeded autoDraw(*this, bitmap);
+ AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
drawingCanvas()->drawBitmapNine(bitmap, center,
dst, paint);
}
getDeferredDevice()->contentsCleared();
}
- AutoImmediateDrawIfNeeded autoDraw(*this, bitmap);
+ AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
drawingCanvas()->drawSprite(bitmap, left, top,
paint);
}
void SkDeferredCanvas::drawText(const void* text, size_t byteLength,
SkScalar x, SkScalar y, const SkPaint& paint) {
+ AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
drawingCanvas()->drawText(text, byteLength, x, y, paint);
}
void SkDeferredCanvas::drawPosText(const void* text, size_t byteLength,
const SkPoint pos[], const SkPaint& paint) {
+ AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
drawingCanvas()->drawPosText(text, byteLength, pos, paint);
}
void SkDeferredCanvas::drawPosTextH(const void* text, size_t byteLength,
const SkScalar xpos[], SkScalar constY,
const SkPaint& paint) {
+ AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
drawingCanvas()->drawPosTextH(text, byteLength, xpos, constY, paint);
}
const SkPath& path,
const SkMatrix* matrix,
const SkPaint& paint) {
+ AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
drawingCanvas()->drawTextOnPath(text, byteLength,
path, matrix,
paint);
const SkColor colors[], SkXfermode* xmode,
const uint16_t indices[], int indexCount,
const SkPaint& paint) {
+ AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
drawingCanvas()->drawVertices(vmode, vertexCount,
vertices, texs,
colors, xmode,
SkPaint paint;
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
- if (shouldDrawImmediately(bitmap)) {
+ if (shouldDrawImmediately(&bitmap, NULL)) {
this->flushPending();
fImmediateCanvas->drawSprite(bitmap, x, y, &paint);
} else {