• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 SkPictureData_DEFINED
9 #define SkPictureData_DEFINED
10 
11 #include "SkBitmap.h"
12 #include "SkDrawable.h"
13 #include "SkPicture.h"
14 #include "SkPictureContentInfo.h"
15 #include "SkPictureFlat.h"
16 
17 class SkData;
18 class SkPictureRecord;
19 class SkPixelSerializer;
20 class SkReader32;
21 class SkStream;
22 class SkWStream;
23 class SkBBoxHierarchy;
24 class SkMatrix;
25 class SkPaint;
26 class SkPath;
27 class SkReadBuffer;
28 class SkTextBlob;
29 
30 struct SkPictInfo {
31     enum Flags {
32         kCrossProcess_Flag      = 1 << 0,
33         kScalarIsFloat_Flag     = 1 << 1,
34         kPtrIs64Bit_Flag        = 1 << 2,
35     };
36 
SkPictInfoSkPictInfo37     SkPictInfo() : fVersion(~0U) {}
38 
getVersionSkPictInfo39     uint32_t getVersion() const {
40         SkASSERT(fVersion != ~0U);
41         return fVersion;
42     }
43 
setVersionSkPictInfo44     void setVersion(uint32_t version) {
45         SkASSERT(version != ~0U);
46         fVersion = version;
47     }
48 
49 public:
50     char        fMagic[8];
51 private:
52     uint32_t    fVersion;
53 public:
54     SkRect      fCullRect;
55     uint32_t    fFlags;
56 };
57 
58 #define SK_PICT_READER_TAG     SkSetFourByteTag('r', 'e', 'a', 'd')
59 #define SK_PICT_FACTORY_TAG    SkSetFourByteTag('f', 'a', 'c', 't')
60 #define SK_PICT_TYPEFACE_TAG   SkSetFourByteTag('t', 'p', 'f', 'c')
61 #define SK_PICT_PICTURE_TAG    SkSetFourByteTag('p', 'c', 't', 'r')
62 #define SK_PICT_DRAWABLE_TAG   SkSetFourByteTag('d', 'r', 'a', 'w')
63 
64 // This tag specifies the size of the ReadBuffer, needed for the following tags
65 #define SK_PICT_BUFFER_SIZE_TAG     SkSetFourByteTag('a', 'r', 'a', 'y')
66 // these are all inside the ARRAYS tag
67 #define SK_PICT_BITMAP_BUFFER_TAG   SkSetFourByteTag('b', 't', 'm', 'p')
68 #define SK_PICT_PAINT_BUFFER_TAG    SkSetFourByteTag('p', 'n', 't', ' ')
69 #define SK_PICT_PATH_BUFFER_TAG     SkSetFourByteTag('p', 't', 'h', ' ')
70 #define SK_PICT_TEXTBLOB_BUFFER_TAG SkSetFourByteTag('b', 'l', 'o', 'b')
71 #define SK_PICT_VERTICES_BUFFER_TAG SkSetFourByteTag('v', 'e', 'r', 't')
72 #define SK_PICT_IMAGE_BUFFER_TAG    SkSetFourByteTag('i', 'm', 'a', 'g')
73 
74 // Always write this guy last (with no length field afterwards)
75 #define SK_PICT_EOF_TAG     SkSetFourByteTag('e', 'o', 'f', ' ')
76 
77 class SkPictureData {
78 public:
79     SkPictureData(const SkPictureRecord& record, const SkPictInfo&);
80     // Does not affect ownership of SkStream.
81     static SkPictureData* CreateFromStream(SkStream*,
82                                            const SkPictInfo&,
83                                            SkImageDeserializer*,
84                                            SkTypefacePlayback*);
85     static SkPictureData* CreateFromBuffer(SkReadBuffer&, const SkPictInfo&);
86 
87     virtual ~SkPictureData();
88 
89     void serialize(SkWStream*, SkPixelSerializer*, SkRefCntSet*) const;
90     void flatten(SkWriteBuffer&) const;
91 
92     bool containsBitmaps() const;
93 
hasText()94     bool hasText() const { return fContentInfo.hasText(); }
95 
opCount()96     int opCount() const { return fContentInfo.numOperations(); }
97 
opData()98     const sk_sp<SkData>& opData() const { return fOpData; }
99 
100 protected:
101     explicit SkPictureData(const SkPictInfo& info);
102 
103     // Does not affect ownership of SkStream.
104     bool parseStream(SkStream*, SkImageDeserializer*, SkTypefacePlayback*);
105     bool parseBuffer(SkReadBuffer& buffer);
106 
107 public:
getBitmapAsImage(SkReadBuffer * reader)108     const SkImage* getBitmapAsImage(SkReadBuffer* reader) const {
109         const int index = reader->readInt();
110         return reader->validateIndex(index, fBitmapImageCount) ? fBitmapImageRefs[index] : nullptr;
111     }
112 
getImage(SkReadBuffer * reader)113     const SkImage* getImage(SkReadBuffer* reader) const {
114         const int index = reader->readInt();
115         return reader->validateIndex(index, fImageCount) ? fImageRefs[index] : nullptr;
116     }
117 
getPath(SkReadBuffer * reader)118     const SkPath& getPath(SkReadBuffer* reader) const {
119         const int index = reader->readInt() - 1;
120         return reader->validateIndex(index, fPaths.count()) ? fPaths[index] : fEmptyPath;
121     }
122 
getPicture(SkReadBuffer * reader)123     const SkPicture* getPicture(SkReadBuffer* reader) const {
124         const int index = reader->readInt() - 1;
125         return reader->validateIndex(index, fPictureCount) ? fPictureRefs[index] : nullptr;
126     }
127 
getDrawable(SkReadBuffer * reader)128     SkDrawable* getDrawable(SkReadBuffer* reader) const {
129         int index = reader->readInt();
130         SkASSERT(index > 0 && index <= fDrawableCount);
131         return fDrawableRefs[index - 1];
132     }
133 
getPaint(SkReadBuffer * reader)134     const SkPaint* getPaint(SkReadBuffer* reader) const {
135         const int index = reader->readInt() - 1;
136         if (index == -1) {  // recorder wrote a zero for no paint (likely drawimage)
137             return nullptr;
138         }
139         return reader->validateIndex(index, fPaints.count()) ? &fPaints[index] : nullptr;
140     }
141 
getTextBlob(SkReadBuffer * reader)142     const SkTextBlob* getTextBlob(SkReadBuffer* reader) const {
143         const int index = reader->readInt() - 1;
144         return reader->validateIndex(index, fTextBlobCount) ? fTextBlobRefs[index] : nullptr;
145     }
146 
getVertices(SkReadBuffer * reader)147     const SkVertices* getVertices(SkReadBuffer* reader) const {
148         const int index = reader->readInt() - 1;
149         return reader->validateIndex(index, fVerticesCount) ? fVerticesRefs[index] : nullptr;
150     }
151 
152 #if SK_SUPPORT_GPU
153     /**
154      * sampleCount is the number of samples-per-pixel or zero if non-MSAA.
155      * It is defaulted to be zero.
156      */
157     bool suitableForGpuRasterization(GrContext* context, const char **reason,
158                                      int sampleCount = 0) const;
159 
160     /**
161      * Calls getRecommendedSampleCount with GrPixelConfig and dpi to calculate sampleCount
162      * and then calls the above version of suitableForGpuRasterization
163      */
164     bool suitableForGpuRasterization(GrContext* context, const char **reason,
165                                      GrPixelConfig config, SkScalar dpi) const;
166 
167     bool suitableForLayerOptimization() const;
168 #endif
169 
170 private:
171     void init();
172 
173     // these help us with reading/writing
174     // Does not affect ownership of SkStream.
175     bool parseStreamTag(SkStream*, uint32_t tag, uint32_t size,
176                         SkImageDeserializer*, SkTypefacePlayback*);
177     bool parseBufferTag(SkReadBuffer&, uint32_t tag, uint32_t size);
178     void flattenToBuffer(SkWriteBuffer&) const;
179 
180     SkTArray<SkPaint>  fPaints;
181     SkTArray<SkPath>   fPaths;
182 
183     sk_sp<SkData>   fOpData;    // opcodes and parameters
184 
185     const SkPath    fEmptyPath;
186     const SkBitmap  fEmptyBitmap;
187 
188     const SkPicture** fPictureRefs;
189     int fPictureCount;
190     SkDrawable** fDrawableRefs;
191     int fDrawableCount;
192     const SkTextBlob** fTextBlobRefs;
193     int fTextBlobCount;
194     const SkVertices** fVerticesRefs;
195     int fVerticesCount;
196     const SkImage** fImageRefs;
197     int fImageCount;
198     const SkImage** fBitmapImageRefs;
199     int fBitmapImageCount;
200 
201     SkPictureContentInfo fContentInfo;
202 
203     SkTypefacePlayback fTFPlayback;
204     SkFactoryPlayback* fFactoryPlayback;
205 
206     const SkPictInfo fInfo;
207 
208     static void WriteFactories(SkWStream* stream, const SkFactorySet& rec);
209     static void WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec);
210 
211     void initForPlayback() const;
212 };
213 
214 #endif
215