SkPicturePlayback.h revision 306ab9d5de38f2a547fd1d69aedbe69b5c6617cc
1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8#ifndef SkPicturePlayback_DEFINED
9#define SkPicturePlayback_DEFINED
10
11#include "SkPicture.h"
12#include "SkReader32.h"
13
14#include "SkBitmap.h"
15#include "SkData.h"
16#include "SkMatrix.h"
17#include "SkOrderedReadBuffer.h"
18#include "SkPaint.h"
19#include "SkPath.h"
20#include "SkPathHeap.h"
21#include "SkRegion.h"
22#include "SkRRect.h"
23#include "SkPictureFlat.h"
24#include "SkSerializationHelpers.h"
25
26#ifdef SK_BUILD_FOR_ANDROID
27#include "SkThread.h"
28#endif
29
30class SkPictureRecord;
31class SkStream;
32class SkWStream;
33class SkBBoxHierarchy;
34class SkPictureStateTree;
35
36struct SkPictInfo {
37    enum Flags {
38        kCrossProcess_Flag      = 1 << 0,
39        kScalarIsFloat_Flag     = 1 << 1,
40        kPtrIs64Bit_Flag        = 1 << 2,
41    };
42
43    uint32_t    fVersion;
44    uint32_t    fWidth;
45    uint32_t    fHeight;
46    uint32_t    fFlags;
47};
48
49/**
50 * Container for data that is needed to deep copy a SkPicture. The container
51 * enables the data to be generated once and reused for subsequent copies.
52 */
53struct SkPictCopyInfo {
54    SkPictCopyInfo() : initialized(false), controller(1024) {}
55
56    bool initialized;
57    SkChunkFlatController controller;
58    SkTDArray<SkFlatData*> paintData;
59};
60
61class SkPicturePlayback {
62public:
63    SkPicturePlayback();
64    SkPicturePlayback(const SkPicturePlayback& src, SkPictCopyInfo* deepCopyInfo = NULL);
65    explicit SkPicturePlayback(const SkPictureRecord& record, bool deepCopy = false);
66    SkPicturePlayback(SkStream*, const SkPictInfo&, bool* isValid,
67                      SkSerializationHelpers::DecodeBitmap decoder);
68
69    virtual ~SkPicturePlayback();
70
71    void draw(SkCanvas& canvas);
72
73    void serialize(SkWStream*, SkSerializationHelpers::EncodeBitmap) const;
74
75    void dumpSize() const;
76
77    // Can be called in the middle of playback (the draw() call). WIll abort the
78    // drawing and return from draw() after the "current" op code is done
79    void abort();
80
81protected:
82#ifdef SK_PICTURE_PROFILING_STUBS
83    virtual size_t preDraw(size_t offset, int type);
84    virtual void postDraw(size_t offset);
85#endif
86
87private:
88    class TextContainer {
89    public:
90        size_t length() { return fByteLength; }
91        const void* text() { return (const void*) fText; }
92        size_t fByteLength;
93        const char* fText;
94    };
95
96    const SkBitmap& getBitmap(SkReader32& reader) {
97        const int index = reader.readInt();
98        if (SkBitmapHeap::INVALID_SLOT == index) {
99            SkDebugf("An invalid bitmap was recorded!\n");
100            return fBadBitmap;
101        }
102        return (*fBitmaps)[index];
103    }
104
105    const SkMatrix* getMatrix(SkReader32& reader) {
106        int index = reader.readInt();
107        if (index == 0) {
108            return NULL;
109        }
110        return &(*fMatrices)[index - 1];
111    }
112
113    const SkPath& getPath(SkReader32& reader) {
114        return (*fPathHeap)[reader.readInt() - 1];
115    }
116
117    SkPicture& getPicture(SkReader32& reader) {
118        int index = reader.readInt();
119        SkASSERT(index > 0 && index <= fPictureCount);
120        return *fPictureRefs[index - 1];
121    }
122
123    const SkPaint* getPaint(SkReader32& reader) {
124        int index = reader.readInt();
125        if (index == 0) {
126            return NULL;
127        }
128        return &(*fPaints)[index - 1];
129    }
130
131    const SkRect* getRectPtr(SkReader32& reader) {
132        if (reader.readBool()) {
133            return &reader.skipT<SkRect>();
134        } else {
135            return NULL;
136        }
137    }
138
139    const SkIRect* getIRectPtr(SkReader32& reader) {
140        if (reader.readBool()) {
141            return &reader.skipT<SkIRect>();
142        } else {
143            return NULL;
144        }
145    }
146
147    const SkRegion& getRegion(SkReader32& reader) {
148        int index = reader.readInt();
149        return (*fRegions)[index - 1];
150    }
151
152    void getText(SkReader32& reader, TextContainer* text) {
153        size_t length = text->fByteLength = reader.readInt();
154        text->fText = (const char*)reader.skip(length);
155    }
156
157    void init();
158
159#ifdef SK_DEBUG_SIZE
160public:
161    int size(size_t* sizePtr);
162    int bitmaps(size_t* size);
163    int paints(size_t* size);
164    int paths(size_t* size);
165    int regions(size_t* size);
166#endif
167
168#ifdef SK_DEBUG_DUMP
169private:
170    void dumpBitmap(const SkBitmap& bitmap) const;
171    void dumpMatrix(const SkMatrix& matrix) const;
172    void dumpPaint(const SkPaint& paint) const;
173    void dumpPath(const SkPath& path) const;
174    void dumpPicture(const SkPicture& picture) const;
175    void dumpRegion(const SkRegion& region) const;
176    int dumpDrawType(char* bufferPtr, char* buffer, DrawType drawType);
177    int dumpInt(char* bufferPtr, char* buffer, char* name);
178    int dumpRect(char* bufferPtr, char* buffer, char* name);
179    int dumpPoint(char* bufferPtr, char* buffer, char* name);
180    void dumpPointArray(char** bufferPtrPtr, char* buffer, int count);
181    int dumpPtr(char* bufferPtr, char* buffer, char* name, void* ptr);
182    int dumpRectPtr(char* bufferPtr, char* buffer, char* name);
183    int dumpScalar(char* bufferPtr, char* buffer, char* name);
184    void dumpText(char** bufferPtrPtr, char* buffer);
185    void dumpStream();
186
187public:
188    void dump() const;
189#endif
190
191private:    // these help us with reading/writing
192    bool parseStreamTag(SkStream*, const SkPictInfo&, uint32_t tag, size_t size,
193                        SkSerializationHelpers::DecodeBitmap decoder);
194    bool parseBufferTag(SkOrderedReadBuffer&, uint32_t tag, size_t size);
195    void flattenToBuffer(SkOrderedWriteBuffer&) const;
196
197private:
198    // Only used by getBitmap() if the passed in index is SkBitmapHeap::INVALID_SLOT. This empty
199    // bitmap allows playback to draw nothing and move on.
200    SkBitmap fBadBitmap;
201
202    SkAutoTUnref<SkBitmapHeap> fBitmapHeap;
203    SkAutoTUnref<SkPathHeap> fPathHeap;
204
205    SkTRefArray<SkBitmap>* fBitmaps;
206    SkTRefArray<SkMatrix>* fMatrices;
207    SkTRefArray<SkPaint>* fPaints;
208    SkTRefArray<SkRegion>* fRegions;
209
210    SkData* fOpData;    // opcodes and parameters
211
212    SkPicture** fPictureRefs;
213    int fPictureCount;
214
215    SkBBoxHierarchy* fBoundingHierarchy;
216    SkPictureStateTree* fStateTree;
217
218    SkTypefacePlayback fTFPlayback;
219    SkFactoryPlayback* fFactoryPlayback;
220#ifdef SK_BUILD_FOR_ANDROID
221    SkMutex fDrawMutex;
222#endif
223};
224
225#endif
226