diff options
author | scroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-07-30 14:40:01 +0000 |
---|---|---|
committer | scroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-07-30 14:40:01 +0000 |
commit | 58be682c77c76d9a0caf23337f9b357798179b6c (patch) | |
tree | 6b5af87b0eb6dbcc33f9e7c5318f616e20ad8c92 | |
parent | 8e1034e9ca0e3009f65125239e21b06ec51a55a6 (diff) |
Share code in various SkGPipeCanvas::drawBitmap_ calls.
Also implement SkGPipeCanvas::drawBitmapMatrix, and
create a GM to make sure it works properly.
Use a flag instead of writing a bool for determining whether
drawBitmap_ has a paint and whether drawBitmapRect has a source
rectangle.
BUG=
TEST=drawbitmapmatrix GM
Review URL: https://codereview.appspot.com/6450053
git-svn-id: http://skia.googlecode.com/svn/trunk@4828 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | gm/bitmapmatrix.cpp | 103 | ||||
-rw-r--r-- | gyp/gmslides.gypi | 1 | ||||
-rw-r--r-- | src/pipe/SkGPipePriv.h | 6 | ||||
-rw-r--r-- | src/pipe/SkGPipeRead.cpp | 18 | ||||
-rw-r--r-- | src/pipe/SkGPipeWrite.cpp | 193 |
5 files changed, 210 insertions, 111 deletions
diff --git a/gm/bitmapmatrix.cpp b/gm/bitmapmatrix.cpp new file mode 100644 index 0000000000..d05dbebd2f --- /dev/null +++ b/gm/bitmapmatrix.cpp @@ -0,0 +1,103 @@ + +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "gm.h" +#include "SkBitmap.h" +#include "SkCanvas.h" +#include "SkColor.h" +#include "SkMatrix.h" +#include "SkPath.h" +#include "SkRect.h" +#include "SkSize.h" +#include "SkString.h" + +namespace skiagm { + +class DrawBitmapMatrixGM : public GM { +public: + DrawBitmapMatrixGM() {} + +protected: + virtual SkString onShortName() SK_OVERRIDE { + return SkString("drawbitmapmatrix"); + } + + virtual SkISize onISize() SK_OVERRIDE { return make_isize(1024, 256); } + + virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { + SkBitmap bm; + this->setupBitmap(&bm); + + // Draw normally. + SkMatrix matrix; + matrix.reset(); + SkPaint paint; + paint.setAntiAlias(true); + paint.setDither(true); + canvas->drawBitmapMatrix(bm, matrix, &paint); + + // Draw stretched horizontally and squished vertically. + canvas->translate(SkIntToScalar(bm.width() + 5), 0); + matrix.setScale(SkIntToScalar(2), SK_ScalarHalf); + canvas->drawBitmapMatrix(bm, matrix, &paint); + + // Draw rotated + canvas->translate(SkIntToScalar(bm.width()*2 + 5), 0); + matrix.reset(); + matrix.setRotate(SkIntToScalar(45), SkIntToScalar(bm.width() / 2), + SkIntToScalar(bm.height() / 2)); + canvas->save(); + canvas->translate(0, SkIntToScalar(10)); + canvas->drawBitmapMatrix(bm, matrix, &paint); + canvas->restore(); + + // Draw with perspective + canvas->translate(SkIntToScalar(bm.width() + 15), 0); + matrix.reset(); + matrix.setPerspX(SkScalarDiv(SK_Scalar1, SkIntToScalar(1000))); + matrix.setPerspY(SkScalarDiv(SK_Scalar1, SkIntToScalar(1000))); + canvas->drawBitmapMatrix(bm, matrix, &paint); + + // Draw with skew + canvas->translate(SkIntToScalar(bm.width() + 5), 0); + matrix.reset(); + matrix.setSkew(SkIntToScalar(2), SkIntToScalar(2)); + canvas->drawBitmapMatrix(bm, matrix, &paint); + + // Draw with sin/cos + canvas->translate(SkIntToScalar(bm.width() * 4), 0); + matrix.reset(); + matrix.setSinCos(SK_ScalarHalf, SkIntToScalar(2)); + canvas->drawBitmapMatrix(bm, matrix, &paint); + } +private: + void setupBitmap(SkBitmap* bm) { + SkASSERT(bm); + static const int SIZE = 64; + bm->setConfig(SkBitmap::kARGB_8888_Config, SIZE, SIZE); + bm->allocPixels(); + SkCanvas canvas(*bm); + + SkPaint paint; + paint.setColor(SK_ColorGREEN); + canvas.drawPaint(paint); + + paint.setColor(SK_ColorBLUE); + paint.setAntiAlias(true); + SkRect rect = SkRect::MakeWH(SkIntToScalar(SIZE), SkIntToScalar(SIZE)); + SkPath path; + path.addOval(rect); + canvas.drawPath(path, paint); + } +}; + +//////////////////////////////////////////////////////////////////////////////// + +static GM* MyFactory(void*) { return new DrawBitmapMatrixGM; } +static GMRegistry reg(MyFactory); + +} diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi index 5e25eb37b8..18592d62da 100644 --- a/gyp/gmslides.gypi +++ b/gyp/gmslides.gypi @@ -6,6 +6,7 @@ '../gm/arithmode.cpp', '../gm/bigmatrix.cpp', '../gm/bitmapcopy.cpp', + '../gm/bitmapmatrix.cpp', '../gm/bitmapfilters.cpp', '../gm/bitmapscroll.cpp', '../gm/blurs.cpp', diff --git a/src/pipe/SkGPipePriv.h b/src/pipe/SkGPipePriv.h index 3f8a7480d8..d9a36e9c86 100644 --- a/src/pipe/SkGPipePriv.h +++ b/src/pipe/SkGPipePriv.h @@ -137,6 +137,12 @@ enum { kDrawVertices_HasColors_DrawOpFlag = 1 << 1, kDrawVertices_HasIndices_DrawOpFlag = 1 << 2, }; +enum { + kDrawBitmap_HasPaint_DrawOpsFlag = 1 << 0, + // Specific to drawBitmapRect, but needs to be different from HasPaint, + // which is used for all drawBitmap calls, so include it here. + kDrawBitmap_HasSrcRect_DrawOpsFlag = 1 << 1, +}; /////////////////////////////////////////////////////////////////////////////// diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp index 450f19ce77..41650b17fd 100644 --- a/src/pipe/SkGPipeRead.cpp +++ b/src/pipe/SkGPipeRead.cpp @@ -407,7 +407,7 @@ BitmapHolder::BitmapHolder(SkReader32* reader, uint32_t op32, static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) { BitmapHolder holder(reader, op32, state); - bool hasPaint = reader->readBool(); + bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpsFlag); SkScalar left = reader->readScalar(); SkScalar top = reader->readScalar(); canvas->drawBitmap(*holder.getBitmap(), left, top, hasPaint ? &state->paint() : NULL); @@ -415,13 +415,18 @@ static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) { - UNIMPLEMENTED + BitmapHolder holder(reader, op32, state); + bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpsFlag); + SkMatrix matrix; + reader->readMatrix(&matrix); + canvas->drawBitmapMatrix(*holder.getBitmap(), matrix, + hasPaint ? &state->paint() : NULL); } static void drawBitmapNine_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) { BitmapHolder holder(reader, op32, state); - bool hasPaint = reader->readBool(); + bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpsFlag); const SkIRect* center = skip<SkIRect>(reader); const SkRect* dst = skip<SkRect>(reader); canvas->drawBitmapNine(*holder.getBitmap(), *center, *dst, @@ -431,8 +436,9 @@ static void drawBitmapNine_rp(SkCanvas* canvas, SkReader32* reader, static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) { BitmapHolder holder(reader, op32, state); - bool hasPaint = reader->readBool(); - bool hasSrc = reader->readBool(); + unsigned flags = DrawOp_unpackFlags(op32); + bool hasPaint = SkToBool(flags & kDrawBitmap_HasPaint_DrawOpsFlag); + bool hasSrc = SkToBool(flags & kDrawBitmap_HasSrcRect_DrawOpsFlag); const SkIRect* src; if (hasSrc) { src = skip<SkIRect>(reader); @@ -446,7 +452,7 @@ static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader, static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) { BitmapHolder holder(reader, op32, state); - bool hasPaint = reader->readBool(); + bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpsFlag); const SkIPoint* point = skip<SkIPoint>(reader); canvas->drawSprite(*holder.getBitmap(), point->fX, point->fY, hasPaint ? &state->paint() : NULL); } diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp index 66cde1bd15..9efc0b58bb 100644 --- a/src/pipe/SkGPipeWrite.cpp +++ b/src/pipe/SkGPipeWrite.cpp @@ -483,6 +483,17 @@ private: int fCurrFlatIndex[kCount_PaintFlats]; int flattenToIndex(SkFlattenable* obj, PaintFlats); + // Common code used by drawBitmap* when flattening. + bool commonDrawBitmapFlatten(const SkBitmap& bm, DrawOps op, unsigned flags, + size_t opBytesNeeded, const SkPaint* paint); + // Common code used by drawBitmap* when storing in the heap. + bool commonDrawBitmapHeap(const SkBitmap& bm, DrawOps op, unsigned flags, + size_t opBytesNeeded, const SkPaint* paint); + // Convenience type for function pointer + typedef bool (SkGPipeCanvas::*BitmapCommonFunction)(const SkBitmap&, + DrawOps, unsigned, + size_t, const SkPaint*); + SkPaint fPaint; void writePaint(const SkPaint&); @@ -831,74 +842,75 @@ void SkGPipeCanvas::drawPath(const SkPath& path, const SkPaint& paint) { } } -void SkGPipeCanvas::drawBitmap(const SkBitmap& bm, SkScalar left, SkScalar top, - const SkPaint* paint) { - bool flatten = shouldFlattenBitmaps(fFlags); - const void* ptr = 0; - int bitmapIndex = 0; - if (flatten) { - bitmapIndex = this->flattenToIndex(bm); - } else { - ptr = fSharedHeap.addBitmap(bm); - if (NULL == ptr) { - return; - } +bool SkGPipeCanvas::commonDrawBitmapFlatten(const SkBitmap& bm, DrawOps op, + unsigned flags, + size_t opBytesNeeded, + const SkPaint* paint) { + if (paint != NULL) { + flags |= kDrawBitmap_HasPaint_DrawOpsFlag; + this->writePaint(*paint); + } + int bitmapIndex = this->flattenToIndex(bm); + if (this->needOpBytes(opBytesNeeded)) { + this->writeOp(op, flags, bitmapIndex); + return true; } + return false; +} - NOTIFY_SETUP(this); - if (paint) { +bool SkGPipeCanvas::commonDrawBitmapHeap(const SkBitmap& bm, DrawOps op, + unsigned flags, + size_t opBytesNeeded, + const SkPaint* paint) { + const void* ptr = fSharedHeap.addBitmap(bm); + if (NULL == ptr) { + return false; + } + if (paint != NULL) { + flags |= kDrawBitmap_HasPaint_DrawOpsFlag; this->writePaint(*paint); } - - size_t opBytesNeeded = sizeof(SkScalar) * 2 + sizeof(bool); - if (!flatten) { - opBytesNeeded += sizeof(void*); + if (this->needOpBytes(opBytesNeeded + sizeof(void*))) { + this->writeOp(op, flags, 0); + fWriter.writePtr(const_cast<void*>(ptr)); + return true; } - if (this->needOpBytes(opBytesNeeded)) { - this->writeOp(kDrawBitmap_DrawOp, 0, bitmapIndex); - if (!flatten) { - fWriter.writePtr(const_cast<void*>(ptr)); - } - fWriter.writeBool(paint != NULL); + return false; +} + +void SkGPipeCanvas::drawBitmap(const SkBitmap& bm, SkScalar left, SkScalar top, + const SkPaint* paint) { + NOTIFY_SETUP(this); + size_t opBytesNeeded = sizeof(SkScalar) * 2; + + BitmapCommonFunction bitmapCommon = shouldFlattenBitmaps(fFlags) ? + &SkGPipeCanvas::commonDrawBitmapFlatten : + &SkGPipeCanvas::commonDrawBitmapHeap; + + if ((*this.*bitmapCommon)(bm, kDrawBitmap_DrawOp, 0, opBytesNeeded, paint)) { fWriter.writeScalar(left); fWriter.writeScalar(top); } } void SkGPipeCanvas::drawBitmapRect(const SkBitmap& bm, const SkIRect* src, - const SkRect& dst, const SkPaint* paint) { - bool flatten = shouldFlattenBitmaps(fFlags); - const void* ptr = 0; - int bitmapIndex = 0; - if (flatten) { - bitmapIndex = this->flattenToIndex(bm); - } else { - ptr = fSharedHeap.addBitmap(bm); - if (NULL == ptr) { - return; - } - } - + const SkRect& dst, const SkPaint* paint) { NOTIFY_SETUP(this); - if (paint) { - this->writePaint(*paint); - } - - size_t opBytesNeeded = sizeof(SkRect) + sizeof(bool) * 2; + size_t opBytesNeeded = sizeof(SkRect); bool hasSrc = src != NULL; + unsigned flags; if (hasSrc) { + flags = kDrawBitmap_HasSrcRect_DrawOpsFlag; opBytesNeeded += sizeof(int32_t) * 4; + } else { + flags = 0; } - if (!flatten) { - opBytesNeeded += sizeof(void*); - } - if (this->needOpBytes(opBytesNeeded)) { - this->writeOp(kDrawBitmapRect_DrawOp, 0, bitmapIndex); - if (!flatten) { - fWriter.writePtr(const_cast<void*>(ptr)); - } - fWriter.writeBool(paint != NULL); - fWriter.writeBool(hasSrc); + + BitmapCommonFunction bitmapCommon = shouldFlattenBitmaps(fFlags) ? + &SkGPipeCanvas::commonDrawBitmapFlatten : + &SkGPipeCanvas::commonDrawBitmapHeap; + + if ((*this.*bitmapCommon)(bm, kDrawBitmapRect_DrawOp, flags, opBytesNeeded, paint)) { if (hasSrc) { fWriter.write32(src->fLeft); fWriter.write32(src->fTop); @@ -909,40 +921,30 @@ void SkGPipeCanvas::drawBitmapRect(const SkBitmap& bm, const SkIRect* src, } } -void SkGPipeCanvas::drawBitmapMatrix(const SkBitmap&, const SkMatrix&, - const SkPaint*) { - UNIMPLEMENTED +void SkGPipeCanvas::drawBitmapMatrix(const SkBitmap& bm, const SkMatrix& matrix, + const SkPaint* paint) { + NOTIFY_SETUP(this); + size_t opBytesNeeded = matrix.writeToMemory(NULL); + + BitmapCommonFunction bitmapCommon = shouldFlattenBitmaps(fFlags) ? + &SkGPipeCanvas::commonDrawBitmapFlatten : + &SkGPipeCanvas::commonDrawBitmapHeap; + + if ((*this.*bitmapCommon)(bm, kDrawBitmapMatrix_DrawOp, 0, opBytesNeeded, paint)) { + fWriter.writeMatrix(matrix); + } } void SkGPipeCanvas::drawBitmapNine(const SkBitmap& bm, const SkIRect& center, const SkRect& dst, const SkPaint* paint) { - bool flatten = shouldFlattenBitmaps(fFlags); - const void* ptr = 0; - int bitmapIndex = 0; - if (flatten) { - bitmapIndex = this->flattenToIndex(bm); - } else { - ptr = fSharedHeap.addBitmap(bm); - if (NULL == ptr) { - return; - } - } - NOTIFY_SETUP(this); - if (paint) { - this->writePaint(*paint); - } + size_t opBytesNeeded = sizeof(int32_t) * 4 + sizeof(SkRect); - size_t opBytesNeeded = sizeof(int32_t) * 4 + sizeof(bool) + sizeof(SkRect); - if (!flatten) { - opBytesNeeded += sizeof(void*); - } - if (this->needOpBytes(opBytesNeeded)) { - this->writeOp(kDrawBitmapNine_DrawOp, 0, bitmapIndex); - if (!flatten) { - fWriter.writePtr(const_cast<void*>(ptr)); - } - fWriter.writeBool(paint != NULL); + BitmapCommonFunction bitmapCommon = shouldFlattenBitmaps(fFlags) ? + &SkGPipeCanvas::commonDrawBitmapFlatten : + &SkGPipeCanvas::commonDrawBitmapHeap; + + if ((*this.*bitmapCommon)(bm, kDrawBitmapNine_DrawOp, 0, opBytesNeeded, paint)) { fWriter.write32(center.fLeft); fWriter.write32(center.fTop); fWriter.write32(center.fRight); @@ -953,33 +955,14 @@ void SkGPipeCanvas::drawBitmapNine(const SkBitmap& bm, const SkIRect& center, void SkGPipeCanvas::drawSprite(const SkBitmap& bm, int left, int top, const SkPaint* paint) { - bool flatten = shouldFlattenBitmaps(fFlags); - const void* ptr = 0; - int bitmapIndex = 0; - if (flatten) { - bitmapIndex = this->flattenToIndex(bm); - } else { - ptr = fSharedHeap.addBitmap(bm); - if (NULL == ptr) { - return; - } - } - NOTIFY_SETUP(this); - if (paint) { - this->writePaint(*paint); - } + size_t opBytesNeeded = sizeof(int32_t) * 2; - size_t opBytesNeeded = sizeof(int32_t) * 2 + sizeof(bool); - if (!flatten) { - opBytesNeeded += sizeof(void*); - } - if (this->needOpBytes(opBytesNeeded)) { - this->writeOp(kDrawSprite_DrawOp, 0, bitmapIndex); - if (!flatten) { - fWriter.writePtr(const_cast<void*>(ptr)); - } - fWriter.writeBool(paint != NULL); + BitmapCommonFunction bitmapCommon = shouldFlattenBitmaps(fFlags) ? + &SkGPipeCanvas::commonDrawBitmapFlatten : + &SkGPipeCanvas::commonDrawBitmapHeap; + + if ((*this.*bitmapCommon)(bm, kDrawSprite_DrawOp, 0, opBytesNeeded, paint)) { fWriter.write32(left); fWriter.write32(top); } |