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