Fixes for drawing through an SkGPipe.

Implement SkGPipeCanvas::drawBitmap.

Fix a bug where needOpBytes did not necessarily provide as
many bytes as requested.

Fix a bug where needOpBytes would wipe old data without
calling notify.

Register SkEmbossMaskFilter so it can be flattened.

Override drawBitmapNine (currently unimplemented) so an
SkGPipeCanvas does not call its base class' method (which
would fail).
Review URL: https://codereview.appspot.com/6071045

git-svn-id: http://skia.googlecode.com/svn/trunk@3741 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
scroggo@google.com 2012-04-20 17:39:51 +00:00
parent 90b7e386ca
commit 5a2e879ef8
3 changed files with 56 additions and 7 deletions

View File

@ -131,3 +131,6 @@ void SkEmbossMaskFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
buffer.writeScalar(fBlurRadius);
}
SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkEmbossMaskFilter)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkEmbossMaskFilter)
SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END

View File

@ -329,7 +329,14 @@ static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op3
static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
SkGPipeState* state) {
UNIMPLEMENTED
uint32_t bitmapSize = reader->readU32();
SkOrderedReadBuffer readBuffer(reader->skip(bitmapSize), bitmapSize);
SkBitmap bm;
bm.unflatten(readBuffer);
bool hasPaint = reader->readBool();
SkScalar left = reader->readScalar();
SkScalar top = reader->readScalar();
canvas->drawBitmap(bm, left, top, hasPaint ? &state->paint() : NULL);
}
static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,

View File

@ -114,6 +114,8 @@ public:
const SkRect& dst, const SkPaint*) SK_OVERRIDE;
virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
const SkPaint*) SK_OVERRIDE;
virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
const SkRect& dst, const SkPaint* paint = NULL) SK_OVERRIDE;
virtual void drawSprite(const SkBitmap&, int left, int top,
const SkPaint*) SK_OVERRIDE;
virtual void drawText(const void* text, size_t byteLength, SkScalar x,
@ -200,7 +202,13 @@ int SkGPipeCanvas::flattenToIndex(SkFlattenable* obj, PaintFlats paintflat) {
}
SkOrderedWriteBuffer tmpWriter(1024);
tmpWriter.setFlags(SkFlattenableWriteBuffer::kInlineFactoryNames_Flag);
// Needs to be cross process so a bitmap shader will be preserved
// 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::Flags)
(SkFlattenableWriteBuffer::kInlineFactoryNames_Flag
| SkFlattenableWriteBuffer::kCrossProcess_Flag));
tmpWriter.setFactoryRecorder(fFactorySet);
tmpWriter.writeFlattenable(obj);
@ -243,6 +251,7 @@ SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller,
fController = controller;
fDone = false;
fBlockSize = 0; // need first block from controller
fBytesNotified = 0;
sk_bzero(fCurrFlatIndex, sizeof(fCurrFlatIndex));
// we need a device to limit our clip
@ -267,7 +276,11 @@ bool SkGPipeCanvas::needOpBytes(size_t needed) {
needed += 4; // size of DrawOp atom
if (fWriter.size() + needed > fBlockSize) {
void* block = fController->requestBlock(MIN_BLOCK_SIZE, &fBlockSize);
// Before we wipe out any data that has already been written, read it
// out.
this->doNotify();
size_t blockSize = SkMax32(MIN_BLOCK_SIZE, needed);
void* block = fController->requestBlock(blockSize, &fBlockSize);
if (NULL == block) {
fDone = true;
return false;
@ -495,9 +508,32 @@ void SkGPipeCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
}
}
void SkGPipeCanvas::drawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
const SkPaint*) {
UNIMPLEMENTED
void SkGPipeCanvas::drawBitmap(const SkBitmap& bm, SkScalar left, SkScalar top,
const SkPaint* paint) {
// This is the brute-force solution
// TODO: add the notion of a shared, counted for large immutable resources
NOTIFY_SETUP(this);
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();
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);
fWriter.writeBool(paint != NULL);
fWriter.writeScalar(left);
fWriter.writeScalar(top);
}
}
void SkGPipeCanvas::drawBitmapRect(const SkBitmap&, const SkIRect* src,
@ -509,7 +545,10 @@ void SkGPipeCanvas::drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
const SkPaint*) {
UNIMPLEMENTED
}
void SkGPipeCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
const SkRect& dst, const SkPaint* paint) {
UNIMPLEMENTED
}
void SkGPipeCanvas::drawSprite(const SkBitmap&, int left, int top,
const SkPaint*) {
UNIMPLEMENTED