SkFlattenable.h revision 4bdfb8c9d6482a56c7212034a6f73046227ed023
1
2/*
3 * Copyright 2006 The Android Open Source Project
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
9
10#ifndef SkFlattenable_DEFINED
11#define SkFlattenable_DEFINED
12
13#include "SkRefCnt.h"
14#include "SkReader32.h"
15#include "SkTDArray.h"
16#include "SkWriter32.h"
17
18class SkBitmap;
19class SkFlattenableReadBuffer;
20class SkFlattenableWriteBuffer;
21class SkPath;
22struct SkPoint;
23class SkString;
24
25#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
26
27#define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable) \
28    static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \
29                                                       flattenable::CreateProc);
30#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
31    static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \
32                                                       flattenable::CreateProc);
33
34#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
35#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable)
36#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
37
38#else
39
40#define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable)
41#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
42        SkFlattenable::Registrar(#flattenable, flattenable::CreateProc);
43
44#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables();
45
46#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \
47    void flattenable::InitializeFlattenables() {
48
49#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \
50    }
51
52#endif
53
54#define SK_DECLARE_UNFLATTENABLE_OBJECT() \
55    virtual Factory getFactory() SK_OVERRIDE { return NULL; }; \
56
57#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \
58    virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }; \
59    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { \
60        return SkNEW_ARGS(flattenable, (buffer)); \
61    }
62
63/** \class SkFlattenable
64
65 SkFlattenable is the base class for objects that need to be flattened
66 into a data stream for either transport or as part of the key to the
67 font cache.
68 */
69class SK_API SkFlattenable : public SkRefCnt {
70public:
71    typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&);
72
73    SkFlattenable() {}
74
75    /** Implement this to return a factory function pointer that can be called
76     to recreate your class given a buffer (previously written to by your
77     override of flatten().
78     */
79    virtual Factory getFactory() = 0;
80
81    static Factory NameToFactory(const char name[]);
82    static const char* FactoryToName(Factory);
83    static void Register(const char name[], Factory);
84
85    class Registrar {
86    public:
87        Registrar(const char name[], Factory factory) {
88            SkFlattenable::Register(name, factory);
89        }
90    };
91
92protected:
93    SkFlattenable(SkFlattenableReadBuffer&) {}
94    /** Override this to write data specific to your subclass into the buffer,
95     being sure to call your super-class' version first. This data will later
96     be passed to your Factory function, returned by getFactory().
97     */
98    virtual void flatten(SkFlattenableWriteBuffer&) const;
99
100private:
101#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
102    static void InitializeFlattenables();
103#endif
104
105    friend class SkGraphics;
106    friend class SkFlattenableWriteBuffer;
107};
108
109// helpers for matrix and region
110
111class SkMatrix;
112extern void SkReadMatrix(SkReader32*, SkMatrix*);
113extern void SkWriteMatrix(SkWriter32*, const SkMatrix&);
114
115class SkRegion;
116extern void SkReadRegion(SkReader32*, SkRegion*);
117extern void SkWriteRegion(SkWriter32*, const SkRegion&);
118
119///////////////////////////////////////////////////////////////////////////////
120///////////////////////////////////////////////////////////////////////////////
121
122class SkTypeface;
123
124class SkFlattenableReadBuffer {
125public:
126    SkFlattenableReadBuffer();
127    virtual ~SkFlattenableReadBuffer() {}
128
129
130    virtual uint8_t readU8() = 0;
131    virtual uint16_t readU16() = 0;
132    virtual uint32_t readU32() = 0;
133    virtual void read(void* dst, size_t size) = 0;
134    virtual bool readBool() = 0;
135    virtual int32_t readInt() = 0;
136    virtual SkScalar readScalar() = 0;
137    virtual const void* skip(size_t size) = 0;
138
139    virtual int32_t readS32() { return readInt(); }
140    template <typename T> const T& skipT() {
141        SkASSERT(SkAlign4(sizeof(T)) == sizeof(T));
142        return *(const T*)this->skip(sizeof(T));
143    }
144
145    virtual void readMatrix(SkMatrix*) = 0;
146    virtual void readPath(SkPath*) = 0;
147    virtual void readPoint(SkPoint*) = 0;
148
149    // helper function for classes with const SkPoint members
150    SkPoint readPoint() {
151        SkPoint point;
152        this->readPoint(&point);
153        return point;
154    }
155
156    void setRefCntArray(SkRefCnt* array[], int count) {
157        fRCArray = array;
158        fRCCount = count;
159    }
160
161    void setTypefaceArray(SkTypeface* array[], int count) {
162        fTFArray = array;
163        fTFCount = count;
164    }
165
166    /**
167     *  Call this with a pre-loaded array of Factories, in the same order as
168     *  were created/written by the writer. SkPicture uses this.
169     */
170    void setFactoryPlayback(SkFlattenable::Factory array[], int count) {
171        fFactoryTDArray = NULL;
172        fFactoryArray = array;
173        fFactoryCount = count;
174    }
175
176    /**
177     *  Call this with an initially empty array, so the reader can cache each
178     *  factory it sees by name. Used by the pipe code in conjunction with
179     *  the writer's kInlineFactoryNames_Flag.
180     */
181    void setFactoryArray(SkTDArray<SkFlattenable::Factory>* array) {
182        fFactoryTDArray = array;
183        fFactoryArray = NULL;
184        fFactoryCount = 0;
185    }
186
187    virtual SkTypeface* readTypeface() = 0;
188    virtual SkRefCnt* readRefCnt() = 0;
189    virtual void* readFunctionPtr() = 0;
190    virtual SkFlattenable* readFlattenable() = 0;
191
192protected:
193    SkRefCnt** fRCArray;
194    int        fRCCount;
195
196    SkTypeface** fTFArray;
197    int        fTFCount;
198
199    SkTDArray<SkFlattenable::Factory>* fFactoryTDArray;
200    SkFlattenable::Factory* fFactoryArray;
201    int                     fFactoryCount;
202};
203
204///////////////////////////////////////////////////////////////////////////////
205
206#include "SkPtrRecorder.h"
207
208/**
209 *  Subclass of SkTPtrSet specialed to call ref() and unref() when the
210 *  base class's incPtr() and decPtr() are called. This makes it a valid owner
211 *  of each ptr, which is released when the set is reset or destroyed.
212 */
213class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
214public:
215    virtual ~SkRefCntSet();
216
217protected:
218    // overrides
219    virtual void incPtr(void*);
220    virtual void decPtr(void*);
221};
222
223class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {};
224
225class SkFlattenableWriteBuffer {
226public:
227    SkFlattenableWriteBuffer();
228    virtual ~SkFlattenableWriteBuffer();
229
230    // deprecated naming convention that will be removed after callers are updated
231    virtual bool writeBool(bool value) = 0;
232    virtual void writeInt(int32_t value) = 0;
233    virtual void write8(int32_t value) = 0;
234    virtual void write16(int32_t value) = 0;
235    virtual void write32(int32_t value) = 0;
236    virtual void writeScalar(SkScalar value) = 0;
237    virtual void writeMul4(const void* values, size_t size) = 0;
238
239    virtual void writePad(const void* src, size_t size) = 0;
240    virtual void writeString(const char* str, size_t len = (size_t)-1) = 0;
241    virtual uint32_t* reserve(size_t size) = 0;
242    virtual void flatten(void* dst) = 0;
243    virtual uint32_t size() = 0;
244    virtual void write(const void* values, size_t size) = 0;
245    virtual void writeRect(const SkRect& rect) = 0;
246    virtual size_t readFromStream(SkStream*, size_t length) = 0;
247
248    virtual void writeMatrix(const SkMatrix& matrix) = 0;
249    virtual void writePath(const SkPath& path) = 0;
250    virtual void writePoint(const SkPoint& point) = 0;
251
252    virtual bool writeToStream(SkWStream*) = 0;
253
254    virtual void writeFunctionPtr(void*)= 0;
255    virtual void writeFlattenable(SkFlattenable* flattenable)= 0;
256
257    void writeTypeface(SkTypeface*);
258    void writeRefCnt(SkRefCnt* obj);
259
260    SkRefCntSet* getTypefaceRecorder() const { return fTFSet; }
261    SkRefCntSet* setTypefaceRecorder(SkRefCntSet*);
262
263    SkRefCntSet* getRefCntRecorder() const { return fRCSet; }
264    SkRefCntSet* setRefCntRecorder(SkRefCntSet*);
265
266    SkFactorySet* getFactoryRecorder() const { return fFactorySet; }
267    SkFactorySet* setFactoryRecorder(SkFactorySet*);
268
269    enum Flags {
270        kCrossProcess_Flag               = 0x01,
271        /**
272         *  Instructs the writer to inline Factory names as there are seen the
273         *  first time (after that we store an index). The pipe code uses this.
274         */
275        kInlineFactoryNames_Flag         = 0x02,
276        /**
277         *  Instructs the writer to always serialize bitmap pixel data.
278         */
279        kForceFlattenBitmapPixels_Flag   = 0x04
280    };
281
282    uint32_t getFlags() const { return fFlags; }
283    void setFlags(uint32_t flags) { fFlags = flags; }
284
285    bool isCrossProcess() const {
286        return SkToBool(fFlags & kCrossProcess_Flag);
287    }
288    bool inlineFactoryNames() const {
289        return SkToBool(fFlags & kInlineFactoryNames_Flag);
290    }
291
292    bool persistBitmapPixels() const {
293        return (fFlags & (kCrossProcess_Flag | kForceFlattenBitmapPixels_Flag)) != 0;
294    }
295
296    bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; }
297
298protected:
299
300    // A helper function so that each subclass does not have to be a friend of
301    // SkFlattenable.
302    void flattenObject(SkFlattenable* obj, SkFlattenableWriteBuffer& buffer) {
303        obj->flatten(buffer);
304    }
305
306    uint32_t        fFlags;
307    SkRefCntSet*    fTFSet;
308    SkRefCntSet*    fRCSet;
309    SkFactorySet*   fFactorySet;
310};
311
312#endif
313
314