case kShader_PaintFlat:
paint->setShader((SkShader*)obj);
break;
+ case kImageFilter_PaintFlat:
+ paint->setImageFilter((SkImageFilter*)obj);
+ break;
case kXfermode_PaintFlat:
paint->setXfermode((SkXfermode*)obj);
break;
*fFlatArray.append() = obj;
}
+ void addBitmap(int index) {
+ SkASSERT(fBitmaps.count() == index);
+ SkBitmap* bm = new SkBitmap();
+ size_t size = fReader->readU32();
+ SkOrderedReadBuffer readBuffer(fReader->skip(size), size);
+ bm->unflatten(readBuffer);
+ *fBitmaps.append() = bm;
+ }
+
+ SkBitmap* getBitmap(unsigned index) {
+ return fBitmaps[index];
+ }
+
void addTypeface() {
size_t size = fReader->readU32();
const void* data = fReader->skip(SkAlign4(size));
SkTDArray<SkFlattenable*> fFlatArray;
SkTDArray<SkTypeface*> fTypefaces;
SkTDArray<SkFlattenable::Factory> fFactoryArray;
+ SkTDArray<SkBitmap*> fBitmaps;
};
///////////////////////////////////////////////////////////////////////////////
static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
SkGPipeState* state) {
- uint32_t bitmapSize = reader->readU32();
- SkOrderedReadBuffer readBuffer(reader->skip(bitmapSize), bitmapSize);
- SkBitmap bm;
- bm.unflatten(readBuffer);
+ unsigned index = DrawOp_unpackData(op32);
+ SkBitmap* bm = state->getBitmap(index);
bool hasPaint = reader->readBool();
SkScalar left = reader->readScalar();
SkScalar top = reader->readScalar();
- canvas->drawBitmap(bm, left, top, hasPaint ? &state->paint() : NULL);
+ canvas->drawBitmap(*bm, left, top, hasPaint ? &state->paint() : NULL);
}
static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
UNIMPLEMENTED
}
-static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
- SkGPipeState* state) {
- UNIMPLEMENTED
+static void drawBitmapNine_rp(SkCanvas* canvas, SkReader32* reader,
+ uint32_t op32, SkGPipeState* state) {
+ unsigned index = DrawOp_unpackData(op32);
+ SkBitmap* bm = state->getBitmap(index);
+ bool hasPaint = reader->readBool();
+ SkIRect center = SkIRect::MakeLTRB(reader->readInt(), reader->readInt(),
+ reader->readInt(), reader->readInt());
+ const SkRect* dst = skip<SkRect>(reader);
+ canvas->drawBitmapNine(*bm, center, *dst,
+ hasPaint ? &state->paint() : NULL);
+}
+
+static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader,
+ uint32_t op32, SkGPipeState* state) {
+ unsigned index = DrawOp_unpackData(op32);
+ SkBitmap* bm = state->getBitmap(index);
+ bool hasPaint = reader->readBool();
+ bool hasSrc = reader->readBool();
+ SkIRect src;
+ if (hasSrc) {
+ src = SkIRect::MakeLTRB(reader->readInt(), reader->readInt(),
+ reader->readInt(), reader->readInt());
+ }
+ const SkRect* dst = skip<SkRect>(reader);
+ canvas->drawBitmapRect(*bm, hasSrc ? &src : NULL, *dst,
+ hasPaint ? &state->paint() : NULL);
}
static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
SkGPipeState* state) {
- UNIMPLEMENTED
+ unsigned index = DrawOp_unpackData(op32);
+ SkBitmap* bm = state->getBitmap(index);
+ bool hasPaint = reader->readBool();
+ canvas->drawSprite(*bm, reader->readInt(), reader->readInt(),
+ hasPaint ? &state->paint() : NULL);
}
///////////////////////////////////////////////////////////////////////////////
state->defFlattenable(pf, index);
}
+static void def_Bitmap_rp(SkCanvas*, SkReader32*, uint32_t op32,
+ SkGPipeState* state) {
+ unsigned index = DrawOp_unpackData(op32);
+ state->addBitmap(index);
+}
+
///////////////////////////////////////////////////////////////////////////////
static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
concat_rp,
drawBitmap_rp,
drawBitmapMatrix_rp,
+ drawBitmapNine_rp,
drawBitmapRect_rp,
drawClear_rp,
drawData_rp,
paintOp_rp,
def_Typeface_rp,
def_PaintFlat_rp,
+ def_Bitmap_rp,
done_rp
};
SkGPipeState::~SkGPipeState() {
fTypefaces.safeUnrefAll();
fFlatArray.safeUnrefAll();
+ fBitmaps.deleteAll();
}
///////////////////////////////////////////////////////////////////////////////
if (readAtom &&
(table[op] != paintOp_rp &&
table[op] != def_Typeface_rp &&
- table[op] != def_PaintFlat_rp
+ table[op] != def_PaintFlat_rp &&
+ table[op] != def_Bitmap_rp
)) {
status = kReadAtom_Status;
break;
#include "SkPaint.h"
#include "SkGPipe.h"
#include "SkGPipePriv.h"
+#include "SkImageFilter.h"
#include "SkStream.h"
#include "SkTSearch.h"
#include "SkTypeface.h"
case kPathEffect_PaintFlat: return paint.getPathEffect();
case kRasterizer_PaintFlat: return paint.getRasterizer();
case kShader_PaintFlat: return paint.getShader();
+ case kImageFilter_PaintFlat: return paint.getImageFilter();
case kXfermode_PaintFlat: return paint.getXfermode();
}
SkDEBUGFAIL("never gets here");
inline void doNotify() {
if (!fDone) {
size_t bytes = fWriter.size() - fBytesNotified;
- fController->notifyWritten(bytes);
- fBytesNotified += bytes;
+ if (bytes > 0) {
+ fController->notifyWritten(bytes);
+ fBytesNotified += bytes;
+ }
}
}
return memcmp(&a->fSize, &b->fSize, a->fSize + sizeof(a->fSize));
}
};
+
+ SkTDArray<FlatData*> fBitmapArray;
+ int flattenToIndex(const SkBitmap&);
+
SkTDArray<FlatData*> fFlatArray;
int fCurrFlatIndex[kCount_PaintFlats];
int flattenToIndex(SkFlattenable* obj, PaintFlats);
typedef SkCanvas INHERITED;
};
+int SkGPipeCanvas::flattenToIndex(const SkBitmap & bitmap) {
+ SkOrderedWriteBuffer tmpWriter(1024);
+ // FIXME: Rather than forcing CrossProcess, we should create an SkRefCntSet
+ // so that we can store a pointer to a bitmap's pixels during flattening.
+ tmpWriter.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag);
+ bitmap.flatten(tmpWriter);
+
+ size_t len = tmpWriter.size();
+ size_t allocSize = len + sizeof(FlatData);
+
+ SkAutoSMalloc<1024> storage(allocSize);
+ FlatData* flat = (FlatData*)storage.get();
+ flat->fSize = len;
+ tmpWriter.flatten(flat->data());
+
+ int index = SkTSearch<FlatData>((const FlatData**)fBitmapArray.begin(),
+ fBitmapArray.count(), flat, sizeof(flat),
+ &FlatData::Compare);
+ if (index < 0) {
+ index = ~index;
+ FlatData* copy = (FlatData*)sk_malloc_throw(allocSize);
+ memcpy(copy, flat, allocSize);
+ // For bitmaps, we can use zero based indices, since we will never ask
+ // for a NULL bitmap (unlike with paint flattenables).
+ copy->fIndex = fBitmapArray.count();
+ *fBitmapArray.insert(index) = copy;
+ if (this->needOpBytes(len + sizeof(uint32_t))) {
+ this->writeOp(kDef_Bitmap_DrawOp, 0, copy->fIndex);
+ fWriter.write32(len);
+ fWriter.write(copy->data(), len);
+ }
+ }
+ return fBitmapArray[index]->fIndex;
+}
+
// return 0 for NULL (or unflattenable obj), or index-base-1
int SkGPipeCanvas::flattenToIndex(SkFlattenable* obj, PaintFlats paintflat) {
if (NULL == obj) {
this->finish();
fFlatArray.freeAll();
+ fBitmapArray.freeAll();
}
bool SkGPipeCanvas::needOpBytes(size_t needed) {
if (paint) {
this->writePaint(*paint);
}
- SkOrderedWriteBuffer writeBuffer(0);
- // FIXME: Rather than forcing CrossProcess, we should create an SkRefCntSet
- // so that we can store a pointer to a bitmap's pixels during flattening.
- writeBuffer.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag);
- bm.flatten(writeBuffer);
- int size = writeBuffer.size();
+
+ int bitmapIndex = this->flattenToIndex(bm);
- if (this->needOpBytes(sizeof(uint32_t) + size + sizeof(SkScalar)*2)
- + sizeof(bool)) {
- // Record the act of drawing the bitmap
- this->writeOp(kDrawBitmap_DrawOp);
- fWriter.writeInt(size);
- void* ptr = (void*) fWriter.reserve(size);
- writeBuffer.flatten(ptr);
+ if (this->needOpBytes(sizeof(SkScalar) * 2 + sizeof(bool))) {
+ this->writeOp(kDrawBitmap_DrawOp, 0, bitmapIndex);
fWriter.writeBool(paint != NULL);
fWriter.writeScalar(left);
fWriter.writeScalar(top);
}
}
-void SkGPipeCanvas::drawBitmapRect(const SkBitmap&, const SkIRect* src,
- const SkRect& dst, const SkPaint*) {
- UNIMPLEMENTED
+void SkGPipeCanvas::drawBitmapRect(const SkBitmap& bm, const SkIRect* src,
+ const SkRect& dst, const SkPaint* paint) {
+ NOTIFY_SETUP(this);
+ if (paint) {
+ this->writePaint(*paint);
+ }
+
+ int bitmapIndex = this->flattenToIndex(bm);
+
+ size_t opBytesNeeded = sizeof(SkRect) + sizeof(bool) * 2;
+ bool hasSrc = src != NULL;
+ if (hasSrc) {
+ opBytesNeeded += sizeof(int32_t) * 4;
+ }
+ if (this->needOpBytes(opBytesNeeded)) {
+ this->writeOp(kDrawBitmapRect_DrawOp, 0, bitmapIndex);
+ fWriter.writeBool(paint != NULL);
+ fWriter.writeBool(hasSrc);
+ if (hasSrc) {
+ fWriter.write32(src->fLeft);
+ fWriter.write32(src->fTop);
+ fWriter.write32(src->fRight);
+ fWriter.write32(src->fBottom);
+ }
+ fWriter.writeRect(dst);
+ }
}
void SkGPipeCanvas::drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
const SkPaint*) {
UNIMPLEMENTED
}
-void SkGPipeCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
+
+void SkGPipeCanvas::drawBitmapNine(const SkBitmap& bm, const SkIRect& center,
const SkRect& dst, const SkPaint* paint) {
- UNIMPLEMENTED
+ NOTIFY_SETUP(this);
+ if (paint) {
+ this->writePaint(*paint);
+ }
+ int bitmapIndex = this->flattenToIndex(bm);
+
+ if (this->needOpBytes(sizeof(int32_t) * 4 + sizeof(bool)
+ + sizeof(SkRect))) {
+ this->writeOp(kDrawBitmapNine_DrawOp, 0, bitmapIndex);
+ fWriter.writeBool(paint != NULL);
+ fWriter.write32(center.fLeft);
+ fWriter.write32(center.fTop);
+ fWriter.write32(center.fRight);
+ fWriter.write32(center.fBottom);
+ fWriter.writeRect(dst);
+ }
}
-void SkGPipeCanvas::drawSprite(const SkBitmap&, int left, int top,
- const SkPaint*) {
- UNIMPLEMENTED
+
+void SkGPipeCanvas::drawSprite(const SkBitmap& bm, int left, int top,
+ const SkPaint* paint) {
+ NOTIFY_SETUP(this);
+ if (paint) {
+ this->writePaint(*paint);
+ }
+ int bitmapIndex = this->flattenToIndex(bm);
+
+ if (this->needOpBytes(sizeof(int32_t) * 2 + sizeof(bool))) {
+ this->writeOp(kDrawSprite_DrawOp, 0, bitmapIndex);
+ fWriter.writeBool(paint != NULL);
+ fWriter.write32(left);
+ fWriter.write32(top);
+ }
}
void SkGPipeCanvas::drawText(const void* text, size_t byteLength, SkScalar x,