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