SkGPipeWrite.cpp revision bb6793bd7751f7a4e48c942567cd6c5270661a2f
1bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com/*
2bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    Copyright 2011 Google Inc.
3bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
4bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    Licensed under the Apache License, Version 2.0 (the "License");
5bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    you may not use this file except in compliance with the License.
6bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    You may obtain a copy of the License at
7bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
8bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    http://www.apache.org/licenses/LICENSE-2.0
9bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
10bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    Unless required by applicable law or agreed to in writing, software
11bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    distributed under the License is distributed on an "AS IS" BASIS,
12bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    See the License for the specific language governing permissions and
14bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    limitations under the License.
15bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com */
16bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
17bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
18bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com#include "SkCanvas.h"
19bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com#include "SkDevice.h"
20bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com#include "SkPaint.h"
21acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com#include "SkGPipe.h"
22bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com#include "SkGPipePriv.h"
23f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com#include "SkStream.h"
24f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com#include "SkTypeface.h"
25bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com#include "SkWriter32.h"
26bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
27acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.comstatic size_t estimateFlattenSize(const SkPath& path) {
28acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    int n = path.countPoints();
29acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    size_t bytes = 3 * sizeof(int32_t);
30acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    bytes += n * sizeof(SkPoint);
31acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    bytes += SkAlign4(n + 2);    // verbs: add 2 for move/close extras
32acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
33acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com#ifdef SK_DEBUG
34acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    {
35acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        SkWriter32 writer(1024);
36acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        path.flatten(writer);
37acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        SkASSERT(writer.size() <= bytes);
38acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
39acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com#endif
40acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    return bytes;
41acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com}
42acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
43bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comstatic void writeRegion(SkWriter32* writer, const SkRegion& rgn) {
44bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    size_t size = rgn.flatten(NULL);
45bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    SkASSERT(SkAlign4(size) == size);
46bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    rgn.flatten(writer->reserve(size));
47bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
48bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
49bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comstatic void writeMatrix(SkWriter32* writer, const SkMatrix& matrix) {
50bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    size_t size = matrix.flatten(NULL);
51bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    SkASSERT(SkAlign4(size) == size);
52bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    matrix.flatten(writer->reserve(size));
53bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
54bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
55f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.comstatic size_t writeTypeface(SkWriter32* writer, SkTypeface* typeface) {
56f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    SkASSERT(typeface);
57f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    SkDynamicMemoryWStream stream;
58f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    typeface->serialize(&stream);
59f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    size_t size = stream.getOffset();
60f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    if (writer) {
61f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        writer->write32(size);
62f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        writer->write(stream.getStream(), size);
63f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    }
64f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    return 4 + size;
65f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com}
66f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com
67bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
68bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
69bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comclass SkGPipeCanvas : public SkCanvas {
70bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.compublic:
71acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    SkGPipeCanvas(SkGPipeController*, SkWriter32*);
72bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual ~SkGPipeCanvas();
73bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
74bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    void finish() {
75bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        if (!fDone) {
76bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com            this->writeOp(kDone_DrawOp);
77bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com            fDone = true;
78bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
79bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
80bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
81bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    // overrides from SkCanvas
82bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual int save(SaveFlags);
83bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual int saveLayer(const SkRect* bounds, const SkPaint*, SaveFlags);
84bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void restore();
85bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual bool translate(SkScalar dx, SkScalar dy);
86bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual bool scale(SkScalar sx, SkScalar sy);
87bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual bool rotate(SkScalar degrees);
88bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual bool skew(SkScalar sx, SkScalar sy);
89bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual bool concat(const SkMatrix& matrix);
90bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void setMatrix(const SkMatrix& matrix);
91bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual bool clipRect(const SkRect& rect, SkRegion::Op op);
92bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual bool clipPath(const SkPath& path, SkRegion::Op op);
93bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual bool clipRegion(const SkRegion& region, SkRegion::Op op);
94bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void clear(SkColor);
95bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawPaint(const SkPaint& paint);
96bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawPoints(PointMode, size_t count, const SkPoint pts[],
97bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                            const SkPaint&);
98bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawRect(const SkRect& rect, const SkPaint&);
99bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawPath(const SkPath& path, const SkPaint&);
100bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
101bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                            const SkPaint*);
102bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawBitmapRect(const SkBitmap&, const SkIRect* src,
103bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                const SkRect& dst, const SkPaint*);
104bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
105bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                  const SkPaint*);
106bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawSprite(const SkBitmap&, int left, int top,
107bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                            const SkPaint*);
108bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawText(const void* text, size_t byteLength, SkScalar x,
109bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                          SkScalar y, const SkPaint&);
110bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawPosText(const void* text, size_t byteLength,
111bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                             const SkPoint pos[], const SkPaint&);
112bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawPosTextH(const void* text, size_t byteLength,
113bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                      const SkScalar xpos[], SkScalar constY, const SkPaint&);
114bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawTextOnPath(const void* text, size_t byteLength,
115bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                            const SkPath& path, const SkMatrix* matrix,
116bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                const SkPaint&);
117bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawPicture(SkPicture& picture);
118bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawShape(SkShape*);
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,
123bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                              const SkPaint&);
124bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawData(const void*, size_t);
125bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
126bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comprivate:
127acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    SkGPipeController* fController;
128bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    SkWriter32& fWriter;
129acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    size_t      fBlockSize; // amount allocated for writer
130acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    size_t      fBytesNotified;
131bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    bool        fDone;
132bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
133f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    SkRefCntSet fTypefaceSet;
134f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com
135f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    uint32_t getTypefaceID(SkTypeface*);
136f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com
137acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    inline void writeOp(DrawOps op, unsigned flags, unsigned data) {
138bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        fWriter.write32(DrawOp_packOpFlagData(op, flags, data));
139bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
140bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
141acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    inline void writeOp(DrawOps op) {
142bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        fWriter.write32(DrawOp_packOpFlagData(op, 0, 0));
143bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
144acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
145acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    bool needOpBytes(size_t size = 0);
146acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
147acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    inline void doNotify() {
148acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (!fDone) {
149acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            size_t bytes = fWriter.size() - fBytesNotified;
150acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fController->notifyWritten(bytes);
151acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fBytesNotified += bytes;
152acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
153acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
154bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
155bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    SkTDArray<SkPaint*> fPaints;
156bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    unsigned writePaint(const SkPaint&);
157bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
158acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    class AutoPipeNotify {
159acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    public:
160acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        AutoPipeNotify(SkGPipeCanvas* canvas) : fCanvas(canvas) {}
161acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        ~AutoPipeNotify() { fCanvas->doNotify(); }
162acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    private:
163acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        SkGPipeCanvas* fCanvas;
164acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    };
165acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    friend class AutoPipeNotify;
166acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
167bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    typedef SkCanvas INHERITED;
168bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com};
169bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
170bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
171bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
172acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com#define MIN_BLOCK_SIZE  (16 * 1024)
173bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
174acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.comSkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller,
175acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com                             SkWriter32* writer) : fWriter(*writer) {
176acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    fController = controller;
177bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    fDone = false;
178acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    fBlockSize = 0; // need first block from controller
179acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
180bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    // always begin with 1 default paint
181bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    *fPaints.append() = SkNEW(SkPaint);
182bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com
183bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com    // we need a device to limit our clip
184bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com    // should the caller give us the bounds?
185bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com    SkBitmap bitmap;
186bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com    bitmap.setConfig(SkBitmap::kARGB_8888_Config, 32767, 32767);
187bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com    SkDevice* device = SkNEW_ARGS(SkDevice, (this, bitmap, false));
188bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com    this->setDevice(device)->unref();
189bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
190bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
191bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comSkGPipeCanvas::~SkGPipeCanvas() {
192bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    this->finish();
193bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
194bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    fPaints.deleteAll();
195bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
196bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
197acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.combool SkGPipeCanvas::needOpBytes(size_t needed) {
198acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (fDone) {
199acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        return false;
200acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
201acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
202acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    needed += 4;  // size of DrawOp atom
203acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (fWriter.size() + needed > fBlockSize) {
204acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        void* block = fController->requestBlock(MIN_BLOCK_SIZE, &fBlockSize);
205acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (NULL == block) {
206acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fDone = true;
207acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            return false;
208acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
209acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.reset(block, fBlockSize);
210acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fBytesNotified = 0;
211acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
212acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    return true;
213acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com}
214acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
215f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.comuint32_t SkGPipeCanvas::getTypefaceID(SkTypeface* face) {
216f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    uint32_t id = 0; // 0 means default/null typeface
217f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    if (face) {
218f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        id = fTypefaceSet.find(face);
219f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        if (0 == id) {
220f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com            id = fTypefaceSet.add(face);
221f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com            size_t size = writeTypeface(NULL, face);
222f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com            if (this->needOpBytes(size)) {
223bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com                this->writeOp(kDef_Typeface_DrawOp);
224f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com                writeTypeface(&fWriter, face);
225f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com            }
226f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        }
227f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    }
228f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    return id;
229f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com}
230f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com
231bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
232bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
233acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com#define NOTIFY_SETUP(canvas)    \
234acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    AutoPipeNotify apn(canvas)
235acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
236bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comint SkGPipeCanvas::save(SaveFlags flags) {
237acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
238acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes()) {
239acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kSave_DrawOp, 0, flags);
240acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
241bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::save(flags);
242bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
243bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
244bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comint SkGPipeCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
245bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                             SaveFlags saveFlags) {
246acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
247acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    size_t size = 0;
248bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    unsigned index = 0; // just to avoid the warning
249bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    unsigned opFlags = 0;
250acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
251bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (bounds) {
252bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        opFlags |= kSaveLayer_HasBounds_DrawOpFlag;
253acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        size += sizeof(SkRect);
254bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
255bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (paint) {
256bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        opFlags |= kSaveLayer_HasPaint_DrawOpFlag;
257bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        index = this->writePaint(*paint);
258acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        size += 4;
259bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
260bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
261acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(size)) {
262acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kSaveLayer_DrawOp, opFlags, saveFlags);
263acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (bounds) {
264acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeRect(*bounds);
265acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
266acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (paint) {
267acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(index);
268acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
269bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
270bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
271bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    // we just pass on the save, so we don't create a layer
272bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::save(saveFlags);
273bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
274bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
275bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::restore() {
276acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
277acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes()) {
278acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kRestore_DrawOp);
279acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
280bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    this->INHERITED::restore();
281bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
282bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
283bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::translate(SkScalar dx, SkScalar dy) {
284bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (dx || dy) {
285acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
286acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(2 * sizeof(SkScalar))) {
287acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kTranslate_DrawOp);
288acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(dx);
289acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(dy);
290acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
291bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
292bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::translate(dx, dy);
293bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
294bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
295bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::scale(SkScalar sx, SkScalar sy) {
296bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (sx || sy) {
297acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
298acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(2 * sizeof(SkScalar))) {
299acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kScale_DrawOp);
300acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(sx);
301acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(sy);
302acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
303bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
304bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::scale(sx, sy);
305bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
306bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
307bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::rotate(SkScalar degrees) {
308bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (degrees) {
309acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
310acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(sizeof(SkScalar))) {
311acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kRotate_DrawOp);
312acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(degrees);
313acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
314bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
315bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::rotate(degrees);
316bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
317bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
318bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::skew(SkScalar sx, SkScalar sy) {
319bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (sx || sy) {
320acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
321acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(2 * sizeof(SkScalar))) {
322acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kSkew_DrawOp);
323acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(sx);
324acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(sy);
325acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
326bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
327bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::skew(sx, sy);
328bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
329bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
330bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::concat(const SkMatrix& matrix) {
331bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (!matrix.isIdentity()) {
332acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
333acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(matrix.flatten(NULL))) {
334acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kConcat_DrawOp);
335acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            writeMatrix(&fWriter, matrix);
336acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
337bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
338bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::concat(matrix);
339bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
340bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
341bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::setMatrix(const SkMatrix& matrix) {
342acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
343acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(matrix.flatten(NULL))) {
344acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kSetMatrix_DrawOp);
345acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        writeMatrix(&fWriter, matrix);
346acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
347bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    this->INHERITED::setMatrix(matrix);
348bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
349bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
350bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::clipRect(const SkRect& rect, SkRegion::Op rgnOp) {
351acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
352acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(sizeof(SkRect))) {
353acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kClipRect_DrawOp, 0, rgnOp);
354acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.writeRect(rect);
355acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
356bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::clipRect(rect, rgnOp);
357bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
358bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
359bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::clipPath(const SkPath& path, SkRegion::Op rgnOp) {
360acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
361acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(estimateFlattenSize(path))) {
362acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kClipPath_DrawOp, 0, rgnOp);
363acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        path.flatten(fWriter);
364acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
365bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    // we just pass on the bounds of the path
366bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::clipRect(path.getBounds(), rgnOp);
367bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
368bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
369bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::clipRegion(const SkRegion& region, SkRegion::Op rgnOp) {
370acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
371acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(region.flatten(NULL))) {
372acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kClipRegion_DrawOp, 0, rgnOp);
373acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        writeRegion(&fWriter, region);
374acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
375bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::clipRegion(region, rgnOp);
376bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
377bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
378bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
379bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
380bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::clear(SkColor color) {
381acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
382bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    unsigned flags = 0;
383bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (color) {
384bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        flags |= kClear_HasColor_DrawOpFlag;
385bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
386acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(sizeof(SkColor))) {
387acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kDrawClear_DrawOp, flags, 0);
388acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (color) {
389acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(color);
390acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
391bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
392bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
393bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
394bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawPaint(const SkPaint& paint) {
395acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
396bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    unsigned paintIndex = this->writePaint(paint);
397acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes()) {
398acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kDrawPaint_DrawOp, 0, paintIndex);
399acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
400bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
401bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
402bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawPoints(PointMode mode, size_t count,
403bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                   const SkPoint pts[], const SkPaint& paint) {
404bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (count) {
405acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
406bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        unsigned paintIndex = this->writePaint(paint);
407acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(4 + count * sizeof(SkPoint))) {
408acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kDrawPoints_DrawOp, mode, paintIndex);
409acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(count);
410acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write(pts, count * sizeof(SkPoint));
411acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
412bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
413bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
414bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
415bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
416acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
417bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    unsigned paintIndex = this->writePaint(paint);
418acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(sizeof(SkRect))) {
419acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kDrawRect_DrawOp, 0, paintIndex);
420acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.writeRect(rect);
421acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
422bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
423bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
424bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
425acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
426bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    unsigned paintIndex = this->writePaint(paint);
427acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(estimateFlattenSize(path))) {
428acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kDrawPath_DrawOp, 0, paintIndex);
429acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        path.flatten(fWriter);
430acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
431bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
432bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
433bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
434bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                   const SkPaint*) {
435bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    UNIMPLEMENTED
436bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
437bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
438bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawBitmapRect(const SkBitmap&, const SkIRect* src,
439bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                       const SkRect& dst, const SkPaint*) {
440bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    UNIMPLEMENTED
441bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
442bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
443bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
444bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                         const SkPaint*) {
445bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    UNIMPLEMENTED
446bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
447bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
448bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawSprite(const SkBitmap&, int left, int top,
449bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                   const SkPaint*) {
450bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    UNIMPLEMENTED
451bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
452bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
453bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawText(const void* text, size_t byteLength, SkScalar x,
454bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 SkScalar y, const SkPaint& paint) {
455bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (byteLength) {
456acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
457bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        unsigned paintIndex = this->writePaint(paint);
458acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(4 + SkAlign4(byteLength) + 2 * sizeof(SkScalar))) {
459acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kDrawText_DrawOp, 0, paintIndex);
460acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(byteLength);
461acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writePad(text, byteLength);
462acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(x);
463acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(y);
464acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
465bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
466bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
467bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
468bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawPosText(const void* text, size_t byteLength,
469bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                const SkPoint pos[], const SkPaint& paint) {
470bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (byteLength) {
471acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
472bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        unsigned paintIndex = this->writePaint(paint);
473bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        int count = paint.textToGlyphs(text, byteLength, NULL);
474acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(4 + SkAlign4(byteLength) + 4 + count * sizeof(SkPoint))) {
475acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kDrawPosText_DrawOp, 0, paintIndex);
476acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(byteLength);
477acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writePad(text, byteLength);
478acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(count);
479acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write(pos, count * sizeof(SkPoint));
480acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
481bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
482bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
483bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
484bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawPosTextH(const void* text, size_t byteLength,
485bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const SkScalar xpos[], SkScalar constY,
486bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const SkPaint& paint) {
487bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (byteLength) {
488acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
489bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        unsigned paintIndex = this->writePaint(paint);
490bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        int count = paint.textToGlyphs(text, byteLength, NULL);
491acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(4 + SkAlign4(byteLength) + 4 + count * sizeof(SkScalar) + 4)) {
492acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kDrawPosTextH_DrawOp, 0, paintIndex);
493acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(byteLength);
494acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writePad(text, byteLength);
495acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(count);
496acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write(xpos, count * sizeof(SkScalar));
497acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(constY);
498acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
499bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
500bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
501bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
502bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawTextOnPath(const void* text, size_t byteLength,
503bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                   const SkPath& path, const SkMatrix* matrix,
504bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                   const SkPaint& paint) {
505bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (byteLength) {
506acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
507bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        unsigned flags = 0;
508acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        size_t size = 4 + SkAlign4(byteLength) + estimateFlattenSize(path);
509bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        if (matrix) {
510bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com            flags |= kDrawTextOnPath_HasMatrix_DrawOpFlag;
511acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            size += matrix->flatten(NULL);
512bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
513bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        unsigned paintIndex = this->writePaint(paint);
514acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(size)) {
515acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kDrawTextOnPath_DrawOp, flags, paintIndex);
516bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
517acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(byteLength);
518acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writePad(text, byteLength);
519bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
520acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            path.flatten(fWriter);
521acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            if (matrix) {
522acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com                writeMatrix(&fWriter, *matrix);
523acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            }
524bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
525bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
526bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
527bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
528bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawPicture(SkPicture& picture) {
529bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    UNIMPLEMENTED
530bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
531bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
532bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawShape(SkShape* shape) {
533bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    UNIMPLEMENTED
534bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
535bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
536bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawVertices(VertexMode mode, int vertexCount,
537bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const SkPoint vertices[], const SkPoint texs[],
538bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const SkColor colors[], SkXfermode*,
539bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const uint16_t indices[], int indexCount,
540bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const SkPaint& paint) {
541bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (0 == vertexCount) {
542bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        return;
543bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
544bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
545acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
546acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    size_t size = 4 + vertexCount * sizeof(SkPoint);
547bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    unsigned paintIndex = this->writePaint(paint);
548bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    unsigned flags = 0;
549bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (texs) {
550bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        flags |= kDrawVertices_HasTexs_DrawOpFlag;
551acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        size += vertexCount * sizeof(SkPoint);
552bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
553bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (colors) {
554bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        flags |= kDrawVertices_HasColors_DrawOpFlag;
555acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        size += vertexCount * sizeof(SkColor);
556bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
557bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (indices && indexCount > 0) {
558bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        flags |= kDrawVertices_HasIndices_DrawOpFlag;
559acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        size += 4 + SkAlign4(indexCount * sizeof(uint16_t));
560bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
561bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
562acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(size)) {
563acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kDrawVertices_DrawOp, flags, paintIndex);
564acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.write32(mode);
565acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.write32(vertexCount);
566acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.write(vertices, vertexCount * sizeof(SkPoint));
567acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (texs) {
568acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write(texs, vertexCount * sizeof(SkPoint));
569acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
570acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (colors) {
571acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write(colors, vertexCount * sizeof(SkColor));
572acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
573bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
574acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        // TODO: flatten xfermode
575bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
576acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (indices && indexCount > 0) {
577acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(indexCount);
578acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writePad(indices, indexCount * sizeof(uint16_t));
579acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
580bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
581bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
582bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
583acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.comvoid SkGPipeCanvas::drawData(const void* ptr, size_t size) {
584acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (size && ptr) {
585acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
586bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        unsigned data = 0;
587bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        if (size < (1 << DRAWOPS_DATA_BITS)) {
588bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com            data = (unsigned)size;
589bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
590acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(4 + SkAlign4(size))) {
591acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kDrawData_DrawOp, 0, data);
592acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            if (0 == data) {
593acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com                fWriter.write32(size);
594acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            }
595bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com            fWriter.writePad(ptr, size);
596bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
597bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
598bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
599bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
600bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
601bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
602bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comtemplate <typename T> uint32_t castToU32(T value) {
603bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    union {
604bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        T           fSrc;
605bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        uint32_t    fDst;
606bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    } data;
607bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    data.fSrc = value;
608bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return data.fDst;
609bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
610bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
611bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comunsigned SkGPipeCanvas::writePaint(const SkPaint& paint) {
612f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    SkPaint& base = *fPaints[0];
613bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    uint32_t storage[32];
614bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    uint32_t* ptr = storage;
615bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    uint32_t* last = NULL;
616bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
617bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getFlags() != paint.getFlags()) {
618bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        last = ptr;
619bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kFlags_PaintOp, paint.getFlags());
620f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setFlags(paint.getFlags());
621bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
622bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getColor() != paint.getColor()) {
623bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        last = ptr;
624bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kColor_PaintOp);
625bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = paint.getColor();
626f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setColor(paint.getColor());
627bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
628bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getStyle() != paint.getStyle()) {
629bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        last = ptr;
630bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kStyle_PaintOp, paint.getStyle());
631f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setStyle(paint.getStyle());
632bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
633bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getStrokeJoin() != paint.getStrokeJoin()) {
634bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        last = ptr;
635bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kJoin_PaintOp, paint.getStrokeJoin());
636f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setStrokeJoin(paint.getStrokeJoin());
637bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
638bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getStrokeCap() != paint.getStrokeCap()) {
639bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        last = ptr;
640bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kCap_PaintOp, paint.getStrokeCap());
641f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setStrokeCap(paint.getStrokeCap());
642bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
643bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getStrokeWidth() != paint.getStrokeWidth()) {
644bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        last = ptr;
645bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kWidth_PaintOp);
646bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = castToU32(paint.getStrokeWidth());
647f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setStrokeWidth(paint.getStrokeWidth());
648bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
649bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getStrokeMiter() != paint.getStrokeMiter()) {
650bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        last = ptr;
651bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kMiter_PaintOp);
652bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = castToU32(paint.getStrokeMiter());
653f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setStrokeMiter(paint.getStrokeMiter());
654bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
655bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getTextEncoding() != paint.getTextEncoding()) {
656bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        last = ptr;
657bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kEncoding_PaintOp, paint.getTextEncoding());
658f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTextEncoding(paint.getTextEncoding());
659bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
660bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getHinting() != paint.getHinting()) {
661bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        last = ptr;
662bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kHinting_PaintOp, paint.getHinting());
663f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setHinting(paint.getHinting());
664bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
665bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getTextAlign() != paint.getTextAlign()) {
666bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        last = ptr;
667bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kAlign_PaintOp, paint.getTextAlign());
668f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTextAlign(paint.getTextAlign());
669bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
670bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getTextSize() != paint.getTextSize()) {
671bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        last = ptr;
672bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kTextSize_PaintOp);
673bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = castToU32(paint.getTextSize());
674f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTextSize(paint.getTextSize());
675bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
676bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getTextScaleX() != paint.getTextScaleX()) {
677bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        last = ptr;
678bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kTextScaleX_PaintOp);
679bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = castToU32(paint.getTextScaleX());
680f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTextScaleX(paint.getTextScaleX());
681bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
682bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getTextSkewX() != paint.getTextSkewX()) {
683bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        last = ptr;
684bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kTextSkewX_PaintOp);
685bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = castToU32(paint.getTextSkewX());
686f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTextSkewX(paint.getTextSkewX());
687f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    }
688f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com
689f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    if (!SkTypeface::Equal(base.getTypeface(), paint.getTypeface())) {
690f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        uint32_t id = this->getTypefaceID(paint.getTypeface());
691f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        last = ptr;
692f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        *ptr++ = PaintOp_packOpData(kTypeface_PaintOp, id);
693f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTypeface(paint.getTypeface());
694bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
695bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
696acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    size_t size = (char*)ptr - (char*)storage;
697acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (size && this->needOpBytes(size)) {
698bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        this->writeOp(kPaintOp_DrawOp, 0, 0);
699bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        size_t size = (char*)ptr - (char*)storage;
700bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *last |= kLastOp_PaintOpFlag << PAINTOPS_DATA_BITS;
701bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        fWriter.write(storage, (char*)ptr - (char*)storage);
702bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        for (size_t i = 0; i < size/4; i++) {
703bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com            SkDebugf("[%d] %08X\n", i, storage[i]);
704bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
705bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
706bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return 0;
707bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
708bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
709bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
710bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
711bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com#include "SkGPipe.h"
712bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
713acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.comSkGPipeWriter::SkGPipeWriter() : fWriter(0) {
714bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    fCanvas = NULL;
715bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
716bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
717bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comSkGPipeWriter::~SkGPipeWriter() {
718acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    this->endRecording();
719bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    SkSafeUnref(fCanvas);
720bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
721bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
722acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.comSkCanvas* SkGPipeWriter::startRecording(SkGPipeController* controller) {
723bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (NULL == fCanvas) {
724acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.reset(NULL, 0);
725acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fCanvas = SkNEW_ARGS(SkGPipeCanvas, (controller, &fWriter));
726bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
727bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return fCanvas;
728bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
729bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
730bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeWriter::endRecording() {
731bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (fCanvas) {
732bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        fCanvas->finish();
733bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        fCanvas->unref();
734bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        fCanvas = NULL;
735bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
736bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
737bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
738