blob: 554ffc035a66f647ae7ddd5df91c0658d2406522 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@android.com8a1c16f2008-12-17 15:59:43 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#ifndef SkFlattenable_DEFINED
11#define SkFlattenable_DEFINED
12
13#include "SkRefCnt.h"
14#include "SkBitmap.h"
15#include "SkReader32.h"
16#include "SkTDArray.h"
17#include "SkWriter32.h"
18
19class SkFlattenableReadBuffer;
20class SkFlattenableWriteBuffer;
21class SkString;
22
caryclark@google.comd26147a2011-12-15 14:16:43 +000023#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
24
caryclark@google.comd26147a2011-12-15 14:16:43 +000025#define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable) \
26 static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \
djsollen@google.coma2ca41e2012-03-23 19:00:34 +000027 flattenable::CreateProc);
caryclark@google.comd26147a2011-12-15 14:16:43 +000028#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
29 static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \
djsollen@google.coma2ca41e2012-03-23 19:00:34 +000030 flattenable::CreateProc);
31
32#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
33#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable)
caryclark@google.comd26147a2011-12-15 14:16:43 +000034#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
35
36#else
37
djsollen@google.coma2ca41e2012-03-23 19:00:34 +000038#define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable)
caryclark@google.comd26147a2011-12-15 14:16:43 +000039#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
40 SkFlattenable::Registrar(#flattenable, flattenable::CreateProc);
djsollen@google.coma2ca41e2012-03-23 19:00:34 +000041
42#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables();
43
44#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \
45 void flattenable::InitializeFlattenables() {
46
caryclark@google.comd26147a2011-12-15 14:16:43 +000047#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \
48 }
49
50#endif
51
djsollen@google.comba28d032012-03-26 17:57:35 +000052#define SK_DECLARE_UNFLATTENABLE_OBJECT() \
53 virtual Factory getFactory() SK_OVERRIDE { return NULL; }; \
54
55#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \
56 virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }; \
57 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { \
58 return SkNEW_ARGS(flattenable, (buffer)); \
59 }
60
reed@android.com8a1c16f2008-12-17 15:59:43 +000061/** \class SkFlattenable
62
63 SkFlattenable is the base class for objects that need to be flattened
64 into a data stream for either transport or as part of the key to the
65 font cache.
66 */
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +000067class SK_API SkFlattenable : public SkRefCnt {
reed@android.com8a1c16f2008-12-17 15:59:43 +000068public:
69 typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&);
70
71 SkFlattenable() {}
72
73 /** Implement this to return a factory function pointer that can be called
74 to recreate your class given a buffer (previously written to by your
75 override of flatten().
76 */
77 virtual Factory getFactory() = 0;
78 /** Override this to write data specific to your subclass into the buffer,
79 being sure to call your super-class' version first. This data will later
80 be passed to your Factory function, returned by getFactory().
81 */
82 virtual void flatten(SkFlattenableWriteBuffer&);
83
reed@android.com8a1c16f2008-12-17 15:59:43 +000084 static Factory NameToFactory(const char name[]);
85 static const char* FactoryToName(Factory);
86 static void Register(const char name[], Factory);
djsollen@google.coma2ca41e2012-03-23 19:00:34 +000087
reed@android.com8a1c16f2008-12-17 15:59:43 +000088 class Registrar {
89 public:
90 Registrar(const char name[], Factory factory) {
91 SkFlattenable::Register(name, factory);
92 }
93 };
djsollen@google.coma2ca41e2012-03-23 19:00:34 +000094
reed@android.com8a1c16f2008-12-17 15:59:43 +000095protected:
96 SkFlattenable(SkFlattenableReadBuffer&) {}
caryclark@google.comd26147a2011-12-15 14:16:43 +000097
98private:
99#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
100 static void InitializeFlattenables();
101#endif
caryclark@google.com9d0c6ec2011-12-20 20:26:56 +0000102
103 friend class SkGraphics;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000104};
105
reed@google.comf2eb5ab2011-05-10 22:56:42 +0000106// helpers for matrix and region
107
108class SkMatrix;
109extern void SkReadMatrix(SkReader32*, SkMatrix*);
110extern void SkWriteMatrix(SkWriter32*, const SkMatrix&);
111
112class SkRegion;
113extern void SkReadRegion(SkReader32*, SkRegion*);
114extern void SkWriteRegion(SkWriter32*, const SkRegion&);
115
reed@android.com8a1c16f2008-12-17 15:59:43 +0000116///////////////////////////////////////////////////////////////////////////////
117///////////////////////////////////////////////////////////////////////////////
118
119class SkTypeface;
120
121class SkFlattenableReadBuffer : public SkReader32 {
122public:
123 SkFlattenableReadBuffer();
124 explicit SkFlattenableReadBuffer(const void* data);
125 SkFlattenableReadBuffer(const void* data, size_t size);
126
127 void setRefCntArray(SkRefCnt* array[], int count) {
128 fRCArray = array;
129 fRCCount = count;
130 }
131
132 void setTypefaceArray(SkTypeface* array[], int count) {
133 fTFArray = array;
134 fTFCount = count;
135 }
reed@google.com6bac9472011-06-21 19:24:00 +0000136
137 /**
138 * Call this with a pre-loaded array of Factories, in the same order as
139 * were created/written by the writer. SkPicture uses this.
140 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000141 void setFactoryPlayback(SkFlattenable::Factory array[], int count) {
reed@google.com6bac9472011-06-21 19:24:00 +0000142 fFactoryTDArray = NULL;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000143 fFactoryArray = array;
144 fFactoryCount = count;
145 }
reed@google.com6bac9472011-06-21 19:24:00 +0000146
147 /**
148 * Call this with an initially empty array, so the reader can cache each
149 * factory it sees by name. Used by the pipe code in conjunction with
150 * the writer's kInlineFactoryNames_Flag.
151 */
152 void setFactoryArray(SkTDArray<SkFlattenable::Factory>* array) {
153 fFactoryTDArray = array;
154 fFactoryArray = NULL;
155 fFactoryCount = 0;
156 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000157
158 SkTypeface* readTypeface();
159 SkRefCnt* readRefCnt();
160 void* readFunctionPtr();
161 SkFlattenable* readFlattenable();
162
163private:
164 SkRefCnt** fRCArray;
165 int fRCCount;
166
167 SkTypeface** fTFArray;
168 int fTFCount;
169
reed@google.com6bac9472011-06-21 19:24:00 +0000170 SkTDArray<SkFlattenable::Factory>* fFactoryTDArray;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000171 SkFlattenable::Factory* fFactoryArray;
172 int fFactoryCount;
173
174 typedef SkReader32 INHERITED;
175};
176
177///////////////////////////////////////////////////////////////////////////////
178
179#include "SkPtrRecorder.h"
180
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +0000181/**
182 * Subclass of SkTPtrSet specialed to call ref() and unref() when the
183 * base class's incPtr() and decPtr() are called. This makes it a valid owner
184 * of each ptr, which is released when the set is reset or destroyed.
185 */
186class SkRefCntSet : public SkTPtrSet<SkRefCnt*> {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000187public:
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +0000188 virtual ~SkRefCntSet();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000189
reed@android.com8a1c16f2008-12-17 15:59:43 +0000190protected:
191 // overrides
192 virtual void incPtr(void*);
193 virtual void decPtr(void*);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000194};
195
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +0000196class SkFactorySet : public SkTPtrSet<SkFlattenable::Factory> {};
reed@android.com8a1c16f2008-12-17 15:59:43 +0000197
198class SkFlattenableWriteBuffer : public SkWriter32 {
199public:
200 SkFlattenableWriteBuffer(size_t minSize);
201 virtual ~SkFlattenableWriteBuffer();
202
203 void writeTypeface(SkTypeface*);
204 void writeRefCnt(SkRefCnt*);
205 void writeFunctionPtr(void*);
206 void writeFlattenable(SkFlattenable* flattenable);
207
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +0000208 SkRefCntSet* getTypefaceRecorder() const { return fTFSet; }
209 SkRefCntSet* setTypefaceRecorder(SkRefCntSet*);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000210
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +0000211 SkRefCntSet* getRefCntRecorder() const { return fRCSet; }
212 SkRefCntSet* setRefCntRecorder(SkRefCntSet*);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000213
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +0000214 SkFactorySet* getFactoryRecorder() const { return fFactorySet; }
215 SkFactorySet* setFactoryRecorder(SkFactorySet*);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000216
217 enum Flags {
reed@google.com6bac9472011-06-21 19:24:00 +0000218 kCrossProcess_Flag = 0x01,
219 /**
220 * Instructs the writer to inline Factory names as there are seen the
221 * first time (after that we store an index). The pipe code uses this.
222 */
223 kInlineFactoryNames_Flag = 0x02,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000224 };
reed@google.com6bac9472011-06-21 19:24:00 +0000225 Flags getFlags() const { return (Flags)fFlags; }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000226 void setFlags(Flags flags) { fFlags = flags; }
227
reed@google.com6bac9472011-06-21 19:24:00 +0000228 bool isCrossProcess() const {
229 return SkToBool(fFlags & kCrossProcess_Flag);
230 }
231 bool inlineFactoryNames() const {
232 return SkToBool(fFlags & kInlineFactoryNames_Flag);
233 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000234
235 bool persistBitmapPixels() const {
236 return (fFlags & kCrossProcess_Flag) != 0;
237 }
238
239 bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; }
240
241private:
reed@google.com6bac9472011-06-21 19:24:00 +0000242 uint32_t fFlags;
243 SkRefCntSet* fTFSet;
244 SkRefCntSet* fRCSet;
245 SkFactorySet* fFactorySet;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000246
247 typedef SkWriter32 INHERITED;
248};
249
250#endif
251