Override SkCanvas::drawImage() in SkDeferredCanvas and SkGPipe

Depend on https://codereview.chromium.org/663233002

BUG=skia:2947

Committed: https://skia.googlesource.com/skia/+/687732fe046c9cfec940f2d7f661cd97651d10a8

Review URL: https://codereview.chromium.org/613673005
This commit is contained in:
piotaixr 2014-10-22 11:02:32 -07:00 committed by Commit bot
parent c369e7c999
commit 9bb7539a59
5 changed files with 177 additions and 12 deletions

View File

@ -164,8 +164,12 @@ public:
virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
const SkPaint* paint) SK_OVERRIDE;
virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
const SkRect& dst, const SkPaint* paint)
SK_OVERRIDE;
const SkRect& dst, const SkPaint* paint) SK_OVERRIDE;
virtual void drawImage(const SkImage* image, SkScalar left, SkScalar top,
const SkPaint* paint) SK_OVERRIDE;
virtual void drawImageRect(const SkImage* image, const SkRect* src,
const SkRect& dst,
const SkPaint* paint) SK_OVERRIDE;
virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
const SkPaint* paint) SK_OVERRIDE;
virtual void drawVertices(VertexMode vmode, int vertexCount,
@ -197,7 +201,7 @@ protected:
virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], SkXfermode* xmode,
const SkPaint& paint) SK_OVERRIDE;
virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;

View File

@ -46,6 +46,8 @@ enum DrawOps {
kDrawClear_DrawOp,
kDrawData_DrawOp,
kDrawDRRect_DrawOp,
kDrawImage_DrawOp,
kDrawImageRect_DrawOp,
kDrawOval_DrawOp,
kDrawPaint_DrawOp,
kDrawPatch_DrawOp,
@ -156,6 +158,10 @@ enum {
// converted into and out of this flag to save space
kDrawBitmap_Bleed_DrawOpFlag = 1 << 2,
};
enum {
kDrawImage_HasPaint_DrawOpFlag = 1 << 0,
kDrawImage_HasSrcRect_DrawOpFlag = 1 << 1,
};
enum {
kClip_HasAntiAlias_DrawOpFlag = 1 << 0,
};

View File

@ -408,11 +408,11 @@ static void drawDRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
static void drawPatch_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
SkGPipeState* state) {
unsigned flags = DrawOp_unpackFlags(op32);
const SkPoint* cubics = skip<SkPoint>(reader, SkPatchUtils::kNumCtrlPts);
const SkColor* colors = NULL;
if (flags & kDrawVertices_HasColors_DrawOpFlag) {
colors = skip<SkColor>(reader, SkPatchUtils::kNumCorners);
@ -651,6 +651,40 @@ static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
}
}
static void drawImage_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
SkGPipeState* state) {
bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
// Balances call to ref() in SkGPipeWrite
SkAutoTUnref<const SkImage> image (static_cast<const SkImage*>(reader->readPtr()));
SkScalar left = reader->readScalar();
SkScalar top = reader->readScalar();
if (state->shouldDraw()) {
canvas->drawImage(image, left, top, hasPaint ? &state->paint() : NULL);
}
}
static void drawImageRect_rp(SkCanvas* canvas, SkReader32* reader,
uint32_t op32, SkGPipeState* state) {
unsigned flags = DrawOp_unpackFlags(op32);
bool hasPaint = SkToBool(flags & kDrawBitmap_HasPaint_DrawOpFlag);
bool hasSrc = SkToBool(flags & kDrawBitmap_HasSrcRect_DrawOpFlag);
// Balances call to ref() in SkGPipeWrite
SkAutoTUnref<const SkImage> image (static_cast<const SkImage*>(reader->readPtr()));
const SkRect* src;
if (hasSrc) {
src = skip<SkRect>(reader);
} else {
src = NULL;
}
const SkRect* dst = skip<SkRect>(reader);
if (state->shouldDraw()) {
canvas->drawImageRect(image, src, *dst, hasPaint ? &state->paint() : NULL);
}
}
///////////////////////////////////////////////////////////////////////////////
static void drawData_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
@ -831,6 +865,8 @@ static const ReadProc gReadTable[] = {
drawClear_rp,
drawData_rp,
drawDRRect_rp,
drawImage_rp,
drawImageRect_rp,
drawOval_rp,
drawPaint_rp,
drawPatch_rp,

View File

@ -250,6 +250,11 @@ public:
const SkPaint*) SK_OVERRIDE;
virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
const SkRect& dst, const SkPaint* paint = NULL) SK_OVERRIDE;
virtual void drawImage(const SkImage* image, SkScalar left, SkScalar top,
const SkPaint* paint) SK_OVERRIDE;
virtual void drawImageRect(const SkImage* image, const SkRect* src,
const SkRect& dst,
const SkPaint* paint) SK_OVERRIDE;
virtual void drawSprite(const SkBitmap&, int left, int top,
const SkPaint*) SK_OVERRIDE;
virtual void drawVertices(VertexMode, int vertexCount,
@ -359,6 +364,9 @@ private:
bool commonDrawBitmap(const SkBitmap& bm, DrawOps op, unsigned flags,
size_t opBytesNeeded, const SkPaint* paint);
bool commonDrawImage(const SkImage* image, DrawOps op, unsigned flags,
size_t opBytesNeeded, const SkPaint* paint);
SkPaint fPaint;
void writePaint(const SkPaint&);
@ -471,6 +479,7 @@ SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller,
}
}
fFlattenableHeap.setBitmapStorage(fBitmapHeap);
this->doNotify();
}
@ -799,6 +808,79 @@ bool SkGPipeCanvas::commonDrawBitmap(const SkBitmap& bm, DrawOps op,
return false;
}
bool SkGPipeCanvas::commonDrawImage(const SkImage* image, DrawOps op,
unsigned flags,
size_t opBytesNeeded,
const SkPaint* paint) {
if (fDone) {
return false;
}
if (paint != NULL) {
flags |= kDrawBitmap_HasPaint_DrawOpFlag;
this->writePaint(*paint);
}
opBytesNeeded += sizeof (SkImage*);
if (this->needOpBytes(opBytesNeeded)) {
this->writeOp(op, flags, 0);
image->ref(); // The SkGPipeReader will have to call unref()
fWriter.writePtr(static_cast<void*>(const_cast<SkImage*>(image)));
return true;
}
return false;
}
void SkGPipeCanvas::drawImage(const SkImage* image, SkScalar left, SkScalar top,
const SkPaint* paint) {
if (is_cross_process(fFlags)){
// If the SkGPipe is cross-process, we will have to flatten the data in the SkImage, so
// fallback to the default implementation in SkCanvas (which calls SkImage::draw())
// https://code.google.com//p/skia/issues/detail?id=2985
this->INHERITED::drawImage(image, left, top, paint);
} else {
NOTIFY_SETUP(this);
size_t opBytesNeeded = sizeof(SkScalar) * 2;
if (this->commonDrawImage(image, kDrawImage_DrawOp, 0, opBytesNeeded, paint)) {
fWriter.writeScalar(left);
fWriter.writeScalar(top);
}
}
}
void SkGPipeCanvas::drawImageRect(const SkImage* image, const SkRect* src,
const SkRect& dst,
const SkPaint* paint) {
if (is_cross_process(fFlags)){
// If the SkGPipe is cross-process, we will have to flatten the data in the SkImage, so
// fallback to the default implementation in SkCanvas (which calls SkImage::drawRect())
// https://code.google.com//p/skia/issues/detail?id=2985
this->INHERITED::drawImageRect(image, src, dst, paint);
} else {
NOTIFY_SETUP(this);
size_t opBytesNeeded = sizeof (SkRect);
bool hasSrc = src != NULL;
unsigned flags;
if (hasSrc) {
flags = kDrawImage_HasSrcRect_DrawOpFlag;
opBytesNeeded += sizeof (SkRect);
} else {
flags = 0;
}
if (this->commonDrawImage(image, kDrawImageRect_DrawOp, flags, opBytesNeeded, paint)) {
if (hasSrc) {
fWriter.writeRect(*src);
}
fWriter.writeRect(dst);
}
}
}
void SkGPipeCanvas::drawBitmap(const SkBitmap& bm, SkScalar left, SkScalar top,
const SkPaint* paint) {
NOTIFY_SETUP(this);
@ -1090,7 +1172,7 @@ void SkGPipeCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4
const SkPoint texCoords[4], SkXfermode* xmode,
const SkPaint& paint) {
NOTIFY_SETUP(this);
size_t size = SkPatchUtils::kNumCtrlPts * sizeof(SkPoint);
unsigned flags = 0;
if (colors) {
@ -1108,21 +1190,21 @@ void SkGPipeCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4
size += sizeof(int32_t);
}
}
this->writePaint(paint);
if (this->needOpBytes(size)) {
this->writeOp(kDrawPatch_DrawOp, flags, 0);
fWriter.write(cubics, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
if (colors) {
fWriter.write(colors, SkPatchUtils::kNumCorners * sizeof(SkColor));
}
if (texCoords) {
fWriter.write(texCoords, SkPatchUtils::kNumCorners * sizeof(SkPoint));
}
if (flags & kDrawVertices_HasXfermode_DrawOpFlag) {
SkXfermode::Mode mode = SkXfermode::kModulate_Mode;
SkAssertResult(xmode->asMode(&mode));

View File

@ -866,6 +866,43 @@ void SkDeferredCanvas::drawBitmapNine(const SkBitmap& bitmap,
this->recordedDrawCommand();
}
void SkDeferredCanvas::drawImage(const SkImage* image, SkScalar left, SkScalar top,
const SkPaint* paint) {
SkRect imageRect = SkRect::MakeXYWH(left, top,
SkIntToScalar(image->width()), SkIntToScalar(image->height()));
bool isImageOpaque = image->isOpaque();
SkPaintBitmapOpacity pct = isImageOpaque
? kOpaque_SkPaintBitmapOpacity : kUnknown_SkPaintBitmapOpacity;
if (fDeferredDrawing &&
this->isFullFrame(&imageRect, paint) &&
(isImageOpaque ||isPaintOpaque(paint, pct))) {
this->getDeferredDevice()->skipPendingCommands();
}
AutoImmediateDrawIfNeeded autoDraw(*this, paint);
this->drawingCanvas()->drawImage(image, left, top, paint);
this->recordedDrawCommand();
}
void SkDeferredCanvas::drawImageRect(const SkImage* image, const SkRect* src,
const SkRect& dst,
const SkPaint* paint) {
bool isImageOpaque = image->isOpaque();
SkPaintBitmapOpacity pct = isImageOpaque
? kOpaque_SkPaintBitmapOpacity : kUnknown_SkPaintBitmapOpacity;
if (fDeferredDrawing &&
this->isFullFrame(&dst, paint) &&
(isImageOpaque || isPaintOpaque(paint, pct))) {
this->getDeferredDevice()->skipPendingCommands();
}
AutoImmediateDrawIfNeeded autoDraw(*this, paint);
this->drawingCanvas()->drawImageRect(image, src, dst, paint);
this->recordedDrawCommand();
}
void SkDeferredCanvas::drawSprite(const SkBitmap& bitmap, int left, int top,
const SkPaint* paint) {
SkRect bitmapRect = SkRect::MakeXYWH(