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_RECORDEDEVENTIMPL_H_
8 #define MOZILLA_GFX_RECORDEDEVENTIMPL_H_
9
10 #include "RecordedEvent.h"
11
12 #include "PathRecording.h"
13 #include "RecordingTypes.h"
14 #include "Tools.h"
15 #include "Filters.h"
16 #include "Logging.h"
17 #include "ScaledFontBase.h"
18 #include "SFNTData.h"
19
20 namespace mozilla {
21 namespace gfx {
22
23 template <class Derived>
24 class RecordedDrawingEvent : public RecordedEventDerived<Derived> {
25 public:
GetDestinedDT()26 ReferencePtr GetDestinedDT() override { return mDT; }
27
28 protected:
RecordedDrawingEvent(RecordedEvent::EventType aType,DrawTarget * aTarget)29 RecordedDrawingEvent(RecordedEvent::EventType aType, DrawTarget* aTarget)
30 : RecordedEventDerived<Derived>(aType), mDT(aTarget) {}
31
32 template <class S>
33 RecordedDrawingEvent(RecordedEvent::EventType aType, S& aStream);
34 template <class S>
35 void Record(S& aStream) const;
36
37 ReferencePtr mDT;
38 };
39
40 class RecordedDrawTargetCreation
41 : public RecordedEventDerived<RecordedDrawTargetCreation> {
42 public:
43 RecordedDrawTargetCreation(ReferencePtr aRefPtr, BackendType aType,
44 const IntRect& aRect, SurfaceFormat aFormat,
45 bool aHasExistingData = false,
46 SourceSurface* aExistingData = nullptr)
RecordedEventDerived(DRAWTARGETCREATION)47 : RecordedEventDerived(DRAWTARGETCREATION),
48 mRefPtr(aRefPtr),
49 mBackendType(aType),
50 mRect(aRect),
51 mFormat(aFormat),
52 mHasExistingData(aHasExistingData),
53 mExistingData(aExistingData) {}
54
55 bool PlayEvent(Translator* aTranslator) const override;
56
57 template <class S>
58 void Record(S& aStream) const;
59 virtual void OutputSimpleEventInfo(
60 std::stringstream& aStringStream) const override;
61
GetName()62 std::string GetName() const override { return "DrawTarget Creation"; }
63
64 ReferencePtr mRefPtr;
65 BackendType mBackendType;
66 IntRect mRect;
67 SurfaceFormat mFormat;
68 bool mHasExistingData;
69 RefPtr<SourceSurface> mExistingData;
70
71 private:
72 friend class RecordedEvent;
73
74 template <class S>
75 MOZ_IMPLICIT RecordedDrawTargetCreation(S& aStream);
76 };
77
78 class RecordedDrawTargetDestruction
79 : public RecordedEventDerived<RecordedDrawTargetDestruction> {
80 public:
RecordedDrawTargetDestruction(ReferencePtr aRefPtr)81 MOZ_IMPLICIT RecordedDrawTargetDestruction(ReferencePtr aRefPtr)
82 : RecordedEventDerived(DRAWTARGETDESTRUCTION),
83 mRefPtr(aRefPtr),
84 mBackendType(BackendType::NONE) {}
85
86 bool PlayEvent(Translator* aTranslator) const override;
87
88 template <class S>
89 void Record(S& aStream) const;
90 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
91
GetName()92 std::string GetName() const override { return "DrawTarget Destruction"; }
93
94 ReferencePtr mRefPtr;
95
96 BackendType mBackendType;
97
98 private:
99 friend class RecordedEvent;
100
101 template <class S>
102 MOZ_IMPLICIT RecordedDrawTargetDestruction(S& aStream);
103 };
104
105 class RecordedCreateSimilarDrawTarget
106 : public RecordedEventDerived<RecordedCreateSimilarDrawTarget> {
107 public:
RecordedCreateSimilarDrawTarget(ReferencePtr aRefPtr,const IntSize & aSize,SurfaceFormat aFormat)108 RecordedCreateSimilarDrawTarget(ReferencePtr aRefPtr, const IntSize& aSize,
109 SurfaceFormat aFormat)
110 : RecordedEventDerived(CREATESIMILARDRAWTARGET),
111 mRefPtr(aRefPtr),
112 mSize(aSize),
113 mFormat(aFormat) {}
114
115 bool PlayEvent(Translator* aTranslator) const override;
116
117 template <class S>
118 void Record(S& aStream) const;
119 virtual void OutputSimpleEventInfo(
120 std::stringstream& aStringStream) const override;
121
GetName()122 std::string GetName() const override { return "CreateSimilarDrawTarget"; }
123
124 ReferencePtr mRefPtr;
125 IntSize mSize;
126 SurfaceFormat mFormat;
127
128 private:
129 friend class RecordedEvent;
130
131 template <class S>
132 MOZ_IMPLICIT RecordedCreateSimilarDrawTarget(S& aStream);
133 };
134
135 class RecordedCreateClippedDrawTarget
136 : public RecordedDrawingEvent<RecordedCreateClippedDrawTarget> {
137 public:
RecordedCreateClippedDrawTarget(DrawTarget * aDT,ReferencePtr aRefPtr,const Rect & aBounds,SurfaceFormat aFormat)138 RecordedCreateClippedDrawTarget(DrawTarget* aDT, ReferencePtr aRefPtr,
139 const Rect& aBounds, SurfaceFormat aFormat)
140 : RecordedDrawingEvent(CREATECLIPPEDDRAWTARGET, aDT),
141 mRefPtr(aRefPtr),
142 mBounds(aBounds),
143 mFormat(aFormat) {}
144
145 bool PlayEvent(Translator* aTranslator) const override;
146
147 template <class S>
148 void Record(S& aStream) const;
149 virtual void OutputSimpleEventInfo(
150 std::stringstream& aStringStream) const override;
151
GetName()152 std::string GetName() const override { return "CreateClippedDrawTarget"; }
153
154 ReferencePtr mRefPtr;
155 Rect mBounds;
156 SurfaceFormat mFormat;
157
158 private:
159 friend class RecordedEvent;
160
161 template <class S>
162 MOZ_IMPLICIT RecordedCreateClippedDrawTarget(S& aStream);
163 };
164
165 class RecordedCreateDrawTargetForFilter
166 : public RecordedDrawingEvent<RecordedCreateDrawTargetForFilter> {
167 public:
RecordedCreateDrawTargetForFilter(DrawTarget * aDT,ReferencePtr aRefPtr,const IntSize & aMaxSize,SurfaceFormat aFormat,FilterNode * aFilter,FilterNode * aSource,const Rect & aSourceRect,const Point & aDestPoint)168 RecordedCreateDrawTargetForFilter(DrawTarget* aDT, ReferencePtr aRefPtr,
169 const IntSize& aMaxSize,
170 SurfaceFormat aFormat, FilterNode* aFilter,
171 FilterNode* aSource,
172 const Rect& aSourceRect,
173 const Point& aDestPoint)
174 : RecordedDrawingEvent(CREATEDRAWTARGETFORFILTER, aDT),
175 mRefPtr(aRefPtr),
176 mMaxSize(aMaxSize),
177 mFormat(aFormat),
178 mFilter(aFilter),
179 mSource(aSource),
180 mSourceRect(aSourceRect),
181 mDestPoint(aDestPoint) {}
182
183 bool PlayEvent(Translator* aTranslator) const override;
184
185 template <class S>
186 void Record(S& aStream) const;
187 virtual void OutputSimpleEventInfo(
188 std::stringstream& aStringStream) const override;
189
GetName()190 std::string GetName() const override {
191 return "CreateSimilarDrawTargetForFilter";
192 }
193
194 ReferencePtr mRefPtr;
195 IntSize mMaxSize;
196 SurfaceFormat mFormat;
197 ReferencePtr mFilter;
198 ReferencePtr mSource;
199 Rect mSourceRect;
200 Point mDestPoint;
201
202 private:
203 friend class RecordedEvent;
204
205 template <class S>
206 MOZ_IMPLICIT RecordedCreateDrawTargetForFilter(S& aStream);
207 };
208
209 class RecordedFillRect : public RecordedDrawingEvent<RecordedFillRect> {
210 public:
RecordedFillRect(DrawTarget * aDT,const Rect & aRect,const Pattern & aPattern,const DrawOptions & aOptions)211 RecordedFillRect(DrawTarget* aDT, const Rect& aRect, const Pattern& aPattern,
212 const DrawOptions& aOptions)
213 : RecordedDrawingEvent(FILLRECT, aDT),
214 mRect(aRect),
215 mPattern(),
216 mOptions(aOptions) {
217 StorePattern(mPattern, aPattern);
218 }
219
220 bool PlayEvent(Translator* aTranslator) const override;
221
222 template <class S>
223 void Record(S& aStream) const;
224 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
225
GetName()226 std::string GetName() const override { return "FillRect"; }
227
228 private:
229 friend class RecordedEvent;
230
231 template <class S>
232 MOZ_IMPLICIT RecordedFillRect(S& aStream);
233
234 Rect mRect;
235 PatternStorage mPattern;
236 DrawOptions mOptions;
237 };
238
239 class RecordedStrokeRect : public RecordedDrawingEvent<RecordedStrokeRect> {
240 public:
RecordedStrokeRect(DrawTarget * aDT,const Rect & aRect,const Pattern & aPattern,const StrokeOptions & aStrokeOptions,const DrawOptions & aOptions)241 RecordedStrokeRect(DrawTarget* aDT, const Rect& aRect,
242 const Pattern& aPattern,
243 const StrokeOptions& aStrokeOptions,
244 const DrawOptions& aOptions)
245 : RecordedDrawingEvent(STROKERECT, aDT),
246 mRect(aRect),
247 mPattern(),
248 mStrokeOptions(aStrokeOptions),
249 mOptions(aOptions) {
250 StorePattern(mPattern, aPattern);
251 }
252
253 bool PlayEvent(Translator* aTranslator) const override;
254
255 template <class S>
256 void Record(S& aStream) const;
257 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
258
GetName()259 std::string GetName() const override { return "StrokeRect"; }
260
261 private:
262 friend class RecordedEvent;
263
264 template <class S>
265 MOZ_IMPLICIT RecordedStrokeRect(S& aStream);
266
267 Rect mRect;
268 PatternStorage mPattern;
269 StrokeOptions mStrokeOptions;
270 DrawOptions mOptions;
271 };
272
273 class RecordedStrokeLine : public RecordedDrawingEvent<RecordedStrokeLine> {
274 public:
RecordedStrokeLine(DrawTarget * aDT,const Point & aBegin,const Point & aEnd,const Pattern & aPattern,const StrokeOptions & aStrokeOptions,const DrawOptions & aOptions)275 RecordedStrokeLine(DrawTarget* aDT, const Point& aBegin, const Point& aEnd,
276 const Pattern& aPattern,
277 const StrokeOptions& aStrokeOptions,
278 const DrawOptions& aOptions)
279 : RecordedDrawingEvent(STROKELINE, aDT),
280 mBegin(aBegin),
281 mEnd(aEnd),
282 mPattern(),
283 mStrokeOptions(aStrokeOptions),
284 mOptions(aOptions) {
285 StorePattern(mPattern, aPattern);
286 }
287
288 bool PlayEvent(Translator* aTranslator) const override;
289
290 template <class S>
291 void Record(S& aStream) const;
292 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
293
GetName()294 std::string GetName() const override { return "StrokeLine"; }
295
296 private:
297 friend class RecordedEvent;
298
299 template <class S>
300 MOZ_IMPLICIT RecordedStrokeLine(S& aStream);
301
302 Point mBegin;
303 Point mEnd;
304 PatternStorage mPattern;
305 StrokeOptions mStrokeOptions;
306 DrawOptions mOptions;
307 };
308
309 class RecordedFill : public RecordedDrawingEvent<RecordedFill> {
310 public:
RecordedFill(DrawTarget * aDT,ReferencePtr aPath,const Pattern & aPattern,const DrawOptions & aOptions)311 RecordedFill(DrawTarget* aDT, ReferencePtr aPath, const Pattern& aPattern,
312 const DrawOptions& aOptions)
313 : RecordedDrawingEvent(FILL, aDT),
314 mPath(aPath),
315 mPattern(),
316 mOptions(aOptions) {
317 StorePattern(mPattern, aPattern);
318 }
319
320 bool PlayEvent(Translator* aTranslator) const override;
321
322 template <class S>
323 void Record(S& aStream) const;
324 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
325
GetName()326 std::string GetName() const override { return "Fill"; }
327
328 private:
329 friend class RecordedEvent;
330
331 template <class S>
332 MOZ_IMPLICIT RecordedFill(S& aStream);
333
334 ReferencePtr mPath;
335 PatternStorage mPattern;
336 DrawOptions mOptions;
337 };
338
339 class RecordedFillGlyphs : public RecordedDrawingEvent<RecordedFillGlyphs> {
340 public:
RecordedFillGlyphs(DrawTarget * aDT,ReferencePtr aScaledFont,const Pattern & aPattern,const DrawOptions & aOptions,const Glyph * aGlyphs,uint32_t aNumGlyphs)341 RecordedFillGlyphs(DrawTarget* aDT, ReferencePtr aScaledFont,
342 const Pattern& aPattern, const DrawOptions& aOptions,
343 const Glyph* aGlyphs, uint32_t aNumGlyphs)
344 : RecordedDrawingEvent(FILLGLYPHS, aDT),
345 mScaledFont(aScaledFont),
346 mPattern(),
347 mOptions(aOptions) {
348 StorePattern(mPattern, aPattern);
349 mNumGlyphs = aNumGlyphs;
350 mGlyphs = new Glyph[aNumGlyphs];
351 memcpy(mGlyphs, aGlyphs, sizeof(Glyph) * aNumGlyphs);
352 }
353 virtual ~RecordedFillGlyphs();
354
355 bool PlayEvent(Translator* aTranslator) const override;
356
357 template <class S>
358 void Record(S& aStream) const;
359 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
360
GetName()361 std::string GetName() const override { return "FillGlyphs"; }
362
363 private:
364 friend class RecordedEvent;
365
366 template <class S>
367 MOZ_IMPLICIT RecordedFillGlyphs(S& aStream);
368
369 ReferencePtr mScaledFont;
370 PatternStorage mPattern;
371 DrawOptions mOptions;
372 Glyph* mGlyphs = nullptr;
373 uint32_t mNumGlyphs = 0;
374 };
375
376 class RecordedMask : public RecordedDrawingEvent<RecordedMask> {
377 public:
RecordedMask(DrawTarget * aDT,const Pattern & aSource,const Pattern & aMask,const DrawOptions & aOptions)378 RecordedMask(DrawTarget* aDT, const Pattern& aSource, const Pattern& aMask,
379 const DrawOptions& aOptions)
380 : RecordedDrawingEvent(MASK, aDT),
381 mSource(),
382 mMask(),
383 mOptions(aOptions) {
384 StorePattern(mSource, aSource);
385 StorePattern(mMask, aMask);
386 }
387
388 bool PlayEvent(Translator* aTranslator) const override;
389
390 template <class S>
391 void Record(S& aStream) const;
392 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
393
GetName()394 std::string GetName() const override { return "Mask"; }
395
396 private:
397 friend class RecordedEvent;
398
399 template <class S>
400 MOZ_IMPLICIT RecordedMask(S& aStream);
401
402 PatternStorage mSource;
403 PatternStorage mMask;
404 DrawOptions mOptions;
405 };
406
407 class RecordedStroke : public RecordedDrawingEvent<RecordedStroke> {
408 public:
RecordedStroke(DrawTarget * aDT,ReferencePtr aPath,const Pattern & aPattern,const StrokeOptions & aStrokeOptions,const DrawOptions & aOptions)409 RecordedStroke(DrawTarget* aDT, ReferencePtr aPath, const Pattern& aPattern,
410 const StrokeOptions& aStrokeOptions,
411 const DrawOptions& aOptions)
412 : RecordedDrawingEvent(STROKE, aDT),
413 mPath(aPath),
414 mPattern(),
415 mStrokeOptions(aStrokeOptions),
416 mOptions(aOptions) {
417 StorePattern(mPattern, aPattern);
418 }
419
420 bool PlayEvent(Translator* aTranslator) const override;
421
422 template <class S>
423 void Record(S& aStream) const;
424 virtual void OutputSimpleEventInfo(
425 std::stringstream& aStringStream) const override;
426
GetName()427 std::string GetName() const override { return "Stroke"; }
428
429 private:
430 friend class RecordedEvent;
431
432 template <class S>
433 MOZ_IMPLICIT RecordedStroke(S& aStream);
434
435 ReferencePtr mPath;
436 PatternStorage mPattern;
437 StrokeOptions mStrokeOptions;
438 DrawOptions mOptions;
439 };
440
441 class RecordedClearRect : public RecordedDrawingEvent<RecordedClearRect> {
442 public:
RecordedClearRect(DrawTarget * aDT,const Rect & aRect)443 RecordedClearRect(DrawTarget* aDT, const Rect& aRect)
444 : RecordedDrawingEvent(CLEARRECT, aDT), mRect(aRect) {}
445
446 bool PlayEvent(Translator* aTranslator) const override;
447
448 template <class S>
449 void Record(S& aStream) const;
450 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
451
GetName()452 std::string GetName() const override { return "ClearRect"; }
453
454 private:
455 friend class RecordedEvent;
456
457 template <class S>
458 MOZ_IMPLICIT RecordedClearRect(S& aStream);
459
460 Rect mRect;
461 };
462
463 class RecordedCopySurface : public RecordedDrawingEvent<RecordedCopySurface> {
464 public:
RecordedCopySurface(DrawTarget * aDT,ReferencePtr aSourceSurface,const IntRect & aSourceRect,const IntPoint & aDest)465 RecordedCopySurface(DrawTarget* aDT, ReferencePtr aSourceSurface,
466 const IntRect& aSourceRect, const IntPoint& aDest)
467 : RecordedDrawingEvent(COPYSURFACE, aDT),
468 mSourceSurface(aSourceSurface),
469 mSourceRect(aSourceRect),
470 mDest(aDest) {}
471
472 bool PlayEvent(Translator* aTranslator) const override;
473
474 template <class S>
475 void Record(S& aStream) const;
476 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
477
GetName()478 std::string GetName() const override { return "CopySurface"; }
479
480 private:
481 friend class RecordedEvent;
482
483 template <class S>
484 MOZ_IMPLICIT RecordedCopySurface(S& aStream);
485
486 ReferencePtr mSourceSurface;
487 IntRect mSourceRect;
488 IntPoint mDest;
489 };
490
491 class RecordedPushClip : public RecordedDrawingEvent<RecordedPushClip> {
492 public:
RecordedPushClip(DrawTarget * aDT,ReferencePtr aPath)493 RecordedPushClip(DrawTarget* aDT, ReferencePtr aPath)
494 : RecordedDrawingEvent(PUSHCLIP, aDT), mPath(aPath) {}
495
496 bool PlayEvent(Translator* aTranslator) const override;
497
498 template <class S>
499 void Record(S& aStream) const;
500 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
501
GetName()502 std::string GetName() const override { return "PushClip"; }
503
504 private:
505 friend class RecordedEvent;
506
507 template <class S>
508 MOZ_IMPLICIT RecordedPushClip(S& aStream);
509
510 ReferencePtr mPath;
511 };
512
513 class RecordedPushClipRect : public RecordedDrawingEvent<RecordedPushClipRect> {
514 public:
RecordedPushClipRect(DrawTarget * aDT,const Rect & aRect)515 RecordedPushClipRect(DrawTarget* aDT, const Rect& aRect)
516 : RecordedDrawingEvent(PUSHCLIPRECT, aDT), mRect(aRect) {}
517
518 bool PlayEvent(Translator* aTranslator) const override;
519
520 template <class S>
521 void Record(S& aStream) const;
522 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
523
GetName()524 std::string GetName() const override { return "PushClipRect"; }
525
526 private:
527 friend class RecordedEvent;
528
529 template <class S>
530 MOZ_IMPLICIT RecordedPushClipRect(S& aStream);
531
532 Rect mRect;
533 };
534
535 class RecordedPopClip : public RecordedDrawingEvent<RecordedPopClip> {
536 public:
RecordedPopClip(DrawTarget * aDT)537 MOZ_IMPLICIT RecordedPopClip(DrawTarget* aDT)
538 : RecordedDrawingEvent(POPCLIP, aDT) {}
539
540 bool PlayEvent(Translator* aTranslator) const override;
541
542 template <class S>
543 void Record(S& aStream) const;
544 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
545
GetName()546 std::string GetName() const override { return "PopClip"; }
547
548 private:
549 friend class RecordedEvent;
550
551 template <class S>
552 MOZ_IMPLICIT RecordedPopClip(S& aStream);
553 };
554
555 class RecordedPushLayer : public RecordedDrawingEvent<RecordedPushLayer> {
556 public:
RecordedPushLayer(DrawTarget * aDT,bool aOpaque,Float aOpacity,SourceSurface * aMask,const Matrix & aMaskTransform,const IntRect & aBounds,bool aCopyBackground)557 RecordedPushLayer(DrawTarget* aDT, bool aOpaque, Float aOpacity,
558 SourceSurface* aMask, const Matrix& aMaskTransform,
559 const IntRect& aBounds, bool aCopyBackground)
560 : RecordedDrawingEvent(PUSHLAYER, aDT),
561 mOpaque(aOpaque),
562 mOpacity(aOpacity),
563 mMask(aMask),
564 mMaskTransform(aMaskTransform),
565 mBounds(aBounds),
566 mCopyBackground(aCopyBackground) {}
567
568 bool PlayEvent(Translator* aTranslator) const override;
569
570 template <class S>
571 void Record(S& aStream) const;
572 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
573
GetName()574 std::string GetName() const override { return "PushLayer"; }
575
576 private:
577 friend class RecordedEvent;
578
579 template <class S>
580 MOZ_IMPLICIT RecordedPushLayer(S& aStream);
581
582 bool mOpaque;
583 Float mOpacity;
584 ReferencePtr mMask;
585 Matrix mMaskTransform;
586 IntRect mBounds;
587 bool mCopyBackground;
588 };
589
590 class RecordedPushLayerWithBlend
591 : public RecordedDrawingEvent<RecordedPushLayerWithBlend> {
592 public:
RecordedPushLayerWithBlend(DrawTarget * aDT,bool aOpaque,Float aOpacity,SourceSurface * aMask,const Matrix & aMaskTransform,const IntRect & aBounds,bool aCopyBackground,CompositionOp aCompositionOp)593 RecordedPushLayerWithBlend(DrawTarget* aDT, bool aOpaque, Float aOpacity,
594 SourceSurface* aMask, const Matrix& aMaskTransform,
595 const IntRect& aBounds, bool aCopyBackground,
596 CompositionOp aCompositionOp)
597 : RecordedDrawingEvent(PUSHLAYERWITHBLEND, aDT),
598 mOpaque(aOpaque),
599 mOpacity(aOpacity),
600 mMask(aMask),
601 mMaskTransform(aMaskTransform),
602 mBounds(aBounds),
603 mCopyBackground(aCopyBackground),
604 mCompositionOp(aCompositionOp) {}
605
606 bool PlayEvent(Translator* aTranslator) const override;
607
608 template <class S>
609 void Record(S& aStream) const;
610 virtual void OutputSimpleEventInfo(
611 std::stringstream& aStringStream) const override;
612
GetName()613 std::string GetName() const override { return "PushLayerWithBlend"; }
614
615 private:
616 friend class RecordedEvent;
617
618 template <class S>
619 MOZ_IMPLICIT RecordedPushLayerWithBlend(S& aStream);
620
621 bool mOpaque;
622 Float mOpacity;
623 ReferencePtr mMask;
624 Matrix mMaskTransform;
625 IntRect mBounds;
626 bool mCopyBackground;
627 CompositionOp mCompositionOp;
628 };
629
630 class RecordedPopLayer : public RecordedDrawingEvent<RecordedPopLayer> {
631 public:
RecordedPopLayer(DrawTarget * aDT)632 MOZ_IMPLICIT RecordedPopLayer(DrawTarget* aDT)
633 : RecordedDrawingEvent(POPLAYER, aDT) {}
634
635 bool PlayEvent(Translator* aTranslator) const override;
636
637 template <class S>
638 void Record(S& aStream) const;
639 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
640
GetName()641 std::string GetName() const override { return "PopLayer"; }
642
643 private:
644 friend class RecordedEvent;
645
646 template <class S>
647 MOZ_IMPLICIT RecordedPopLayer(S& aStream);
648 };
649
650 class RecordedSetTransform : public RecordedDrawingEvent<RecordedSetTransform> {
651 public:
RecordedSetTransform(DrawTarget * aDT,const Matrix & aTransform)652 RecordedSetTransform(DrawTarget* aDT, const Matrix& aTransform)
653 : RecordedDrawingEvent(SETTRANSFORM, aDT), mTransform(aTransform) {}
654
655 bool PlayEvent(Translator* aTranslator) const override;
656
657 template <class S>
658 void Record(S& aStream) const;
659 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
660
GetName()661 std::string GetName() const override { return "SetTransform"; }
662
663 Matrix mTransform;
664
665 private:
666 friend class RecordedEvent;
667
668 template <class S>
669 MOZ_IMPLICIT RecordedSetTransform(S& aStream);
670 };
671
672 class RecordedDrawSurface : public RecordedDrawingEvent<RecordedDrawSurface> {
673 public:
RecordedDrawSurface(DrawTarget * aDT,ReferencePtr aRefSource,const Rect & aDest,const Rect & aSource,const DrawSurfaceOptions & aDSOptions,const DrawOptions & aOptions)674 RecordedDrawSurface(DrawTarget* aDT, ReferencePtr aRefSource,
675 const Rect& aDest, const Rect& aSource,
676 const DrawSurfaceOptions& aDSOptions,
677 const DrawOptions& aOptions)
678 : RecordedDrawingEvent(DRAWSURFACE, aDT),
679 mRefSource(aRefSource),
680 mDest(aDest),
681 mSource(aSource),
682 mDSOptions(aDSOptions),
683 mOptions(aOptions) {}
684
685 bool PlayEvent(Translator* aTranslator) const override;
686
687 template <class S>
688 void Record(S& aStream) const;
689 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
690
GetName()691 std::string GetName() const override { return "DrawSurface"; }
692
693 private:
694 friend class RecordedEvent;
695
696 template <class S>
697 MOZ_IMPLICIT RecordedDrawSurface(S& aStream);
698
699 ReferencePtr mRefSource;
700 Rect mDest;
701 Rect mSource;
702 DrawSurfaceOptions mDSOptions;
703 DrawOptions mOptions;
704 };
705
706 class RecordedDrawDependentSurface
707 : public RecordedDrawingEvent<RecordedDrawDependentSurface> {
708 public:
RecordedDrawDependentSurface(DrawTarget * aDT,uint64_t aId,const Rect & aDest,const DrawSurfaceOptions & aDSOptions,const DrawOptions & aOptions)709 RecordedDrawDependentSurface(DrawTarget* aDT, uint64_t aId, const Rect& aDest,
710 const DrawSurfaceOptions& aDSOptions,
711 const DrawOptions& aOptions)
712 : RecordedDrawingEvent(DRAWDEPENDENTSURFACE, aDT),
713 mId(aId),
714 mDest(aDest),
715 mDSOptions(aDSOptions),
716 mOptions(aOptions) {}
717
718 bool PlayEvent(Translator* aTranslator) const override;
719
720 template <class S>
721 void Record(S& aStream) const;
722 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
723
GetName()724 std::string GetName() const override { return "DrawDependentSurface"; }
725
726 private:
727 friend class RecordedEvent;
728
729 template <class S>
730 MOZ_IMPLICIT RecordedDrawDependentSurface(S& aStream);
731
732 uint64_t mId;
733 Rect mDest;
734 DrawSurfaceOptions mDSOptions;
735 DrawOptions mOptions;
736 };
737
738 class RecordedDrawSurfaceWithShadow
739 : public RecordedDrawingEvent<RecordedDrawSurfaceWithShadow> {
740 public:
RecordedDrawSurfaceWithShadow(DrawTarget * aDT,ReferencePtr aRefSource,const Point & aDest,const DeviceColor & aColor,const Point & aOffset,Float aSigma,CompositionOp aOp)741 RecordedDrawSurfaceWithShadow(DrawTarget* aDT, ReferencePtr aRefSource,
742 const Point& aDest, const DeviceColor& aColor,
743 const Point& aOffset, Float aSigma,
744 CompositionOp aOp)
745 : RecordedDrawingEvent(DRAWSURFACEWITHSHADOW, aDT),
746 mRefSource(aRefSource),
747 mDest(aDest),
748 mColor(aColor),
749 mOffset(aOffset),
750 mSigma(aSigma),
751 mOp(aOp) {}
752
753 bool PlayEvent(Translator* aTranslator) const override;
754
755 template <class S>
756 void Record(S& aStream) const;
757 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
758
GetName()759 std::string GetName() const override { return "DrawSurfaceWithShadow"; }
760
761 private:
762 friend class RecordedEvent;
763
764 template <class S>
765 MOZ_IMPLICIT RecordedDrawSurfaceWithShadow(S& aStream);
766
767 ReferencePtr mRefSource;
768 Point mDest;
769 DeviceColor mColor;
770 Point mOffset;
771 Float mSigma;
772 CompositionOp mOp;
773 };
774
775 class RecordedDrawFilter : public RecordedDrawingEvent<RecordedDrawFilter> {
776 public:
RecordedDrawFilter(DrawTarget * aDT,ReferencePtr aNode,const Rect & aSourceRect,const Point & aDestPoint,const DrawOptions & aOptions)777 RecordedDrawFilter(DrawTarget* aDT, ReferencePtr aNode,
778 const Rect& aSourceRect, const Point& aDestPoint,
779 const DrawOptions& aOptions)
780 : RecordedDrawingEvent(DRAWFILTER, aDT),
781 mNode(aNode),
782 mSourceRect(aSourceRect),
783 mDestPoint(aDestPoint),
784 mOptions(aOptions) {}
785
786 bool PlayEvent(Translator* aTranslator) const override;
787
788 template <class S>
789 void Record(S& aStream) const;
790 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
791
GetName()792 std::string GetName() const override { return "DrawFilter"; }
793
794 private:
795 friend class RecordedEvent;
796
797 template <class S>
798 MOZ_IMPLICIT RecordedDrawFilter(S& aStream);
799
800 ReferencePtr mNode;
801 Rect mSourceRect;
802 Point mDestPoint;
803 DrawOptions mOptions;
804 };
805
806 class RecordedPathCreation : public RecordedEventDerived<RecordedPathCreation> {
807 public:
808 MOZ_IMPLICIT RecordedPathCreation(PathRecording* aPath);
809
810 bool PlayEvent(Translator* aTranslator) const override;
811
812 template <class S>
813 void Record(S& aStream) const;
814 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
815
GetName()816 std::string GetName() const override { return "Path Creation"; }
817
818 private:
819 friend class RecordedEvent;
820
821 ReferencePtr mRefPtr;
822 FillRule mFillRule;
823 RefPtr<PathRecording> mPath;
824 UniquePtr<PathOps> mPathOps;
825
826 template <class S>
827 MOZ_IMPLICIT RecordedPathCreation(S& aStream);
828 };
829
830 class RecordedPathDestruction
831 : public RecordedEventDerived<RecordedPathDestruction> {
832 public:
RecordedPathDestruction(PathRecording * aPath)833 MOZ_IMPLICIT RecordedPathDestruction(PathRecording* aPath)
834 : RecordedEventDerived(PATHDESTRUCTION), mRefPtr(aPath) {}
835
836 bool PlayEvent(Translator* aTranslator) const override;
837
838 template <class S>
839 void Record(S& aStream) const;
840 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
841
GetName()842 std::string GetName() const override { return "Path Destruction"; }
843
844 private:
845 friend class RecordedEvent;
846
847 ReferencePtr mRefPtr;
848
849 template <class S>
850 MOZ_IMPLICIT RecordedPathDestruction(S& aStream);
851 };
852
853 class RecordedSourceSurfaceCreation
854 : public RecordedEventDerived<RecordedSourceSurfaceCreation> {
855 public:
RecordedSourceSurfaceCreation(ReferencePtr aRefPtr,uint8_t * aData,int32_t aStride,const IntSize & aSize,SurfaceFormat aFormat)856 RecordedSourceSurfaceCreation(ReferencePtr aRefPtr, uint8_t* aData,
857 int32_t aStride, const IntSize& aSize,
858 SurfaceFormat aFormat)
859 : RecordedEventDerived(SOURCESURFACECREATION),
860 mRefPtr(aRefPtr),
861 mData(aData),
862 mStride(aStride),
863 mSize(aSize),
864 mFormat(aFormat),
865 mDataOwned(false) {}
866
867 ~RecordedSourceSurfaceCreation();
868
869 bool PlayEvent(Translator* aTranslator) const override;
870
871 template <class S>
872 void Record(S& aStream) const;
873 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
874
GetName()875 std::string GetName() const override { return "SourceSurface Creation"; }
876
877 private:
878 friend class RecordedEvent;
879
880 ReferencePtr mRefPtr;
881 uint8_t* mData = nullptr;
882 int32_t mStride;
883 IntSize mSize;
884 SurfaceFormat mFormat;
885 mutable bool mDataOwned;
886
887 template <class S>
888 MOZ_IMPLICIT RecordedSourceSurfaceCreation(S& aStream);
889 };
890
891 class RecordedSourceSurfaceDestruction
892 : public RecordedEventDerived<RecordedSourceSurfaceDestruction> {
893 public:
RecordedSourceSurfaceDestruction(ReferencePtr aRefPtr)894 MOZ_IMPLICIT RecordedSourceSurfaceDestruction(ReferencePtr aRefPtr)
895 : RecordedEventDerived(SOURCESURFACEDESTRUCTION), mRefPtr(aRefPtr) {}
896
897 bool PlayEvent(Translator* aTranslator) const override;
898
899 template <class S>
900 void Record(S& aStream) const;
901 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
902
GetName()903 std::string GetName() const override { return "SourceSurface Destruction"; }
904
905 private:
906 friend class RecordedEvent;
907
908 ReferencePtr mRefPtr;
909
910 template <class S>
911 MOZ_IMPLICIT RecordedSourceSurfaceDestruction(S& aStream);
912 };
913
914 class RecordedOptimizeSourceSurface
915 : public RecordedEventDerived<RecordedOptimizeSourceSurface> {
916 public:
RecordedOptimizeSourceSurface(ReferencePtr aSurface,ReferencePtr aDT,ReferencePtr aOptimizedSurface)917 RecordedOptimizeSourceSurface(ReferencePtr aSurface, ReferencePtr aDT,
918 ReferencePtr aOptimizedSurface)
919 : RecordedEventDerived(OPTIMIZESOURCESURFACE),
920 mSurface(aSurface),
921 mDT(aDT),
922 mOptimizedSurface(aOptimizedSurface) {}
923
924 bool PlayEvent(Translator* aTranslator) const override;
925
926 template <class S>
927 void Record(S& aStream) const;
928 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
929
GetName()930 std::string GetName() const override { return "OptimizeSourceSurface"; }
931
932 private:
933 friend class RecordedEvent;
934
935 ReferencePtr mSurface;
936 ReferencePtr mDT;
937 ReferencePtr mOptimizedSurface;
938
939 template <class S>
940 MOZ_IMPLICIT RecordedOptimizeSourceSurface(S& aStream);
941 };
942
943 class RecordedExternalSurfaceCreation
944 : public RecordedEventDerived<RecordedExternalSurfaceCreation> {
945 public:
RecordedExternalSurfaceCreation(ReferencePtr aRefPtr,const uint64_t aKey)946 RecordedExternalSurfaceCreation(ReferencePtr aRefPtr, const uint64_t aKey)
947 : RecordedEventDerived(EXTERNALSURFACECREATION),
948 mRefPtr(aRefPtr),
949 mKey(aKey) {}
950
951 ~RecordedExternalSurfaceCreation() = default;
952
953 virtual bool PlayEvent(Translator* aTranslator) const;
954
955 template <class S>
956 void Record(S& aStream) const;
957 virtual void OutputSimpleEventInfo(std::stringstream& aStringStream) const;
958
GetName()959 virtual std::string GetName() const {
960 return "SourceSurfaceSharedData Creation";
961 }
962
963 private:
964 friend class RecordedEvent;
965
966 ReferencePtr mRefPtr;
967 uint64_t mKey;
968
969 template <class S>
970 MOZ_IMPLICIT RecordedExternalSurfaceCreation(S& aStream);
971 };
972
973 class RecordedFilterNodeCreation
974 : public RecordedEventDerived<RecordedFilterNodeCreation> {
975 public:
RecordedFilterNodeCreation(ReferencePtr aRefPtr,FilterType aType)976 RecordedFilterNodeCreation(ReferencePtr aRefPtr, FilterType aType)
977 : RecordedEventDerived(FILTERNODECREATION),
978 mRefPtr(aRefPtr),
979 mType(aType) {}
980
981 ~RecordedFilterNodeCreation();
982
983 bool PlayEvent(Translator* aTranslator) const override;
984
985 template <class S>
986 void Record(S& aStream) const;
987 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
988
GetName()989 std::string GetName() const override { return "FilterNode Creation"; }
990
991 private:
992 friend class RecordedEvent;
993
994 ReferencePtr mRefPtr;
995 FilterType mType;
996
997 template <class S>
998 MOZ_IMPLICIT RecordedFilterNodeCreation(S& aStream);
999 };
1000
1001 class RecordedFilterNodeDestruction
1002 : public RecordedEventDerived<RecordedFilterNodeDestruction> {
1003 public:
RecordedFilterNodeDestruction(ReferencePtr aRefPtr)1004 MOZ_IMPLICIT RecordedFilterNodeDestruction(ReferencePtr aRefPtr)
1005 : RecordedEventDerived(FILTERNODEDESTRUCTION), mRefPtr(aRefPtr) {}
1006
1007 bool PlayEvent(Translator* aTranslator) const override;
1008
1009 template <class S>
1010 void Record(S& aStream) const;
1011 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1012
GetName()1013 std::string GetName() const override { return "FilterNode Destruction"; }
1014
1015 private:
1016 friend class RecordedEvent;
1017
1018 ReferencePtr mRefPtr;
1019
1020 template <class S>
1021 MOZ_IMPLICIT RecordedFilterNodeDestruction(S& aStream);
1022 };
1023
1024 class RecordedGradientStopsCreation
1025 : public RecordedEventDerived<RecordedGradientStopsCreation> {
1026 public:
RecordedGradientStopsCreation(ReferencePtr aRefPtr,GradientStop * aStops,uint32_t aNumStops,ExtendMode aExtendMode)1027 RecordedGradientStopsCreation(ReferencePtr aRefPtr, GradientStop* aStops,
1028 uint32_t aNumStops, ExtendMode aExtendMode)
1029 : RecordedEventDerived(GRADIENTSTOPSCREATION),
1030 mRefPtr(aRefPtr),
1031 mStops(aStops),
1032 mNumStops(aNumStops),
1033 mExtendMode(aExtendMode),
1034 mDataOwned(false) {}
1035
1036 ~RecordedGradientStopsCreation();
1037
1038 bool PlayEvent(Translator* aTranslator) const override;
1039
1040 template <class S>
1041 void Record(S& aStream) const;
1042 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1043
GetName()1044 std::string GetName() const override { return "GradientStops Creation"; }
1045
1046 private:
1047 friend class RecordedEvent;
1048
1049 ReferencePtr mRefPtr;
1050 GradientStop* mStops = nullptr;
1051 uint32_t mNumStops = 0;
1052 ExtendMode mExtendMode;
1053 bool mDataOwned;
1054
1055 template <class S>
1056 MOZ_IMPLICIT RecordedGradientStopsCreation(S& aStream);
1057 };
1058
1059 class RecordedGradientStopsDestruction
1060 : public RecordedEventDerived<RecordedGradientStopsDestruction> {
1061 public:
RecordedGradientStopsDestruction(ReferencePtr aRefPtr)1062 MOZ_IMPLICIT RecordedGradientStopsDestruction(ReferencePtr aRefPtr)
1063 : RecordedEventDerived(GRADIENTSTOPSDESTRUCTION), mRefPtr(aRefPtr) {}
1064
1065 bool PlayEvent(Translator* aTranslator) const override;
1066
1067 template <class S>
1068 void Record(S& aStream) const;
1069 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1070
GetName()1071 std::string GetName() const override { return "GradientStops Destruction"; }
1072
1073 private:
1074 friend class RecordedEvent;
1075
1076 ReferencePtr mRefPtr;
1077
1078 template <class S>
1079 MOZ_IMPLICIT RecordedGradientStopsDestruction(S& aStream);
1080 };
1081
1082 class RecordedFlush : public RecordedDrawingEvent<RecordedFlush> {
1083 public:
RecordedFlush(DrawTarget * aDT)1084 explicit RecordedFlush(DrawTarget* aDT) : RecordedDrawingEvent(FLUSH, aDT) {}
1085
1086 bool PlayEvent(Translator* aTranslator) const final;
1087
1088 template <class S>
1089 void Record(S& aStream) const;
1090 virtual void OutputSimpleEventInfo(
1091 std::stringstream& aStringStream) const override;
1092
GetName()1093 virtual std::string GetName() const override { return "Flush"; }
1094
1095 private:
1096 friend class RecordedEvent;
1097
1098 template <class S>
1099 MOZ_IMPLICIT RecordedFlush(S& aStream);
1100 };
1101
1102 class RecordedDetachAllSnapshots
1103 : public RecordedDrawingEvent<RecordedDetachAllSnapshots> {
1104 public:
RecordedDetachAllSnapshots(DrawTarget * aDT)1105 explicit RecordedDetachAllSnapshots(DrawTarget* aDT)
1106 : RecordedDrawingEvent(DETACHALLSNAPSHOTS, aDT) {}
1107
1108 bool PlayEvent(Translator* aTranslator) const final;
1109
1110 template <class S>
1111 void Record(S& aStream) const;
1112 virtual void OutputSimpleEventInfo(
1113 std::stringstream& aStringStream) const override;
1114
GetName()1115 virtual std::string GetName() const override { return "DetachAllSnapshots"; }
1116
1117 private:
1118 friend class RecordedEvent;
1119
1120 template <class S>
1121 MOZ_IMPLICIT RecordedDetachAllSnapshots(S& aStream);
1122 };
1123
1124 class RecordedSnapshot : public RecordedEventDerived<RecordedSnapshot> {
1125 public:
RecordedSnapshot(ReferencePtr aRefPtr,DrawTarget * aDT)1126 RecordedSnapshot(ReferencePtr aRefPtr, DrawTarget* aDT)
1127 : RecordedEventDerived(SNAPSHOT), mRefPtr(aRefPtr), mDT(aDT) {}
1128
1129 bool PlayEvent(Translator* aTranslator) const override;
1130
1131 template <class S>
1132 void Record(S& aStream) const;
1133 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1134
GetName()1135 std::string GetName() const override { return "Snapshot"; }
1136
1137 private:
1138 friend class RecordedEvent;
1139
1140 ReferencePtr mRefPtr;
1141 ReferencePtr mDT;
1142
1143 template <class S>
1144 MOZ_IMPLICIT RecordedSnapshot(S& aStream);
1145 };
1146
1147 class RecordedIntoLuminanceSource
1148 : public RecordedEventDerived<RecordedIntoLuminanceSource> {
1149 public:
RecordedIntoLuminanceSource(ReferencePtr aRefPtr,DrawTarget * aDT,LuminanceType aLuminanceType,float aOpacity)1150 RecordedIntoLuminanceSource(ReferencePtr aRefPtr, DrawTarget* aDT,
1151 LuminanceType aLuminanceType, float aOpacity)
1152 : RecordedEventDerived(INTOLUMINANCE),
1153 mRefPtr(aRefPtr),
1154 mDT(aDT),
1155 mLuminanceType(aLuminanceType),
1156 mOpacity(aOpacity) {}
1157
1158 bool PlayEvent(Translator* aTranslator) const override;
1159
1160 template <class S>
1161 void Record(S& aStream) const;
1162 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1163
GetName()1164 std::string GetName() const override { return "IntoLuminanceSource"; }
1165
1166 private:
1167 friend class RecordedEvent;
1168
1169 ReferencePtr mRefPtr;
1170 ReferencePtr mDT;
1171 LuminanceType mLuminanceType;
1172 float mOpacity;
1173
1174 template <class S>
1175 MOZ_IMPLICIT RecordedIntoLuminanceSource(S& aStream);
1176 };
1177
1178 class RecordedFontData : public RecordedEventDerived<RecordedFontData> {
1179 public:
FontDataProc(const uint8_t * aData,uint32_t aSize,uint32_t aIndex,void * aBaton)1180 static void FontDataProc(const uint8_t* aData, uint32_t aSize,
1181 uint32_t aIndex, void* aBaton) {
1182 auto recordedFontData = static_cast<RecordedFontData*>(aBaton);
1183 recordedFontData->SetFontData(aData, aSize, aIndex);
1184 }
1185
RecordedFontData(UnscaledFont * aUnscaledFont)1186 explicit RecordedFontData(UnscaledFont* aUnscaledFont)
1187 : RecordedEventDerived(FONTDATA),
1188 mType(aUnscaledFont->GetType()),
1189 mFontDetails() {
1190 mGetFontFileDataSucceeded =
1191 aUnscaledFont->GetFontFileData(&FontDataProc, this) && mData;
1192 }
1193
1194 virtual ~RecordedFontData();
1195
IsValid()1196 bool IsValid() const { return mGetFontFileDataSucceeded; }
1197
1198 bool PlayEvent(Translator* aTranslator) const override;
1199
1200 template <class S>
1201 void Record(S& aStream) const;
1202 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1203
GetName()1204 std::string GetName() const override { return "Font Data"; }
1205
1206 void SetFontData(const uint8_t* aData, uint32_t aSize, uint32_t aIndex);
1207
1208 bool GetFontDetails(RecordedFontDetails& fontDetails);
1209
1210 private:
1211 friend class RecordedEvent;
1212
1213 FontType mType;
1214 uint8_t* mData = nullptr;
1215 RecordedFontDetails mFontDetails;
1216
1217 bool mGetFontFileDataSucceeded;
1218
1219 template <class S>
1220 MOZ_IMPLICIT RecordedFontData(S& aStream);
1221 };
1222
1223 class RecordedFontDescriptor
1224 : public RecordedEventDerived<RecordedFontDescriptor> {
1225 public:
FontDescCb(const uint8_t * aData,uint32_t aSize,uint32_t aIndex,void * aBaton)1226 static void FontDescCb(const uint8_t* aData, uint32_t aSize, uint32_t aIndex,
1227 void* aBaton) {
1228 auto recordedFontDesc = static_cast<RecordedFontDescriptor*>(aBaton);
1229 recordedFontDesc->SetFontDescriptor(aData, aSize, aIndex);
1230 }
1231
RecordedFontDescriptor(UnscaledFont * aUnscaledFont)1232 explicit RecordedFontDescriptor(UnscaledFont* aUnscaledFont)
1233 : RecordedEventDerived(FONTDESC),
1234 mType(aUnscaledFont->GetType()),
1235 mIndex(0),
1236 mRefPtr(aUnscaledFont) {
1237 mHasDesc = aUnscaledFont->GetFontDescriptor(FontDescCb, this);
1238 }
1239
1240 virtual ~RecordedFontDescriptor();
1241
IsValid()1242 bool IsValid() const { return mHasDesc; }
1243
1244 bool PlayEvent(Translator* aTranslator) const override;
1245
1246 template <class S>
1247 void Record(S& aStream) const;
1248 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1249
GetName()1250 std::string GetName() const override { return "Font Desc"; }
1251
1252 private:
1253 friend class RecordedEvent;
1254
1255 void SetFontDescriptor(const uint8_t* aData, uint32_t aSize, uint32_t aIndex);
1256
1257 bool mHasDesc;
1258
1259 FontType mType;
1260 std::vector<uint8_t> mData;
1261 uint32_t mIndex;
1262 ReferencePtr mRefPtr;
1263
1264 template <class S>
1265 MOZ_IMPLICIT RecordedFontDescriptor(S& aStream);
1266 };
1267
1268 class RecordedUnscaledFontCreation
1269 : public RecordedEventDerived<RecordedUnscaledFontCreation> {
1270 public:
FontInstanceDataProc(const uint8_t * aData,uint32_t aSize,void * aBaton)1271 static void FontInstanceDataProc(const uint8_t* aData, uint32_t aSize,
1272 void* aBaton) {
1273 auto recordedUnscaledFontCreation =
1274 static_cast<RecordedUnscaledFontCreation*>(aBaton);
1275 recordedUnscaledFontCreation->SetFontInstanceData(aData, aSize);
1276 }
1277
RecordedUnscaledFontCreation(UnscaledFont * aUnscaledFont,RecordedFontDetails aFontDetails)1278 RecordedUnscaledFontCreation(UnscaledFont* aUnscaledFont,
1279 RecordedFontDetails aFontDetails)
1280 : RecordedEventDerived(UNSCALEDFONTCREATION),
1281 mRefPtr(aUnscaledFont),
1282 mFontDataKey(aFontDetails.fontDataKey),
1283 mIndex(aFontDetails.index) {
1284 aUnscaledFont->GetFontInstanceData(FontInstanceDataProc, this);
1285 }
1286
1287 bool PlayEvent(Translator* aTranslator) const override;
1288
1289 template <class S>
1290 void Record(S& aStream) const;
1291 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1292
GetName()1293 std::string GetName() const override { return "UnscaledFont Creation"; }
1294
1295 void SetFontInstanceData(const uint8_t* aData, uint32_t aSize);
1296
1297 private:
1298 friend class RecordedEvent;
1299
1300 ReferencePtr mRefPtr;
1301 uint64_t mFontDataKey;
1302 uint32_t mIndex;
1303 std::vector<uint8_t> mInstanceData;
1304
1305 template <class S>
1306 MOZ_IMPLICIT RecordedUnscaledFontCreation(S& aStream);
1307 };
1308
1309 class RecordedUnscaledFontDestruction
1310 : public RecordedEventDerived<RecordedUnscaledFontDestruction> {
1311 public:
RecordedUnscaledFontDestruction(ReferencePtr aRefPtr)1312 MOZ_IMPLICIT RecordedUnscaledFontDestruction(ReferencePtr aRefPtr)
1313 : RecordedEventDerived(UNSCALEDFONTDESTRUCTION), mRefPtr(aRefPtr) {}
1314
1315 bool PlayEvent(Translator* aTranslator) const override;
1316 template <class S>
1317 void Record(S& aStream) const;
1318 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1319
GetName()1320 std::string GetName() const override { return "UnscaledFont Destruction"; }
1321
1322 private:
1323 friend class RecordedEvent;
1324
1325 ReferencePtr mRefPtr;
1326
1327 template <class S>
1328 MOZ_IMPLICIT RecordedUnscaledFontDestruction(S& aStream);
1329 };
1330
1331 class RecordedScaledFontCreation
1332 : public RecordedEventDerived<RecordedScaledFontCreation> {
1333 public:
FontInstanceDataProc(const uint8_t * aData,uint32_t aSize,const FontVariation * aVariations,uint32_t aNumVariations,void * aBaton)1334 static void FontInstanceDataProc(const uint8_t* aData, uint32_t aSize,
1335 const FontVariation* aVariations,
1336 uint32_t aNumVariations, void* aBaton) {
1337 auto recordedScaledFontCreation =
1338 static_cast<RecordedScaledFontCreation*>(aBaton);
1339 recordedScaledFontCreation->SetFontInstanceData(aData, aSize, aVariations,
1340 aNumVariations);
1341 }
1342
RecordedScaledFontCreation(ScaledFont * aScaledFont,UnscaledFont * aUnscaledFont)1343 RecordedScaledFontCreation(ScaledFont* aScaledFont,
1344 UnscaledFont* aUnscaledFont)
1345 : RecordedEventDerived(SCALEDFONTCREATION),
1346 mRefPtr(aScaledFont),
1347 mUnscaledFont(aUnscaledFont),
1348 mGlyphSize(aScaledFont->GetSize()) {
1349 aScaledFont->GetFontInstanceData(FontInstanceDataProc, this);
1350 }
1351
1352 bool PlayEvent(Translator* aTranslator) const override;
1353
1354 template <class S>
1355 void Record(S& aStream) const;
1356 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1357
GetName()1358 std::string GetName() const override { return "ScaledFont Creation"; }
1359
1360 void SetFontInstanceData(const uint8_t* aData, uint32_t aSize,
1361 const FontVariation* aVariations,
1362 uint32_t aNumVariations);
1363
1364 private:
1365 friend class RecordedEvent;
1366
1367 ReferencePtr mRefPtr;
1368 ReferencePtr mUnscaledFont;
1369 Float mGlyphSize;
1370 std::vector<uint8_t> mInstanceData;
1371 std::vector<FontVariation> mVariations;
1372
1373 template <class S>
1374 MOZ_IMPLICIT RecordedScaledFontCreation(S& aStream);
1375 };
1376
1377 class RecordedScaledFontDestruction
1378 : public RecordedEventDerived<RecordedScaledFontDestruction> {
1379 public:
RecordedScaledFontDestruction(ReferencePtr aRefPtr)1380 MOZ_IMPLICIT RecordedScaledFontDestruction(ReferencePtr aRefPtr)
1381 : RecordedEventDerived(SCALEDFONTDESTRUCTION), mRefPtr(aRefPtr) {}
1382
1383 bool PlayEvent(Translator* aTranslator) const override;
1384
1385 template <class S>
1386 void Record(S& aStream) const;
1387 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1388
GetName()1389 std::string GetName() const override { return "ScaledFont Destruction"; }
1390
1391 private:
1392 friend class RecordedEvent;
1393
1394 ReferencePtr mRefPtr;
1395
1396 template <class S>
1397 MOZ_IMPLICIT RecordedScaledFontDestruction(S& aStream);
1398 };
1399
1400 class RecordedMaskSurface : public RecordedDrawingEvent<RecordedMaskSurface> {
1401 public:
RecordedMaskSurface(DrawTarget * aDT,const Pattern & aPattern,ReferencePtr aRefMask,const Point & aOffset,const DrawOptions & aOptions)1402 RecordedMaskSurface(DrawTarget* aDT, const Pattern& aPattern,
1403 ReferencePtr aRefMask, const Point& aOffset,
1404 const DrawOptions& aOptions)
1405 : RecordedDrawingEvent(MASKSURFACE, aDT),
1406 mPattern(),
1407 mRefMask(aRefMask),
1408 mOffset(aOffset),
1409 mOptions(aOptions) {
1410 StorePattern(mPattern, aPattern);
1411 }
1412
1413 bool PlayEvent(Translator* aTranslator) const override;
1414
1415 template <class S>
1416 void Record(S& aStream) const;
1417 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1418
GetName()1419 std::string GetName() const override { return "MaskSurface"; }
1420
1421 private:
1422 friend class RecordedEvent;
1423
1424 template <class S>
1425 MOZ_IMPLICIT RecordedMaskSurface(S& aStream);
1426
1427 PatternStorage mPattern;
1428 ReferencePtr mRefMask;
1429 Point mOffset;
1430 DrawOptions mOptions;
1431 };
1432
1433 class RecordedFilterNodeSetAttribute
1434 : public RecordedEventDerived<RecordedFilterNodeSetAttribute> {
1435 public:
1436 enum ArgType {
1437 ARGTYPE_UINT32,
1438 ARGTYPE_BOOL,
1439 ARGTYPE_FLOAT,
1440 ARGTYPE_SIZE,
1441 ARGTYPE_INTSIZE,
1442 ARGTYPE_INTPOINT,
1443 ARGTYPE_RECT,
1444 ARGTYPE_INTRECT,
1445 ARGTYPE_POINT,
1446 ARGTYPE_MATRIX,
1447 ARGTYPE_MATRIX5X4,
1448 ARGTYPE_POINT3D,
1449 ARGTYPE_COLOR,
1450 ARGTYPE_FLOAT_ARRAY
1451 };
1452
1453 template <typename T>
RecordedFilterNodeSetAttribute(FilterNode * aNode,uint32_t aIndex,T aArgument,ArgType aArgType)1454 RecordedFilterNodeSetAttribute(FilterNode* aNode, uint32_t aIndex,
1455 T aArgument, ArgType aArgType)
1456 : RecordedEventDerived(FILTERNODESETATTRIBUTE),
1457 mNode(aNode),
1458 mIndex(aIndex),
1459 mArgType(aArgType) {
1460 mPayload.resize(sizeof(T));
1461 memcpy(&mPayload.front(), &aArgument, sizeof(T));
1462 }
1463
RecordedFilterNodeSetAttribute(FilterNode * aNode,uint32_t aIndex,const Float * aFloat,uint32_t aSize)1464 RecordedFilterNodeSetAttribute(FilterNode* aNode, uint32_t aIndex,
1465 const Float* aFloat, uint32_t aSize)
1466 : RecordedEventDerived(FILTERNODESETATTRIBUTE),
1467 mNode(aNode),
1468 mIndex(aIndex),
1469 mArgType(ARGTYPE_FLOAT_ARRAY) {
1470 mPayload.resize(sizeof(Float) * aSize);
1471 memcpy(&mPayload.front(), aFloat, sizeof(Float) * aSize);
1472 }
1473
1474 bool PlayEvent(Translator* aTranslator) const override;
1475 template <class S>
1476 void Record(S& aStream) const;
1477 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1478
GetName()1479 std::string GetName() const override { return "SetAttribute"; }
1480
1481 private:
1482 friend class RecordedEvent;
1483
1484 ReferencePtr mNode;
1485
1486 uint32_t mIndex;
1487 ArgType mArgType;
1488 std::vector<uint8_t> mPayload;
1489
1490 template <class S>
1491 MOZ_IMPLICIT RecordedFilterNodeSetAttribute(S& aStream);
1492 };
1493
1494 class RecordedFilterNodeSetInput
1495 : public RecordedEventDerived<RecordedFilterNodeSetInput> {
1496 public:
RecordedFilterNodeSetInput(FilterNode * aNode,uint32_t aIndex,FilterNode * aInputNode)1497 RecordedFilterNodeSetInput(FilterNode* aNode, uint32_t aIndex,
1498 FilterNode* aInputNode)
1499 : RecordedEventDerived(FILTERNODESETINPUT),
1500 mNode(aNode),
1501 mIndex(aIndex),
1502 mInputFilter(aInputNode),
1503 mInputSurface(nullptr) {}
1504
RecordedFilterNodeSetInput(FilterNode * aNode,uint32_t aIndex,SourceSurface * aInputSurface)1505 RecordedFilterNodeSetInput(FilterNode* aNode, uint32_t aIndex,
1506 SourceSurface* aInputSurface)
1507 : RecordedEventDerived(FILTERNODESETINPUT),
1508 mNode(aNode),
1509 mIndex(aIndex),
1510 mInputFilter(nullptr),
1511 mInputSurface(aInputSurface) {}
1512
1513 bool PlayEvent(Translator* aTranslator) const override;
1514 template <class S>
1515 void Record(S& aStream) const;
1516 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1517
GetName()1518 std::string GetName() const override { return "SetInput"; }
1519
1520 private:
1521 friend class RecordedEvent;
1522
1523 ReferencePtr mNode;
1524 uint32_t mIndex;
1525 ReferencePtr mInputFilter;
1526 ReferencePtr mInputSurface;
1527
1528 template <class S>
1529 MOZ_IMPLICIT RecordedFilterNodeSetInput(S& aStream);
1530 };
1531
1532 class RecordedLink : public RecordedDrawingEvent<RecordedLink> {
1533 public:
RecordedLink(DrawTarget * aDT,const char * aDestination,const Rect & aRect)1534 RecordedLink(DrawTarget* aDT, const char* aDestination, const Rect& aRect)
1535 : RecordedDrawingEvent(LINK, aDT),
1536 mDestination(aDestination),
1537 mRect(aRect) {}
1538
1539 bool PlayEvent(Translator* aTranslator) const override;
1540 template <class S>
1541 void Record(S& aStream) const;
1542 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1543
GetName()1544 std::string GetName() const override { return "Link"; }
1545
1546 private:
1547 friend class RecordedEvent;
1548
1549 std::string mDestination;
1550 Rect mRect;
1551
1552 template <class S>
1553 MOZ_IMPLICIT RecordedLink(S& aStream);
1554 };
1555
NameFromBackend(BackendType aType)1556 static std::string NameFromBackend(BackendType aType) {
1557 switch (aType) {
1558 case BackendType::NONE:
1559 return "None";
1560 case BackendType::DIRECT2D:
1561 return "Direct2D";
1562 default:
1563 return "Unknown";
1564 }
1565 }
1566
1567 template <class S>
RecordPatternData(S & aStream,const PatternStorage & aPattern)1568 void RecordedEvent::RecordPatternData(S& aStream,
1569 const PatternStorage& aPattern) const {
1570 WriteElement(aStream, aPattern.mType);
1571
1572 switch (aPattern.mType) {
1573 case PatternType::COLOR: {
1574 WriteElement(aStream, *reinterpret_cast<const ColorPatternStorage*>(
1575 &aPattern.mStorage));
1576 return;
1577 }
1578 case PatternType::LINEAR_GRADIENT: {
1579 WriteElement(aStream,
1580 *reinterpret_cast<const LinearGradientPatternStorage*>(
1581 &aPattern.mStorage));
1582 return;
1583 }
1584 case PatternType::RADIAL_GRADIENT: {
1585 WriteElement(aStream,
1586 *reinterpret_cast<const RadialGradientPatternStorage*>(
1587 &aPattern.mStorage));
1588 return;
1589 }
1590 case PatternType::CONIC_GRADIENT: {
1591 WriteElement(aStream,
1592 *reinterpret_cast<const ConicGradientPatternStorage*>(
1593 &aPattern.mStorage));
1594 return;
1595 }
1596 case PatternType::SURFACE: {
1597 WriteElement(aStream, *reinterpret_cast<const SurfacePatternStorage*>(
1598 &aPattern.mStorage));
1599 return;
1600 }
1601 default:
1602 return;
1603 }
1604 }
1605
1606 template <class S>
ReadPatternData(S & aStream,PatternStorage & aPattern)1607 void RecordedEvent::ReadPatternData(S& aStream,
1608 PatternStorage& aPattern) const {
1609 ReadElementConstrained(aStream, aPattern.mType, PatternType::COLOR,
1610 kHighestPatternType);
1611
1612 switch (aPattern.mType) {
1613 case PatternType::COLOR: {
1614 ReadElement(aStream,
1615 *reinterpret_cast<ColorPatternStorage*>(&aPattern.mStorage));
1616 return;
1617 }
1618 case PatternType::LINEAR_GRADIENT: {
1619 ReadElement(aStream, *reinterpret_cast<LinearGradientPatternStorage*>(
1620 &aPattern.mStorage));
1621 return;
1622 }
1623 case PatternType::RADIAL_GRADIENT: {
1624 ReadElement(aStream, *reinterpret_cast<RadialGradientPatternStorage*>(
1625 &aPattern.mStorage));
1626 return;
1627 }
1628 case PatternType::CONIC_GRADIENT: {
1629 ReadElement(aStream, *reinterpret_cast<ConicGradientPatternStorage*>(
1630 &aPattern.mStorage));
1631 return;
1632 }
1633 case PatternType::SURFACE: {
1634 SurfacePatternStorage* sps =
1635 reinterpret_cast<SurfacePatternStorage*>(&aPattern.mStorage);
1636 ReadElement(aStream, *sps);
1637 if (sps->mExtend < ExtendMode::CLAMP ||
1638 sps->mExtend > ExtendMode::REFLECT) {
1639 aStream.SetIsBad();
1640 return;
1641 }
1642
1643 if (sps->mSamplingFilter < SamplingFilter::GOOD ||
1644 sps->mSamplingFilter >= SamplingFilter::SENTINEL) {
1645 aStream.SetIsBad();
1646 }
1647 return;
1648 }
1649 default:
1650 return;
1651 }
1652 }
1653
StorePattern(PatternStorage & aDestination,const Pattern & aSource)1654 inline void RecordedEvent::StorePattern(PatternStorage& aDestination,
1655 const Pattern& aSource) const {
1656 aDestination.mType = aSource.GetType();
1657
1658 switch (aSource.GetType()) {
1659 case PatternType::COLOR: {
1660 reinterpret_cast<ColorPatternStorage*>(&aDestination.mStorage)->mColor =
1661 static_cast<const ColorPattern*>(&aSource)->mColor;
1662 return;
1663 }
1664 case PatternType::LINEAR_GRADIENT: {
1665 LinearGradientPatternStorage* store =
1666 reinterpret_cast<LinearGradientPatternStorage*>(
1667 &aDestination.mStorage);
1668 const LinearGradientPattern* pat =
1669 static_cast<const LinearGradientPattern*>(&aSource);
1670 store->mBegin = pat->mBegin;
1671 store->mEnd = pat->mEnd;
1672 store->mMatrix = pat->mMatrix;
1673 store->mStops = pat->mStops.get();
1674 return;
1675 }
1676 case PatternType::RADIAL_GRADIENT: {
1677 RadialGradientPatternStorage* store =
1678 reinterpret_cast<RadialGradientPatternStorage*>(
1679 &aDestination.mStorage);
1680 const RadialGradientPattern* pat =
1681 static_cast<const RadialGradientPattern*>(&aSource);
1682 store->mCenter1 = pat->mCenter1;
1683 store->mCenter2 = pat->mCenter2;
1684 store->mRadius1 = pat->mRadius1;
1685 store->mRadius2 = pat->mRadius2;
1686 store->mMatrix = pat->mMatrix;
1687 store->mStops = pat->mStops.get();
1688 return;
1689 }
1690 case PatternType::CONIC_GRADIENT: {
1691 ConicGradientPatternStorage* store =
1692 reinterpret_cast<ConicGradientPatternStorage*>(
1693 &aDestination.mStorage);
1694 const ConicGradientPattern* pat =
1695 static_cast<const ConicGradientPattern*>(&aSource);
1696 store->mCenter = pat->mCenter;
1697 store->mAngle = pat->mAngle;
1698 store->mStartOffset = pat->mStartOffset;
1699 store->mEndOffset = pat->mEndOffset;
1700 store->mMatrix = pat->mMatrix;
1701 store->mStops = pat->mStops.get();
1702 return;
1703 }
1704 case PatternType::SURFACE: {
1705 SurfacePatternStorage* store =
1706 reinterpret_cast<SurfacePatternStorage*>(&aDestination.mStorage);
1707 const SurfacePattern* pat = static_cast<const SurfacePattern*>(&aSource);
1708 store->mExtend = pat->mExtendMode;
1709 store->mSamplingFilter = pat->mSamplingFilter;
1710 store->mMatrix = pat->mMatrix;
1711 store->mSurface = pat->mSurface;
1712 store->mSamplingRect = pat->mSamplingRect;
1713 return;
1714 }
1715 }
1716 }
1717
1718 template <class S>
RecordStrokeOptions(S & aStream,const StrokeOptions & aStrokeOptions)1719 void RecordedEvent::RecordStrokeOptions(
1720 S& aStream, const StrokeOptions& aStrokeOptions) const {
1721 JoinStyle joinStyle = aStrokeOptions.mLineJoin;
1722 CapStyle capStyle = aStrokeOptions.mLineCap;
1723
1724 WriteElement(aStream, uint64_t(aStrokeOptions.mDashLength));
1725 WriteElement(aStream, aStrokeOptions.mDashOffset);
1726 WriteElement(aStream, aStrokeOptions.mLineWidth);
1727 WriteElement(aStream, aStrokeOptions.mMiterLimit);
1728 WriteElement(aStream, joinStyle);
1729 WriteElement(aStream, capStyle);
1730
1731 if (!aStrokeOptions.mDashPattern) {
1732 return;
1733 }
1734
1735 aStream.write((char*)aStrokeOptions.mDashPattern,
1736 sizeof(Float) * aStrokeOptions.mDashLength);
1737 }
1738
1739 template <class S>
ReadStrokeOptions(S & aStream,StrokeOptions & aStrokeOptions)1740 void RecordedEvent::ReadStrokeOptions(S& aStream,
1741 StrokeOptions& aStrokeOptions) {
1742 uint64_t dashLength;
1743 JoinStyle joinStyle;
1744 CapStyle capStyle;
1745
1746 ReadElement(aStream, dashLength);
1747 ReadElement(aStream, aStrokeOptions.mDashOffset);
1748 ReadElement(aStream, aStrokeOptions.mLineWidth);
1749 ReadElement(aStream, aStrokeOptions.mMiterLimit);
1750 ReadElementConstrained(aStream, joinStyle, JoinStyle::BEVEL,
1751 JoinStyle::MITER_OR_BEVEL);
1752 ReadElementConstrained(aStream, capStyle, CapStyle::BUTT, CapStyle::SQUARE);
1753 // On 32 bit we truncate the value of dashLength.
1754 // See also bug 811850 for history.
1755 aStrokeOptions.mDashLength = size_t(dashLength);
1756 aStrokeOptions.mLineJoin = joinStyle;
1757 aStrokeOptions.mLineCap = capStyle;
1758
1759 if (!aStrokeOptions.mDashLength || !aStream.good()) {
1760 return;
1761 }
1762
1763 mDashPatternStorage.resize(aStrokeOptions.mDashLength);
1764 aStrokeOptions.mDashPattern = &mDashPatternStorage.front();
1765 aStream.read((char*)aStrokeOptions.mDashPattern,
1766 sizeof(Float) * aStrokeOptions.mDashLength);
1767 }
1768
1769 template <class S>
ReadDrawOptions(S & aStream,DrawOptions & aDrawOptions)1770 static void ReadDrawOptions(S& aStream, DrawOptions& aDrawOptions) {
1771 ReadElement(aStream, aDrawOptions);
1772 if (aDrawOptions.mAntialiasMode < AntialiasMode::NONE ||
1773 aDrawOptions.mAntialiasMode > AntialiasMode::DEFAULT) {
1774 aStream.SetIsBad();
1775 return;
1776 }
1777
1778 if (aDrawOptions.mCompositionOp < CompositionOp::OP_OVER ||
1779 aDrawOptions.mCompositionOp > CompositionOp::OP_COUNT) {
1780 aStream.SetIsBad();
1781 }
1782 }
1783
1784 template <class S>
ReadDrawSurfaceOptions(S & aStream,DrawSurfaceOptions & aDrawSurfaceOptions)1785 static void ReadDrawSurfaceOptions(S& aStream,
1786 DrawSurfaceOptions& aDrawSurfaceOptions) {
1787 ReadElement(aStream, aDrawSurfaceOptions);
1788 if (aDrawSurfaceOptions.mSamplingFilter < SamplingFilter::GOOD ||
1789 aDrawSurfaceOptions.mSamplingFilter >= SamplingFilter::SENTINEL) {
1790 aStream.SetIsBad();
1791 return;
1792 }
1793
1794 if (aDrawSurfaceOptions.mSamplingBounds < SamplingBounds::UNBOUNDED ||
1795 aDrawSurfaceOptions.mSamplingBounds > SamplingBounds::BOUNDED) {
1796 aStream.SetIsBad();
1797 }
1798 }
1799
OutputSimplePatternInfo(const PatternStorage & aStorage,std::stringstream & aOutput)1800 inline void RecordedEvent::OutputSimplePatternInfo(
1801 const PatternStorage& aStorage, std::stringstream& aOutput) const {
1802 switch (aStorage.mType) {
1803 case PatternType::COLOR: {
1804 const DeviceColor color =
1805 reinterpret_cast<const ColorPatternStorage*>(&aStorage.mStorage)
1806 ->mColor;
1807 aOutput << "DeviceColor: (" << color.r << ", " << color.g << ", "
1808 << color.b << ", " << color.a << ")";
1809 return;
1810 }
1811 case PatternType::LINEAR_GRADIENT: {
1812 const LinearGradientPatternStorage* store =
1813 reinterpret_cast<const LinearGradientPatternStorage*>(
1814 &aStorage.mStorage);
1815
1816 aOutput << "LinearGradient (" << store->mBegin.x << ", "
1817 << store->mBegin.y << ") - (" << store->mEnd.x << ", "
1818 << store->mEnd.y << ") Stops: " << store->mStops;
1819 return;
1820 }
1821 case PatternType::RADIAL_GRADIENT: {
1822 const RadialGradientPatternStorage* store =
1823 reinterpret_cast<const RadialGradientPatternStorage*>(
1824 &aStorage.mStorage);
1825 aOutput << "RadialGradient (Center 1: (" << store->mCenter1.x << ", "
1826 << store->mCenter2.y << ") Radius 2: " << store->mRadius2;
1827 return;
1828 }
1829 case PatternType::CONIC_GRADIENT: {
1830 const ConicGradientPatternStorage* store =
1831 reinterpret_cast<const ConicGradientPatternStorage*>(
1832 &aStorage.mStorage);
1833 aOutput << "ConicGradient (Center: (" << store->mCenter.x << ", "
1834 << store->mCenter.y << ") Angle: " << store->mAngle
1835 << " Range:" << store->mStartOffset << " - " << store->mEndOffset;
1836 return;
1837 }
1838 case PatternType::SURFACE: {
1839 const SurfacePatternStorage* store =
1840 reinterpret_cast<const SurfacePatternStorage*>(&aStorage.mStorage);
1841 aOutput << "Surface (0x" << store->mSurface << ")";
1842 return;
1843 }
1844 }
1845 }
1846
1847 template <class T>
1848 template <class S>
RecordedDrawingEvent(RecordedEvent::EventType aType,S & aStream)1849 RecordedDrawingEvent<T>::RecordedDrawingEvent(RecordedEvent::EventType aType,
1850 S& aStream)
1851 : RecordedEventDerived<T>(aType) {
1852 ReadElement(aStream, mDT);
1853 }
1854
1855 template <class T>
1856 template <class S>
Record(S & aStream)1857 void RecordedDrawingEvent<T>::Record(S& aStream) const {
1858 WriteElement(aStream, mDT);
1859 }
1860
PlayEvent(Translator * aTranslator)1861 inline bool RecordedDrawTargetCreation::PlayEvent(
1862 Translator* aTranslator) const {
1863 RefPtr<DrawTarget> newDT =
1864 aTranslator->CreateDrawTarget(mRefPtr, mRect.Size(), mFormat);
1865
1866 // If we couldn't create a DrawTarget this will probably cause us to crash
1867 // with nullptr later in the playback, so return false to abort.
1868 if (!newDT) {
1869 return false;
1870 }
1871
1872 if (mHasExistingData) {
1873 Rect dataRect(0, 0, mExistingData->GetSize().width,
1874 mExistingData->GetSize().height);
1875 newDT->DrawSurface(mExistingData, dataRect, dataRect);
1876 }
1877
1878 return true;
1879 }
1880
1881 template <class S>
Record(S & aStream)1882 void RecordedDrawTargetCreation::Record(S& aStream) const {
1883 WriteElement(aStream, mRefPtr);
1884 WriteElement(aStream, mBackendType);
1885 WriteElement(aStream, mRect);
1886 WriteElement(aStream, mFormat);
1887 WriteElement(aStream, mHasExistingData);
1888
1889 if (mHasExistingData) {
1890 MOZ_ASSERT(mExistingData);
1891 MOZ_ASSERT(mExistingData->GetSize() == mRect.Size());
1892 RefPtr<DataSourceSurface> dataSurf = mExistingData->GetDataSurface();
1893
1894 DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ);
1895 for (int y = 0; y < mRect.height; y++) {
1896 aStream.write((const char*)map.GetData() + y * map.GetStride(),
1897 BytesPerPixel(mFormat) * mRect.width);
1898 }
1899 }
1900 }
1901
1902 template <class S>
RecordedDrawTargetCreation(S & aStream)1903 RecordedDrawTargetCreation::RecordedDrawTargetCreation(S& aStream)
1904 : RecordedEventDerived(DRAWTARGETCREATION), mExistingData(nullptr) {
1905 ReadElement(aStream, mRefPtr);
1906 ReadElementConstrained(aStream, mBackendType, BackendType::NONE,
1907 BackendType::CAPTURE);
1908 ReadElement(aStream, mRect);
1909 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
1910 SurfaceFormat::UNKNOWN);
1911 ReadElement(aStream, mHasExistingData);
1912
1913 if (mHasExistingData) {
1914 RefPtr<DataSourceSurface> dataSurf =
1915 Factory::CreateDataSourceSurface(mRect.Size(), mFormat);
1916 if (!dataSurf) {
1917 gfxWarning()
1918 << "RecordedDrawTargetCreation had to reset mHasExistingData";
1919 mHasExistingData = false;
1920 return;
1921 }
1922
1923 DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ);
1924 for (int y = 0; y < mRect.height; y++) {
1925 aStream.read((char*)map.GetData() + y * map.GetStride(),
1926 BytesPerPixel(mFormat) * mRect.width);
1927 }
1928 mExistingData = dataSurf;
1929 }
1930 }
1931
OutputSimpleEventInfo(std::stringstream & aStringStream)1932 inline void RecordedDrawTargetCreation::OutputSimpleEventInfo(
1933 std::stringstream& aStringStream) const {
1934 aStringStream << "[" << mRefPtr << "] DrawTarget Creation (Type: "
1935 << NameFromBackend(mBackendType) << ", Size: " << mRect.width
1936 << "x" << mRect.height << ")";
1937 }
1938
PlayEvent(Translator * aTranslator)1939 inline bool RecordedDrawTargetDestruction::PlayEvent(
1940 Translator* aTranslator) const {
1941 aTranslator->RemoveDrawTarget(mRefPtr);
1942 return true;
1943 }
1944
1945 template <class S>
Record(S & aStream)1946 void RecordedDrawTargetDestruction::Record(S& aStream) const {
1947 WriteElement(aStream, mRefPtr);
1948 }
1949
1950 template <class S>
RecordedDrawTargetDestruction(S & aStream)1951 RecordedDrawTargetDestruction::RecordedDrawTargetDestruction(S& aStream)
1952 : RecordedEventDerived(DRAWTARGETDESTRUCTION) {
1953 ReadElement(aStream, mRefPtr);
1954 }
1955
OutputSimpleEventInfo(std::stringstream & aStringStream)1956 inline void RecordedDrawTargetDestruction::OutputSimpleEventInfo(
1957 std::stringstream& aStringStream) const {
1958 aStringStream << "[" << mRefPtr << "] DrawTarget Destruction";
1959 }
1960
PlayEvent(Translator * aTranslator)1961 inline bool RecordedCreateSimilarDrawTarget::PlayEvent(
1962 Translator* aTranslator) const {
1963 RefPtr<DrawTarget> drawTarget = aTranslator->GetReferenceDrawTarget();
1964 if (!drawTarget) {
1965 // We might end up with a null reference draw target due to a device
1966 // failure, just return false so that we can recover.
1967 return false;
1968 }
1969
1970 RefPtr<DrawTarget> newDT =
1971 drawTarget->CreateSimilarDrawTarget(mSize, mFormat);
1972
1973 // If we couldn't create a DrawTarget this will probably cause us to crash
1974 // with nullptr later in the playback, so return false to abort.
1975 if (!newDT) {
1976 return false;
1977 }
1978
1979 aTranslator->AddDrawTarget(mRefPtr, newDT);
1980 return true;
1981 }
1982
1983 template <class S>
Record(S & aStream)1984 void RecordedCreateSimilarDrawTarget::Record(S& aStream) const {
1985 WriteElement(aStream, mRefPtr);
1986 WriteElement(aStream, mSize);
1987 WriteElement(aStream, mFormat);
1988 }
1989
1990 template <class S>
RecordedCreateSimilarDrawTarget(S & aStream)1991 RecordedCreateSimilarDrawTarget::RecordedCreateSimilarDrawTarget(S& aStream)
1992 : RecordedEventDerived(CREATESIMILARDRAWTARGET) {
1993 ReadElement(aStream, mRefPtr);
1994 ReadElement(aStream, mSize);
1995 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
1996 SurfaceFormat::UNKNOWN);
1997 }
1998
OutputSimpleEventInfo(std::stringstream & aStringStream)1999 inline void RecordedCreateSimilarDrawTarget::OutputSimpleEventInfo(
2000 std::stringstream& aStringStream) const {
2001 aStringStream << "[" << mRefPtr
2002 << "] CreateSimilarDrawTarget (Size: " << mSize.width << "x"
2003 << mSize.height << ")";
2004 }
2005
PlayEvent(Translator * aTranslator)2006 inline bool RecordedCreateDrawTargetForFilter::PlayEvent(
2007 Translator* aTranslator) const {
2008 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2009 if (!dt) {
2010 return false;
2011 }
2012
2013 IntRect baseRect = dt->GetRect();
2014
2015 auto maxRect = IntRect(IntPoint(0, 0), mMaxSize);
2016
2017 auto clone = dt->GetTransform();
2018 bool invertible = clone.Invert();
2019 // mSourceRect is in filter space. The filter outputs from mSourceRect need
2020 // to be drawn at mDestPoint in user space.
2021 Rect userSpaceSource = Rect(mDestPoint, mSourceRect.Size());
2022 if (invertible) {
2023 // Try to reduce the source rect so that it's not much bigger
2024 // than the draw target. The result is not minimal. Examples
2025 // are left as an exercise for the reader.
2026 auto destRect = IntRectToRect(baseRect);
2027 Rect userSpaceBounds = clone.TransformBounds(destRect);
2028 userSpaceSource = userSpaceSource.Intersect(userSpaceBounds);
2029 }
2030
2031 // Compute how much we moved the top-left of the source rect by, and use that
2032 // to compute the new dest point, and move our intersected source rect back
2033 // into the (new) filter space.
2034 Point shift = userSpaceSource.TopLeft() - mDestPoint;
2035 Rect filterSpaceSource =
2036 Rect(mSourceRect.TopLeft() + shift, userSpaceSource.Size());
2037
2038 baseRect = RoundedOut(filterSpaceSource);
2039 FilterNode* filter = aTranslator->LookupFilterNode(mFilter);
2040 if (!filter) {
2041 return false;
2042 }
2043
2044 IntRect transformedRect = filter->MapRectToSource(
2045 baseRect, maxRect, aTranslator->LookupFilterNode(mSource));
2046
2047 // Intersect with maxRect to make sure we didn't end up with something bigger
2048 transformedRect = transformedRect.Intersect(maxRect);
2049
2050 // If we end up with an empty rect make it 1x1 so that things don't break.
2051 if (transformedRect.IsEmpty()) {
2052 transformedRect = IntRect(0, 0, 1, 1);
2053 }
2054
2055 RefPtr<DrawTarget> newDT =
2056 dt->CreateSimilarDrawTarget(transformedRect.Size(), mFormat);
2057 newDT =
2058 gfx::Factory::CreateOffsetDrawTarget(newDT, transformedRect.TopLeft());
2059
2060 // If we couldn't create a DrawTarget this will probably cause us to crash
2061 // with nullptr later in the playback, so return false to abort.
2062 if (!newDT) {
2063 return false;
2064 }
2065
2066 aTranslator->AddDrawTarget(mRefPtr, newDT);
2067 return true;
2068 }
2069
PlayEvent(Translator * aTranslator)2070 inline bool RecordedCreateClippedDrawTarget::PlayEvent(
2071 Translator* aTranslator) const {
2072 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2073 if (!dt) {
2074 return false;
2075 }
2076
2077 RefPtr<DrawTarget> newDT = dt->CreateClippedDrawTarget(mBounds, mFormat);
2078
2079 // If we couldn't create a DrawTarget this will probably cause us to crash
2080 // with nullptr later in the playback, so return false to abort.
2081 if (!newDT) {
2082 return false;
2083 }
2084
2085 aTranslator->AddDrawTarget(mRefPtr, newDT);
2086 return true;
2087 }
2088
2089 template <class S>
Record(S & aStream)2090 void RecordedCreateClippedDrawTarget::Record(S& aStream) const {
2091 RecordedDrawingEvent::Record(aStream);
2092 WriteElement(aStream, mRefPtr);
2093 WriteElement(aStream, mBounds);
2094 WriteElement(aStream, mFormat);
2095 }
2096
2097 template <class S>
RecordedCreateClippedDrawTarget(S & aStream)2098 RecordedCreateClippedDrawTarget::RecordedCreateClippedDrawTarget(S& aStream)
2099 : RecordedDrawingEvent(CREATECLIPPEDDRAWTARGET, aStream) {
2100 ReadElement(aStream, mRefPtr);
2101 ReadElement(aStream, mBounds);
2102 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2103 SurfaceFormat::UNKNOWN);
2104 }
2105
OutputSimpleEventInfo(std::stringstream & aStringStream)2106 inline void RecordedCreateClippedDrawTarget::OutputSimpleEventInfo(
2107 std::stringstream& aStringStream) const {
2108 aStringStream << "[" << mRefPtr << "] CreateClippedDrawTarget ()";
2109 }
2110
2111 template <class S>
Record(S & aStream)2112 void RecordedCreateDrawTargetForFilter::Record(S& aStream) const {
2113 RecordedDrawingEvent::Record(aStream);
2114 WriteElement(aStream, mRefPtr);
2115 WriteElement(aStream, mMaxSize);
2116 WriteElement(aStream, mFormat);
2117 WriteElement(aStream, mFilter);
2118 WriteElement(aStream, mSource);
2119 WriteElement(aStream, mSourceRect);
2120 WriteElement(aStream, mDestPoint);
2121 }
2122
2123 template <class S>
RecordedCreateDrawTargetForFilter(S & aStream)2124 RecordedCreateDrawTargetForFilter::RecordedCreateDrawTargetForFilter(S& aStream)
2125 : RecordedDrawingEvent(CREATEDRAWTARGETFORFILTER, aStream) {
2126 ReadElement(aStream, mRefPtr);
2127 ReadElement(aStream, mMaxSize);
2128 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2129 SurfaceFormat::UNKNOWN);
2130 ReadElement(aStream, mFilter);
2131 ReadElement(aStream, mSource);
2132 ReadElement(aStream, mSourceRect);
2133 ReadElement(aStream, mDestPoint);
2134 }
2135
OutputSimpleEventInfo(std::stringstream & aStringStream)2136 inline void RecordedCreateDrawTargetForFilter::OutputSimpleEventInfo(
2137 std::stringstream& aStringStream) const {
2138 aStringStream << "[" << mRefPtr << "] CreateDrawTargetForFilter ()";
2139 }
2140
2141 struct GenericPattern {
GenericPatternGenericPattern2142 GenericPattern(const PatternStorage& aStorage, Translator* aTranslator)
2143 : mPattern(nullptr), mTranslator(aTranslator) {
2144 mStorage = const_cast<PatternStorage*>(&aStorage);
2145 }
2146
~GenericPatternGenericPattern2147 ~GenericPattern() {
2148 if (mPattern) {
2149 mPattern->~Pattern();
2150 }
2151 }
2152
2153 operator Pattern*() {
2154 switch (mStorage->mType) {
2155 case PatternType::COLOR:
2156 return new (mColPat) ColorPattern(
2157 reinterpret_cast<ColorPatternStorage*>(&mStorage->mStorage)
2158 ->mColor);
2159 case PatternType::SURFACE: {
2160 SurfacePatternStorage* storage =
2161 reinterpret_cast<SurfacePatternStorage*>(&mStorage->mStorage);
2162 mPattern = new (mSurfPat)
2163 SurfacePattern(mTranslator->LookupSourceSurface(storage->mSurface),
2164 storage->mExtend, storage->mMatrix,
2165 storage->mSamplingFilter, storage->mSamplingRect);
2166 return mPattern;
2167 }
2168 case PatternType::LINEAR_GRADIENT: {
2169 LinearGradientPatternStorage* storage =
2170 reinterpret_cast<LinearGradientPatternStorage*>(
2171 &mStorage->mStorage);
2172 mPattern = new (mLinGradPat) LinearGradientPattern(
2173 storage->mBegin, storage->mEnd,
2174 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2175 : nullptr,
2176 storage->mMatrix);
2177 return mPattern;
2178 }
2179 case PatternType::RADIAL_GRADIENT: {
2180 RadialGradientPatternStorage* storage =
2181 reinterpret_cast<RadialGradientPatternStorage*>(
2182 &mStorage->mStorage);
2183 mPattern = new (mRadGradPat) RadialGradientPattern(
2184 storage->mCenter1, storage->mCenter2, storage->mRadius1,
2185 storage->mRadius2,
2186 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2187 : nullptr,
2188 storage->mMatrix);
2189 return mPattern;
2190 }
2191 case PatternType::CONIC_GRADIENT: {
2192 ConicGradientPatternStorage* storage =
2193 reinterpret_cast<ConicGradientPatternStorage*>(&mStorage->mStorage);
2194 mPattern = new (mConGradPat) ConicGradientPattern(
2195 storage->mCenter, storage->mAngle, storage->mStartOffset,
2196 storage->mEndOffset,
2197 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2198 : nullptr,
2199 storage->mMatrix);
2200 return mPattern;
2201 }
2202 default:
2203 return new (mColPat) ColorPattern(DeviceColor());
2204 }
2205
2206 return mPattern;
2207 }
2208
2209 union {
2210 char mColPat[sizeof(ColorPattern)];
2211 char mLinGradPat[sizeof(LinearGradientPattern)];
2212 char mRadGradPat[sizeof(RadialGradientPattern)];
2213 char mConGradPat[sizeof(ConicGradientPattern)];
2214 char mSurfPat[sizeof(SurfacePattern)];
2215 };
2216
2217 PatternStorage* mStorage;
2218 Pattern* mPattern;
2219 Translator* mTranslator;
2220 };
2221
PlayEvent(Translator * aTranslator)2222 inline bool RecordedFillRect::PlayEvent(Translator* aTranslator) const {
2223 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2224 if (!dt) {
2225 return false;
2226 }
2227
2228 dt->FillRect(mRect, *GenericPattern(mPattern, aTranslator), mOptions);
2229 return true;
2230 }
2231
2232 template <class S>
Record(S & aStream)2233 void RecordedFillRect::Record(S& aStream) const {
2234 RecordedDrawingEvent::Record(aStream);
2235 WriteElement(aStream, mRect);
2236 WriteElement(aStream, mOptions);
2237 RecordPatternData(aStream, mPattern);
2238 }
2239
2240 template <class S>
RecordedFillRect(S & aStream)2241 RecordedFillRect::RecordedFillRect(S& aStream)
2242 : RecordedDrawingEvent(FILLRECT, aStream) {
2243 ReadElement(aStream, mRect);
2244 ReadDrawOptions(aStream, mOptions);
2245 ReadPatternData(aStream, mPattern);
2246 }
2247
OutputSimpleEventInfo(std::stringstream & aStringStream)2248 inline void RecordedFillRect::OutputSimpleEventInfo(
2249 std::stringstream& aStringStream) const {
2250 aStringStream << "[" << mDT << "] FillRect (" << mRect.X() << ", "
2251 << mRect.Y() << " - " << mRect.Width() << " x "
2252 << mRect.Height() << ") ";
2253 OutputSimplePatternInfo(mPattern, aStringStream);
2254 }
2255
PlayEvent(Translator * aTranslator)2256 inline bool RecordedStrokeRect::PlayEvent(Translator* aTranslator) const {
2257 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2258 if (!dt) {
2259 return false;
2260 }
2261
2262 dt->StrokeRect(mRect, *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2263 mOptions);
2264 return true;
2265 }
2266
2267 template <class S>
Record(S & aStream)2268 void RecordedStrokeRect::Record(S& aStream) const {
2269 RecordedDrawingEvent::Record(aStream);
2270 WriteElement(aStream, mRect);
2271 WriteElement(aStream, mOptions);
2272 RecordPatternData(aStream, mPattern);
2273 RecordStrokeOptions(aStream, mStrokeOptions);
2274 }
2275
2276 template <class S>
RecordedStrokeRect(S & aStream)2277 RecordedStrokeRect::RecordedStrokeRect(S& aStream)
2278 : RecordedDrawingEvent(STROKERECT, aStream) {
2279 ReadElement(aStream, mRect);
2280 ReadDrawOptions(aStream, mOptions);
2281 ReadPatternData(aStream, mPattern);
2282 ReadStrokeOptions(aStream, mStrokeOptions);
2283 }
2284
OutputSimpleEventInfo(std::stringstream & aStringStream)2285 inline void RecordedStrokeRect::OutputSimpleEventInfo(
2286 std::stringstream& aStringStream) const {
2287 aStringStream << "[" << mDT << "] StrokeRect (" << mRect.X() << ", "
2288 << mRect.Y() << " - " << mRect.Width() << " x "
2289 << mRect.Height()
2290 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2291 OutputSimplePatternInfo(mPattern, aStringStream);
2292 }
2293
PlayEvent(Translator * aTranslator)2294 inline bool RecordedStrokeLine::PlayEvent(Translator* aTranslator) const {
2295 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2296 if (!dt) {
2297 return false;
2298 }
2299
2300 dt->StrokeLine(mBegin, mEnd, *GenericPattern(mPattern, aTranslator),
2301 mStrokeOptions, mOptions);
2302 return true;
2303 }
2304
2305 template <class S>
Record(S & aStream)2306 void RecordedStrokeLine::Record(S& aStream) const {
2307 RecordedDrawingEvent::Record(aStream);
2308 WriteElement(aStream, mBegin);
2309 WriteElement(aStream, mEnd);
2310 WriteElement(aStream, mOptions);
2311 RecordPatternData(aStream, mPattern);
2312 RecordStrokeOptions(aStream, mStrokeOptions);
2313 }
2314
2315 template <class S>
RecordedStrokeLine(S & aStream)2316 RecordedStrokeLine::RecordedStrokeLine(S& aStream)
2317 : RecordedDrawingEvent(STROKELINE, aStream) {
2318 ReadElement(aStream, mBegin);
2319 ReadElement(aStream, mEnd);
2320 ReadDrawOptions(aStream, mOptions);
2321 ReadPatternData(aStream, mPattern);
2322 ReadStrokeOptions(aStream, mStrokeOptions);
2323 }
2324
OutputSimpleEventInfo(std::stringstream & aStringStream)2325 inline void RecordedStrokeLine::OutputSimpleEventInfo(
2326 std::stringstream& aStringStream) const {
2327 aStringStream << "[" << mDT << "] StrokeLine (" << mBegin.x << ", "
2328 << mBegin.y << " - " << mEnd.x << ", " << mEnd.y
2329 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2330 OutputSimplePatternInfo(mPattern, aStringStream);
2331 }
2332
PlayEvent(Translator * aTranslator)2333 inline bool RecordedFill::PlayEvent(Translator* aTranslator) const {
2334 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2335 if (!dt) {
2336 return false;
2337 }
2338
2339 dt->Fill(aTranslator->LookupPath(mPath),
2340 *GenericPattern(mPattern, aTranslator), mOptions);
2341 return true;
2342 }
2343
2344 template <class S>
RecordedFill(S & aStream)2345 RecordedFill::RecordedFill(S& aStream) : RecordedDrawingEvent(FILL, aStream) {
2346 ReadElement(aStream, mPath);
2347 ReadDrawOptions(aStream, mOptions);
2348 ReadPatternData(aStream, mPattern);
2349 }
2350
2351 template <class S>
Record(S & aStream)2352 void RecordedFill::Record(S& aStream) const {
2353 RecordedDrawingEvent::Record(aStream);
2354 WriteElement(aStream, mPath);
2355 WriteElement(aStream, mOptions);
2356 RecordPatternData(aStream, mPattern);
2357 }
2358
OutputSimpleEventInfo(std::stringstream & aStringStream)2359 inline void RecordedFill::OutputSimpleEventInfo(
2360 std::stringstream& aStringStream) const {
2361 aStringStream << "[" << mDT << "] Fill (" << mPath << ") ";
2362 OutputSimplePatternInfo(mPattern, aStringStream);
2363 }
2364
~RecordedFillGlyphs()2365 inline RecordedFillGlyphs::~RecordedFillGlyphs() { delete[] mGlyphs; }
2366
PlayEvent(Translator * aTranslator)2367 inline bool RecordedFillGlyphs::PlayEvent(Translator* aTranslator) const {
2368 if (mNumGlyphs > 0 && !mGlyphs) {
2369 // Glyph allocation failed
2370 return false;
2371 }
2372
2373 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2374 if (!dt) {
2375 return false;
2376 }
2377
2378 ScaledFont* scaledFont = aTranslator->LookupScaledFont(mScaledFont);
2379 if (!scaledFont) {
2380 return false;
2381 }
2382
2383 GlyphBuffer buffer;
2384 buffer.mGlyphs = mGlyphs;
2385 buffer.mNumGlyphs = mNumGlyphs;
2386 dt->FillGlyphs(scaledFont, buffer, *GenericPattern(mPattern, aTranslator),
2387 mOptions);
2388 return true;
2389 }
2390
2391 template <class S>
RecordedFillGlyphs(S & aStream)2392 RecordedFillGlyphs::RecordedFillGlyphs(S& aStream)
2393 : RecordedDrawingEvent(FILLGLYPHS, aStream) {
2394 ReadElement(aStream, mScaledFont);
2395 ReadDrawOptions(aStream, mOptions);
2396 ReadPatternData(aStream, mPattern);
2397 ReadElement(aStream, mNumGlyphs);
2398 if (!aStream.good() || mNumGlyphs <= 0) {
2399 return;
2400 }
2401
2402 mGlyphs = new (fallible) Glyph[mNumGlyphs];
2403 if (!mGlyphs) {
2404 gfxCriticalNote
2405 << "RecordedFillGlyphs failed to allocate glyphs of size "
2406 << mNumGlyphs;
2407 aStream.SetIsBad();
2408 } else {
2409 aStream.read((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
2410 }
2411 }
2412
2413 template <class S>
Record(S & aStream)2414 void RecordedFillGlyphs::Record(S& aStream) const {
2415 RecordedDrawingEvent::Record(aStream);
2416 WriteElement(aStream, mScaledFont);
2417 WriteElement(aStream, mOptions);
2418 RecordPatternData(aStream, mPattern);
2419 WriteElement(aStream, mNumGlyphs);
2420 aStream.write((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
2421 }
2422
OutputSimpleEventInfo(std::stringstream & aStringStream)2423 inline void RecordedFillGlyphs::OutputSimpleEventInfo(
2424 std::stringstream& aStringStream) const {
2425 aStringStream << "[" << mDT << "] FillGlyphs (" << mScaledFont << ") ";
2426 OutputSimplePatternInfo(mPattern, aStringStream);
2427 }
2428
PlayEvent(Translator * aTranslator)2429 inline bool RecordedMask::PlayEvent(Translator* aTranslator) const {
2430 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2431 if (!dt) {
2432 return false;
2433 }
2434
2435 dt->Mask(*GenericPattern(mSource, aTranslator),
2436 *GenericPattern(mMask, aTranslator), mOptions);
2437 return true;
2438 }
2439
2440 template <class S>
RecordedMask(S & aStream)2441 RecordedMask::RecordedMask(S& aStream) : RecordedDrawingEvent(MASK, aStream) {
2442 ReadDrawOptions(aStream, mOptions);
2443 ReadPatternData(aStream, mSource);
2444 ReadPatternData(aStream, mMask);
2445 }
2446
2447 template <class S>
Record(S & aStream)2448 void RecordedMask::Record(S& aStream) const {
2449 RecordedDrawingEvent::Record(aStream);
2450 WriteElement(aStream, mOptions);
2451 RecordPatternData(aStream, mSource);
2452 RecordPatternData(aStream, mMask);
2453 }
2454
OutputSimpleEventInfo(std::stringstream & aStringStream)2455 inline void RecordedMask::OutputSimpleEventInfo(
2456 std::stringstream& aStringStream) const {
2457 aStringStream << "[" << mDT << "] Mask (Source: ";
2458 OutputSimplePatternInfo(mSource, aStringStream);
2459 aStringStream << " Mask: ";
2460 OutputSimplePatternInfo(mMask, aStringStream);
2461 }
2462
PlayEvent(Translator * aTranslator)2463 inline bool RecordedStroke::PlayEvent(Translator* aTranslator) const {
2464 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2465 if (!dt) {
2466 return false;
2467 }
2468
2469 Path* path = aTranslator->LookupPath(mPath);
2470 if (!path) {
2471 return false;
2472 }
2473
2474 dt->Stroke(path, *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2475 mOptions);
2476 return true;
2477 }
2478
2479 template <class S>
Record(S & aStream)2480 void RecordedStroke::Record(S& aStream) const {
2481 RecordedDrawingEvent::Record(aStream);
2482 WriteElement(aStream, mPath);
2483 WriteElement(aStream, mOptions);
2484 RecordPatternData(aStream, mPattern);
2485 RecordStrokeOptions(aStream, mStrokeOptions);
2486 }
2487
2488 template <class S>
RecordedStroke(S & aStream)2489 RecordedStroke::RecordedStroke(S& aStream)
2490 : RecordedDrawingEvent(STROKE, aStream) {
2491 ReadElement(aStream, mPath);
2492 ReadDrawOptions(aStream, mOptions);
2493 ReadPatternData(aStream, mPattern);
2494 ReadStrokeOptions(aStream, mStrokeOptions);
2495 }
2496
OutputSimpleEventInfo(std::stringstream & aStringStream)2497 inline void RecordedStroke::OutputSimpleEventInfo(
2498 std::stringstream& aStringStream) const {
2499 aStringStream << "[" << mDT << "] Stroke (" << mPath
2500 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2501 OutputSimplePatternInfo(mPattern, aStringStream);
2502 }
2503
PlayEvent(Translator * aTranslator)2504 inline bool RecordedClearRect::PlayEvent(Translator* aTranslator) const {
2505 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2506 if (!dt) {
2507 return false;
2508 }
2509
2510 dt->ClearRect(mRect);
2511 return true;
2512 }
2513
2514 template <class S>
Record(S & aStream)2515 void RecordedClearRect::Record(S& aStream) const {
2516 RecordedDrawingEvent::Record(aStream);
2517 WriteElement(aStream, mRect);
2518 }
2519
2520 template <class S>
RecordedClearRect(S & aStream)2521 RecordedClearRect::RecordedClearRect(S& aStream)
2522 : RecordedDrawingEvent(CLEARRECT, aStream) {
2523 ReadElement(aStream, mRect);
2524 }
2525
OutputSimpleEventInfo(std::stringstream & aStringStream)2526 inline void RecordedClearRect::OutputSimpleEventInfo(
2527 std::stringstream& aStringStream) const {
2528 aStringStream << "[" << mDT << "] ClearRect (" << mRect.X() << ", "
2529 << mRect.Y() << " - " << mRect.Width() << " x "
2530 << mRect.Height() << ") ";
2531 }
2532
PlayEvent(Translator * aTranslator)2533 inline bool RecordedCopySurface::PlayEvent(Translator* aTranslator) const {
2534 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2535 if (!dt) {
2536 return false;
2537 }
2538
2539 SourceSurface* surface = aTranslator->LookupSourceSurface(mSourceSurface);
2540 if (!surface) {
2541 return false;
2542 }
2543
2544 dt->CopySurface(surface, mSourceRect, mDest);
2545 return true;
2546 }
2547
2548 template <class S>
Record(S & aStream)2549 void RecordedCopySurface::Record(S& aStream) const {
2550 RecordedDrawingEvent::Record(aStream);
2551 WriteElement(aStream, mSourceSurface);
2552 WriteElement(aStream, mSourceRect);
2553 WriteElement(aStream, mDest);
2554 }
2555
2556 template <class S>
RecordedCopySurface(S & aStream)2557 RecordedCopySurface::RecordedCopySurface(S& aStream)
2558 : RecordedDrawingEvent(COPYSURFACE, aStream) {
2559 ReadElement(aStream, mSourceSurface);
2560 ReadElement(aStream, mSourceRect);
2561 ReadElement(aStream, mDest);
2562 }
2563
OutputSimpleEventInfo(std::stringstream & aStringStream)2564 inline void RecordedCopySurface::OutputSimpleEventInfo(
2565 std::stringstream& aStringStream) const {
2566 aStringStream << "[" << mDT << "] CopySurface (" << mSourceSurface << ")";
2567 }
2568
PlayEvent(Translator * aTranslator)2569 inline bool RecordedPushClip::PlayEvent(Translator* aTranslator) const {
2570 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2571 if (!dt) {
2572 return false;
2573 }
2574
2575 Path* path = aTranslator->LookupPath(mPath);
2576 if (!path) {
2577 return false;
2578 }
2579
2580 dt->PushClip(path);
2581 return true;
2582 }
2583
2584 template <class S>
Record(S & aStream)2585 void RecordedPushClip::Record(S& aStream) const {
2586 RecordedDrawingEvent::Record(aStream);
2587 WriteElement(aStream, mPath);
2588 }
2589
2590 template <class S>
RecordedPushClip(S & aStream)2591 RecordedPushClip::RecordedPushClip(S& aStream)
2592 : RecordedDrawingEvent(PUSHCLIP, aStream) {
2593 ReadElement(aStream, mPath);
2594 }
2595
OutputSimpleEventInfo(std::stringstream & aStringStream)2596 inline void RecordedPushClip::OutputSimpleEventInfo(
2597 std::stringstream& aStringStream) const {
2598 aStringStream << "[" << mDT << "] PushClip (" << mPath << ") ";
2599 }
2600
PlayEvent(Translator * aTranslator)2601 inline bool RecordedPushClipRect::PlayEvent(Translator* aTranslator) const {
2602 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2603 if (!dt) {
2604 return false;
2605 }
2606
2607 dt->PushClipRect(mRect);
2608 return true;
2609 }
2610
2611 template <class S>
Record(S & aStream)2612 void RecordedPushClipRect::Record(S& aStream) const {
2613 RecordedDrawingEvent::Record(aStream);
2614 WriteElement(aStream, mRect);
2615 }
2616
2617 template <class S>
RecordedPushClipRect(S & aStream)2618 RecordedPushClipRect::RecordedPushClipRect(S& aStream)
2619 : RecordedDrawingEvent(PUSHCLIPRECT, aStream) {
2620 ReadElement(aStream, mRect);
2621 }
2622
OutputSimpleEventInfo(std::stringstream & aStringStream)2623 inline void RecordedPushClipRect::OutputSimpleEventInfo(
2624 std::stringstream& aStringStream) const {
2625 aStringStream << "[" << mDT << "] PushClipRect (" << mRect.X() << ", "
2626 << mRect.Y() << " - " << mRect.Width() << " x "
2627 << mRect.Height() << ") ";
2628 }
2629
PlayEvent(Translator * aTranslator)2630 inline bool RecordedPopClip::PlayEvent(Translator* aTranslator) const {
2631 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2632 if (!dt) {
2633 return false;
2634 }
2635
2636 dt->PopClip();
2637 return true;
2638 }
2639
2640 template <class S>
Record(S & aStream)2641 void RecordedPopClip::Record(S& aStream) const {
2642 RecordedDrawingEvent::Record(aStream);
2643 }
2644
2645 template <class S>
RecordedPopClip(S & aStream)2646 RecordedPopClip::RecordedPopClip(S& aStream)
2647 : RecordedDrawingEvent(POPCLIP, aStream) {}
2648
OutputSimpleEventInfo(std::stringstream & aStringStream)2649 inline void RecordedPopClip::OutputSimpleEventInfo(
2650 std::stringstream& aStringStream) const {
2651 aStringStream << "[" << mDT << "] PopClip";
2652 }
2653
PlayEvent(Translator * aTranslator)2654 inline bool RecordedPushLayer::PlayEvent(Translator* aTranslator) const {
2655 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2656 if (!dt) {
2657 return false;
2658 }
2659
2660 SourceSurface* mask =
2661 mMask ? aTranslator->LookupSourceSurface(mMask) : nullptr;
2662 dt->PushLayer(mOpaque, mOpacity, mask, mMaskTransform, mBounds,
2663 mCopyBackground);
2664 return true;
2665 }
2666
2667 template <class S>
Record(S & aStream)2668 void RecordedPushLayer::Record(S& aStream) const {
2669 RecordedDrawingEvent::Record(aStream);
2670 WriteElement(aStream, mOpaque);
2671 WriteElement(aStream, mOpacity);
2672 WriteElement(aStream, mMask);
2673 WriteElement(aStream, mMaskTransform);
2674 WriteElement(aStream, mBounds);
2675 WriteElement(aStream, mCopyBackground);
2676 }
2677
2678 template <class S>
RecordedPushLayer(S & aStream)2679 RecordedPushLayer::RecordedPushLayer(S& aStream)
2680 : RecordedDrawingEvent(PUSHLAYER, aStream) {
2681 ReadElement(aStream, mOpaque);
2682 ReadElement(aStream, mOpacity);
2683 ReadElement(aStream, mMask);
2684 ReadElement(aStream, mMaskTransform);
2685 ReadElement(aStream, mBounds);
2686 ReadElement(aStream, mCopyBackground);
2687 }
2688
OutputSimpleEventInfo(std::stringstream & aStringStream)2689 inline void RecordedPushLayer::OutputSimpleEventInfo(
2690 std::stringstream& aStringStream) const {
2691 aStringStream << "[" << mDT << "] PushPLayer (Opaque=" << mOpaque
2692 << ", Opacity=" << mOpacity << ", Mask Ref=" << mMask << ") ";
2693 }
2694
PlayEvent(Translator * aTranslator)2695 inline bool RecordedPushLayerWithBlend::PlayEvent(
2696 Translator* aTranslator) const {
2697 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2698 if (!dt) {
2699 return false;
2700 }
2701
2702 SourceSurface* mask =
2703 mMask ? aTranslator->LookupSourceSurface(mMask) : nullptr;
2704 dt->PushLayerWithBlend(mOpaque, mOpacity, mask, mMaskTransform, mBounds,
2705 mCopyBackground, mCompositionOp);
2706 return true;
2707 }
2708
2709 template <class S>
Record(S & aStream)2710 void RecordedPushLayerWithBlend::Record(S& aStream) const {
2711 RecordedDrawingEvent::Record(aStream);
2712 WriteElement(aStream, mOpaque);
2713 WriteElement(aStream, mOpacity);
2714 WriteElement(aStream, mMask);
2715 WriteElement(aStream, mMaskTransform);
2716 WriteElement(aStream, mBounds);
2717 WriteElement(aStream, mCopyBackground);
2718 WriteElement(aStream, mCompositionOp);
2719 }
2720
2721 template <class S>
RecordedPushLayerWithBlend(S & aStream)2722 RecordedPushLayerWithBlend::RecordedPushLayerWithBlend(S& aStream)
2723 : RecordedDrawingEvent(PUSHLAYERWITHBLEND, aStream) {
2724 ReadElement(aStream, mOpaque);
2725 ReadElement(aStream, mOpacity);
2726 ReadElement(aStream, mMask);
2727 ReadElement(aStream, mMaskTransform);
2728 ReadElement(aStream, mBounds);
2729 ReadElement(aStream, mCopyBackground);
2730 ReadElementConstrained(aStream, mCompositionOp, CompositionOp::OP_OVER,
2731 CompositionOp::OP_COUNT);
2732 }
2733
OutputSimpleEventInfo(std::stringstream & aStringStream)2734 inline void RecordedPushLayerWithBlend::OutputSimpleEventInfo(
2735 std::stringstream& aStringStream) const {
2736 aStringStream << "[" << mDT << "] PushLayerWithBlend (Opaque=" << mOpaque
2737 << ", Opacity=" << mOpacity << ", Mask Ref=" << mMask << ") ";
2738 }
2739
PlayEvent(Translator * aTranslator)2740 inline bool RecordedPopLayer::PlayEvent(Translator* aTranslator) const {
2741 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2742 if (!dt) {
2743 return false;
2744 }
2745
2746 dt->PopLayer();
2747 return true;
2748 }
2749
2750 template <class S>
Record(S & aStream)2751 void RecordedPopLayer::Record(S& aStream) const {
2752 RecordedDrawingEvent::Record(aStream);
2753 }
2754
2755 template <class S>
RecordedPopLayer(S & aStream)2756 RecordedPopLayer::RecordedPopLayer(S& aStream)
2757 : RecordedDrawingEvent(POPLAYER, aStream) {}
2758
OutputSimpleEventInfo(std::stringstream & aStringStream)2759 inline void RecordedPopLayer::OutputSimpleEventInfo(
2760 std::stringstream& aStringStream) const {
2761 aStringStream << "[" << mDT << "] PopLayer";
2762 }
2763
PlayEvent(Translator * aTranslator)2764 inline bool RecordedSetTransform::PlayEvent(Translator* aTranslator) const {
2765 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2766 if (!dt) {
2767 return false;
2768 }
2769
2770 dt->SetTransform(mTransform);
2771 return true;
2772 }
2773
2774 template <class S>
Record(S & aStream)2775 void RecordedSetTransform::Record(S& aStream) const {
2776 RecordedDrawingEvent::Record(aStream);
2777 WriteElement(aStream, mTransform);
2778 }
2779
2780 template <class S>
RecordedSetTransform(S & aStream)2781 RecordedSetTransform::RecordedSetTransform(S& aStream)
2782 : RecordedDrawingEvent(SETTRANSFORM, aStream) {
2783 ReadElement(aStream, mTransform);
2784 }
2785
OutputSimpleEventInfo(std::stringstream & aStringStream)2786 inline void RecordedSetTransform::OutputSimpleEventInfo(
2787 std::stringstream& aStringStream) const {
2788 aStringStream << "[" << mDT << "] SetTransform [ " << mTransform._11 << " "
2789 << mTransform._12 << " ; " << mTransform._21 << " "
2790 << mTransform._22 << " ; " << mTransform._31 << " "
2791 << mTransform._32 << " ]";
2792 }
2793
PlayEvent(Translator * aTranslator)2794 inline bool RecordedDrawSurface::PlayEvent(Translator* aTranslator) const {
2795 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2796 if (!dt) {
2797 return false;
2798 }
2799
2800 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefSource);
2801 if (!surface) {
2802 return false;
2803 }
2804
2805 dt->DrawSurface(surface, mDest, mSource, mDSOptions, mOptions);
2806 return true;
2807 }
2808
2809 template <class S>
Record(S & aStream)2810 void RecordedDrawSurface::Record(S& aStream) const {
2811 RecordedDrawingEvent::Record(aStream);
2812 WriteElement(aStream, mRefSource);
2813 WriteElement(aStream, mDest);
2814 WriteElement(aStream, mSource);
2815 WriteElement(aStream, mDSOptions);
2816 WriteElement(aStream, mOptions);
2817 }
2818
2819 template <class S>
RecordedDrawSurface(S & aStream)2820 RecordedDrawSurface::RecordedDrawSurface(S& aStream)
2821 : RecordedDrawingEvent(DRAWSURFACE, aStream) {
2822 ReadElement(aStream, mRefSource);
2823 ReadElement(aStream, mDest);
2824 ReadElement(aStream, mSource);
2825 ReadDrawSurfaceOptions(aStream, mDSOptions);
2826 ReadDrawOptions(aStream, mOptions);
2827 }
2828
OutputSimpleEventInfo(std::stringstream & aStringStream)2829 inline void RecordedDrawSurface::OutputSimpleEventInfo(
2830 std::stringstream& aStringStream) const {
2831 aStringStream << "[" << mDT << "] DrawSurface (" << mRefSource << ")";
2832 }
2833
PlayEvent(Translator * aTranslator)2834 inline bool RecordedDrawDependentSurface::PlayEvent(
2835 Translator* aTranslator) const {
2836 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2837 if (!dt) {
2838 return false;
2839 }
2840
2841 // We still return true even if this fails, since dependent surfaces are
2842 // used for cross-origin iframe drawing and can fail.
2843 RefPtr<SourceSurface> surface = aTranslator->LookupExternalSurface(mId);
2844 if (!surface) {
2845 return true;
2846 }
2847
2848 dt->DrawSurface(surface, mDest, Rect(Point(), Size(surface->GetSize())),
2849 mDSOptions, mOptions);
2850 return true;
2851 }
2852
2853 template <class S>
Record(S & aStream)2854 void RecordedDrawDependentSurface::Record(S& aStream) const {
2855 RecordedDrawingEvent::Record(aStream);
2856 WriteElement(aStream, mId);
2857 WriteElement(aStream, mDest);
2858 WriteElement(aStream, mDSOptions);
2859 WriteElement(aStream, mOptions);
2860 }
2861
2862 template <class S>
RecordedDrawDependentSurface(S & aStream)2863 RecordedDrawDependentSurface::RecordedDrawDependentSurface(S& aStream)
2864 : RecordedDrawingEvent(DRAWDEPENDENTSURFACE, aStream) {
2865 ReadElement(aStream, mId);
2866 ReadElement(aStream, mDest);
2867 ReadDrawSurfaceOptions(aStream, mDSOptions);
2868 ReadDrawOptions(aStream, mOptions);
2869 }
2870
OutputSimpleEventInfo(std::stringstream & aStringStream)2871 inline void RecordedDrawDependentSurface::OutputSimpleEventInfo(
2872 std::stringstream& aStringStream) const {
2873 aStringStream << "[" << mDT << "] DrawDependentSurface (" << mId << ")";
2874 }
2875
PlayEvent(Translator * aTranslator)2876 inline bool RecordedDrawFilter::PlayEvent(Translator* aTranslator) const {
2877 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2878 if (!dt) {
2879 return false;
2880 }
2881
2882 FilterNode* filter = aTranslator->LookupFilterNode(mNode);
2883 if (!filter) {
2884 return false;
2885 }
2886
2887 dt->DrawFilter(filter, mSourceRect, mDestPoint, mOptions);
2888 return true;
2889 }
2890
2891 template <class S>
Record(S & aStream)2892 void RecordedDrawFilter::Record(S& aStream) const {
2893 RecordedDrawingEvent::Record(aStream);
2894 WriteElement(aStream, mNode);
2895 WriteElement(aStream, mSourceRect);
2896 WriteElement(aStream, mDestPoint);
2897 WriteElement(aStream, mOptions);
2898 }
2899
2900 template <class S>
RecordedDrawFilter(S & aStream)2901 RecordedDrawFilter::RecordedDrawFilter(S& aStream)
2902 : RecordedDrawingEvent(DRAWFILTER, aStream) {
2903 ReadElement(aStream, mNode);
2904 ReadElement(aStream, mSourceRect);
2905 ReadElement(aStream, mDestPoint);
2906 ReadDrawOptions(aStream, mOptions);
2907 }
2908
OutputSimpleEventInfo(std::stringstream & aStringStream)2909 inline void RecordedDrawFilter::OutputSimpleEventInfo(
2910 std::stringstream& aStringStream) const {
2911 aStringStream << "[" << mDT << "] DrawFilter (" << mNode << ")";
2912 }
2913
PlayEvent(Translator * aTranslator)2914 inline bool RecordedDrawSurfaceWithShadow::PlayEvent(
2915 Translator* aTranslator) const {
2916 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2917 if (!dt) {
2918 return false;
2919 }
2920
2921 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefSource);
2922 if (!surface) {
2923 return false;
2924 }
2925
2926 dt->DrawSurfaceWithShadow(surface, mDest, mColor, mOffset, mSigma, mOp);
2927 return true;
2928 }
2929
2930 template <class S>
Record(S & aStream)2931 void RecordedDrawSurfaceWithShadow::Record(S& aStream) const {
2932 RecordedDrawingEvent::Record(aStream);
2933 WriteElement(aStream, mRefSource);
2934 WriteElement(aStream, mDest);
2935 WriteElement(aStream, mColor);
2936 WriteElement(aStream, mOffset);
2937 WriteElement(aStream, mSigma);
2938 WriteElement(aStream, mOp);
2939 }
2940
2941 template <class S>
RecordedDrawSurfaceWithShadow(S & aStream)2942 RecordedDrawSurfaceWithShadow::RecordedDrawSurfaceWithShadow(S& aStream)
2943 : RecordedDrawingEvent(DRAWSURFACEWITHSHADOW, aStream) {
2944 ReadElement(aStream, mRefSource);
2945 ReadElement(aStream, mDest);
2946 ReadElement(aStream, mColor);
2947 ReadElement(aStream, mOffset);
2948 ReadElement(aStream, mSigma);
2949 ReadElementConstrained(aStream, mOp, CompositionOp::OP_OVER,
2950 CompositionOp::OP_COUNT);
2951 }
2952
OutputSimpleEventInfo(std::stringstream & aStringStream)2953 inline void RecordedDrawSurfaceWithShadow::OutputSimpleEventInfo(
2954 std::stringstream& aStringStream) const {
2955 aStringStream << "[" << mDT << "] DrawSurfaceWithShadow (" << mRefSource
2956 << ") DeviceColor: (" << mColor.r << ", " << mColor.g << ", "
2957 << mColor.b << ", " << mColor.a << ")";
2958 }
2959
RecordedPathCreation(PathRecording * aPath)2960 inline RecordedPathCreation::RecordedPathCreation(PathRecording* aPath)
2961 : RecordedEventDerived(PATHCREATION),
2962 mRefPtr(aPath),
2963 mFillRule(aPath->mFillRule),
2964 mPath(aPath) {}
2965
PlayEvent(Translator * aTranslator)2966 inline bool RecordedPathCreation::PlayEvent(Translator* aTranslator) const {
2967 RefPtr<DrawTarget> drawTarget = aTranslator->GetReferenceDrawTarget();
2968 if (!drawTarget) {
2969 // We might end up with a null reference draw target due to a device
2970 // failure, just return false so that we can recover.
2971 return false;
2972 }
2973
2974 RefPtr<PathBuilder> builder = drawTarget->CreatePathBuilder(mFillRule);
2975 if (!mPathOps->StreamToSink(*builder)) {
2976 return false;
2977 }
2978
2979 RefPtr<Path> path = builder->Finish();
2980 aTranslator->AddPath(mRefPtr, path);
2981 return true;
2982 }
2983
2984 template <class S>
Record(S & aStream)2985 void RecordedPathCreation::Record(S& aStream) const {
2986 WriteElement(aStream, mRefPtr);
2987 WriteElement(aStream, mFillRule);
2988 mPath->mPathOps.Record(aStream);
2989 }
2990
2991 template <class S>
RecordedPathCreation(S & aStream)2992 RecordedPathCreation::RecordedPathCreation(S& aStream)
2993 : RecordedEventDerived(PATHCREATION) {
2994 ReadElement(aStream, mRefPtr);
2995 ReadElementConstrained(aStream, mFillRule, FillRule::FILL_WINDING,
2996 FillRule::FILL_EVEN_ODD);
2997 mPathOps = MakeUnique<PathOps>(aStream);
2998 }
2999
OutputSimpleEventInfo(std::stringstream & aStringStream)3000 inline void RecordedPathCreation::OutputSimpleEventInfo(
3001 std::stringstream& aStringStream) const {
3002 size_t numberOfOps =
3003 mPath ? mPath->mPathOps.NumberOfOps() : mPathOps->NumberOfOps();
3004 aStringStream << "[" << mRefPtr << "] Path created (OpCount: " << numberOfOps
3005 << ")";
3006 }
PlayEvent(Translator * aTranslator)3007 inline bool RecordedPathDestruction::PlayEvent(Translator* aTranslator) const {
3008 aTranslator->RemovePath(mRefPtr);
3009 return true;
3010 }
3011
3012 template <class S>
Record(S & aStream)3013 void RecordedPathDestruction::Record(S& aStream) const {
3014 WriteElement(aStream, mRefPtr);
3015 }
3016
3017 template <class S>
RecordedPathDestruction(S & aStream)3018 RecordedPathDestruction::RecordedPathDestruction(S& aStream)
3019 : RecordedEventDerived(PATHDESTRUCTION) {
3020 ReadElement(aStream, mRefPtr);
3021 }
3022
OutputSimpleEventInfo(std::stringstream & aStringStream)3023 inline void RecordedPathDestruction::OutputSimpleEventInfo(
3024 std::stringstream& aStringStream) const {
3025 aStringStream << "[" << mRefPtr << "] Path Destroyed";
3026 }
3027
~RecordedSourceSurfaceCreation()3028 inline RecordedSourceSurfaceCreation::~RecordedSourceSurfaceCreation() {
3029 if (mDataOwned) {
3030 delete[] mData;
3031 }
3032 }
3033
PlayEvent(Translator * aTranslator)3034 inline bool RecordedSourceSurfaceCreation::PlayEvent(
3035 Translator* aTranslator) const {
3036 if (!mData) {
3037 return false;
3038 }
3039
3040 RefPtr<SourceSurface> src = Factory::CreateWrappingDataSourceSurface(
3041 mData, mSize.width * BytesPerPixel(mFormat), mSize, mFormat,
3042 [](void* aClosure) { delete[] static_cast<uint8_t*>(aClosure); }, mData);
3043 if (src) {
3044 mDataOwned = false;
3045 }
3046
3047 aTranslator->AddSourceSurface(mRefPtr, src);
3048 return true;
3049 }
3050
3051 template <class S>
Record(S & aStream)3052 void RecordedSourceSurfaceCreation::Record(S& aStream) const {
3053 WriteElement(aStream, mRefPtr);
3054 WriteElement(aStream, mSize);
3055 WriteElement(aStream, mFormat);
3056 MOZ_ASSERT(mData);
3057 size_t dataFormatWidth = BytesPerPixel(mFormat) * mSize.width;
3058 const char* endSrc = (const char*)(mData + (mSize.height * mStride));
3059 for (const char* src = (const char*)mData; src < endSrc; src += mStride) {
3060 aStream.write(src, dataFormatWidth);
3061 }
3062 }
3063
3064 template <class S>
RecordedSourceSurfaceCreation(S & aStream)3065 RecordedSourceSurfaceCreation::RecordedSourceSurfaceCreation(S& aStream)
3066 : RecordedEventDerived(SOURCESURFACECREATION), mDataOwned(true) {
3067 ReadElement(aStream, mRefPtr);
3068 ReadElement(aStream, mSize);
3069 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
3070 SurfaceFormat::UNKNOWN);
3071 if (!aStream.good()) {
3072 return;
3073 }
3074
3075 size_t size = 0;
3076 if (mSize.width >= 0 && mSize.height >= 0) {
3077 size = size_t(mSize.width) * size_t(mSize.height) * BytesPerPixel(mFormat);
3078 mData = new (fallible) uint8_t[size];
3079 }
3080 if (!mData) {
3081 gfxCriticalNote
3082 << "RecordedSourceSurfaceCreation failed to allocate data of size "
3083 << size;
3084 aStream.SetIsBad();
3085 } else {
3086 aStream.read((char*)mData, size);
3087 }
3088 }
3089
OutputSimpleEventInfo(std::stringstream & aStringStream)3090 inline void RecordedSourceSurfaceCreation::OutputSimpleEventInfo(
3091 std::stringstream& aStringStream) const {
3092 aStringStream << "[" << mRefPtr
3093 << "] SourceSurface created (Size: " << mSize.width << "x"
3094 << mSize.height << ")";
3095 }
3096
PlayEvent(Translator * aTranslator)3097 inline bool RecordedSourceSurfaceDestruction::PlayEvent(
3098 Translator* aTranslator) const {
3099 aTranslator->RemoveSourceSurface(mRefPtr);
3100 return true;
3101 }
3102
3103 template <class S>
Record(S & aStream)3104 void RecordedSourceSurfaceDestruction::Record(S& aStream) const {
3105 WriteElement(aStream, mRefPtr);
3106 }
3107
3108 template <class S>
RecordedSourceSurfaceDestruction(S & aStream)3109 RecordedSourceSurfaceDestruction::RecordedSourceSurfaceDestruction(S& aStream)
3110 : RecordedEventDerived(SOURCESURFACEDESTRUCTION) {
3111 ReadElement(aStream, mRefPtr);
3112 }
3113
OutputSimpleEventInfo(std::stringstream & aStringStream)3114 inline void RecordedSourceSurfaceDestruction::OutputSimpleEventInfo(
3115 std::stringstream& aStringStream) const {
3116 aStringStream << "[" << mRefPtr << "] SourceSurface Destroyed";
3117 }
3118
PlayEvent(Translator * aTranslator)3119 inline bool RecordedOptimizeSourceSurface::PlayEvent(
3120 Translator* aTranslator) const {
3121 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
3122 if (!dt) {
3123 return false;
3124 }
3125
3126 SourceSurface* surface = aTranslator->LookupSourceSurface(mSurface);
3127 if (!surface) {
3128 return false;
3129 }
3130
3131 RefPtr<SourceSurface> optimizedSurface = dt->OptimizeSourceSurface(surface);
3132 aTranslator->AddSourceSurface(mOptimizedSurface, optimizedSurface);
3133 return true;
3134 }
3135
3136 template <class S>
Record(S & aStream)3137 void RecordedOptimizeSourceSurface::Record(S& aStream) const {
3138 WriteElement(aStream, mSurface);
3139 WriteElement(aStream, mDT);
3140 WriteElement(aStream, mOptimizedSurface);
3141 }
3142
3143 template <class S>
RecordedOptimizeSourceSurface(S & aStream)3144 RecordedOptimizeSourceSurface::RecordedOptimizeSourceSurface(S& aStream)
3145 : RecordedEventDerived(OPTIMIZESOURCESURFACE) {
3146 ReadElement(aStream, mSurface);
3147 ReadElement(aStream, mDT);
3148 ReadElement(aStream, mOptimizedSurface);
3149 }
3150
OutputSimpleEventInfo(std::stringstream & aStringStream)3151 inline void RecordedOptimizeSourceSurface::OutputSimpleEventInfo(
3152 std::stringstream& aStringStream) const {
3153 aStringStream << "[" << mSurface << "] Surface Optimized (DT: " << mDT << ")";
3154 }
3155
PlayEvent(Translator * aTranslator)3156 inline bool RecordedExternalSurfaceCreation::PlayEvent(
3157 Translator* aTranslator) const {
3158 RefPtr<SourceSurface> surface = aTranslator->LookupExternalSurface(mKey);
3159 if (!surface) {
3160 return false;
3161 }
3162
3163 aTranslator->AddSourceSurface(mRefPtr, surface);
3164 return true;
3165 }
3166
3167 template <class S>
Record(S & aStream)3168 void RecordedExternalSurfaceCreation::Record(S& aStream) const {
3169 WriteElement(aStream, mRefPtr);
3170 WriteElement(aStream, mKey);
3171 }
3172
3173 template <class S>
RecordedExternalSurfaceCreation(S & aStream)3174 RecordedExternalSurfaceCreation::RecordedExternalSurfaceCreation(S& aStream)
3175 : RecordedEventDerived(EXTERNALSURFACECREATION) {
3176 ReadElement(aStream, mRefPtr);
3177 ReadElement(aStream, mKey);
3178 }
3179
OutputSimpleEventInfo(std::stringstream & aStringStream)3180 inline void RecordedExternalSurfaceCreation::OutputSimpleEventInfo(
3181 std::stringstream& aStringStream) const {
3182 aStringStream << "[" << mRefPtr
3183 << "] SourceSurfaceSharedData created (Key: " << mKey << ")";
3184 }
3185
3186 inline RecordedFilterNodeCreation::~RecordedFilterNodeCreation() = default;
3187
PlayEvent(Translator * aTranslator)3188 inline bool RecordedFilterNodeCreation::PlayEvent(
3189 Translator* aTranslator) const {
3190 RefPtr<DrawTarget> drawTarget = aTranslator->GetReferenceDrawTarget();
3191 if (!drawTarget) {
3192 // We might end up with a null reference draw target due to a device
3193 // failure, just return false so that we can recover.
3194 return false;
3195 }
3196
3197 RefPtr<FilterNode> node = drawTarget->CreateFilter(mType);
3198 aTranslator->AddFilterNode(mRefPtr, node);
3199 return true;
3200 }
3201
3202 template <class S>
Record(S & aStream)3203 void RecordedFilterNodeCreation::Record(S& aStream) const {
3204 WriteElement(aStream, mRefPtr);
3205 WriteElement(aStream, mType);
3206 }
3207
3208 template <class S>
RecordedFilterNodeCreation(S & aStream)3209 RecordedFilterNodeCreation::RecordedFilterNodeCreation(S& aStream)
3210 : RecordedEventDerived(FILTERNODECREATION) {
3211 ReadElement(aStream, mRefPtr);
3212 ReadElementConstrained(aStream, mType, FilterType::BLEND,
3213 FilterType::OPACITY);
3214 }
3215
OutputSimpleEventInfo(std::stringstream & aStringStream)3216 inline void RecordedFilterNodeCreation::OutputSimpleEventInfo(
3217 std::stringstream& aStringStream) const {
3218 aStringStream << "[" << mRefPtr
3219 << "] FilterNode created (Type: " << int(mType) << ")";
3220 }
3221
PlayEvent(Translator * aTranslator)3222 inline bool RecordedFilterNodeDestruction::PlayEvent(
3223 Translator* aTranslator) const {
3224 aTranslator->RemoveFilterNode(mRefPtr);
3225 return true;
3226 }
3227
3228 template <class S>
Record(S & aStream)3229 void RecordedFilterNodeDestruction::Record(S& aStream) const {
3230 WriteElement(aStream, mRefPtr);
3231 }
3232
3233 template <class S>
RecordedFilterNodeDestruction(S & aStream)3234 RecordedFilterNodeDestruction::RecordedFilterNodeDestruction(S& aStream)
3235 : RecordedEventDerived(FILTERNODEDESTRUCTION) {
3236 ReadElement(aStream, mRefPtr);
3237 }
3238
OutputSimpleEventInfo(std::stringstream & aStringStream)3239 inline void RecordedFilterNodeDestruction::OutputSimpleEventInfo(
3240 std::stringstream& aStringStream) const {
3241 aStringStream << "[" << mRefPtr << "] FilterNode Destroyed";
3242 }
3243
~RecordedGradientStopsCreation()3244 inline RecordedGradientStopsCreation::~RecordedGradientStopsCreation() {
3245 if (mDataOwned) {
3246 delete[] mStops;
3247 }
3248 }
3249
PlayEvent(Translator * aTranslator)3250 inline bool RecordedGradientStopsCreation::PlayEvent(
3251 Translator* aTranslator) const {
3252 if (mNumStops > 0 && !mStops) {
3253 // Stops allocation failed
3254 return false;
3255 }
3256 RefPtr<GradientStops> src =
3257 aTranslator->GetOrCreateGradientStops(mStops, mNumStops, mExtendMode);
3258 aTranslator->AddGradientStops(mRefPtr, src);
3259 return true;
3260 }
3261
3262 template <class S>
Record(S & aStream)3263 void RecordedGradientStopsCreation::Record(S& aStream) const {
3264 WriteElement(aStream, mRefPtr);
3265 WriteElement(aStream, mExtendMode);
3266 WriteElement(aStream, mNumStops);
3267 aStream.write((const char*)mStops, mNumStops * sizeof(GradientStop));
3268 }
3269
3270 template <class S>
RecordedGradientStopsCreation(S & aStream)3271 RecordedGradientStopsCreation::RecordedGradientStopsCreation(S& aStream)
3272 : RecordedEventDerived(GRADIENTSTOPSCREATION), mDataOwned(true) {
3273 ReadElement(aStream, mRefPtr);
3274 ReadElementConstrained(aStream, mExtendMode, ExtendMode::CLAMP,
3275 ExtendMode::REFLECT);
3276 ReadElement(aStream, mNumStops);
3277 if (!aStream.good() || mNumStops <= 0) {
3278 return;
3279 }
3280
3281 mStops = new (fallible) GradientStop[mNumStops];
3282 if (!mStops) {
3283 gfxCriticalNote
3284 << "RecordedGradientStopsCreation failed to allocate stops of size "
3285 << mNumStops;
3286 aStream.SetIsBad();
3287 } else {
3288 aStream.read((char*)mStops, mNumStops * sizeof(GradientStop));
3289 }
3290 }
3291
OutputSimpleEventInfo(std::stringstream & aStringStream)3292 inline void RecordedGradientStopsCreation::OutputSimpleEventInfo(
3293 std::stringstream& aStringStream) const {
3294 aStringStream << "[" << mRefPtr
3295 << "] GradientStops created (Stops: " << mNumStops << ")";
3296 }
3297
PlayEvent(Translator * aTranslator)3298 inline bool RecordedGradientStopsDestruction::PlayEvent(
3299 Translator* aTranslator) const {
3300 aTranslator->RemoveGradientStops(mRefPtr);
3301 return true;
3302 }
3303
3304 template <class S>
Record(S & aStream)3305 void RecordedGradientStopsDestruction::Record(S& aStream) const {
3306 WriteElement(aStream, mRefPtr);
3307 }
3308
3309 template <class S>
RecordedGradientStopsDestruction(S & aStream)3310 RecordedGradientStopsDestruction::RecordedGradientStopsDestruction(S& aStream)
3311 : RecordedEventDerived(GRADIENTSTOPSDESTRUCTION) {
3312 ReadElement(aStream, mRefPtr);
3313 }
3314
OutputSimpleEventInfo(std::stringstream & aStringStream)3315 inline void RecordedGradientStopsDestruction::OutputSimpleEventInfo(
3316 std::stringstream& aStringStream) const {
3317 aStringStream << "[" << mRefPtr << "] GradientStops Destroyed";
3318 }
3319
PlayEvent(Translator * aTranslator)3320 inline bool RecordedIntoLuminanceSource::PlayEvent(
3321 Translator* aTranslator) const {
3322 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
3323 if (!dt) {
3324 return false;
3325 }
3326
3327 RefPtr<SourceSurface> src = dt->IntoLuminanceSource(mLuminanceType, mOpacity);
3328 aTranslator->AddSourceSurface(mRefPtr, src);
3329 return true;
3330 }
3331
3332 template <class S>
Record(S & aStream)3333 void RecordedIntoLuminanceSource::Record(S& aStream) const {
3334 WriteElement(aStream, mRefPtr);
3335 WriteElement(aStream, mDT);
3336 WriteElement(aStream, mLuminanceType);
3337 WriteElement(aStream, mOpacity);
3338 }
3339
3340 template <class S>
RecordedIntoLuminanceSource(S & aStream)3341 RecordedIntoLuminanceSource::RecordedIntoLuminanceSource(S& aStream)
3342 : RecordedEventDerived(INTOLUMINANCE) {
3343 ReadElement(aStream, mRefPtr);
3344 ReadElement(aStream, mDT);
3345 ReadElementConstrained(aStream, mLuminanceType, LuminanceType::LUMINANCE,
3346 LuminanceType::LINEARRGB);
3347 ReadElement(aStream, mOpacity);
3348 }
3349
OutputSimpleEventInfo(std::stringstream & aStringStream)3350 inline void RecordedIntoLuminanceSource::OutputSimpleEventInfo(
3351 std::stringstream& aStringStream) const {
3352 aStringStream << "[" << mRefPtr << "] Into Luminance Source (DT: " << mDT
3353 << ")";
3354 }
3355
PlayEvent(Translator * aTranslator)3356 inline bool RecordedFlush::PlayEvent(Translator* aTranslator) const {
3357 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
3358 if (!dt) {
3359 return false;
3360 }
3361
3362 dt->Flush();
3363 return true;
3364 }
3365
3366 template <class S>
Record(S & aStream)3367 void RecordedFlush::Record(S& aStream) const {
3368 RecordedDrawingEvent::Record(aStream);
3369 }
3370
3371 template <class S>
RecordedFlush(S & aStream)3372 RecordedFlush::RecordedFlush(S& aStream)
3373 : RecordedDrawingEvent(FLUSH, aStream) {}
3374
OutputSimpleEventInfo(std::stringstream & aStringStream)3375 inline void RecordedFlush::OutputSimpleEventInfo(
3376 std::stringstream& aStringStream) const {
3377 aStringStream << "[" << mDT << "] Flush";
3378 }
3379
PlayEvent(Translator * aTranslator)3380 inline bool RecordedDetachAllSnapshots::PlayEvent(
3381 Translator* aTranslator) const {
3382 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
3383 if (!dt) {
3384 return false;
3385 }
3386
3387 dt->DetachAllSnapshots();
3388 return true;
3389 }
3390
3391 template <class S>
Record(S & aStream)3392 void RecordedDetachAllSnapshots::Record(S& aStream) const {
3393 RecordedDrawingEvent::Record(aStream);
3394 }
3395
3396 template <class S>
RecordedDetachAllSnapshots(S & aStream)3397 RecordedDetachAllSnapshots::RecordedDetachAllSnapshots(S& aStream)
3398 : RecordedDrawingEvent(DETACHALLSNAPSHOTS, aStream) {}
3399
OutputSimpleEventInfo(std::stringstream & aStringStream)3400 inline void RecordedDetachAllSnapshots::OutputSimpleEventInfo(
3401 std::stringstream& aStringStream) const {
3402 aStringStream << "[" << mDT << "] DetachAllSnapshots";
3403 }
3404
PlayEvent(Translator * aTranslator)3405 inline bool RecordedSnapshot::PlayEvent(Translator* aTranslator) const {
3406 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
3407 if (!dt) {
3408 return false;
3409 }
3410
3411 RefPtr<SourceSurface> src = aTranslator->LookupDrawTarget(mDT)->Snapshot();
3412 aTranslator->AddSourceSurface(mRefPtr, src);
3413 return true;
3414 }
3415
3416 template <class S>
Record(S & aStream)3417 void RecordedSnapshot::Record(S& aStream) const {
3418 WriteElement(aStream, mRefPtr);
3419 WriteElement(aStream, mDT);
3420 }
3421
3422 template <class S>
RecordedSnapshot(S & aStream)3423 RecordedSnapshot::RecordedSnapshot(S& aStream)
3424 : RecordedEventDerived(SNAPSHOT) {
3425 ReadElement(aStream, mRefPtr);
3426 ReadElement(aStream, mDT);
3427 }
3428
OutputSimpleEventInfo(std::stringstream & aStringStream)3429 inline void RecordedSnapshot::OutputSimpleEventInfo(
3430 std::stringstream& aStringStream) const {
3431 aStringStream << "[" << mRefPtr << "] Snapshot Created (DT: " << mDT << ")";
3432 }
3433
~RecordedFontData()3434 inline RecordedFontData::~RecordedFontData() { delete[] mData; }
3435
PlayEvent(Translator * aTranslator)3436 inline bool RecordedFontData::PlayEvent(Translator* aTranslator) const {
3437 if (!mData) {
3438 return false;
3439 }
3440
3441 RefPtr<NativeFontResource> fontResource = Factory::CreateNativeFontResource(
3442 mData, mFontDetails.size, mType, aTranslator->GetFontContext());
3443 if (!fontResource) {
3444 return false;
3445 }
3446
3447 aTranslator->AddNativeFontResource(mFontDetails.fontDataKey, fontResource);
3448 return true;
3449 }
3450
3451 template <class S>
Record(S & aStream)3452 void RecordedFontData::Record(S& aStream) const {
3453 MOZ_ASSERT(mGetFontFileDataSucceeded);
3454
3455 WriteElement(aStream, mType);
3456 WriteElement(aStream, mFontDetails.fontDataKey);
3457 if (!mData) {
3458 WriteElement(aStream, 0);
3459 } else {
3460 WriteElement(aStream, mFontDetails.size);
3461 aStream.write((const char*)mData, mFontDetails.size);
3462 }
3463 }
3464
OutputSimpleEventInfo(std::stringstream & aStringStream)3465 inline void RecordedFontData::OutputSimpleEventInfo(
3466 std::stringstream& aStringStream) const {
3467 aStringStream << "Font Data of size " << mFontDetails.size;
3468 }
3469
SetFontData(const uint8_t * aData,uint32_t aSize,uint32_t aIndex)3470 inline void RecordedFontData::SetFontData(const uint8_t* aData, uint32_t aSize,
3471 uint32_t aIndex) {
3472 mData = new (fallible) uint8_t[aSize];
3473 if (!mData) {
3474 gfxCriticalNote
3475 << "RecordedFontData failed to allocate data for recording of size "
3476 << aSize;
3477 } else {
3478 memcpy(mData, aData, aSize);
3479 }
3480 mFontDetails.fontDataKey = SFNTData::GetUniqueKey(aData, aSize, 0, nullptr);
3481 mFontDetails.size = aSize;
3482 mFontDetails.index = aIndex;
3483 }
3484
GetFontDetails(RecordedFontDetails & fontDetails)3485 inline bool RecordedFontData::GetFontDetails(RecordedFontDetails& fontDetails) {
3486 if (!mGetFontFileDataSucceeded) {
3487 return false;
3488 }
3489
3490 fontDetails.fontDataKey = mFontDetails.fontDataKey;
3491 fontDetails.size = mFontDetails.size;
3492 fontDetails.index = mFontDetails.index;
3493 return true;
3494 }
3495
3496 template <class S>
RecordedFontData(S & aStream)3497 RecordedFontData::RecordedFontData(S& aStream)
3498 : RecordedEventDerived(FONTDATA), mType(FontType::UNKNOWN) {
3499 ReadElementConstrained(aStream, mType, FontType::DWRITE, FontType::UNKNOWN);
3500 ReadElement(aStream, mFontDetails.fontDataKey);
3501 ReadElement(aStream, mFontDetails.size);
3502 if (!mFontDetails.size || !aStream.good()) {
3503 return;
3504 }
3505
3506 mData = new (fallible) uint8_t[mFontDetails.size];
3507 if (!mData) {
3508 gfxCriticalNote
3509 << "RecordedFontData failed to allocate data for playback of size "
3510 << mFontDetails.size;
3511 aStream.SetIsBad();
3512 } else {
3513 aStream.read((char*)mData, mFontDetails.size);
3514 }
3515 }
3516
3517 inline RecordedFontDescriptor::~RecordedFontDescriptor() = default;
3518
PlayEvent(Translator * aTranslator)3519 inline bool RecordedFontDescriptor::PlayEvent(Translator* aTranslator) const {
3520 RefPtr<UnscaledFont> font = Factory::CreateUnscaledFontFromFontDescriptor(
3521 mType, mData.data(), mData.size(), mIndex);
3522 if (!font) {
3523 gfxDevCrash(LogReason::InvalidFont)
3524 << "Failed creating UnscaledFont of type " << int(mType)
3525 << " from font descriptor";
3526 return false;
3527 }
3528
3529 aTranslator->AddUnscaledFont(mRefPtr, font);
3530 return true;
3531 }
3532
3533 template <class S>
Record(S & aStream)3534 void RecordedFontDescriptor::Record(S& aStream) const {
3535 MOZ_ASSERT(mHasDesc);
3536 WriteElement(aStream, mType);
3537 WriteElement(aStream, mRefPtr);
3538 WriteElement(aStream, mIndex);
3539 WriteElement(aStream, (size_t)mData.size());
3540 if (mData.size()) {
3541 aStream.write((char*)mData.data(), mData.size());
3542 }
3543 }
3544
OutputSimpleEventInfo(std::stringstream & aStringStream)3545 inline void RecordedFontDescriptor::OutputSimpleEventInfo(
3546 std::stringstream& aStringStream) const {
3547 aStringStream << "[" << mRefPtr << "] Font Descriptor";
3548 }
3549
SetFontDescriptor(const uint8_t * aData,uint32_t aSize,uint32_t aIndex)3550 inline void RecordedFontDescriptor::SetFontDescriptor(const uint8_t* aData,
3551 uint32_t aSize,
3552 uint32_t aIndex) {
3553 mData.assign(aData, aData + aSize);
3554 mIndex = aIndex;
3555 }
3556
3557 template <class S>
RecordedFontDescriptor(S & aStream)3558 RecordedFontDescriptor::RecordedFontDescriptor(S& aStream)
3559 : RecordedEventDerived(FONTDESC) {
3560 ReadElementConstrained(aStream, mType, FontType::DWRITE, FontType::UNKNOWN);
3561 ReadElement(aStream, mRefPtr);
3562 ReadElement(aStream, mIndex);
3563
3564 size_t size;
3565 ReadElement(aStream, size);
3566 if (!aStream.good()) {
3567 return;
3568 }
3569 if (size) {
3570 mData.resize(size);
3571 aStream.read((char*)mData.data(), size);
3572 }
3573 }
3574
PlayEvent(Translator * aTranslator)3575 inline bool RecordedUnscaledFontCreation::PlayEvent(
3576 Translator* aTranslator) const {
3577 NativeFontResource* fontResource =
3578 aTranslator->LookupNativeFontResource(mFontDataKey);
3579 if (!fontResource) {
3580 gfxDevCrash(LogReason::NativeFontResourceNotFound)
3581 << "NativeFontResource lookup failed for key |" << hexa(mFontDataKey)
3582 << "|.";
3583 return false;
3584 }
3585
3586 RefPtr<UnscaledFont> unscaledFont = fontResource->CreateUnscaledFont(
3587 mIndex, mInstanceData.data(), mInstanceData.size());
3588 aTranslator->AddUnscaledFont(mRefPtr, unscaledFont);
3589 return true;
3590 }
3591
3592 template <class S>
Record(S & aStream)3593 void RecordedUnscaledFontCreation::Record(S& aStream) const {
3594 WriteElement(aStream, mRefPtr);
3595 WriteElement(aStream, mFontDataKey);
3596 WriteElement(aStream, mIndex);
3597 WriteElement(aStream, (size_t)mInstanceData.size());
3598 if (mInstanceData.size()) {
3599 aStream.write((char*)mInstanceData.data(), mInstanceData.size());
3600 }
3601 }
3602
OutputSimpleEventInfo(std::stringstream & aStringStream)3603 inline void RecordedUnscaledFontCreation::OutputSimpleEventInfo(
3604 std::stringstream& aStringStream) const {
3605 aStringStream << "[" << mRefPtr << "] UnscaledFont Created";
3606 }
3607
SetFontInstanceData(const uint8_t * aData,uint32_t aSize)3608 inline void RecordedUnscaledFontCreation::SetFontInstanceData(
3609 const uint8_t* aData, uint32_t aSize) {
3610 if (aSize) {
3611 mInstanceData.assign(aData, aData + aSize);
3612 }
3613 }
3614
3615 template <class S>
RecordedUnscaledFontCreation(S & aStream)3616 RecordedUnscaledFontCreation::RecordedUnscaledFontCreation(S& aStream)
3617 : RecordedEventDerived(UNSCALEDFONTCREATION) {
3618 ReadElement(aStream, mRefPtr);
3619 ReadElement(aStream, mFontDataKey);
3620 ReadElement(aStream, mIndex);
3621
3622 size_t size;
3623 ReadElement(aStream, size);
3624 if (!aStream.good()) {
3625 return;
3626 }
3627 if (size) {
3628 mInstanceData.resize(size);
3629 aStream.read((char*)mInstanceData.data(), size);
3630 }
3631 }
3632
PlayEvent(Translator * aTranslator)3633 inline bool RecordedUnscaledFontDestruction::PlayEvent(
3634 Translator* aTranslator) const {
3635 aTranslator->RemoveUnscaledFont(mRefPtr);
3636 return true;
3637 }
3638
3639 template <class S>
Record(S & aStream)3640 void RecordedUnscaledFontDestruction::Record(S& aStream) const {
3641 WriteElement(aStream, mRefPtr);
3642 }
3643
3644 template <class S>
RecordedUnscaledFontDestruction(S & aStream)3645 RecordedUnscaledFontDestruction::RecordedUnscaledFontDestruction(S& aStream)
3646 : RecordedEventDerived(UNSCALEDFONTDESTRUCTION) {
3647 ReadElement(aStream, mRefPtr);
3648 }
3649
OutputSimpleEventInfo(std::stringstream & aStringStream)3650 inline void RecordedUnscaledFontDestruction::OutputSimpleEventInfo(
3651 std::stringstream& aStringStream) const {
3652 aStringStream << "[" << mRefPtr << "] UnscaledFont Destroyed";
3653 }
3654
PlayEvent(Translator * aTranslator)3655 inline bool RecordedScaledFontCreation::PlayEvent(
3656 Translator* aTranslator) const {
3657 UnscaledFont* unscaledFont = aTranslator->LookupUnscaledFont(mUnscaledFont);
3658 if (!unscaledFont) {
3659 gfxDevCrash(LogReason::UnscaledFontNotFound)
3660 << "UnscaledFont lookup failed for key |" << hexa(mUnscaledFont)
3661 << "|.";
3662 return false;
3663 }
3664
3665 RefPtr<ScaledFont> scaledFont = unscaledFont->CreateScaledFont(
3666 mGlyphSize, mInstanceData.data(), mInstanceData.size(),
3667 mVariations.data(), mVariations.size());
3668
3669 aTranslator->AddScaledFont(mRefPtr, scaledFont);
3670 return true;
3671 }
3672
3673 template <class S>
Record(S & aStream)3674 void RecordedScaledFontCreation::Record(S& aStream) const {
3675 WriteElement(aStream, mRefPtr);
3676 WriteElement(aStream, mUnscaledFont);
3677 WriteElement(aStream, mGlyphSize);
3678 WriteElement(aStream, (size_t)mInstanceData.size());
3679 if (mInstanceData.size()) {
3680 aStream.write((char*)mInstanceData.data(), mInstanceData.size());
3681 }
3682 WriteElement(aStream, (size_t)mVariations.size());
3683 if (mVariations.size()) {
3684 aStream.write((char*)mVariations.data(),
3685 sizeof(FontVariation) * mVariations.size());
3686 }
3687 }
3688
OutputSimpleEventInfo(std::stringstream & aStringStream)3689 inline void RecordedScaledFontCreation::OutputSimpleEventInfo(
3690 std::stringstream& aStringStream) const {
3691 aStringStream << "[" << mRefPtr << "] ScaledFont Created";
3692 }
3693
SetFontInstanceData(const uint8_t * aData,uint32_t aSize,const FontVariation * aVariations,uint32_t aNumVariations)3694 inline void RecordedScaledFontCreation::SetFontInstanceData(
3695 const uint8_t* aData, uint32_t aSize, const FontVariation* aVariations,
3696 uint32_t aNumVariations) {
3697 if (aSize) {
3698 mInstanceData.assign(aData, aData + aSize);
3699 }
3700 if (aNumVariations) {
3701 mVariations.assign(aVariations, aVariations + aNumVariations);
3702 }
3703 }
3704
3705 template <class S>
RecordedScaledFontCreation(S & aStream)3706 RecordedScaledFontCreation::RecordedScaledFontCreation(S& aStream)
3707 : RecordedEventDerived(SCALEDFONTCREATION) {
3708 ReadElement(aStream, mRefPtr);
3709 ReadElement(aStream, mUnscaledFont);
3710 ReadElement(aStream, mGlyphSize);
3711
3712 size_t size;
3713 ReadElement(aStream, size);
3714 if (!aStream.good()) {
3715 return;
3716 }
3717 if (size) {
3718 mInstanceData.resize(size);
3719 aStream.read((char*)mInstanceData.data(), size);
3720 }
3721
3722 size_t numVariations;
3723 ReadElement(aStream, numVariations);
3724 if (!aStream.good()) {
3725 return;
3726 }
3727 if (numVariations) {
3728 mVariations.resize(numVariations);
3729 aStream.read((char*)mVariations.data(),
3730 sizeof(FontVariation) * numVariations);
3731 }
3732 }
3733
PlayEvent(Translator * aTranslator)3734 inline bool RecordedScaledFontDestruction::PlayEvent(
3735 Translator* aTranslator) const {
3736 aTranslator->RemoveScaledFont(mRefPtr);
3737 return true;
3738 }
3739
3740 template <class S>
Record(S & aStream)3741 void RecordedScaledFontDestruction::Record(S& aStream) const {
3742 WriteElement(aStream, mRefPtr);
3743 }
3744
3745 template <class S>
RecordedScaledFontDestruction(S & aStream)3746 RecordedScaledFontDestruction::RecordedScaledFontDestruction(S& aStream)
3747 : RecordedEventDerived(SCALEDFONTDESTRUCTION) {
3748 ReadElement(aStream, mRefPtr);
3749 }
3750
OutputSimpleEventInfo(std::stringstream & aStringStream)3751 inline void RecordedScaledFontDestruction::OutputSimpleEventInfo(
3752 std::stringstream& aStringStream) const {
3753 aStringStream << "[" << mRefPtr << "] ScaledFont Destroyed";
3754 }
3755
PlayEvent(Translator * aTranslator)3756 inline bool RecordedMaskSurface::PlayEvent(Translator* aTranslator) const {
3757 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
3758 if (!dt) {
3759 return false;
3760 }
3761
3762 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefMask);
3763 if (!surface) {
3764 return false;
3765 }
3766
3767 dt->MaskSurface(*GenericPattern(mPattern, aTranslator), surface, mOffset,
3768 mOptions);
3769 return true;
3770 }
3771
3772 template <class S>
Record(S & aStream)3773 void RecordedMaskSurface::Record(S& aStream) const {
3774 RecordedDrawingEvent::Record(aStream);
3775 RecordPatternData(aStream, mPattern);
3776 WriteElement(aStream, mRefMask);
3777 WriteElement(aStream, mOffset);
3778 WriteElement(aStream, mOptions);
3779 }
3780
3781 template <class S>
RecordedMaskSurface(S & aStream)3782 RecordedMaskSurface::RecordedMaskSurface(S& aStream)
3783 : RecordedDrawingEvent(MASKSURFACE, aStream) {
3784 ReadPatternData(aStream, mPattern);
3785 ReadElement(aStream, mRefMask);
3786 ReadElement(aStream, mOffset);
3787 ReadDrawOptions(aStream, mOptions);
3788 }
3789
OutputSimpleEventInfo(std::stringstream & aStringStream)3790 inline void RecordedMaskSurface::OutputSimpleEventInfo(
3791 std::stringstream& aStringStream) const {
3792 aStringStream << "[" << mDT << "] MaskSurface (" << mRefMask << ") Offset: ("
3793 << mOffset.x << "x" << mOffset.y << ") Pattern: ";
3794 OutputSimplePatternInfo(mPattern, aStringStream);
3795 }
3796
3797 template <typename T>
ReplaySetAttribute(FilterNode * aNode,uint32_t aIndex,T aValue)3798 void ReplaySetAttribute(FilterNode* aNode, uint32_t aIndex, T aValue) {
3799 aNode->SetAttribute(aIndex, aValue);
3800 }
3801
PlayEvent(Translator * aTranslator)3802 inline bool RecordedFilterNodeSetAttribute::PlayEvent(
3803 Translator* aTranslator) const {
3804 FilterNode* node = aTranslator->LookupFilterNode(mNode);
3805 if (!node) {
3806 return false;
3807 }
3808
3809 #define REPLAY_SET_ATTRIBUTE(type, argtype) \
3810 case ARGTYPE_##argtype: \
3811 ReplaySetAttribute(node, mIndex, *(type*)&mPayload.front()); \
3812 break
3813
3814 switch (mArgType) {
3815 REPLAY_SET_ATTRIBUTE(bool, BOOL);
3816 REPLAY_SET_ATTRIBUTE(uint32_t, UINT32);
3817 REPLAY_SET_ATTRIBUTE(Float, FLOAT);
3818 REPLAY_SET_ATTRIBUTE(Size, SIZE);
3819 REPLAY_SET_ATTRIBUTE(IntSize, INTSIZE);
3820 REPLAY_SET_ATTRIBUTE(IntPoint, INTPOINT);
3821 REPLAY_SET_ATTRIBUTE(Rect, RECT);
3822 REPLAY_SET_ATTRIBUTE(IntRect, INTRECT);
3823 REPLAY_SET_ATTRIBUTE(Point, POINT);
3824 REPLAY_SET_ATTRIBUTE(Matrix, MATRIX);
3825 REPLAY_SET_ATTRIBUTE(Matrix5x4, MATRIX5X4);
3826 REPLAY_SET_ATTRIBUTE(Point3D, POINT3D);
3827 REPLAY_SET_ATTRIBUTE(DeviceColor, COLOR);
3828 case ARGTYPE_FLOAT_ARRAY:
3829 node->SetAttribute(mIndex,
3830 reinterpret_cast<const Float*>(&mPayload.front()),
3831 mPayload.size() / sizeof(Float));
3832 break;
3833 }
3834
3835 return true;
3836 }
3837
3838 template <class S>
Record(S & aStream)3839 void RecordedFilterNodeSetAttribute::Record(S& aStream) const {
3840 WriteElement(aStream, mNode);
3841 WriteElement(aStream, mIndex);
3842 WriteElement(aStream, mArgType);
3843 WriteElement(aStream, uint64_t(mPayload.size()));
3844 aStream.write((const char*)&mPayload.front(), mPayload.size());
3845 }
3846
3847 template <class S>
RecordedFilterNodeSetAttribute(S & aStream)3848 RecordedFilterNodeSetAttribute::RecordedFilterNodeSetAttribute(S& aStream)
3849 : RecordedEventDerived(FILTERNODESETATTRIBUTE) {
3850 ReadElement(aStream, mNode);
3851 ReadElement(aStream, mIndex);
3852 ReadElementConstrained(aStream, mArgType, ArgType::ARGTYPE_UINT32,
3853 ArgType::ARGTYPE_FLOAT_ARRAY);
3854 uint64_t size;
3855 ReadElement(aStream, size);
3856 if (!aStream.good()) {
3857 return;
3858 }
3859
3860 mPayload.resize(size_t(size));
3861 aStream.read((char*)&mPayload.front(), size);
3862 }
3863
OutputSimpleEventInfo(std::stringstream & aStringStream)3864 inline void RecordedFilterNodeSetAttribute::OutputSimpleEventInfo(
3865 std::stringstream& aStringStream) const {
3866 aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ")";
3867 }
3868
PlayEvent(Translator * aTranslator)3869 inline bool RecordedFilterNodeSetInput::PlayEvent(
3870 Translator* aTranslator) const {
3871 FilterNode* node = aTranslator->LookupFilterNode(mNode);
3872 if (!node) {
3873 return false;
3874 }
3875
3876 if (mInputFilter) {
3877 node->SetInput(mIndex, aTranslator->LookupFilterNode(mInputFilter));
3878 } else {
3879 node->SetInput(mIndex, aTranslator->LookupSourceSurface(mInputSurface));
3880 }
3881
3882 return true;
3883 }
3884
3885 template <class S>
Record(S & aStream)3886 void RecordedFilterNodeSetInput::Record(S& aStream) const {
3887 WriteElement(aStream, mNode);
3888 WriteElement(aStream, mIndex);
3889 WriteElement(aStream, mInputFilter);
3890 WriteElement(aStream, mInputSurface);
3891 }
3892
3893 template <class S>
RecordedFilterNodeSetInput(S & aStream)3894 RecordedFilterNodeSetInput::RecordedFilterNodeSetInput(S& aStream)
3895 : RecordedEventDerived(FILTERNODESETINPUT) {
3896 ReadElement(aStream, mNode);
3897 ReadElement(aStream, mIndex);
3898 ReadElement(aStream, mInputFilter);
3899 ReadElement(aStream, mInputSurface);
3900 }
3901
OutputSimpleEventInfo(std::stringstream & aStringStream)3902 inline void RecordedFilterNodeSetInput::OutputSimpleEventInfo(
3903 std::stringstream& aStringStream) const {
3904 aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ", ";
3905
3906 if (mInputFilter) {
3907 aStringStream << "Filter: " << mInputFilter;
3908 } else {
3909 aStringStream << "Surface: " << mInputSurface;
3910 }
3911
3912 aStringStream << ")";
3913 }
3914
PlayEvent(Translator * aTranslator)3915 inline bool RecordedLink::PlayEvent(Translator* aTranslator) const {
3916 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
3917 if (!dt) {
3918 return false;
3919 }
3920 dt->Link(mDestination.c_str(), mRect);
3921 return true;
3922 }
3923
3924 template <class S>
Record(S & aStream)3925 void RecordedLink::Record(S& aStream) const {
3926 RecordedDrawingEvent::Record(aStream);
3927 WriteElement(aStream, mRect);
3928 uint32_t len = mDestination.length();
3929 WriteElement(aStream, len);
3930 if (len) {
3931 aStream.write(mDestination.data(), len);
3932 }
3933 }
3934
3935 template <class S>
RecordedLink(S & aStream)3936 RecordedLink::RecordedLink(S& aStream) : RecordedDrawingEvent(LINK, aStream) {
3937 ReadElement(aStream, mRect);
3938 uint32_t len;
3939 ReadElement(aStream, len);
3940 mDestination.resize(size_t(len));
3941 if (len && aStream.good()) {
3942 aStream.read(&mDestination.front(), len);
3943 }
3944 }
3945
OutputSimpleEventInfo(std::stringstream & aStringStream)3946 inline void RecordedLink::OutputSimpleEventInfo(
3947 std::stringstream& aStringStream) const {
3948 aStringStream << "Link [" << mDestination << " @ " << mRect << "]";
3949 }
3950
3951 #define FOR_EACH_EVENT(f) \
3952 f(DRAWTARGETCREATION, RecordedDrawTargetCreation); \
3953 f(DRAWTARGETDESTRUCTION, RecordedDrawTargetDestruction); \
3954 f(FILLRECT, RecordedFillRect); \
3955 f(STROKERECT, RecordedStrokeRect); \
3956 f(STROKELINE, RecordedStrokeLine); \
3957 f(CLEARRECT, RecordedClearRect); \
3958 f(COPYSURFACE, RecordedCopySurface); \
3959 f(SETTRANSFORM, RecordedSetTransform); \
3960 f(PUSHCLIPRECT, RecordedPushClipRect); \
3961 f(PUSHCLIP, RecordedPushClip); \
3962 f(POPCLIP, RecordedPopClip); \
3963 f(FILL, RecordedFill); \
3964 f(FILLGLYPHS, RecordedFillGlyphs); \
3965 f(MASK, RecordedMask); \
3966 f(STROKE, RecordedStroke); \
3967 f(DRAWSURFACE, RecordedDrawSurface); \
3968 f(DRAWDEPENDENTSURFACE, RecordedDrawDependentSurface); \
3969 f(DRAWSURFACEWITHSHADOW, RecordedDrawSurfaceWithShadow); \
3970 f(DRAWFILTER, RecordedDrawFilter); \
3971 f(PATHCREATION, RecordedPathCreation); \
3972 f(PATHDESTRUCTION, RecordedPathDestruction); \
3973 f(SOURCESURFACECREATION, RecordedSourceSurfaceCreation); \
3974 f(SOURCESURFACEDESTRUCTION, RecordedSourceSurfaceDestruction); \
3975 f(FILTERNODECREATION, RecordedFilterNodeCreation); \
3976 f(FILTERNODEDESTRUCTION, RecordedFilterNodeDestruction); \
3977 f(GRADIENTSTOPSCREATION, RecordedGradientStopsCreation); \
3978 f(GRADIENTSTOPSDESTRUCTION, RecordedGradientStopsDestruction); \
3979 f(SNAPSHOT, RecordedSnapshot); \
3980 f(SCALEDFONTCREATION, RecordedScaledFontCreation); \
3981 f(SCALEDFONTDESTRUCTION, RecordedScaledFontDestruction); \
3982 f(MASKSURFACE, RecordedMaskSurface); \
3983 f(FILTERNODESETATTRIBUTE, RecordedFilterNodeSetAttribute); \
3984 f(FILTERNODESETINPUT, RecordedFilterNodeSetInput); \
3985 f(CREATESIMILARDRAWTARGET, RecordedCreateSimilarDrawTarget); \
3986 f(CREATECLIPPEDDRAWTARGET, RecordedCreateClippedDrawTarget); \
3987 f(CREATEDRAWTARGETFORFILTER, RecordedCreateDrawTargetForFilter); \
3988 f(FONTDATA, RecordedFontData); \
3989 f(FONTDESC, RecordedFontDescriptor); \
3990 f(PUSHLAYER, RecordedPushLayer); \
3991 f(PUSHLAYERWITHBLEND, RecordedPushLayerWithBlend); \
3992 f(POPLAYER, RecordedPopLayer); \
3993 f(UNSCALEDFONTCREATION, RecordedUnscaledFontCreation); \
3994 f(UNSCALEDFONTDESTRUCTION, RecordedUnscaledFontDestruction); \
3995 f(INTOLUMINANCE, RecordedIntoLuminanceSource); \
3996 f(EXTERNALSURFACECREATION, RecordedExternalSurfaceCreation); \
3997 f(FLUSH, RecordedFlush); \
3998 f(DETACHALLSNAPSHOTS, RecordedDetachAllSnapshots); \
3999 f(OPTIMIZESOURCESURFACE, RecordedOptimizeSourceSurface); \
4000 f(LINK, RecordedLink);
4001
4002 #define DO_WITH_EVENT_TYPE(_typeenum, _class) \
4003 case _typeenum: { \
4004 auto e = _class(aStream); \
4005 return aAction(&e); \
4006 }
4007
4008 template <class S>
DoWithEvent(S & aStream,EventType aType,const std::function<bool (RecordedEvent *)> & aAction)4009 bool RecordedEvent::DoWithEvent(
4010 S& aStream, EventType aType,
4011 const std::function<bool(RecordedEvent*)>& aAction) {
4012 switch (aType) {
4013 FOR_EACH_EVENT(DO_WITH_EVENT_TYPE)
4014 default:
4015 return false;
4016 }
4017 }
4018
4019 } // namespace gfx
4020 } // namespace mozilla
4021
4022 #endif
4023