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/. */
7 #ifndef MOZILLA_GFX_RECORDEDEVENT_H_
8 #define MOZILLA_GFX_RECORDEDEVENT_H_
17 #include "RecordingTypes.h"
22 const uint32_t kMagicInt
= 0xc001feed;
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
= 1;
34 ReferencePtr() : mLongPtr(0) {}
36 MOZ_IMPLICIT
ReferencePtr(const void* aLongPtr
)
37 : mLongPtr(uint64_t(aLongPtr
)) {}
40 MOZ_IMPLICIT
ReferencePtr(const RefPtr
<T
>& aPtr
)
41 : mLongPtr(uint64_t(aPtr
.get())) {}
43 ReferencePtr
& operator=(const void* aLongPtr
) {
44 mLongPtr
= uint64_t(aLongPtr
);
49 ReferencePtr
& operator=(const RefPtr
<T
>& aPtr
) {
50 mLongPtr
= uint64_t(aPtr
.get());
54 operator void*() const { return (void*)mLongPtr
; }
59 struct RecordedFontDetails
{
65 // Used by the Azure drawing debugger (player2d)
66 inline std::string
StringFromPtr(ReferencePtr aPtr
) {
67 std::stringstream stream
;
74 virtual ~Translator() = default;
76 virtual DrawTarget
* LookupDrawTarget(ReferencePtr aRefPtr
) = 0;
77 virtual Path
* LookupPath(ReferencePtr aRefPtr
) = 0;
78 virtual SourceSurface
* LookupSourceSurface(ReferencePtr aRefPtr
) = 0;
79 virtual FilterNode
* LookupFilterNode(ReferencePtr aRefPtr
) = 0;
80 virtual GradientStops
* LookupGradientStops(ReferencePtr aRefPtr
) = 0;
81 virtual ScaledFont
* LookupScaledFont(ReferencePtr aRefPtr
) = 0;
82 virtual UnscaledFont
* LookupUnscaledFont(ReferencePtr aRefPtr
) = 0;
83 virtual NativeFontResource
* LookupNativeFontResource(uint64_t aKey
) = 0;
84 virtual already_AddRefed
<SourceSurface
> LookupExternalSurface(uint64_t aKey
) {
87 virtual void AddDrawTarget(ReferencePtr aRefPtr
, DrawTarget
* aDT
) = 0;
88 virtual void RemoveDrawTarget(ReferencePtr aRefPtr
) = 0;
89 virtual void AddPath(ReferencePtr aRefPtr
, Path
* aPath
) = 0;
90 virtual void RemovePath(ReferencePtr aRefPtr
) = 0;
91 virtual void AddSourceSurface(ReferencePtr aRefPtr
, SourceSurface
* aPath
) = 0;
92 virtual void RemoveSourceSurface(ReferencePtr aRefPtr
) = 0;
93 virtual void AddFilterNode(mozilla::gfx::ReferencePtr aRefPtr
,
94 FilterNode
* aSurface
) = 0;
95 virtual void RemoveFilterNode(mozilla::gfx::ReferencePtr aRefPtr
) = 0;
96 virtual void AddGradientStops(ReferencePtr aRefPtr
, GradientStops
* aPath
) = 0;
97 virtual void RemoveGradientStops(ReferencePtr aRefPtr
) = 0;
98 virtual void AddScaledFont(ReferencePtr aRefPtr
, ScaledFont
* aScaledFont
) = 0;
99 virtual void RemoveScaledFont(ReferencePtr aRefPtr
) = 0;
100 virtual void AddUnscaledFont(ReferencePtr aRefPtr
,
101 UnscaledFont
* aUnscaledFont
) = 0;
102 virtual void RemoveUnscaledFont(ReferencePtr aRefPtr
) = 0;
103 virtual void AddNativeFontResource(
104 uint64_t aKey
, NativeFontResource
* aNativeFontResource
) = 0;
106 virtual already_AddRefed
<DrawTarget
> CreateDrawTarget(ReferencePtr aRefPtr
,
107 const IntSize
& aSize
,
108 SurfaceFormat aFormat
);
109 virtual DrawTarget
* GetReferenceDrawTarget() = 0;
110 virtual void* GetFontContext() { return nullptr; }
113 struct ColorPatternStorage
{
117 struct LinearGradientPatternStorage
{
124 struct RadialGradientPatternStorage
{
133 struct ConicGradientPatternStorage
{
142 struct SurfacePatternStorage
{
144 SamplingFilter mSamplingFilter
;
145 ReferencePtr mSurface
;
147 IntRect mSamplingRect
;
150 struct PatternStorage
{
154 char mColor
[sizeof(ColorPatternStorage
)];
155 char mLinear
[sizeof(LinearGradientPatternStorage
)];
156 char mRadial
[sizeof(RadialGradientPatternStorage
)];
157 char mConic
[sizeof(ConicGradientPatternStorage
)];
158 char mSurface
[sizeof(SurfacePatternStorage
)];
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
167 struct SizeCollector
{
168 SizeCollector() : mTotalSize(0) {}
169 void write(const char*, size_t s
) { mTotalSize
+= s
; }
174 explicit MemWriter(char* aPtr
) : mPtr(aPtr
) {}
175 void write(const char* aData
, size_t aSize
) {
176 memcpy(mPtr
, aData
, aSize
);
182 // This is a simple interface for an EventRingBuffer, so we can use it in the
183 // RecordedEvent reading and writing machinery.
184 class EventRingBuffer
{
187 * Templated RecordEvent function so that when we have enough contiguous
188 * space we can record into the buffer quickly using MemWriter.
190 * @param aRecordedEvent the event to record
193 void RecordEvent(const RE
* aRecordedEvent
) {
195 WriteElement(size
, aRecordedEvent
->GetType());
196 aRecordedEvent
->Record(size
);
197 if (size
.mTotalSize
> mAvailable
) {
198 WaitForAndRecalculateAvailableSpace();
200 if (size
.mTotalSize
<= mAvailable
) {
201 MemWriter
writer(mBufPos
);
202 WriteElement(writer
, aRecordedEvent
->GetType());
203 aRecordedEvent
->Record(writer
);
204 UpdateWriteTotalsBy(size
.mTotalSize
);
206 WriteElement(*this, aRecordedEvent
->GetType());
207 aRecordedEvent
->Record(*this);
212 * Simple write function required by WriteElement.
214 * @param aData the data to be written to the buffer
215 * @param aSize the number of chars to write
217 virtual void write(const char* const aData
, const size_t aSize
) = 0;
220 * Simple read function required by ReadElement.
222 * @param aOut the pointer to read into
223 * @param aSize the number of chars to read
225 virtual void read(char* const aOut
, const size_t aSize
) = 0;
227 virtual bool good() const = 0;
229 virtual void SetIsBad() = 0;
233 * Wait until space is available for writing and then set mBufPos and
236 virtual bool WaitForAndRecalculateAvailableSpace() = 0;
239 * Update write count, mBufPos and mAvailable.
241 * @param aCount number of bytes written
243 virtual void UpdateWriteTotalsBy(uint32_t aCount
) = 0;
245 char* mBufPos
= nullptr;
246 uint32_t mAvailable
= 0;
254 bool Resize(size_t aSize
) {
259 if (mLength
> mCapacity
) {
260 mCapacity
= mCapacity
* 2;
261 // check if the doubled capacity is enough
262 // otherwise use double mLength
263 if (mLength
> mCapacity
) {
264 mCapacity
= mLength
* 2;
266 mData
= (char*)realloc(mData
, mCapacity
);
271 NS_ERROR("Failed to allocate MemStream!");
277 void write(const char* aData
, size_t aSize
) {
278 if (Resize(mLength
+ aSize
)) {
279 memcpy(mData
+ mLength
- aSize
, aData
, aSize
);
283 MemStream() : mData(nullptr), mLength(0), mCapacity(0) {}
284 ~MemStream() { free(mData
); }
289 virtual void write(const char* aData
, size_t aSize
) = 0;
290 virtual void read(char* aOut
, size_t aSize
) = 0;
291 virtual bool good() = 0;
292 virtual void SetIsBad() = 0;
295 class RecordedEvent
{
298 DRAWTARGETCREATION
= 0,
299 DRAWTARGETDESTRUCTION
,
314 DRAWDEPENDENTSURFACE
,
315 DRAWSURFACEWITHSHADOW
,
318 SOURCESURFACECREATION
,
319 SOURCESURFACEDESTRUCTION
,
320 GRADIENTSTOPSCREATION
,
321 GRADIENTSTOPSDESTRUCTION
,
324 SCALEDFONTDESTRUCTION
,
327 FILTERNODEDESTRUCTION
,
329 FILTERNODESETATTRIBUTE
,
331 CREATESIMILARDRAWTARGET
,
332 CREATECLIPPEDDRAWTARGET
,
333 CREATEDRAWTARGETFORFILTER
,
339 UNSCALEDFONTCREATION
,
340 UNSCALEDFONTDESTRUCTION
,
342 EXTERNALSURFACECREATION
,
345 OPTIMIZESOURCESURFACE
,
349 virtual ~RecordedEvent() = default;
351 static std::string
GetEventName(EventType aType
);
354 * Play back this event using the translator. Note that derived classes
356 * only return false when there is a fatal error, as it will probably mean
358 * translation will abort.
359 * @param aTranslator Translator to be used for retrieving other referenced
360 * objects and making playback decisions.
361 * @return true unless a fatal problem has occurred and playback should
364 virtual bool PlayEvent(Translator
* aTranslator
) const { return true; }
366 virtual void RecordToStream(std::ostream
& aStream
) const = 0;
367 virtual void RecordToStream(EventStream
& aStream
) const = 0;
368 virtual void RecordToStream(EventRingBuffer
& aStream
) const = 0;
369 virtual void RecordToStream(MemStream
& aStream
) const = 0;
371 virtual void OutputSimpleEventInfo(std::stringstream
& aStringStream
) const {}
374 void RecordPatternData(S
& aStream
,
375 const PatternStorage
& aPatternStorage
) const;
377 void ReadPatternData(S
& aStream
, PatternStorage
& aPatternStorage
) const;
378 void StorePattern(PatternStorage
& aDestination
, const Pattern
& aSource
) const;
380 void RecordStrokeOptions(S
& aStream
,
381 const StrokeOptions
& aStrokeOptions
) const;
383 void ReadStrokeOptions(S
& aStream
, StrokeOptions
& aStrokeOptions
);
385 virtual std::string
GetName() const = 0;
387 virtual ReferencePtr
GetDestinedDT() { return nullptr; }
389 void OutputSimplePatternInfo(const PatternStorage
& aStorage
,
390 std::stringstream
& aOutput
) const;
393 static bool DoWithEvent(S
& aStream
, EventType aType
,
394 const std::function
<bool(RecordedEvent
*)>& aAction
);
395 static bool DoWithEventFromStream(
396 EventStream
& aStream
, EventType aType
,
397 const std::function
<bool(RecordedEvent
*)>& aAction
);
398 static bool DoWithEventFromStream(
399 EventRingBuffer
& aStream
, EventType aType
,
400 const std::function
<bool(RecordedEvent
*)>& aAction
);
402 EventType
GetType() const { return (EventType
)mType
; }
405 friend class DrawEventRecorderPrivate
;
406 friend class DrawEventRecorderFile
;
407 friend class DrawEventRecorderMemory
;
408 static void RecordUnscaledFont(UnscaledFont
* aUnscaledFont
,
409 std::ostream
* aOutput
);
410 static void RecordUnscaledFont(UnscaledFont
* aUnscaledFont
,
413 static void RecordUnscaledFontImpl(UnscaledFont
* aUnscaledFont
, S
& aOutput
);
415 MOZ_IMPLICIT
RecordedEvent(int32_t aType
) : mType(aType
) {}
418 std::vector
<Float
> mDashPatternStorage
;
421 template <class Derived
>
422 class RecordedEventDerived
: public RecordedEvent
{
423 using RecordedEvent::RecordedEvent
;
426 void RecordToStream(std::ostream
& aStream
) const override
{
427 WriteElement(aStream
, this->mType
);
428 static_cast<const Derived
*>(this)->Record(aStream
);
430 void RecordToStream(EventStream
& aStream
) const override
{
431 WriteElement(aStream
, this->mType
);
432 static_cast<const Derived
*>(this)->Record(aStream
);
434 void RecordToStream(EventRingBuffer
& aStream
) const final
{
435 aStream
.RecordEvent(static_cast<const Derived
*>(this));
437 void RecordToStream(MemStream
& aStream
) const override
{
439 WriteElement(size
, this->mType
);
440 static_cast<const Derived
*>(this)->Record(size
);
442 if (!aStream
.Resize(aStream
.mLength
+ size
.mTotalSize
)) {
446 MemWriter
writer(aStream
.mData
+ aStream
.mLength
- size
.mTotalSize
);
447 WriteElement(writer
, this->mType
);
448 static_cast<const Derived
*>(this)->Record(writer
);
453 } // namespace mozilla