Updates for SkGPipe.

Keep track of SkBitmaps which have been flattened by
the PipeWriter so we can reuse them.

Implement other flavors of drawBitmap (except
drawBitmapMatrix).

Flatten SkImageFilters in SkPaints.

Do not notify if no new data has been written.
Review URL: https://codereview.appspot.com/6128062

git-svn-id: http://skia.googlecode.com/svn/trunk@3826 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp
index 7642f35..cc7361f 100644
--- a/src/pipe/SkGPipeRead.cpp
+++ b/src/pipe/SkGPipeRead.cpp
@@ -46,6 +46,9 @@
         case kShader_PaintFlat:
             paint->setShader((SkShader*)obj);
             break;
+        case kImageFilter_PaintFlat:
+            paint->setImageFilter((SkImageFilter*)obj);
+            break;
         case kXfermode_PaintFlat:
             paint->setXfermode((SkXfermode*)obj);
             break;
@@ -85,6 +88,19 @@
         *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));
@@ -102,6 +118,7 @@
     SkTDArray<SkFlattenable*> fFlatArray;
     SkTDArray<SkTypeface*>    fTypefaces;
     SkTDArray<SkFlattenable::Factory> fFactoryArray;
+    SkTDArray<SkBitmap*>      fBitmaps;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -329,14 +346,12 @@
 
 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,
@@ -344,14 +359,41 @@
     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);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -432,6 +474,12 @@
     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*) {
@@ -451,6 +499,7 @@
     concat_rp,
     drawBitmap_rp,
     drawBitmapMatrix_rp,
+    drawBitmapNine_rp,
     drawBitmapRect_rp,
     drawClear_rp,
     drawData_rp,
@@ -477,6 +526,7 @@
     paintOp_rp,
     def_Typeface_rp,
     def_PaintFlat_rp,
+    def_Bitmap_rp,
 
     done_rp
 };
@@ -488,6 +538,7 @@
 SkGPipeState::~SkGPipeState() {
     fTypefaces.safeUnrefAll();
     fFlatArray.safeUnrefAll();
+    fBitmaps.deleteAll();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -541,7 +592,8 @@
         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;