10b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc.
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
70b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger */
80b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
90b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkCanvas.h"
121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkData.h"
130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkDevice.h"
140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkPaint.h"
150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkGPipe.h"
160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkGPipePriv.h"
170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkStream.h"
180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkTSearch.h"
190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkTypeface.h"
200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkWriter32.h"
210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkColorFilter.h"
220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkDrawLooper.h"
230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkMaskFilter.h"
240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkRasterizer.h"
250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkShader.h"
260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic SkFlattenable* get_paintflat(const SkPaint& paint, unsigned paintFlat) {
280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkASSERT(paintFlat < kCount_PaintFlats);
290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    switch (paintFlat) {
300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        case kColorFilter_PaintFlat:    return paint.getColorFilter();
310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        case kDrawLooper_PaintFlat:     return paint.getLooper();
320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        case kMaskFilter_PaintFlat:     return paint.getMaskFilter();
330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        case kPathEffect_PaintFlat:     return paint.getPathEffect();
340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        case kRasterizer_PaintFlat:     return paint.getRasterizer();
350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        case kShader_PaintFlat:         return paint.getShader();
360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        case kXfermode_PaintFlat:       return paint.getXfermode();
370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkDEBUGFAIL("never gets here");
390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return NULL;
400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic size_t estimateFlattenSize(const SkPath& path) {
430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    int n = path.countPoints();
440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    size_t bytes = 3 * sizeof(int32_t);
450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    bytes += n * sizeof(SkPoint);
460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    bytes += SkAlign4(n + 2);    // verbs: add 2 for move/close extras
470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#ifdef SK_DEBUG
490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    {
500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkWriter32 writer(1024);
510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        path.flatten(writer);
520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkASSERT(writer.size() <= bytes);
530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#endif
550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return bytes;
560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic size_t writeTypeface(SkWriter32* writer, SkTypeface* typeface) {
590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkASSERT(typeface);
600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkDynamicMemoryWStream stream;
610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    typeface->serialize(&stream);
620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    size_t size = stream.getOffset();
630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (writer) {
640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        writer->write32(size);
651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkAutoDataUnref data(stream.copyToData());
661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        writer->write(data.data(), size);
670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return 4 + size;
690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerclass SkGPipeCanvas : public SkCanvas {
740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerpublic:
750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkGPipeCanvas(SkGPipeController*, SkWriter32*, SkFactorySet*);
760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual ~SkGPipeCanvas();
770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    void finish() {
790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (!fDone) {
801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (this->needOpBytes()) {
811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                this->writeOp(kDone_DrawOp);
821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                this->doNotify();
831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fDone = true;
850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // overrides from SkCanvas
890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual int save(SaveFlags);
900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual int saveLayer(const SkRect* bounds, const SkPaint*, SaveFlags);
910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void restore();
920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual bool translate(SkScalar dx, SkScalar dy);
930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual bool scale(SkScalar sx, SkScalar sy);
940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual bool rotate(SkScalar degrees);
950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual bool skew(SkScalar sx, SkScalar sy);
960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual bool concat(const SkMatrix& matrix);
970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void setMatrix(const SkMatrix& matrix);
980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual bool clipRect(const SkRect& rect, SkRegion::Op op);
990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual bool clipPath(const SkPath& path, SkRegion::Op op);
1000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual bool clipRegion(const SkRegion& region, SkRegion::Op op);
1010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void clear(SkColor);
1020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void drawPaint(const SkPaint& paint);
1030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void drawPoints(PointMode, size_t count, const SkPoint pts[],
1040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                            const SkPaint&);
1050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void drawRect(const SkRect& rect, const SkPaint&);
1060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void drawPath(const SkPath& path, const SkPaint&);
1070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
1080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                            const SkPaint*);
1090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void drawBitmapRect(const SkBitmap&, const SkIRect* src,
1100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                const SkRect& dst, const SkPaint*);
1110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
1120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                  const SkPaint*);
1130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void drawSprite(const SkBitmap&, int left, int top,
1140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                            const SkPaint*);
1154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    virtual void drawText(const void* text, size_t byteLength, SkScalar x,
1160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                          SkScalar y, const SkPaint&);
1174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    virtual void drawPosText(const void* text, size_t byteLength,
1180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                             const SkPoint pos[], const SkPaint&);
1190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void drawPosTextH(const void* text, size_t byteLength,
1200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                      const SkScalar xpos[], SkScalar constY, const SkPaint&);
1214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    virtual void drawTextOnPath(const void* text, size_t byteLength,
1224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                            const SkPath& path, const SkMatrix* matrix,
1230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                const SkPaint&);
1240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void drawPicture(SkPicture& picture);
1250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void drawVertices(VertexMode, int vertexCount,
1260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                          const SkPoint vertices[], const SkPoint texs[],
1270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                          const SkColor colors[], SkXfermode*,
1280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                          const uint16_t indices[], int indexCount,
1290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                              const SkPaint&);
1300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void drawData(const void*, size_t);
1310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerprivate:
1330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkFactorySet* fFactorySet;  // optional, only used if cross-process
1340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkGPipeController* fController;
1350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkWriter32& fWriter;
1360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    size_t      fBlockSize; // amount allocated for writer
1370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    size_t      fBytesNotified;
1380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    bool        fDone;
1390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkRefCntSet fTypefaceSet;
1410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    uint32_t getTypefaceID(SkTypeface*);
1430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    inline void writeOp(DrawOps op, unsigned flags, unsigned data) {
1450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fWriter.write32(DrawOp_packOpFlagData(op, flags, data));
1460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
1474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    inline void writeOp(DrawOps op) {
1490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fWriter.write32(DrawOp_packOpFlagData(op, 0, 0));
1500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
1510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    bool needOpBytes(size_t size = 0);
1530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    inline void doNotify() {
1550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (!fDone) {
1560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            size_t bytes = fWriter.size() - fBytesNotified;
1570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fController->notifyWritten(bytes);
1580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fBytesNotified += bytes;
1590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
1600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
1610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    struct FlatData {
1630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        uint32_t    fIndex; // always > 0
1640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        uint32_t    fSize;
1650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        void*       data() { return (char*)this + sizeof(*this); }
1674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        static int Compare(const FlatData* a, const FlatData* b) {
1690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            return memcmp(&a->fSize, &b->fSize, a->fSize + sizeof(a->fSize));
1700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
1710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    };
1720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkTDArray<FlatData*> fFlatArray;
1730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    int fCurrFlatIndex[kCount_PaintFlats];
1740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    int flattenToIndex(SkFlattenable* obj, PaintFlats);
1750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkPaint fPaint;
1770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    void writePaint(const SkPaint&);
1780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    class AutoPipeNotify {
1800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    public:
1810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        AutoPipeNotify(SkGPipeCanvas* canvas) : fCanvas(canvas) {}
1820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        ~AutoPipeNotify() { fCanvas->doNotify(); }
1830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    private:
1840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkGPipeCanvas* fCanvas;
1850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    };
1860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    friend class AutoPipeNotify;
1870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    typedef SkCanvas INHERITED;
1890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger};
1900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger// return 0 for NULL (or unflattenable obj), or index-base-1
1920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerint SkGPipeCanvas::flattenToIndex(SkFlattenable* obj, PaintFlats paintflat) {
1930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (NULL == obj) {
1940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        return 0;
1950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
1960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkFlattenableWriteBuffer tmpWriter(1024);
1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    tmpWriter.setFlags(SkFlattenableWriteBuffer::kInlineFactoryNames_Flag);
1990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    tmpWriter.setFactoryRecorder(fFactorySet);
2000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    tmpWriter.writeFlattenable(obj);
2020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    size_t len = tmpWriter.size();
2030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    size_t allocSize = len + sizeof(FlatData);
2040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkAutoSMalloc<1024> storage(allocSize);
2060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    FlatData* flat = (FlatData*)storage.get();
2070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    flat->fSize = len;
2080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    tmpWriter.flatten(flat->data());
2090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    int index = SkTSearch<FlatData>((const FlatData**)fFlatArray.begin(),
2110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                    fFlatArray.count(), flat, sizeof(flat),
2120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                    &FlatData::Compare);
2130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (index < 0) {
2140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        index = ~index;
2150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        FlatData* copy = (FlatData*)sk_malloc_throw(allocSize);
2160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        memcpy(copy, flat, allocSize);
2170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *fFlatArray.insert(index) = copy;
2180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        // call this after the insert, so that count() will have been grown
2190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        copy->fIndex = fFlatArray.count();
2200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger//        SkDebugf("--- add flattenable[%d] size=%d index=%d\n", paintflat, len, copy->fIndex);
2210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (this->needOpBytes(len)) {
2230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            this->writeOp(kDef_Flattenable_DrawOp, paintflat, copy->fIndex);
2240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.write(copy->data(), len);
2250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
2260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
2270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return fFlatArray[index]->fIndex;
2280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
2290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
2310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#define MIN_BLOCK_SIZE  (16 * 1024)
2330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2340b15698a8c76bb8abc1b555c1d91892669b4118fDerek SollenbergerSkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller,
2350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                             SkWriter32* writer, SkFactorySet* fset)
2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        : fWriter(*writer) {
2371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fFactorySet = fset;
2380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    fController = controller;
2390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    fDone = false;
2400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    fBlockSize = 0; // need first block from controller
2410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    sk_bzero(fCurrFlatIndex, sizeof(fCurrFlatIndex));
2420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // we need a device to limit our clip
2440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // should the caller give us the bounds?
2451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // We don't allocate pixels for the bitmap
2460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkBitmap bitmap;
2470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    bitmap.setConfig(SkBitmap::kARGB_8888_Config, 32767, 32767);
2481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkDevice* device = SkNEW_ARGS(SkDevice, (bitmap));
2490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    this->setDevice(device)->unref();
2500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
2510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2520b15698a8c76bb8abc1b555c1d91892669b4118fDerek SollenbergerSkGPipeCanvas::~SkGPipeCanvas() {
2530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    this->finish();
2540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    fFlatArray.freeAll();
2560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
2570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerbool SkGPipeCanvas::needOpBytes(size_t needed) {
2590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (fDone) {
2600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        return false;
2610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
2620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    needed += 4;  // size of DrawOp atom
2640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (fWriter.size() + needed > fBlockSize) {
2650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        void* block = fController->requestBlock(MIN_BLOCK_SIZE, &fBlockSize);
2660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (NULL == block) {
2670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fDone = true;
2680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            return false;
2690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
2700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fWriter.reset(block, fBlockSize);
2710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fBytesNotified = 0;
2720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
2730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return true;
2740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
2750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergeruint32_t SkGPipeCanvas::getTypefaceID(SkTypeface* face) {
2770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    uint32_t id = 0; // 0 means default/null typeface
2780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (face) {
2790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        id = fTypefaceSet.find(face);
2800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (0 == id) {
2810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            id = fTypefaceSet.add(face);
2820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            size_t size = writeTypeface(NULL, face);
2830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            if (this->needOpBytes(size)) {
2840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                this->writeOp(kDef_Typeface_DrawOp);
2850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                writeTypeface(&fWriter, face);
2860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            }
2870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
2880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
2890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return id;
2900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
2910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
2930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#define NOTIFY_SETUP(canvas)    \
2950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    AutoPipeNotify apn(canvas)
2960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerint SkGPipeCanvas::save(SaveFlags flags) {
2980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    NOTIFY_SETUP(this);
2990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (this->needOpBytes()) {
3000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writeOp(kSave_DrawOp, 0, flags);
3010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
3020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return this->INHERITED::save(flags);
3030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
3040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
3050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerint SkGPipeCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
3060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                             SaveFlags saveFlags) {
3070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    NOTIFY_SETUP(this);
3080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    size_t size = 0;
3090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    unsigned opFlags = 0;
3104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
3110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (bounds) {
3120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        opFlags |= kSaveLayer_HasBounds_DrawOpFlag;
3130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        size += sizeof(SkRect);
3140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
3150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (paint) {
3160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        opFlags |= kSaveLayer_HasPaint_DrawOpFlag;
3170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writePaint(*paint);
3180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
3190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
3200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (this->needOpBytes(size)) {
3210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writeOp(kSaveLayer_DrawOp, opFlags, saveFlags);
3220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (bounds) {
3230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writeRect(*bounds);
3240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
3250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
3264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
3270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // we just pass on the save, so we don't create a layer
3280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return this->INHERITED::save(saveFlags);
3290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
3300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
3310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeCanvas::restore() {
3320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    NOTIFY_SETUP(this);
3330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (this->needOpBytes()) {
3340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writeOp(kRestore_DrawOp);
3350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
3360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    this->INHERITED::restore();
3370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
3380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
3390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerbool SkGPipeCanvas::translate(SkScalar dx, SkScalar dy) {
3400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (dx || dy) {
3410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        NOTIFY_SETUP(this);
3420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (this->needOpBytes(2 * sizeof(SkScalar))) {
3430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            this->writeOp(kTranslate_DrawOp);
3440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writeScalar(dx);
3450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writeScalar(dy);
3460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
3470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
3480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return this->INHERITED::translate(dx, dy);
3490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
3500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
3510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerbool SkGPipeCanvas::scale(SkScalar sx, SkScalar sy) {
3520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (sx || sy) {
3530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        NOTIFY_SETUP(this);
3540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (this->needOpBytes(2 * sizeof(SkScalar))) {
3550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            this->writeOp(kScale_DrawOp);
3560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writeScalar(sx);
3570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writeScalar(sy);
3580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
3590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
3600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return this->INHERITED::scale(sx, sy);
3610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
3620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
3630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerbool SkGPipeCanvas::rotate(SkScalar degrees) {
3640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (degrees) {
3650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        NOTIFY_SETUP(this);
3660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (this->needOpBytes(sizeof(SkScalar))) {
3670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            this->writeOp(kRotate_DrawOp);
3680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writeScalar(degrees);
3690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
3700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
3710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return this->INHERITED::rotate(degrees);
3720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
3730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
3740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerbool SkGPipeCanvas::skew(SkScalar sx, SkScalar sy) {
3750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (sx || sy) {
3760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        NOTIFY_SETUP(this);
3770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (this->needOpBytes(2 * sizeof(SkScalar))) {
3780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            this->writeOp(kSkew_DrawOp);
3790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writeScalar(sx);
3800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writeScalar(sy);
3810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
3820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
3830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return this->INHERITED::skew(sx, sy);
3840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
3850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
3860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerbool SkGPipeCanvas::concat(const SkMatrix& matrix) {
3870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (!matrix.isIdentity()) {
3880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        NOTIFY_SETUP(this);
3890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (this->needOpBytes(matrix.flatten(NULL))) {
3900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            this->writeOp(kConcat_DrawOp);
3910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            SkWriteMatrix(&fWriter, matrix);
3920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
3930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
3940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return this->INHERITED::concat(matrix);
3950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
3960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
3970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeCanvas::setMatrix(const SkMatrix& matrix) {
3980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    NOTIFY_SETUP(this);
3990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (this->needOpBytes(matrix.flatten(NULL))) {
4000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writeOp(kSetMatrix_DrawOp);
4010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkWriteMatrix(&fWriter, matrix);
4020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
4030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    this->INHERITED::setMatrix(matrix);
4040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
4050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
4060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerbool SkGPipeCanvas::clipRect(const SkRect& rect, SkRegion::Op rgnOp) {
4070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    NOTIFY_SETUP(this);
4080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (this->needOpBytes(sizeof(SkRect))) {
4090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writeOp(kClipRect_DrawOp, 0, rgnOp);
4100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fWriter.writeRect(rect);
4110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
4120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return this->INHERITED::clipRect(rect, rgnOp);
4130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
4140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
4150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerbool SkGPipeCanvas::clipPath(const SkPath& path, SkRegion::Op rgnOp) {
4160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    NOTIFY_SETUP(this);
4170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (this->needOpBytes(estimateFlattenSize(path))) {
4180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writeOp(kClipPath_DrawOp, 0, rgnOp);
4190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        path.flatten(fWriter);
4200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
4210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // we just pass on the bounds of the path
4220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return this->INHERITED::clipRect(path.getBounds(), rgnOp);
4230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
4240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
4250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerbool SkGPipeCanvas::clipRegion(const SkRegion& region, SkRegion::Op rgnOp) {
4260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    NOTIFY_SETUP(this);
4270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (this->needOpBytes(region.flatten(NULL))) {
4280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writeOp(kClipRegion_DrawOp, 0, rgnOp);
4290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkWriteRegion(&fWriter, region);
4300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
4310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return this->INHERITED::clipRegion(region, rgnOp);
4320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
4330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
4340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
4350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
4360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeCanvas::clear(SkColor color) {
4370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    NOTIFY_SETUP(this);
4380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    unsigned flags = 0;
4390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (color) {
4400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        flags |= kClear_HasColor_DrawOpFlag;
4410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
4420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (this->needOpBytes(sizeof(SkColor))) {
4430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writeOp(kDrawClear_DrawOp, flags, 0);
4440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (color) {
4450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.write32(color);
4460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
4470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
4480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
4490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
4500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeCanvas::drawPaint(const SkPaint& paint) {
4510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    NOTIFY_SETUP(this);
4520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    this->writePaint(paint);
4530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (this->needOpBytes()) {
4540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writeOp(kDrawPaint_DrawOp);
4550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
4560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
4570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
4580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeCanvas::drawPoints(PointMode mode, size_t count,
4590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                   const SkPoint pts[], const SkPaint& paint) {
4600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (count) {
4610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        NOTIFY_SETUP(this);
4620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writePaint(paint);
4630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (this->needOpBytes(4 + count * sizeof(SkPoint))) {
4640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            this->writeOp(kDrawPoints_DrawOp, mode, 0);
4650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.write32(count);
4660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.write(pts, count * sizeof(SkPoint));
4670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
4680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
4690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
4700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
4710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
4720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    NOTIFY_SETUP(this);
4730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    this->writePaint(paint);
4740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (this->needOpBytes(sizeof(SkRect))) {
4750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writeOp(kDrawRect_DrawOp);
4760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fWriter.writeRect(rect);
4770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
4780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
4790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
4800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
4810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    NOTIFY_SETUP(this);
4820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    this->writePaint(paint);
4830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (this->needOpBytes(estimateFlattenSize(path))) {
4840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writeOp(kDrawPath_DrawOp);
4850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        path.flatten(fWriter);
4860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
4870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
4880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
4890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeCanvas::drawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
4900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                   const SkPaint*) {
4910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    UNIMPLEMENTED
4920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
4930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
4940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeCanvas::drawBitmapRect(const SkBitmap&, const SkIRect* src,
4950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                       const SkRect& dst, const SkPaint*) {
4960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    UNIMPLEMENTED
4970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
4980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
4990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeCanvas::drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
5000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                         const SkPaint*) {
5010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    UNIMPLEMENTED
5020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
5030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
5040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeCanvas::drawSprite(const SkBitmap&, int left, int top,
5050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                   const SkPaint*) {
5060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    UNIMPLEMENTED
5070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
5080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
5094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkGPipeCanvas::drawText(const void* text, size_t byteLength, SkScalar x,
5100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                 SkScalar y, const SkPaint& paint) {
5110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (byteLength) {
5120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        NOTIFY_SETUP(this);
5130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writePaint(paint);
5140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (this->needOpBytes(4 + SkAlign4(byteLength) + 2 * sizeof(SkScalar))) {
5150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            this->writeOp(kDrawText_DrawOp);
5160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.write32(byteLength);
5170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writePad(text, byteLength);
5180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writeScalar(x);
5190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writeScalar(y);
5200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
5210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
5220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
5230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
5244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkGPipeCanvas::drawPosText(const void* text, size_t byteLength,
5250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                const SkPoint pos[], const SkPaint& paint) {
5260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (byteLength) {
5270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        NOTIFY_SETUP(this);
5280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writePaint(paint);
5290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        int count = paint.textToGlyphs(text, byteLength, NULL);
5300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (this->needOpBytes(4 + SkAlign4(byteLength) + 4 + count * sizeof(SkPoint))) {
5310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            this->writeOp(kDrawPosText_DrawOp);
5320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.write32(byteLength);
5330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writePad(text, byteLength);
5340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.write32(count);
5350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.write(pos, count * sizeof(SkPoint));
5360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
5370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
5380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
5390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
5400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeCanvas::drawPosTextH(const void* text, size_t byteLength,
5410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                 const SkScalar xpos[], SkScalar constY,
5420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                 const SkPaint& paint) {
5430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (byteLength) {
5440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        NOTIFY_SETUP(this);
5450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writePaint(paint);
5460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        int count = paint.textToGlyphs(text, byteLength, NULL);
5470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (this->needOpBytes(4 + SkAlign4(byteLength) + 4 + count * sizeof(SkScalar) + 4)) {
5480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            this->writeOp(kDrawPosTextH_DrawOp);
5490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.write32(byteLength);
5500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writePad(text, byteLength);
5510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.write32(count);
5520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.write(xpos, count * sizeof(SkScalar));
5530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writeScalar(constY);
5540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
5550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
5560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
5570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
5584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkGPipeCanvas::drawTextOnPath(const void* text, size_t byteLength,
5594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                   const SkPath& path, const SkMatrix* matrix,
5600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                   const SkPaint& paint) {
5610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (byteLength) {
5620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        NOTIFY_SETUP(this);
5630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        unsigned flags = 0;
5640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        size_t size = 4 + SkAlign4(byteLength) + estimateFlattenSize(path);
5650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (matrix) {
5660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            flags |= kDrawTextOnPath_HasMatrix_DrawOpFlag;
5670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            size += matrix->flatten(NULL);
5680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
5690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writePaint(paint);
5700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (this->needOpBytes(size)) {
5710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            this->writeOp(kDrawTextOnPath_DrawOp, flags, 0);
5720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
5730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.write32(byteLength);
5740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writePad(text, byteLength);
5750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
5760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            path.flatten(fWriter);
5770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            if (matrix) {
5780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                SkWriteMatrix(&fWriter, *matrix);
5790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            }
5800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
5810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
5820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
5830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
5840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeCanvas::drawPicture(SkPicture& picture) {
5850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // we want to playback the picture into individual draw calls
5860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    this->INHERITED::drawPicture(picture);
5870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
5880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
5890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeCanvas::drawVertices(VertexMode mode, int vertexCount,
5900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                 const SkPoint vertices[], const SkPoint texs[],
5910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                 const SkColor colors[], SkXfermode*,
5920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                 const uint16_t indices[], int indexCount,
5930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                 const SkPaint& paint) {
5940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (0 == vertexCount) {
5950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        return;
5960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
5970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
5980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    NOTIFY_SETUP(this);
5990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    size_t size = 4 + vertexCount * sizeof(SkPoint);
6000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    this->writePaint(paint);
6010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    unsigned flags = 0;
6020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (texs) {
6030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        flags |= kDrawVertices_HasTexs_DrawOpFlag;
6040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        size += vertexCount * sizeof(SkPoint);
6050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
6060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (colors) {
6070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        flags |= kDrawVertices_HasColors_DrawOpFlag;
6080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        size += vertexCount * sizeof(SkColor);
6090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
6100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (indices && indexCount > 0) {
6110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        flags |= kDrawVertices_HasIndices_DrawOpFlag;
6120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        size += 4 + SkAlign4(indexCount * sizeof(uint16_t));
6130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
6144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
6150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (this->needOpBytes(size)) {
6160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writeOp(kDrawVertices_DrawOp, flags, 0);
6170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fWriter.write32(mode);
6180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fWriter.write32(vertexCount);
6190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fWriter.write(vertices, vertexCount * sizeof(SkPoint));
6200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (texs) {
6210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.write(texs, vertexCount * sizeof(SkPoint));
6220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
6230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (colors) {
6240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.write(colors, vertexCount * sizeof(SkColor));
6250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
6260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
6270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        // TODO: flatten xfermode
6280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
6290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (indices && indexCount > 0) {
6300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.write32(indexCount);
6310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writePad(indices, indexCount * sizeof(uint16_t));
6320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
6330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
6340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
6350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
6360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeCanvas::drawData(const void* ptr, size_t size) {
6370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (size && ptr) {
6380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        NOTIFY_SETUP(this);
6390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        unsigned data = 0;
6400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (size < (1 << DRAWOPS_DATA_BITS)) {
6410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            data = (unsigned)size;
6420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
6430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (this->needOpBytes(4 + SkAlign4(size))) {
6440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            this->writeOp(kDrawData_DrawOp, 0, data);
6450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            if (0 == data) {
6460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                fWriter.write32(size);
6470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            }
6480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fWriter.writePad(ptr, size);
6490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
6500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
6510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
6520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
6530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
6540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
6550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergertemplate <typename T> uint32_t castToU32(T value) {
6560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    union {
6570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        T           fSrc;
6580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        uint32_t    fDst;
6590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    } data;
6600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    data.fSrc = value;
6610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return data.fDst;
6620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
6630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
6640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeCanvas::writePaint(const SkPaint& paint) {
6650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkPaint& base = fPaint;
6660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    uint32_t storage[32];
6670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    uint32_t* ptr = storage;
6680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
6690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (base.getFlags() != paint.getFlags()) {
6700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = PaintOp_packOpData(kFlags_PaintOp, paint.getFlags());
6710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        base.setFlags(paint.getFlags());
6720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
6730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (base.getColor() != paint.getColor()) {
6740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = PaintOp_packOp(kColor_PaintOp);
6750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = paint.getColor();
6760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        base.setColor(paint.getColor());
6770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
6780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (base.getStyle() != paint.getStyle()) {
6790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = PaintOp_packOpData(kStyle_PaintOp, paint.getStyle());
6800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        base.setStyle(paint.getStyle());
6810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
6820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (base.getStrokeJoin() != paint.getStrokeJoin()) {
6830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = PaintOp_packOpData(kJoin_PaintOp, paint.getStrokeJoin());
6840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        base.setStrokeJoin(paint.getStrokeJoin());
6850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
6860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (base.getStrokeCap() != paint.getStrokeCap()) {
6870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = PaintOp_packOpData(kCap_PaintOp, paint.getStrokeCap());
6880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        base.setStrokeCap(paint.getStrokeCap());
6890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
6900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (base.getStrokeWidth() != paint.getStrokeWidth()) {
6910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = PaintOp_packOp(kWidth_PaintOp);
6920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = castToU32(paint.getStrokeWidth());
6930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        base.setStrokeWidth(paint.getStrokeWidth());
6940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
6950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (base.getStrokeMiter() != paint.getStrokeMiter()) {
6960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = PaintOp_packOp(kMiter_PaintOp);
6970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = castToU32(paint.getStrokeMiter());
6980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        base.setStrokeMiter(paint.getStrokeMiter());
6990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
7000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (base.getTextEncoding() != paint.getTextEncoding()) {
7010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = PaintOp_packOpData(kEncoding_PaintOp, paint.getTextEncoding());
7020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        base.setTextEncoding(paint.getTextEncoding());
7030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
7040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (base.getHinting() != paint.getHinting()) {
7050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = PaintOp_packOpData(kHinting_PaintOp, paint.getHinting());
7060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        base.setHinting(paint.getHinting());
7070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
7080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (base.getTextAlign() != paint.getTextAlign()) {
7090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = PaintOp_packOpData(kAlign_PaintOp, paint.getTextAlign());
7100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        base.setTextAlign(paint.getTextAlign());
7110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
7120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (base.getTextSize() != paint.getTextSize()) {
7130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = PaintOp_packOp(kTextSize_PaintOp);
7140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = castToU32(paint.getTextSize());
7150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        base.setTextSize(paint.getTextSize());
7160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
7170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (base.getTextScaleX() != paint.getTextScaleX()) {
7180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = PaintOp_packOp(kTextScaleX_PaintOp);
7190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = castToU32(paint.getTextScaleX());
7200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        base.setTextScaleX(paint.getTextScaleX());
7210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
7220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (base.getTextSkewX() != paint.getTextSkewX()) {
7230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = PaintOp_packOp(kTextSkewX_PaintOp);
7240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = castToU32(paint.getTextSkewX());
7250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        base.setTextSkewX(paint.getTextSkewX());
7260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
7270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
7280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (!SkTypeface::Equal(base.getTypeface(), paint.getTypeface())) {
7290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        uint32_t id = this->getTypefaceID(paint.getTypeface());
7300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = PaintOp_packOpData(kTypeface_PaintOp, id);
7310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        base.setTypeface(paint.getTypeface());
7320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
7330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
7340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    for (int i = 0; i < kCount_PaintFlats; i++) {
7350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        int index = this->flattenToIndex(get_paintflat(paint, i), (PaintFlats)i);
7360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkASSERT(index >= 0 && index <= fFlatArray.count());
7370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (index != fCurrFlatIndex[i]) {
7380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            *ptr++ = PaintOp_packOpFlagData(kFlatIndex_PaintOp, i, index);
7390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fCurrFlatIndex[i] = index;
7400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
7410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
7420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
7430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    size_t size = (char*)ptr - (char*)storage;
7440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (size && this->needOpBytes(size)) {
7450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        this->writeOp(kPaintOp_DrawOp, 0, size);
7460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fWriter.write(storage, size);
7470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        for (size_t i = 0; i < size/4; i++) {
7480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger//            SkDebugf("[%d] %08X\n", i, storage[i]);
7490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
7500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
7510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
7520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
7530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
7540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
7550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkGPipe.h"
7560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
7570b15698a8c76bb8abc1b555c1d91892669b4118fDerek SollenbergerSkGPipeWriter::SkGPipeWriter() : fWriter(0) {
7580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    fCanvas = NULL;
7590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
7600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
7610b15698a8c76bb8abc1b555c1d91892669b4118fDerek SollenbergerSkGPipeWriter::~SkGPipeWriter() {
7620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    this->endRecording();
7630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkSafeUnref(fCanvas);
7640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
7650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
7660b15698a8c76bb8abc1b555c1d91892669b4118fDerek SollenbergerSkCanvas* SkGPipeWriter::startRecording(SkGPipeController* controller,
7670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                        uint32_t flags) {
7680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (NULL == fCanvas) {
7690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fWriter.reset(NULL, 0);
7700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fFactorySet.reset();
7710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fCanvas = SkNEW_ARGS(SkGPipeCanvas, (controller, &fWriter,
7720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                             (flags & kCrossProcess_Flag) ?
7730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                                             &fFactorySet : NULL));
7740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
7750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return fCanvas;
7760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
7770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
7780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkGPipeWriter::endRecording() {
7790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (fCanvas) {
7800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fCanvas->finish();
7810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fCanvas->unref();
7820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fCanvas = NULL;
7830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
7840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
7850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
786