SkGPipeWrite.cpp revision 94e75ee46a569cbcdf61fb7f04ee3a69d3ca0896
1bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com */
8bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
9bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
10ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
11bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com#include "SkCanvas.h"
128a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com#include "SkData.h"
13bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com#include "SkDevice.h"
14bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com#include "SkPaint.h"
1575a0972dd7d0dbc614b9fb81b4450a349c005325reed@google.com#include "SkPathEffect.h"
16acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com#include "SkGPipe.h"
17bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com#include "SkGPipePriv.h"
1816d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com#include "SkImageFilter.h"
19f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com#include "SkStream.h"
20b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com#include "SkTSearch.h"
21f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com#include "SkTypeface.h"
22bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com#include "SkWriter32.h"
23b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com#include "SkColorFilter.h"
240faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com#include "SkDrawLooper.h"
25b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com#include "SkMaskFilter.h"
26b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com#include "SkRasterizer.h"
27b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com#include "SkShader.h"
282b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com#include "SkOrderedWriteBuffer.h"
29b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com
30b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.comstatic SkFlattenable* get_paintflat(const SkPaint& paint, unsigned paintFlat) {
31b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    SkASSERT(paintFlat < kCount_PaintFlats);
32b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    switch (paintFlat) {
33b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        case kColorFilter_PaintFlat:    return paint.getColorFilter();
340faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com        case kDrawLooper_PaintFlat:     return paint.getLooper();
35b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        case kMaskFilter_PaintFlat:     return paint.getMaskFilter();
36b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        case kPathEffect_PaintFlat:     return paint.getPathEffect();
37b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        case kRasterizer_PaintFlat:     return paint.getRasterizer();
38b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        case kShader_PaintFlat:         return paint.getShader();
3916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        case kImageFilter_PaintFlat:    return paint.getImageFilter();
40b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        case kXfermode_PaintFlat:       return paint.getXfermode();
41b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    }
420c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com    SkDEBUGFAIL("never gets here");
43b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    return NULL;
44b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com}
45bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
46f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.comstatic size_t writeTypeface(SkWriter32* writer, SkTypeface* typeface) {
47f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    SkASSERT(typeface);
48f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    SkDynamicMemoryWStream stream;
49f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    typeface->serialize(&stream);
50f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    size_t size = stream.getOffset();
51f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    if (writer) {
52f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        writer->write32(size);
538a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        SkAutoDataUnref data(stream.copyToData());
545af9b2032b552516c9223d9fb22185b022b13c62scroggo@google.com        writer->writePad(data.data(), size);
55f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    }
565af9b2032b552516c9223d9fb22185b022b13c62scroggo@google.com    return 4 + SkAlign4(size);
57f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com}
58f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com
59bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
60bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
61bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comclass SkGPipeCanvas : public SkCanvas {
62bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.compublic:
63dde0956375e87027df2fdd80d430dd819c217aacreed@google.com    SkGPipeCanvas(SkGPipeController*, SkWriter32*, SkFactorySet*);
64bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual ~SkGPipeCanvas();
65bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
66bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    void finish() {
67bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        if (!fDone) {
68dbccc88f84e5330ce6e52512fcefd375ee2eda49reed@google.com            if (this->needOpBytes()) {
69dbccc88f84e5330ce6e52512fcefd375ee2eda49reed@google.com                this->writeOp(kDone_DrawOp);
70dbccc88f84e5330ce6e52512fcefd375ee2eda49reed@google.com                this->doNotify();
71dbccc88f84e5330ce6e52512fcefd375ee2eda49reed@google.com            }
72bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com            fDone = true;
73bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
74bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
75bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
76bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    // overrides from SkCanvas
773b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual int save(SaveFlags) SK_OVERRIDE;
783b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual int saveLayer(const SkRect* bounds, const SkPaint*,
793b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                          SaveFlags) SK_OVERRIDE;
803b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual void restore() SK_OVERRIDE;
813b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE;
823b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE;
833b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual bool rotate(SkScalar degrees) SK_OVERRIDE;
843b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE;
853b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE;
863b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
873b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual bool clipRect(const SkRect& rect, SkRegion::Op op,
883b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                          bool doAntiAlias = false) SK_OVERRIDE;
893b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual bool clipPath(const SkPath& path, SkRegion::Op op,
903b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                          bool doAntiAlias = false) SK_OVERRIDE;
913b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual bool clipRegion(const SkRegion& region, SkRegion::Op op) SK_OVERRIDE;
923b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual void clear(SkColor) SK_OVERRIDE;
933b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
94bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawPoints(PointMode, size_t count, const SkPoint pts[],
953b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                            const SkPaint&) SK_OVERRIDE;
963b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual void drawRect(const SkRect& rect, const SkPaint&) SK_OVERRIDE;
973b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual void drawPath(const SkPath& path, const SkPaint&) SK_OVERRIDE;
98bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
993b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                            const SkPaint*) SK_OVERRIDE;
100bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawBitmapRect(const SkBitmap&, const SkIRect* src,
1013b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                                const SkRect& dst, const SkPaint*) SK_OVERRIDE;
102bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
1033b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                                  const SkPaint*) SK_OVERRIDE;
1045a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com    virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
1055a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com                                const SkRect& dst, const SkPaint* paint = NULL) SK_OVERRIDE;
106bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawSprite(const SkBitmap&, int left, int top,
1073b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                            const SkPaint*) SK_OVERRIDE;
10874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org    virtual void drawText(const void* text, size_t byteLength, SkScalar x,
1093b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                          SkScalar y, const SkPaint&) SK_OVERRIDE;
11074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org    virtual void drawPosText(const void* text, size_t byteLength,
1113b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                             const SkPoint pos[], const SkPaint&) SK_OVERRIDE;
112bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawPosTextH(const void* text, size_t byteLength,
1133b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                              const SkScalar xpos[], SkScalar constY,
1143b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                              const SkPaint&) SK_OVERRIDE;
11574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org    virtual void drawTextOnPath(const void* text, size_t byteLength,
11674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org                            const SkPath& path, const SkMatrix* matrix,
1173b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                                const SkPaint&) SK_OVERRIDE;
1183b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual void drawPicture(SkPicture& picture) SK_OVERRIDE;
119bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawVertices(VertexMode, int vertexCount,
120bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                          const SkPoint vertices[], const SkPoint texs[],
121bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                          const SkColor colors[], SkXfermode*,
122bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                          const uint16_t indices[], int indexCount,
1233b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                              const SkPaint&) SK_OVERRIDE;
1243b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual void drawData(const void*, size_t) SK_OVERRIDE;
125bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
126bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comprivate:
127dde0956375e87027df2fdd80d430dd819c217aacreed@google.com    SkFactorySet* fFactorySet;  // optional, only used if cross-process
128acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    SkGPipeController* fController;
129bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    SkWriter32& fWriter;
130acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    size_t      fBlockSize; // amount allocated for writer
131acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    size_t      fBytesNotified;
132bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    bool        fDone;
133bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
134f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    SkRefCntSet fTypefaceSet;
135f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com
136f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    uint32_t getTypefaceID(SkTypeface*);
137f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com
138acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    inline void writeOp(DrawOps op, unsigned flags, unsigned data) {
139bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        fWriter.write32(DrawOp_packOpFlagData(op, flags, data));
140bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
14174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org
142acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    inline void writeOp(DrawOps op) {
143bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        fWriter.write32(DrawOp_packOpFlagData(op, 0, 0));
144bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
145acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
146acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    bool needOpBytes(size_t size = 0);
147acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
148acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    inline void doNotify() {
149acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (!fDone) {
150acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            size_t bytes = fWriter.size() - fBytesNotified;
15116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com            if (bytes > 0) {
15216d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com                fController->notifyWritten(bytes);
15316d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com                fBytesNotified += bytes;
15416d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com            }
155acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
156acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
157b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com
158b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    struct FlatData {
159b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        uint32_t    fIndex; // always > 0
160b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        uint32_t    fSize;
161b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com
162b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        void*       data() { return (char*)this + sizeof(*this); }
16374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org
164b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        static int Compare(const FlatData* a, const FlatData* b) {
165b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com            return memcmp(&a->fSize, &b->fSize, a->fSize + sizeof(a->fSize));
166b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        }
167b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    };
16816d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
16916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    SkTDArray<FlatData*> fBitmapArray;
17016d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    int flattenToIndex(const SkBitmap&);
17116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
172b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    SkTDArray<FlatData*> fFlatArray;
173b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    int fCurrFlatIndex[kCount_PaintFlats];
174b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    int flattenToIndex(SkFlattenable* obj, PaintFlats);
175b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com
17631891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com    SkPaint fPaint;
17731891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com    void writePaint(const SkPaint&);
178bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
179acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    class AutoPipeNotify {
180acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    public:
181acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        AutoPipeNotify(SkGPipeCanvas* canvas) : fCanvas(canvas) {}
182acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        ~AutoPipeNotify() { fCanvas->doNotify(); }
183acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    private:
184acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        SkGPipeCanvas* fCanvas;
185acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    };
186acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    friend class AutoPipeNotify;
187acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
188bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    typedef SkCanvas INHERITED;
189bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com};
190bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
19116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.comint SkGPipeCanvas::flattenToIndex(const SkBitmap & bitmap) {
19216d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    SkOrderedWriteBuffer tmpWriter(1024);
19316d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    // FIXME: Rather than forcing CrossProcess, we should create an SkRefCntSet
19416d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    // so that we can store a pointer to a bitmap's pixels during flattening.
19516d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    tmpWriter.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag);
19616d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    bitmap.flatten(tmpWriter);
19716d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
19816d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    size_t len = tmpWriter.size();
19916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    size_t allocSize = len + sizeof(FlatData);
20016d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
20116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    SkAutoSMalloc<1024> storage(allocSize);
20216d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    FlatData* flat = (FlatData*)storage.get();
20316d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    flat->fSize = len;
20416d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    tmpWriter.flatten(flat->data());
20516d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
20616d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    int index = SkTSearch<FlatData>((const FlatData**)fBitmapArray.begin(),
20716d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com                                     fBitmapArray.count(), flat, sizeof(flat),
20816d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com                                     &FlatData::Compare);
20916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    if (index < 0) {
21016d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        index = ~index;
21116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        FlatData* copy = (FlatData*)sk_malloc_throw(allocSize);
21216d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        memcpy(copy, flat, allocSize);
21316d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        // For bitmaps, we can use zero based indices, since we will never ask
21416d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        // for a NULL bitmap (unlike with paint flattenables).
21516d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        copy->fIndex = fBitmapArray.count();
21616d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        *fBitmapArray.insert(index) = copy;
21716d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        if (this->needOpBytes(len + sizeof(uint32_t))) {
21816d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com            this->writeOp(kDef_Bitmap_DrawOp, 0, copy->fIndex);
21916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com            fWriter.write32(len);
22016d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com            fWriter.write(copy->data(), len);
22116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        }
22216d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    }
22316d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    return fBitmapArray[index]->fIndex;
22416d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com}
22516d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
226b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com// return 0 for NULL (or unflattenable obj), or index-base-1
227b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.comint SkGPipeCanvas::flattenToIndex(SkFlattenable* obj, PaintFlats paintflat) {
228b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    if (NULL == obj) {
229b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        return 0;
230b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    }
231b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com
2322b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    SkOrderedWriteBuffer tmpWriter(1024);
2335a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com
2345a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com    // Needs to be cross process so a bitmap shader will be preserved
2355a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com    // FIXME: Rather than forcing CrossProcess, we should create an SkRefCntSet
2365a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com    // so that we can store a pointer to a bitmap's pixels during flattening.
2375a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com    tmpWriter.setFlags((SkFlattenableWriteBuffer::Flags)
2385a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com                       (SkFlattenableWriteBuffer::kInlineFactoryNames_Flag
2395a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com                       | SkFlattenableWriteBuffer::kCrossProcess_Flag));
240dde0956375e87027df2fdd80d430dd819c217aacreed@google.com    tmpWriter.setFactoryRecorder(fFactorySet);
241dde0956375e87027df2fdd80d430dd819c217aacreed@google.com
242b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    tmpWriter.writeFlattenable(obj);
243b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    size_t len = tmpWriter.size();
244b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    size_t allocSize = len + sizeof(FlatData);
245b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com
246b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    SkAutoSMalloc<1024> storage(allocSize);
247b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    FlatData* flat = (FlatData*)storage.get();
248b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    flat->fSize = len;
249b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    tmpWriter.flatten(flat->data());
250b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com
251b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    int index = SkTSearch<FlatData>((const FlatData**)fFlatArray.begin(),
252b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com                                    fFlatArray.count(), flat, sizeof(flat),
253b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com                                    &FlatData::Compare);
254b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    if (index < 0) {
255b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        index = ~index;
256b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        FlatData* copy = (FlatData*)sk_malloc_throw(allocSize);
257b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        memcpy(copy, flat, allocSize);
258b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        *fFlatArray.insert(index) = copy;
259b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        // call this after the insert, so that count() will have been grown
260b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        copy->fIndex = fFlatArray.count();
261b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com//        SkDebugf("--- add flattenable[%d] size=%d index=%d\n", paintflat, len, copy->fIndex);
262b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com
263b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        if (this->needOpBytes(len)) {
2640faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com            this->writeOp(kDef_Flattenable_DrawOp, paintflat, copy->fIndex);
265b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com            fWriter.write(copy->data(), len);
266b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        }
267b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    }
268b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    return fFlatArray[index]->fIndex;
269b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com}
270b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com
271bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
272bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
273acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com#define MIN_BLOCK_SIZE  (16 * 1024)
274bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
275acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.comSkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller,
276dde0956375e87027df2fdd80d430dd819c217aacreed@google.com                             SkWriter32* writer, SkFactorySet* fset)
27767908f2faee17a8bce4d074980617cc0d15fabf1reed@google.com        : fWriter(*writer) {
27867908f2faee17a8bce4d074980617cc0d15fabf1reed@google.com    fFactorySet = fset;
279acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    fController = controller;
280bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    fDone = false;
281acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    fBlockSize = 0; // need first block from controller
2825a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com    fBytesNotified = 0;
283b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    sk_bzero(fCurrFlatIndex, sizeof(fCurrFlatIndex));
284acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
285bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com    // we need a device to limit our clip
286bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com    // should the caller give us the bounds?
28706b4da16fd6ed63560d79116c6066534e953a43dyangsu@google.com    // We don't allocate pixels for the bitmap
288bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com    SkBitmap bitmap;
289bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com    bitmap.setConfig(SkBitmap::kARGB_8888_Config, 32767, 32767);
29006b4da16fd6ed63560d79116c6066534e953a43dyangsu@google.com    SkDevice* device = SkNEW_ARGS(SkDevice, (bitmap));
291bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com    this->setDevice(device)->unref();
292bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
293bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
294bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comSkGPipeCanvas::~SkGPipeCanvas() {
295bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    this->finish();
296bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
297b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    fFlatArray.freeAll();
29816d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    fBitmapArray.freeAll();
299bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
300bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
301acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.combool SkGPipeCanvas::needOpBytes(size_t needed) {
302acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (fDone) {
303acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        return false;
304acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
305acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
306acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    needed += 4;  // size of DrawOp atom
307acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (fWriter.size() + needed > fBlockSize) {
3085a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        // Before we wipe out any data that has already been written, read it
3095a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        // out.
3105a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        this->doNotify();
3115a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        size_t blockSize = SkMax32(MIN_BLOCK_SIZE, needed);
3125a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        void* block = fController->requestBlock(blockSize, &fBlockSize);
313acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (NULL == block) {
314acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fDone = true;
315acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            return false;
316acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
317acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.reset(block, fBlockSize);
318acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fBytesNotified = 0;
319acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
320acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    return true;
321acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com}
322acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
323f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.comuint32_t SkGPipeCanvas::getTypefaceID(SkTypeface* face) {
324f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    uint32_t id = 0; // 0 means default/null typeface
325f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    if (face) {
326f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        id = fTypefaceSet.find(face);
327f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        if (0 == id) {
328f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com            id = fTypefaceSet.add(face);
329f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com            size_t size = writeTypeface(NULL, face);
330f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com            if (this->needOpBytes(size)) {
331bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com                this->writeOp(kDef_Typeface_DrawOp);
332f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com                writeTypeface(&fWriter, face);
333f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com            }
334f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        }
335f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    }
336f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    return id;
337f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com}
338f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com
339bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
340bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
341acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com#define NOTIFY_SETUP(canvas)    \
342acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    AutoPipeNotify apn(canvas)
343acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
344bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comint SkGPipeCanvas::save(SaveFlags flags) {
345acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
346acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes()) {
347acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kSave_DrawOp, 0, flags);
348acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
349bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::save(flags);
350bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
351bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
352bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comint SkGPipeCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
353bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                             SaveFlags saveFlags) {
354acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
355acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    size_t size = 0;
356bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    unsigned opFlags = 0;
35774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org
358bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (bounds) {
359bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        opFlags |= kSaveLayer_HasBounds_DrawOpFlag;
360acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        size += sizeof(SkRect);
361bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
362bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (paint) {
363bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        opFlags |= kSaveLayer_HasPaint_DrawOpFlag;
36431891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writePaint(*paint);
365bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
366bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
367acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(size)) {
368acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kSaveLayer_DrawOp, opFlags, saveFlags);
369acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (bounds) {
370acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeRect(*bounds);
371acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
372bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
37374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org
374bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    // we just pass on the save, so we don't create a layer
375bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::save(saveFlags);
376bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
377bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
378bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::restore() {
379acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
380acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes()) {
381acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kRestore_DrawOp);
382acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
383bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    this->INHERITED::restore();
384bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
385bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
386bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::translate(SkScalar dx, SkScalar dy) {
387bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (dx || dy) {
388acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
389acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(2 * sizeof(SkScalar))) {
390acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kTranslate_DrawOp);
391acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(dx);
392acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(dy);
393acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
394bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
395bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::translate(dx, dy);
396bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
397bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
398bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::scale(SkScalar sx, SkScalar sy) {
399bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (sx || sy) {
400acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
401acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(2 * sizeof(SkScalar))) {
402acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kScale_DrawOp);
403acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(sx);
404acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(sy);
405acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
406bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
407bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::scale(sx, sy);
408bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
409bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
410bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::rotate(SkScalar degrees) {
411bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (degrees) {
412acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
413acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(sizeof(SkScalar))) {
414acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kRotate_DrawOp);
415acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(degrees);
416acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
417bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
418bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::rotate(degrees);
419bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
420bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
421bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::skew(SkScalar sx, SkScalar sy) {
422bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (sx || sy) {
423acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
424acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(2 * sizeof(SkScalar))) {
425acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kSkew_DrawOp);
426acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(sx);
427acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(sy);
428acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
429bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
430bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::skew(sx, sy);
431bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
432bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
433bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::concat(const SkMatrix& matrix) {
434bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (!matrix.isIdentity()) {
435acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
43694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        if (this->needOpBytes(matrix.writeToMemory(NULL))) {
437acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kConcat_DrawOp);
4382b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com            fWriter.writeMatrix(matrix);
439acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
440bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
441bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::concat(matrix);
442bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
443bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
444bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::setMatrix(const SkMatrix& matrix) {
445acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
44694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    if (this->needOpBytes(matrix.writeToMemory(NULL))) {
447acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kSetMatrix_DrawOp);
4482b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com        fWriter.writeMatrix(matrix);
449acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
450bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    this->INHERITED::setMatrix(matrix);
451bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
452bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
4533b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.combool SkGPipeCanvas::clipRect(const SkRect& rect, SkRegion::Op rgnOp,
4543b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                             bool doAntiAlias) {
455acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
4563b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    if (this->needOpBytes(sizeof(SkRect)) + sizeof(bool)) {
457acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kClipRect_DrawOp, 0, rgnOp);
458acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.writeRect(rect);
4593b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com        fWriter.writeBool(doAntiAlias);
460acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
4613b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    return this->INHERITED::clipRect(rect, rgnOp, doAntiAlias);
462bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
463bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
4643b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.combool SkGPipeCanvas::clipPath(const SkPath& path, SkRegion::Op rgnOp,
4653b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                             bool doAntiAlias) {
466acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
46794e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    if (this->needOpBytes(path.writeToMemory(NULL)) + sizeof(bool)) {
468acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kClipPath_DrawOp, 0, rgnOp);
46994e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        fWriter.writePath(path);
4703b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com        fWriter.writeBool(doAntiAlias);
471acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
472bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    // we just pass on the bounds of the path
4733b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    return this->INHERITED::clipRect(path.getBounds(), rgnOp, doAntiAlias);
474bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
475bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
476bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::clipRegion(const SkRegion& region, SkRegion::Op rgnOp) {
477acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
47894e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    if (this->needOpBytes(region.writeToMemory(NULL))) {
479acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kClipRegion_DrawOp, 0, rgnOp);
4802b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com        fWriter.writeRegion(region);
481acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
482bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::clipRegion(region, rgnOp);
483bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
484bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
485bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
486bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
487bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::clear(SkColor color) {
488acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
489bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    unsigned flags = 0;
490bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (color) {
491bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        flags |= kClear_HasColor_DrawOpFlag;
492bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
493acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(sizeof(SkColor))) {
494acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kDrawClear_DrawOp, flags, 0);
495acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (color) {
496acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(color);
497acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
498bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
499bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
500bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
501bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawPaint(const SkPaint& paint) {
502acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
50331891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com    this->writePaint(paint);
504acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes()) {
50531891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writeOp(kDrawPaint_DrawOp);
506acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
507bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
508bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
509bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawPoints(PointMode mode, size_t count,
510bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                   const SkPoint pts[], const SkPaint& paint) {
511bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (count) {
512acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
51331891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writePaint(paint);
514acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(4 + count * sizeof(SkPoint))) {
51531891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com            this->writeOp(kDrawPoints_DrawOp, mode, 0);
516acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(count);
517acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write(pts, count * sizeof(SkPoint));
518acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
519bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
520bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
521bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
522bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
523acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
52431891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com    this->writePaint(paint);
525acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(sizeof(SkRect))) {
52631891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writeOp(kDrawRect_DrawOp);
527acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.writeRect(rect);
528acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
529bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
530bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
531bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
532acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
53331891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com    this->writePaint(paint);
53494e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    if (this->needOpBytes(path.writeToMemory(NULL))) {
53531891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writeOp(kDrawPath_DrawOp);
53694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        fWriter.writePath(path);
537acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
538bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
539bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
5405a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.comvoid SkGPipeCanvas::drawBitmap(const SkBitmap& bm, SkScalar left, SkScalar top,
5415a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com                                   const SkPaint* paint) {
5425a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com    // This is the brute-force solution
5435a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com    // TODO: add the notion of a shared, counted for large immutable resources
5445a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com    NOTIFY_SETUP(this);
5455a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com    if (paint) {
5465a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        this->writePaint(*paint);
5475a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com    }
54816d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
54916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    int bitmapIndex = this->flattenToIndex(bm);
5505a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com
55116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    if (this->needOpBytes(sizeof(SkScalar) * 2 + sizeof(bool))) {
55216d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        this->writeOp(kDrawBitmap_DrawOp, 0, bitmapIndex);
5535a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        fWriter.writeBool(paint != NULL);
5545a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        fWriter.writeScalar(left);
5555a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        fWriter.writeScalar(top);
5565a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com    }
557bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
558bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
55916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.comvoid SkGPipeCanvas::drawBitmapRect(const SkBitmap& bm, const SkIRect* src,
56016d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com                                       const SkRect& dst, const SkPaint* paint) {
56116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    NOTIFY_SETUP(this);
56216d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    if (paint) {
56316d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        this->writePaint(*paint);
56416d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    }
56516d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
56616d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    int bitmapIndex = this->flattenToIndex(bm);
56716d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
56816d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    size_t opBytesNeeded = sizeof(SkRect) + sizeof(bool) * 2;
56916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    bool hasSrc = src != NULL;
57016d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    if (hasSrc) {
57116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        opBytesNeeded += sizeof(int32_t) * 4;
57216d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    }
57316d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    if (this->needOpBytes(opBytesNeeded)) {
57416d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        this->writeOp(kDrawBitmapRect_DrawOp, 0, bitmapIndex);
57516d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.writeBool(paint != NULL);
57616d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.writeBool(hasSrc);
57716d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        if (hasSrc) {
57816d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com            fWriter.write32(src->fLeft);
57916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com            fWriter.write32(src->fTop);
58016d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com            fWriter.write32(src->fRight);
58116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com            fWriter.write32(src->fBottom);
58216d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        }
58316d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.writeRect(dst);
58416d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    }
585bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
586bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
587bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
588bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                         const SkPaint*) {
589bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    UNIMPLEMENTED
590bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
59116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
59216d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.comvoid SkGPipeCanvas::drawBitmapNine(const SkBitmap& bm, const SkIRect& center,
5935a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com                                   const SkRect& dst, const SkPaint* paint) {
59416d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    NOTIFY_SETUP(this);
59516d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    if (paint) {
59616d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        this->writePaint(*paint);
59716d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    }
59816d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    int bitmapIndex = this->flattenToIndex(bm);
59916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
60016d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    if (this->needOpBytes(sizeof(int32_t) * 4 + sizeof(bool)
60116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com                          + sizeof(SkRect))) {
60216d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        this->writeOp(kDrawBitmapNine_DrawOp, 0, bitmapIndex);
60316d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.writeBool(paint != NULL);
60416d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.write32(center.fLeft);
60516d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.write32(center.fTop);
60616d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.write32(center.fRight);
60716d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.write32(center.fBottom);
60816d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.writeRect(dst);
60916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    }
6105a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com}
61116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
61216d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.comvoid SkGPipeCanvas::drawSprite(const SkBitmap& bm, int left, int top,
61316d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com                                   const SkPaint* paint) {
61416d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    NOTIFY_SETUP(this);
61516d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    if (paint) {
61616d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        this->writePaint(*paint);
61716d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    }
61816d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    int bitmapIndex = this->flattenToIndex(bm);
61916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
62016d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    if (this->needOpBytes(sizeof(int32_t) * 2 + sizeof(bool))) {
62116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        this->writeOp(kDrawSprite_DrawOp, 0, bitmapIndex);
62216d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.writeBool(paint != NULL);
62316d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.write32(left);
62416d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.write32(top);
62516d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    }
626bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
627bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
62874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.orgvoid SkGPipeCanvas::drawText(const void* text, size_t byteLength, SkScalar x,
629bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 SkScalar y, const SkPaint& paint) {
630bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (byteLength) {
631acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
63231891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writePaint(paint);
633acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(4 + SkAlign4(byteLength) + 2 * sizeof(SkScalar))) {
63431891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com            this->writeOp(kDrawText_DrawOp);
635acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(byteLength);
636acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writePad(text, byteLength);
637acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(x);
638acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(y);
639acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
640bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
641bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
642bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
64374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.orgvoid SkGPipeCanvas::drawPosText(const void* text, size_t byteLength,
644bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                const SkPoint pos[], const SkPaint& paint) {
645bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (byteLength) {
646acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
64731891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writePaint(paint);
648bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        int count = paint.textToGlyphs(text, byteLength, NULL);
649acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(4 + SkAlign4(byteLength) + 4 + count * sizeof(SkPoint))) {
65031891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com            this->writeOp(kDrawPosText_DrawOp);
651acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(byteLength);
652acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writePad(text, byteLength);
653acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(count);
654acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write(pos, count * sizeof(SkPoint));
655acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
656bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
657bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
658bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
659bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawPosTextH(const void* text, size_t byteLength,
660bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const SkScalar xpos[], SkScalar constY,
661bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const SkPaint& paint) {
662bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (byteLength) {
663acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
66431891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writePaint(paint);
665bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        int count = paint.textToGlyphs(text, byteLength, NULL);
666acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(4 + SkAlign4(byteLength) + 4 + count * sizeof(SkScalar) + 4)) {
66731891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com            this->writeOp(kDrawPosTextH_DrawOp);
668acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(byteLength);
669acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writePad(text, byteLength);
670acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(count);
671acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write(xpos, count * sizeof(SkScalar));
672acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(constY);
673acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
674bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
675bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
676bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
67774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.orgvoid SkGPipeCanvas::drawTextOnPath(const void* text, size_t byteLength,
67874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org                                   const SkPath& path, const SkMatrix* matrix,
679bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                   const SkPaint& paint) {
680bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (byteLength) {
681acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
682bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        unsigned flags = 0;
68394e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        size_t size = 4 + SkAlign4(byteLength) + path.writeToMemory(NULL);
684bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        if (matrix) {
685bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com            flags |= kDrawTextOnPath_HasMatrix_DrawOpFlag;
68694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com            size += matrix->writeToMemory(NULL);
687bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
68831891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writePaint(paint);
689acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(size)) {
69031891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com            this->writeOp(kDrawTextOnPath_DrawOp, flags, 0);
691bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
692acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(byteLength);
693acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writePad(text, byteLength);
694bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
69594e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com            fWriter.writePath(path);
696acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            if (matrix) {
6972b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com                fWriter.writeMatrix(*matrix);
698acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            }
699bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
700bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
701bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
702bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
703bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawPicture(SkPicture& picture) {
7040faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com    // we want to playback the picture into individual draw calls
7050faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com    this->INHERITED::drawPicture(picture);
706bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
707bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
708bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawVertices(VertexMode mode, int vertexCount,
709bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const SkPoint vertices[], const SkPoint texs[],
710bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const SkColor colors[], SkXfermode*,
711bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const uint16_t indices[], int indexCount,
712bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const SkPaint& paint) {
713bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (0 == vertexCount) {
714bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        return;
715bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
716bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
717acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
718acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    size_t size = 4 + vertexCount * sizeof(SkPoint);
71931891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com    this->writePaint(paint);
720bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    unsigned flags = 0;
721bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (texs) {
722bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        flags |= kDrawVertices_HasTexs_DrawOpFlag;
723acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        size += vertexCount * sizeof(SkPoint);
724bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
725bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (colors) {
726bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        flags |= kDrawVertices_HasColors_DrawOpFlag;
727acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        size += vertexCount * sizeof(SkColor);
728bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
729bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (indices && indexCount > 0) {
730bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        flags |= kDrawVertices_HasIndices_DrawOpFlag;
731acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        size += 4 + SkAlign4(indexCount * sizeof(uint16_t));
732bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
73374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org
734acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(size)) {
73531891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writeOp(kDrawVertices_DrawOp, flags, 0);
736acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.write32(mode);
737acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.write32(vertexCount);
738acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.write(vertices, vertexCount * sizeof(SkPoint));
739acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (texs) {
740acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write(texs, vertexCount * sizeof(SkPoint));
741acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
742acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (colors) {
743acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write(colors, vertexCount * sizeof(SkColor));
744acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
745bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
746acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        // TODO: flatten xfermode
747bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
748acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (indices && indexCount > 0) {
749acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(indexCount);
750acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writePad(indices, indexCount * sizeof(uint16_t));
751acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
752bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
753bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
754bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
755acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.comvoid SkGPipeCanvas::drawData(const void* ptr, size_t size) {
756acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (size && ptr) {
757acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
758bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        unsigned data = 0;
759bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        if (size < (1 << DRAWOPS_DATA_BITS)) {
760bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com            data = (unsigned)size;
761bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
762acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(4 + SkAlign4(size))) {
763acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kDrawData_DrawOp, 0, data);
764acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            if (0 == data) {
765acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com                fWriter.write32(size);
766acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            }
767bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com            fWriter.writePad(ptr, size);
768bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
769bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
770bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
771bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
772bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
773bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
774bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comtemplate <typename T> uint32_t castToU32(T value) {
775bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    union {
776bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        T           fSrc;
777bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        uint32_t    fDst;
778bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    } data;
779bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    data.fSrc = value;
780bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return data.fDst;
781bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
782bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
78331891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.comvoid SkGPipeCanvas::writePaint(const SkPaint& paint) {
78431891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com    SkPaint& base = fPaint;
785bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    uint32_t storage[32];
786bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    uint32_t* ptr = storage;
787bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
788bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getFlags() != paint.getFlags()) {
789bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kFlags_PaintOp, paint.getFlags());
790f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setFlags(paint.getFlags());
791bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
792bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getColor() != paint.getColor()) {
793bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kColor_PaintOp);
794bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = paint.getColor();
795f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setColor(paint.getColor());
796bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
797bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getStyle() != paint.getStyle()) {
798bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kStyle_PaintOp, paint.getStyle());
799f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setStyle(paint.getStyle());
800bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
801bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getStrokeJoin() != paint.getStrokeJoin()) {
802bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kJoin_PaintOp, paint.getStrokeJoin());
803f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setStrokeJoin(paint.getStrokeJoin());
804bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
805bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getStrokeCap() != paint.getStrokeCap()) {
806bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kCap_PaintOp, paint.getStrokeCap());
807f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setStrokeCap(paint.getStrokeCap());
808bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
809bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getStrokeWidth() != paint.getStrokeWidth()) {
810bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kWidth_PaintOp);
811bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = castToU32(paint.getStrokeWidth());
812f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setStrokeWidth(paint.getStrokeWidth());
813bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
814bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getStrokeMiter() != paint.getStrokeMiter()) {
815bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kMiter_PaintOp);
816bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = castToU32(paint.getStrokeMiter());
817f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setStrokeMiter(paint.getStrokeMiter());
818bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
819bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getTextEncoding() != paint.getTextEncoding()) {
820bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kEncoding_PaintOp, paint.getTextEncoding());
821f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTextEncoding(paint.getTextEncoding());
822bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
823bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getHinting() != paint.getHinting()) {
824bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kHinting_PaintOp, paint.getHinting());
825f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setHinting(paint.getHinting());
826bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
827bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getTextAlign() != paint.getTextAlign()) {
828bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kAlign_PaintOp, paint.getTextAlign());
829f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTextAlign(paint.getTextAlign());
830bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
831bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getTextSize() != paint.getTextSize()) {
832bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kTextSize_PaintOp);
833bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = castToU32(paint.getTextSize());
834f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTextSize(paint.getTextSize());
835bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
836bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getTextScaleX() != paint.getTextScaleX()) {
837bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kTextScaleX_PaintOp);
838bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = castToU32(paint.getTextScaleX());
839f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTextScaleX(paint.getTextScaleX());
840bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
841bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getTextSkewX() != paint.getTextSkewX()) {
842bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kTextSkewX_PaintOp);
843bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = castToU32(paint.getTextSkewX());
844f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTextSkewX(paint.getTextSkewX());
845f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    }
846f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com
847f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    if (!SkTypeface::Equal(base.getTypeface(), paint.getTypeface())) {
848f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        uint32_t id = this->getTypefaceID(paint.getTypeface());
849f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        *ptr++ = PaintOp_packOpData(kTypeface_PaintOp, id);
850f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTypeface(paint.getTypeface());
851bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
852bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
853b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    for (int i = 0; i < kCount_PaintFlats; i++) {
854b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        int index = this->flattenToIndex(get_paintflat(paint, i), (PaintFlats)i);
855b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        SkASSERT(index >= 0 && index <= fFlatArray.count());
856b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        if (index != fCurrFlatIndex[i]) {
857b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com            *ptr++ = PaintOp_packOpFlagData(kFlatIndex_PaintOp, i, index);
858b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com            fCurrFlatIndex[i] = index;
859b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        }
860b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    }
861b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com
862acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    size_t size = (char*)ptr - (char*)storage;
863acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (size && this->needOpBytes(size)) {
864b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        this->writeOp(kPaintOp_DrawOp, 0, size);
865b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        fWriter.write(storage, size);
866bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        for (size_t i = 0; i < size/4; i++) {
867b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com//            SkDebugf("[%d] %08X\n", i, storage[i]);
868bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
869bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
870bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
871bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
872bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
873bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
874bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com#include "SkGPipe.h"
875bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
876acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.comSkGPipeWriter::SkGPipeWriter() : fWriter(0) {
877bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    fCanvas = NULL;
878bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
879bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
880bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comSkGPipeWriter::~SkGPipeWriter() {
881acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    this->endRecording();
882bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    SkSafeUnref(fCanvas);
883bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
884bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
885dde0956375e87027df2fdd80d430dd819c217aacreed@google.comSkCanvas* SkGPipeWriter::startRecording(SkGPipeController* controller,
886dde0956375e87027df2fdd80d430dd819c217aacreed@google.com                                        uint32_t flags) {
887bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (NULL == fCanvas) {
888acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.reset(NULL, 0);
889dde0956375e87027df2fdd80d430dd819c217aacreed@google.com        fFactorySet.reset();
890dde0956375e87027df2fdd80d430dd819c217aacreed@google.com        fCanvas = SkNEW_ARGS(SkGPipeCanvas, (controller, &fWriter,
891dde0956375e87027df2fdd80d430dd819c217aacreed@google.com                                             (flags & kCrossProcess_Flag) ?
892dde0956375e87027df2fdd80d430dd819c217aacreed@google.com                                             &fFactorySet : NULL));
893bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
894bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return fCanvas;
895bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
896bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
897bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeWriter::endRecording() {
898bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (fCanvas) {
899bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        fCanvas->finish();
900bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        fCanvas->unref();
901bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        fCanvas = NULL;
902bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
903bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
904bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
905