SkPictureRecord.h revision af641a1c10f176cb9617026d3cc93c117a85d13d
1/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkPictureRecord_DEFINED
9#define SkPictureRecord_DEFINED
10
11#include "SkCanvas.h"
12#include "SkFlattenable.h"
13#include "SkPicture.h"
14#include "SkPictureData.h"
15#include "SkTemplates.h"
16#include "SkWriter32.h"
17
18// These macros help with packing and unpacking a single byte value and
19// a 3 byte value into/out of a uint32_t
20#define MASK_24 0x00FFFFFF
21#define UNPACK_8_24(combined, small, large)             \
22    small = (combined >> 24) & 0xFF;                    \
23    large = combined & MASK_24;
24#define PACK_8_24(small, large) ((small << 24) | large)
25
26
27class SkPictureRecord : public SkCanvas {
28public:
29    SkPictureRecord(const SkISize& dimensions, uint32_t recordFlags);
30    virtual ~SkPictureRecord();
31
32    virtual void clear(SkColor) SK_OVERRIDE;
33    virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
34    virtual void drawPoints(PointMode, size_t count, const SkPoint pts[],
35                            const SkPaint&) SK_OVERRIDE;
36    virtual void drawOval(const SkRect&, const SkPaint&) SK_OVERRIDE;
37    virtual void drawRect(const SkRect&, const SkPaint&) SK_OVERRIDE;
38    virtual void drawRRect(const SkRRect&, const SkPaint&) SK_OVERRIDE;
39    virtual void drawPath(const SkPath& path, const SkPaint&) SK_OVERRIDE;
40    virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
41                            const SkPaint*) SK_OVERRIDE;
42    virtual void drawBitmapRectToRect(const SkBitmap&, const SkRect* src,
43                                      const SkRect& dst, const SkPaint* paint,
44                                      DrawBitmapRectFlags flags) SK_OVERRIDE;
45    virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
46                                  const SkPaint*) SK_OVERRIDE;
47    virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
48                                const SkRect& dst, const SkPaint*) SK_OVERRIDE;
49    virtual void drawSprite(const SkBitmap&, int left, int top,
50                            const SkPaint*) SK_OVERRIDE;
51    virtual void drawVertices(VertexMode, int vertexCount,
52                          const SkPoint vertices[], const SkPoint texs[],
53                          const SkColor colors[], SkXfermode*,
54                          const uint16_t indices[], int indexCount,
55                              const SkPaint&) SK_OVERRIDE;
56    virtual void drawData(const void*, size_t) SK_OVERRIDE;
57    virtual void beginCommentGroup(const char* description) SK_OVERRIDE;
58    virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE;
59    virtual void endCommentGroup() SK_OVERRIDE;
60    virtual bool isDrawingToLayer() const SK_OVERRIDE;
61
62    const SkTDArray<const SkPicture* >& getPictureRefs() const {
63        return fPictureRefs;
64    }
65
66    const SkTDArray<const SkTextBlob* >& getTextBlobRefs() const {
67        return fTextBlobRefs;
68    }
69
70    SkData* opData(bool deepCopy) const {
71        this->validate(fWriter.bytesWritten(), 0);
72
73        if (fWriter.bytesWritten() == 0) {
74            return SkData::NewEmpty();
75        }
76
77        if (deepCopy) {
78            return SkData::NewWithCopy(fWriter.contiguousArray(), fWriter.bytesWritten());
79        }
80
81        return fWriter.snapshotAsData();
82    }
83
84    const SkPictureContentInfo& contentInfo() const {
85        return fContentInfo;
86    }
87
88    void setFlags(uint32_t recordFlags) {
89        fRecordFlags = recordFlags;
90    }
91
92    const SkWriter32& writeStream() const {
93        return fWriter;
94    }
95
96    void beginRecording();
97    void endRecording();
98
99protected:
100    void addNoOp();
101
102private:
103    void handleOptimization(int opt);
104    size_t recordRestoreOffsetPlaceholder(SkRegion::Op);
105    void fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset);
106
107    SkTDArray<int32_t> fRestoreOffsetStack;
108    int fFirstSavedLayerIndex;
109    enum {
110        kNoSavedLayerIndex = -1
111    };
112
113    SkTDArray<uint32_t> fCullOffsetStack;
114
115    /*
116     * Write the 'drawType' operation and chunk size to the skp. 'size'
117     * can potentially be increased if the chunk size needs its own storage
118     * location (i.e., it overflows 24 bits).
119     * Returns the start offset of the chunk. This is the location at which
120     * the opcode & size are stored.
121     * TODO: since we are handing the size into here we could call reserve
122     * and then return a pointer to the memory storage. This could decrease
123     * allocation overhead but could lead to more wasted space (the tail
124     * end of blocks could go unused). Possibly add a second addDraw that
125     * operates in this manner.
126     */
127    size_t addDraw(DrawType drawType, size_t* size) {
128        size_t offset = fWriter.bytesWritten();
129
130        this->predrawNotify();
131        fContentInfo.addOperation();
132
133        SkASSERT(0 != *size);
134        SkASSERT(((uint8_t) drawType) == drawType);
135
136        if (0 != (*size & ~MASK_24) || *size == MASK_24) {
137            fWriter.writeInt(PACK_8_24(drawType, MASK_24));
138            *size += 1;
139            fWriter.writeInt(SkToU32(*size));
140        } else {
141            fWriter.writeInt(PACK_8_24(drawType, SkToU32(*size)));
142        }
143
144        return offset;
145    }
146
147    void addInt(int value) {
148        fWriter.writeInt(value);
149    }
150    void addScalar(SkScalar scalar) {
151        fWriter.writeScalar(scalar);
152    }
153
154    void addBitmap(const SkBitmap& bitmap);
155    void addMatrix(const SkMatrix& matrix);
156    void addPaint(const SkPaint& paint) { this->addPaintPtr(&paint); }
157    void addPaintPtr(const SkPaint* paint);
158    void addPatch(const SkPoint cubics[12]);
159    void addPath(const SkPath& path);
160    void addPicture(const SkPicture* picture);
161    void addPoint(const SkPoint& point);
162    void addPoints(const SkPoint pts[], int count);
163    void addRect(const SkRect& rect);
164    void addRectPtr(const SkRect* rect);
165    void addIRect(const SkIRect& rect);
166    void addIRectPtr(const SkIRect* rect);
167    void addRRect(const SkRRect&);
168    void addRegion(const SkRegion& region);
169    void addText(const void* text, size_t byteLength);
170    void addTextBlob(const SkTextBlob* blob);
171
172    int find(const SkBitmap& bitmap);
173
174protected:
175    void validate(size_t initialOffset, size_t size) const {
176        SkASSERT(fWriter.bytesWritten() == initialOffset + size);
177    }
178
179    virtual SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
180    const void* onPeekPixels(SkImageInfo*, size_t*) SK_OVERRIDE {
181        return NULL;
182    }
183
184    virtual void willSave() SK_OVERRIDE;
185    virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
186    virtual void willRestore() SK_OVERRIDE;
187
188    virtual void didConcat(const SkMatrix&) SK_OVERRIDE;
189    virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE;
190
191    virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE;
192    virtual void onPushCull(const SkRect&) SK_OVERRIDE;
193    virtual void onPopCull() SK_OVERRIDE;
194
195    virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
196                            const SkPaint&) SK_OVERRIDE;
197    virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
198                               const SkPaint&) SK_OVERRIDE;
199    virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
200                                SkScalar constY, const SkPaint&) SK_OVERRIDE;
201    virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
202                                  const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
203    virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
204                                const SkPaint& paint) SK_OVERRIDE;
205
206    virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
207                             const SkPoint texCoords[4], SkXfermode* xmode,
208                             const SkPaint& paint) SK_OVERRIDE;
209
210    virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
211    virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
212    virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
213    virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE;
214
215    virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
216
217    int addPathToHeap(const SkPath& path);  // does not write to ops stream
218
219    // These entry points allow the writing of matrices, clips, saves &
220    // restores to be deferred (e.g., if the MC state is being collapsed and
221    // only written out as needed).
222    void recordConcat(const SkMatrix& matrix);
223    void recordTranslate(const SkMatrix& matrix);
224    void recordScale(const SkMatrix& matrix);
225    size_t recordClipRect(const SkRect& rect, SkRegion::Op op, bool doAA);
226    size_t recordClipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA);
227    size_t recordClipPath(int pathID, SkRegion::Op op, bool doAA);
228    size_t recordClipRegion(const SkRegion& region, SkRegion::Op op);
229    void recordSave();
230    void recordSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags);
231    void recordRestore(bool fillInSkips = true);
232
233private:
234    SkPictureContentInfo fContentInfo;
235
236    SkTArray<SkBitmap> fBitmaps;
237    SkTArray<SkPaint>  fPaints;
238    SkTArray<SkPath>   fPaths;
239
240    SkWriter32 fWriter;
241
242    // we ref each item in these arrays
243    SkTDArray<const SkPicture*>  fPictureRefs;
244    SkTDArray<const SkTextBlob*> fTextBlobRefs;
245
246    uint32_t fRecordFlags;
247    int      fInitialSaveCount;
248
249    friend class SkPictureData;   // for SkPictureData's SkPictureRecord-based constructor
250
251    typedef SkCanvas INHERITED;
252};
253
254#endif
255