/src/mozilla-central/gfx/2d/RecordedEvent.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef MOZILLA_GFX_RECORDEDEVENT_H_ |
8 | | #define MOZILLA_GFX_RECORDEDEVENT_H_ |
9 | | |
10 | | #include "2D.h" |
11 | | #include <ostream> |
12 | | #include <sstream> |
13 | | #include <cstring> |
14 | | #include <vector> |
15 | | |
16 | | namespace mozilla { |
17 | | namespace gfx { |
18 | | |
19 | | struct PathOp; |
20 | | class PathRecording; |
21 | | |
22 | | const uint32_t kMagicInt = 0xc001feed; |
23 | | |
24 | | // A change in major revision means a change in event binary format, causing |
25 | | // loss of backwards compatibility. Old streams will not work in a player |
26 | | // using a newer major revision. And new streams will not work in a player |
27 | | // using an older major revision. |
28 | | const uint16_t kMajorRevision = 10; |
29 | | // A change in minor revision means additions of new events. New streams will |
30 | | // not play in older players. |
31 | | const uint16_t kMinorRevision = 0; |
32 | | |
33 | | struct ReferencePtr |
34 | | { |
35 | | ReferencePtr() |
36 | | : mLongPtr(0) |
37 | 0 | {} |
38 | | |
39 | | MOZ_IMPLICIT ReferencePtr(const void* aLongPtr) |
40 | | : mLongPtr(uint64_t(aLongPtr)) |
41 | 0 | {} |
42 | | |
43 | | template <typename T> |
44 | | MOZ_IMPLICIT ReferencePtr(const RefPtr<T>& aPtr) |
45 | | : mLongPtr(uint64_t(aPtr.get())) |
46 | 0 | {} Unexecuted instantiation: mozilla::gfx::ReferencePtr::ReferencePtr<mozilla::gfx::PathRecording>(RefPtr<mozilla::gfx::PathRecording> const&) Unexecuted instantiation: mozilla::gfx::ReferencePtr::ReferencePtr<mozilla::gfx::SourceSurface>(RefPtr<mozilla::gfx::SourceSurface> const&) Unexecuted instantiation: mozilla::gfx::ReferencePtr::ReferencePtr<mozilla::gfx::FilterNode>(RefPtr<mozilla::gfx::FilterNode> const&) Unexecuted instantiation: mozilla::gfx::ReferencePtr::ReferencePtr<mozilla::gfx::GradientStops>(RefPtr<mozilla::gfx::GradientStops> const&) |
47 | | |
48 | 0 | ReferencePtr &operator =(const void* aLongPtr) { |
49 | 0 | mLongPtr = uint64_t(aLongPtr); |
50 | 0 | return *this; |
51 | 0 | } |
52 | | |
53 | | template <typename T> |
54 | 0 | ReferencePtr &operator =(const RefPtr<T>& aPtr) { |
55 | 0 | mLongPtr = uint64_t(aPtr.get()); |
56 | 0 | return *this; |
57 | 0 | } |
58 | | |
59 | 0 | operator void*() const { |
60 | 0 | return (void*)mLongPtr; |
61 | 0 | } |
62 | | |
63 | | uint64_t mLongPtr; |
64 | | }; |
65 | | |
66 | | struct RecordedFontDetails |
67 | | { |
68 | | uint64_t fontDataKey; |
69 | | uint32_t size; |
70 | | uint32_t index; |
71 | | }; |
72 | | |
73 | | // Used by the Azure drawing debugger (player2d) |
74 | | inline std::string StringFromPtr(ReferencePtr aPtr) |
75 | 0 | { |
76 | 0 | std::stringstream stream; |
77 | 0 | stream << aPtr; |
78 | 0 | return stream.str(); |
79 | 0 | } |
80 | | |
81 | | class Translator |
82 | | { |
83 | | public: |
84 | 0 | virtual ~Translator() {} |
85 | | |
86 | | virtual DrawTarget *LookupDrawTarget(ReferencePtr aRefPtr) = 0; |
87 | | virtual Path *LookupPath(ReferencePtr aRefPtr) = 0; |
88 | | virtual SourceSurface *LookupSourceSurface(ReferencePtr aRefPtr) = 0; |
89 | | virtual FilterNode *LookupFilterNode(ReferencePtr aRefPtr) = 0; |
90 | | virtual GradientStops *LookupGradientStops(ReferencePtr aRefPtr) = 0; |
91 | | virtual ScaledFont *LookupScaledFont(ReferencePtr aRefPtr) = 0; |
92 | | virtual UnscaledFont* LookupUnscaledFont(ReferencePtr aRefPtr) = 0; |
93 | | virtual NativeFontResource *LookupNativeFontResource(uint64_t aKey) = 0; |
94 | 0 | virtual already_AddRefed<SourceSurface> LookupExternalSurface(uint64_t aKey) { return nullptr; } |
95 | | virtual void AddDrawTarget(ReferencePtr aRefPtr, DrawTarget *aDT) = 0; |
96 | | virtual void RemoveDrawTarget(ReferencePtr aRefPtr) = 0; |
97 | | virtual void AddPath(ReferencePtr aRefPtr, Path *aPath) = 0; |
98 | | virtual void RemovePath(ReferencePtr aRefPtr) = 0; |
99 | | virtual void AddSourceSurface(ReferencePtr aRefPtr, SourceSurface *aPath) = 0; |
100 | | virtual void RemoveSourceSurface(ReferencePtr aRefPtr) = 0; |
101 | | virtual void AddFilterNode(mozilla::gfx::ReferencePtr aRefPtr, FilterNode *aSurface) = 0; |
102 | | virtual void RemoveFilterNode(mozilla::gfx::ReferencePtr aRefPtr) = 0; |
103 | | virtual void AddGradientStops(ReferencePtr aRefPtr, GradientStops *aPath) = 0; |
104 | | virtual void RemoveGradientStops(ReferencePtr aRefPtr) = 0; |
105 | | virtual void AddScaledFont(ReferencePtr aRefPtr, ScaledFont *aScaledFont) = 0; |
106 | | virtual void RemoveScaledFont(ReferencePtr aRefPtr) = 0; |
107 | | virtual void AddUnscaledFont(ReferencePtr aRefPtr, UnscaledFont* aUnscaledFont) = 0; |
108 | | virtual void RemoveUnscaledFont(ReferencePtr aRefPtr) = 0; |
109 | | virtual void AddNativeFontResource(uint64_t aKey, |
110 | | NativeFontResource *aNativeFontResource) = 0; |
111 | | |
112 | | virtual already_AddRefed<DrawTarget> CreateDrawTarget(ReferencePtr aRefPtr, |
113 | | const IntSize &aSize, |
114 | | SurfaceFormat aFormat); |
115 | | virtual DrawTarget *GetReferenceDrawTarget() = 0; |
116 | 0 | virtual void* GetFontContext() { return nullptr; } |
117 | | }; |
118 | | |
119 | | struct ColorPatternStorage |
120 | | { |
121 | | Color mColor; |
122 | | }; |
123 | | |
124 | | struct LinearGradientPatternStorage |
125 | | { |
126 | | Point mBegin; |
127 | | Point mEnd; |
128 | | ReferencePtr mStops; |
129 | | Matrix mMatrix; |
130 | | }; |
131 | | |
132 | | struct RadialGradientPatternStorage |
133 | | { |
134 | | Point mCenter1; |
135 | | Point mCenter2; |
136 | | Float mRadius1; |
137 | | Float mRadius2; |
138 | | ReferencePtr mStops; |
139 | | Matrix mMatrix; |
140 | | }; |
141 | | |
142 | | struct SurfacePatternStorage |
143 | | { |
144 | | ExtendMode mExtend; |
145 | | SamplingFilter mSamplingFilter; |
146 | | ReferencePtr mSurface; |
147 | | Matrix mMatrix; |
148 | | IntRect mSamplingRect; |
149 | | }; |
150 | | |
151 | | struct PatternStorage |
152 | | { |
153 | | PatternType mType; |
154 | | union { |
155 | | char *mStorage; |
156 | | char mColor[sizeof(ColorPatternStorage)]; |
157 | | char mLinear[sizeof(LinearGradientPatternStorage)]; |
158 | | char mRadial[sizeof(RadialGradientPatternStorage)]; |
159 | | char mSurface[sizeof(SurfacePatternStorage)]; |
160 | | }; |
161 | | }; |
162 | | |
163 | | |
164 | | /* SizeCollector and MemWriter are used |
165 | | * in a pair to first collect the size of the |
166 | | * event that we're going to write and then |
167 | | * to write it without checking each individual |
168 | | * size. */ |
169 | | struct SizeCollector { |
170 | 0 | SizeCollector() : mTotalSize(0) {} |
171 | 0 | void write(const char*, size_t s) { |
172 | 0 | mTotalSize += s; |
173 | 0 | } |
174 | | size_t mTotalSize; |
175 | | }; |
176 | | |
177 | | struct MemWriter { |
178 | 0 | explicit MemWriter(char* aPtr) : mPtr(aPtr) {} |
179 | 0 | void write(const char* aData, size_t aSize) { |
180 | 0 | memcpy(mPtr, aData, aSize); |
181 | 0 | mPtr += aSize; |
182 | 0 | } |
183 | | char* mPtr; |
184 | | }; |
185 | | |
186 | | struct MemStream { |
187 | | char *mData; |
188 | | size_t mLength; |
189 | | size_t mCapacity; |
190 | 0 | void Resize(size_t aSize) { |
191 | 0 | mLength = aSize; |
192 | 0 | if (mLength > mCapacity) { |
193 | 0 | mCapacity = mCapacity * 2; |
194 | 0 | // check if the doubled capacity is enough |
195 | 0 | // otherwise use double mLength |
196 | 0 | if (mLength > mCapacity) { |
197 | 0 | mCapacity = mLength * 2; |
198 | 0 | } |
199 | 0 | mData = (char*)realloc(mData, mCapacity); |
200 | 0 | } |
201 | 0 | } |
202 | | |
203 | 0 | void write(const char* aData, size_t aSize) { |
204 | 0 | Resize(mLength + aSize); |
205 | 0 | memcpy(mData + mLength - aSize, aData, aSize); |
206 | 0 | } |
207 | | |
208 | 0 | MemStream() : mData(nullptr), mLength(0), mCapacity(0) {} |
209 | 0 | ~MemStream() { free(mData); } |
210 | | }; |
211 | | |
212 | | class EventStream { |
213 | | public: |
214 | | virtual void write(const char* aData, size_t aSize) = 0; |
215 | | virtual void read(char* aOut, size_t aSize) = 0; |
216 | | }; |
217 | | |
218 | | class RecordedEvent { |
219 | | public: |
220 | | enum EventType { |
221 | | DRAWTARGETCREATION = 0, |
222 | | DRAWTARGETDESTRUCTION, |
223 | | FILLRECT, |
224 | | STROKERECT, |
225 | | STROKELINE, |
226 | | CLEARRECT, |
227 | | COPYSURFACE, |
228 | | SETTRANSFORM, |
229 | | PUSHCLIP, |
230 | | PUSHCLIPRECT, |
231 | | POPCLIP, |
232 | | FILL, |
233 | | FILLGLYPHS, |
234 | | MASK, |
235 | | STROKE, |
236 | | DRAWSURFACE, |
237 | | DRAWSURFACEWITHSHADOW, |
238 | | PATHCREATION, |
239 | | PATHDESTRUCTION, |
240 | | SOURCESURFACECREATION, |
241 | | SOURCESURFACEDESTRUCTION, |
242 | | GRADIENTSTOPSCREATION, |
243 | | GRADIENTSTOPSDESTRUCTION, |
244 | | SNAPSHOT, |
245 | | SCALEDFONTCREATION, |
246 | | SCALEDFONTDESTRUCTION, |
247 | | MASKSURFACE, |
248 | | FILTERNODECREATION, |
249 | | FILTERNODEDESTRUCTION, |
250 | | DRAWFILTER, |
251 | | FILTERNODESETATTRIBUTE, |
252 | | FILTERNODESETINPUT, |
253 | | CREATESIMILARDRAWTARGET, |
254 | | CREATECLIPPEDDRAWTARGET, |
255 | | FONTDATA, |
256 | | FONTDESC, |
257 | | PUSHLAYER, |
258 | | PUSHLAYERWITHBLEND, |
259 | | POPLAYER, |
260 | | UNSCALEDFONTCREATION, |
261 | | UNSCALEDFONTDESTRUCTION, |
262 | | INTOLUMINANCE, |
263 | | EXTERNALSURFACECREATION, |
264 | | }; |
265 | | static const uint32_t kTotalEventTypes = RecordedEvent::FILTERNODESETINPUT + 1; |
266 | | |
267 | 0 | virtual ~RecordedEvent() {} |
268 | | |
269 | | static std::string GetEventName(EventType aType); |
270 | | |
271 | | /** |
272 | | * Play back this event using the translator. Note that derived classes should |
273 | | * only return false when there is a fatal error, as it will probably mean the |
274 | | * translation will abort. |
275 | | * @param aTranslator Translator to be used for retrieving other referenced |
276 | | * objects and making playback decisions. |
277 | | * @return true unless a fatal problem has occurred and playback should abort. |
278 | | */ |
279 | 0 | virtual bool PlayEvent(Translator *aTranslator) const { return true; } |
280 | | |
281 | | virtual void RecordToStream(std::ostream& aStream) const = 0; |
282 | | virtual void RecordToStream(EventStream& aStream) const = 0; |
283 | | virtual void RecordToStream(MemStream& aStream) const = 0; |
284 | | |
285 | 0 | virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const { } |
286 | | |
287 | | template<class S> |
288 | | void RecordPatternData(S &aStream, const PatternStorage &aPatternStorage) const; |
289 | | template<class S> |
290 | | void ReadPatternData(S &aStream, PatternStorage &aPatternStorage) const; |
291 | | void StorePattern(PatternStorage &aDestination, const Pattern &aSource) const; |
292 | | template<class S> |
293 | | void RecordStrokeOptions(S &aStream, const StrokeOptions &aStrokeOptions) const; |
294 | | template<class S> |
295 | | void ReadStrokeOptions(S &aStream, StrokeOptions &aStrokeOptions); |
296 | | |
297 | | virtual std::string GetName() const = 0; |
298 | | |
299 | | virtual ReferencePtr GetObjectRef() const = 0; |
300 | | |
301 | 0 | virtual ReferencePtr GetDestinedDT() { return nullptr; } |
302 | | |
303 | | void OutputSimplePatternInfo(const PatternStorage &aStorage, std::stringstream &aOutput) const; |
304 | | |
305 | | template<class S> |
306 | | static RecordedEvent *LoadEvent(S &aStream, EventType aType); |
307 | | static RecordedEvent *LoadEventFromStream(std::istream &aStream, EventType aType); |
308 | | static RecordedEvent *LoadEventFromStream(EventStream& aStream, EventType aType); |
309 | | |
310 | | // An alternative to LoadEvent that avoids a heap allocation for the event. |
311 | | // This accepts a callable `f' that will take a RecordedEvent* as a single parameter |
312 | | template<class S, class F> |
313 | | static bool DoWithEvent(S &aStream, EventType aType, F f); |
314 | | |
315 | | EventType GetType() const { return (EventType)mType; } |
316 | | protected: |
317 | | friend class DrawEventRecorderPrivate; |
318 | | friend class DrawEventRecorderFile; |
319 | | friend class DrawEventRecorderMemory; |
320 | | static void RecordUnscaledFont(UnscaledFont *aUnscaledFont, std::ostream *aOutput); |
321 | | static void RecordUnscaledFont(UnscaledFont *aUnscaledFont, MemStream &aOutput); |
322 | | template<class S> |
323 | | static void RecordUnscaledFontImpl(UnscaledFont *aUnscaledFont, S &aOutput); |
324 | | |
325 | | MOZ_IMPLICIT RecordedEvent(int32_t aType) : mType(aType) |
326 | 0 | {} |
327 | | |
328 | | int32_t mType; |
329 | | std::vector<Float> mDashPatternStorage; |
330 | | }; |
331 | | |
332 | | } // namespace gfx |
333 | | } // namespace mozilla |
334 | | |
335 | | #endif |