|
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 "SkReadBuffer.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 |
|
25 #ifdef SK_BUILD_FOR_ANDROID |
|
26 #include "SkThread.h" |
|
27 #endif |
|
28 |
|
29 class SkPictureRecord; |
|
30 class SkStream; |
|
31 class SkWStream; |
|
32 class SkBBoxHierarchy; |
|
33 class SkPictureStateTree; |
|
34 class SkOffsetTable; |
|
35 |
|
36 struct SkPictInfo { |
|
37 enum Flags { |
|
38 kCrossProcess_Flag = 1 << 0, |
|
39 kScalarIsFloat_Flag = 1 << 1, |
|
40 kPtrIs64Bit_Flag = 1 << 2, |
|
41 }; |
|
42 |
|
43 char fMagic[8]; |
|
44 uint32_t fVersion; |
|
45 uint32_t fWidth; |
|
46 uint32_t fHeight; |
|
47 uint32_t fFlags; |
|
48 }; |
|
49 |
|
50 #define SK_PICT_READER_TAG SkSetFourByteTag('r', 'e', 'a', 'd') |
|
51 #define SK_PICT_FACTORY_TAG SkSetFourByteTag('f', 'a', 'c', 't') |
|
52 #define SK_PICT_TYPEFACE_TAG SkSetFourByteTag('t', 'p', 'f', 'c') |
|
53 #define SK_PICT_PICTURE_TAG SkSetFourByteTag('p', 'c', 't', 'r') |
|
54 |
|
55 // This tag specifies the size of the ReadBuffer, needed for the following tags |
|
56 #define SK_PICT_BUFFER_SIZE_TAG SkSetFourByteTag('a', 'r', 'a', 'y') |
|
57 // these are all inside the ARRAYS tag |
|
58 #define SK_PICT_BITMAP_BUFFER_TAG SkSetFourByteTag('b', 't', 'm', 'p') |
|
59 #define SK_PICT_PAINT_BUFFER_TAG SkSetFourByteTag('p', 'n', 't', ' ') |
|
60 #define SK_PICT_PATH_BUFFER_TAG SkSetFourByteTag('p', 't', 'h', ' ') |
|
61 |
|
62 // Always write this guy last (with no length field afterwards) |
|
63 #define SK_PICT_EOF_TAG SkSetFourByteTag('e', 'o', 'f', ' ') |
|
64 |
|
65 /** |
|
66 * Container for data that is needed to deep copy a SkPicture. The container |
|
67 * enables the data to be generated once and reused for subsequent copies. |
|
68 */ |
|
69 struct SkPictCopyInfo { |
|
70 SkPictCopyInfo() : initialized(false), controller(1024) {} |
|
71 |
|
72 bool initialized; |
|
73 SkChunkFlatController controller; |
|
74 SkTDArray<SkFlatData*> paintData; |
|
75 }; |
|
76 |
|
77 class SkPicturePlayback { |
|
78 public: |
|
79 SkPicturePlayback(); |
|
80 SkPicturePlayback(const SkPicturePlayback& src, SkPictCopyInfo* deepCopyInfo = NULL); |
|
81 explicit SkPicturePlayback(const SkPictureRecord& record, bool deepCopy = false); |
|
82 static SkPicturePlayback* CreateFromStream(SkStream*, const SkPictInfo&, |
|
83 SkPicture::InstallPixelRefProc); |
|
84 static SkPicturePlayback* CreateFromBuffer(SkReadBuffer&); |
|
85 |
|
86 virtual ~SkPicturePlayback(); |
|
87 |
|
88 void draw(SkCanvas& canvas, SkDrawPictureCallback*); |
|
89 |
|
90 void serialize(SkWStream*, SkPicture::EncodeBitmap) const; |
|
91 void flatten(SkWriteBuffer&) const; |
|
92 |
|
93 void dumpSize() const; |
|
94 |
|
95 bool containsBitmaps() const; |
|
96 |
|
97 #ifdef SK_BUILD_FOR_ANDROID |
|
98 // Can be called in the middle of playback (the draw() call). WIll abort the |
|
99 // drawing and return from draw() after the "current" op code is done |
|
100 void abort() { fAbortCurrentPlayback = true; } |
|
101 #endif |
|
102 |
|
103 protected: |
|
104 bool parseStream(SkStream*, const SkPictInfo&, |
|
105 SkPicture::InstallPixelRefProc); |
|
106 bool parseBuffer(SkReadBuffer& buffer); |
|
107 #ifdef SK_DEVELOPER |
|
108 virtual bool preDraw(int opIndex, int type); |
|
109 virtual void postDraw(int opIndex); |
|
110 #endif |
|
111 |
|
112 void preLoadBitmaps(const SkTDArray<void*>& results); |
|
113 |
|
114 private: |
|
115 class TextContainer { |
|
116 public: |
|
117 size_t length() { return fByteLength; } |
|
118 const void* text() { return (const void*) fText; } |
|
119 size_t fByteLength; |
|
120 const char* fText; |
|
121 }; |
|
122 |
|
123 const SkBitmap& getBitmap(SkReader32& reader) { |
|
124 const int index = reader.readInt(); |
|
125 if (SkBitmapHeap::INVALID_SLOT == index) { |
|
126 #ifdef SK_DEBUG |
|
127 SkDebugf("An invalid bitmap was recorded!\n"); |
|
128 #endif |
|
129 return fBadBitmap; |
|
130 } |
|
131 return (*fBitmaps)[index]; |
|
132 } |
|
133 |
|
134 void getMatrix(SkReader32& reader, SkMatrix* matrix) { |
|
135 reader.readMatrix(matrix); |
|
136 } |
|
137 |
|
138 const SkPath& getPath(SkReader32& reader) { |
|
139 return (*fPathHeap)[reader.readInt() - 1]; |
|
140 } |
|
141 |
|
142 SkPicture& getPicture(SkReader32& reader) { |
|
143 int index = reader.readInt(); |
|
144 SkASSERT(index > 0 && index <= fPictureCount); |
|
145 return *fPictureRefs[index - 1]; |
|
146 } |
|
147 |
|
148 const SkPaint* getPaint(SkReader32& reader) { |
|
149 int index = reader.readInt(); |
|
150 if (index == 0) { |
|
151 return NULL; |
|
152 } |
|
153 return &(*fPaints)[index - 1]; |
|
154 } |
|
155 |
|
156 const SkRect* getRectPtr(SkReader32& reader) { |
|
157 if (reader.readBool()) { |
|
158 return &reader.skipT<SkRect>(); |
|
159 } else { |
|
160 return NULL; |
|
161 } |
|
162 } |
|
163 |
|
164 const SkIRect* getIRectPtr(SkReader32& reader) { |
|
165 if (reader.readBool()) { |
|
166 return &reader.skipT<SkIRect>(); |
|
167 } else { |
|
168 return NULL; |
|
169 } |
|
170 } |
|
171 |
|
172 void getRegion(SkReader32& reader, SkRegion* region) { |
|
173 reader.readRegion(region); |
|
174 } |
|
175 |
|
176 void getText(SkReader32& reader, TextContainer* text) { |
|
177 size_t length = text->fByteLength = reader.readInt(); |
|
178 text->fText = (const char*)reader.skip(length); |
|
179 } |
|
180 |
|
181 void init(); |
|
182 |
|
183 #ifdef SK_DEBUG_SIZE |
|
184 public: |
|
185 int size(size_t* sizePtr); |
|
186 int bitmaps(size_t* size); |
|
187 int paints(size_t* size); |
|
188 int paths(size_t* size); |
|
189 #endif |
|
190 |
|
191 #ifdef SK_DEBUG_DUMP |
|
192 private: |
|
193 void dumpBitmap(const SkBitmap& bitmap) const; |
|
194 void dumpMatrix(const SkMatrix& matrix) const; |
|
195 void dumpPaint(const SkPaint& paint) const; |
|
196 void dumpPath(const SkPath& path) const; |
|
197 void dumpPicture(const SkPicture& picture) const; |
|
198 void dumpRegion(const SkRegion& region) const; |
|
199 int dumpDrawType(char* bufferPtr, char* buffer, DrawType drawType); |
|
200 int dumpInt(char* bufferPtr, char* buffer, char* name); |
|
201 int dumpRect(char* bufferPtr, char* buffer, char* name); |
|
202 int dumpPoint(char* bufferPtr, char* buffer, char* name); |
|
203 void dumpPointArray(char** bufferPtrPtr, char* buffer, int count); |
|
204 int dumpPtr(char* bufferPtr, char* buffer, char* name, void* ptr); |
|
205 int dumpRectPtr(char* bufferPtr, char* buffer, char* name); |
|
206 int dumpScalar(char* bufferPtr, char* buffer, char* name); |
|
207 void dumpText(char** bufferPtrPtr, char* buffer); |
|
208 void dumpStream(); |
|
209 |
|
210 public: |
|
211 void dump() const; |
|
212 #endif |
|
213 |
|
214 private: // these help us with reading/writing |
|
215 bool parseStreamTag(SkStream*, const SkPictInfo&, uint32_t tag, size_t size, |
|
216 SkPicture::InstallPixelRefProc); |
|
217 bool parseBufferTag(SkReadBuffer&, uint32_t tag, size_t size); |
|
218 void flattenToBuffer(SkWriteBuffer&) const; |
|
219 |
|
220 private: |
|
221 // Only used by getBitmap() if the passed in index is SkBitmapHeap::INVALID_SLOT. This empty |
|
222 // bitmap allows playback to draw nothing and move on. |
|
223 SkBitmap fBadBitmap; |
|
224 |
|
225 SkAutoTUnref<SkBitmapHeap> fBitmapHeap; |
|
226 SkAutoTUnref<SkPathHeap> fPathHeap; |
|
227 |
|
228 SkTRefArray<SkBitmap>* fBitmaps; |
|
229 SkTRefArray<SkPaint>* fPaints; |
|
230 |
|
231 SkData* fOpData; // opcodes and parameters |
|
232 SkAutoTUnref<SkOffsetTable> fBitmapUseOffsets; |
|
233 |
|
234 SkPicture** fPictureRefs; |
|
235 int fPictureCount; |
|
236 |
|
237 SkBBoxHierarchy* fBoundingHierarchy; |
|
238 SkPictureStateTree* fStateTree; |
|
239 |
|
240 SkTypefacePlayback fTFPlayback; |
|
241 SkFactoryPlayback* fFactoryPlayback; |
|
242 #ifdef SK_BUILD_FOR_ANDROID |
|
243 SkMutex fDrawMutex; |
|
244 bool fAbortCurrentPlayback; |
|
245 #endif |
|
246 }; |
|
247 |
|
248 #endif |