Backed out changeset 28c56a4f3af6 (bug 1874810) for causing Moz2DImageRenderer relate...
[gecko.git] / gfx / 2d / RecordedEventImpl.h
blob6e39fccb8bd5cb062d25fccdd63ce54e07ccaafb
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef MOZILLA_GFX_RECORDEDEVENTIMPL_H_
8 #define MOZILLA_GFX_RECORDEDEVENTIMPL_H_
10 #include "RecordedEvent.h"
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"
20 namespace mozilla {
21 namespace gfx {
23 class RecordedDrawTargetCreation
24 : public RecordedEventDerived<RecordedDrawTargetCreation> {
25 public:
26 RecordedDrawTargetCreation(ReferencePtr aRefPtr, BackendType aType,
27 const IntRect& aRect, SurfaceFormat aFormat,
28 bool aHasExistingData = false,
29 SourceSurface* aExistingData = nullptr)
30 : RecordedEventDerived(DRAWTARGETCREATION),
31 mRefPtr(aRefPtr),
32 mBackendType(aType),
33 mRect(aRect),
34 mFormat(aFormat),
35 mHasExistingData(aHasExistingData),
36 mExistingData(aExistingData) {}
38 bool PlayEvent(Translator* aTranslator) const override;
40 template <class S>
41 void Record(S& aStream) const;
42 virtual void OutputSimpleEventInfo(
43 std::stringstream& aStringStream) const override;
45 std::string GetName() const override { return "DrawTarget Creation"; }
47 ReferencePtr mRefPtr;
48 BackendType mBackendType;
49 IntRect mRect;
50 SurfaceFormat mFormat;
51 bool mHasExistingData = false;
52 RefPtr<SourceSurface> mExistingData;
54 private:
55 friend class RecordedEvent;
57 template <class S>
58 MOZ_IMPLICIT RecordedDrawTargetCreation(S& aStream);
61 class RecordedDrawTargetDestruction
62 : public RecordedEventDerived<RecordedDrawTargetDestruction> {
63 public:
64 MOZ_IMPLICIT RecordedDrawTargetDestruction(ReferencePtr aRefPtr)
65 : RecordedEventDerived(DRAWTARGETDESTRUCTION),
66 mRefPtr(aRefPtr),
67 mBackendType(BackendType::NONE) {}
69 bool PlayEvent(Translator* aTranslator) const override;
71 template <class S>
72 void Record(S& aStream) const;
73 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
75 std::string GetName() const override { return "DrawTarget Destruction"; }
77 ReferencePtr mRefPtr;
79 BackendType mBackendType;
81 private:
82 friend class RecordedEvent;
84 template <class S>
85 MOZ_IMPLICIT RecordedDrawTargetDestruction(S& aStream);
88 class RecordedSetCurrentDrawTarget
89 : public RecordedEventDerived<RecordedSetCurrentDrawTarget> {
90 public:
91 MOZ_IMPLICIT RecordedSetCurrentDrawTarget(ReferencePtr aRefPtr)
92 : RecordedEventDerived(SETCURRENTDRAWTARGET), mRefPtr(aRefPtr) {}
94 bool PlayEvent(Translator* aTranslator) const override;
96 template <class S>
97 void Record(S& aStream) const;
98 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
100 std::string GetName() const override { return "SetCurrentDrawTarget"; }
102 ReferencePtr mRefPtr;
104 private:
105 friend class RecordedEvent;
107 template <class S>
108 MOZ_IMPLICIT RecordedSetCurrentDrawTarget(S& aStream);
111 class RecordedCreateSimilarDrawTarget
112 : public RecordedEventDerived<RecordedCreateSimilarDrawTarget> {
113 public:
114 RecordedCreateSimilarDrawTarget(ReferencePtr aRefPtr, const IntSize& aSize,
115 SurfaceFormat aFormat)
116 : RecordedEventDerived(CREATESIMILARDRAWTARGET),
117 mRefPtr(aRefPtr),
118 mSize(aSize),
119 mFormat(aFormat) {}
121 bool PlayEvent(Translator* aTranslator) const override;
123 template <class S>
124 void Record(S& aStream) const;
125 virtual void OutputSimpleEventInfo(
126 std::stringstream& aStringStream) const override;
128 std::string GetName() const override { return "CreateSimilarDrawTarget"; }
130 ReferencePtr mRefPtr;
131 IntSize mSize;
132 SurfaceFormat mFormat;
134 private:
135 friend class RecordedEvent;
137 template <class S>
138 MOZ_IMPLICIT RecordedCreateSimilarDrawTarget(S& aStream);
141 class RecordedCreateClippedDrawTarget
142 : public RecordedEventDerived<RecordedCreateClippedDrawTarget> {
143 public:
144 RecordedCreateClippedDrawTarget(ReferencePtr aRefPtr, const Rect& aBounds,
145 SurfaceFormat aFormat)
146 : RecordedEventDerived(CREATECLIPPEDDRAWTARGET),
147 mRefPtr(aRefPtr),
148 mBounds(aBounds),
149 mFormat(aFormat) {}
151 bool PlayEvent(Translator* aTranslator) const override;
153 template <class S>
154 void Record(S& aStream) const;
155 virtual void OutputSimpleEventInfo(
156 std::stringstream& aStringStream) const override;
158 std::string GetName() const override { return "CreateClippedDrawTarget"; }
160 ReferencePtr mRefPtr;
161 Rect mBounds;
162 SurfaceFormat mFormat;
164 private:
165 friend class RecordedEvent;
167 template <class S>
168 MOZ_IMPLICIT RecordedCreateClippedDrawTarget(S& aStream);
171 class RecordedCreateDrawTargetForFilter
172 : public RecordedEventDerived<RecordedCreateDrawTargetForFilter> {
173 public:
174 RecordedCreateDrawTargetForFilter(ReferencePtr aRefPtr,
175 const IntSize& aMaxSize,
176 SurfaceFormat aFormat, FilterNode* aFilter,
177 FilterNode* aSource,
178 const Rect& aSourceRect,
179 const Point& aDestPoint)
180 : RecordedEventDerived(CREATEDRAWTARGETFORFILTER),
181 mRefPtr(aRefPtr),
182 mMaxSize(aMaxSize),
183 mFormat(aFormat),
184 mFilter(aFilter),
185 mSource(aSource),
186 mSourceRect(aSourceRect),
187 mDestPoint(aDestPoint) {}
189 bool PlayEvent(Translator* aTranslator) const override;
191 template <class S>
192 void Record(S& aStream) const;
193 virtual void OutputSimpleEventInfo(
194 std::stringstream& aStringStream) const override;
196 std::string GetName() const override {
197 return "CreateSimilarDrawTargetForFilter";
200 ReferencePtr mRefPtr;
201 IntSize mMaxSize;
202 SurfaceFormat mFormat;
203 ReferencePtr mFilter;
204 ReferencePtr mSource;
205 Rect mSourceRect;
206 Point mDestPoint;
208 private:
209 friend class RecordedEvent;
211 template <class S>
212 MOZ_IMPLICIT RecordedCreateDrawTargetForFilter(S& aStream);
215 class RecordedFillRect : public RecordedEventDerived<RecordedFillRect> {
216 public:
217 RecordedFillRect(const Rect& aRect, const Pattern& aPattern,
218 const DrawOptions& aOptions)
219 : RecordedEventDerived(FILLRECT),
220 mRect(aRect),
221 mPattern(),
222 mOptions(aOptions) {
223 StorePattern(mPattern, aPattern);
226 bool PlayEvent(Translator* aTranslator) const override;
228 template <class S>
229 void Record(S& aStream) const;
230 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
232 std::string GetName() const override { return "FillRect"; }
234 private:
235 friend class RecordedEvent;
237 template <class S>
238 MOZ_IMPLICIT RecordedFillRect(S& aStream);
240 Rect mRect;
241 PatternStorage mPattern;
242 DrawOptions mOptions;
245 class RecordedStrokeRect : public RecordedEventDerived<RecordedStrokeRect> {
246 public:
247 RecordedStrokeRect(const Rect& aRect, const Pattern& aPattern,
248 const StrokeOptions& aStrokeOptions,
249 const DrawOptions& aOptions)
250 : RecordedEventDerived(STROKERECT),
251 mRect(aRect),
252 mPattern(),
253 mStrokeOptions(aStrokeOptions),
254 mOptions(aOptions) {
255 StorePattern(mPattern, aPattern);
258 bool PlayEvent(Translator* aTranslator) const override;
260 template <class S>
261 void Record(S& aStream) const;
262 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
264 std::string GetName() const override { return "StrokeRect"; }
266 private:
267 friend class RecordedEvent;
269 template <class S>
270 MOZ_IMPLICIT RecordedStrokeRect(S& aStream);
272 Rect mRect;
273 PatternStorage mPattern;
274 StrokeOptions mStrokeOptions;
275 DrawOptions mOptions;
278 class RecordedStrokeLine : public RecordedEventDerived<RecordedStrokeLine> {
279 public:
280 RecordedStrokeLine(const Point& aBegin, const Point& aEnd,
281 const Pattern& aPattern,
282 const StrokeOptions& aStrokeOptions,
283 const DrawOptions& aOptions)
284 : RecordedEventDerived(STROKELINE),
285 mBegin(aBegin),
286 mEnd(aEnd),
287 mPattern(),
288 mStrokeOptions(aStrokeOptions),
289 mOptions(aOptions) {
290 StorePattern(mPattern, aPattern);
293 bool PlayEvent(Translator* aTranslator) const override;
295 template <class S>
296 void Record(S& aStream) const;
297 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
299 std::string GetName() const override { return "StrokeLine"; }
301 private:
302 friend class RecordedEvent;
304 template <class S>
305 MOZ_IMPLICIT RecordedStrokeLine(S& aStream);
307 Point mBegin;
308 Point mEnd;
309 PatternStorage mPattern;
310 StrokeOptions mStrokeOptions;
311 DrawOptions mOptions;
314 class RecordedStrokeCircle : public RecordedEventDerived<RecordedStrokeCircle> {
315 public:
316 RecordedStrokeCircle(Circle aCircle, const Pattern& aPattern,
317 const StrokeOptions& aStrokeOptions,
318 const DrawOptions& aOptions)
319 : RecordedEventDerived(STROKECIRCLE),
320 mCircle(aCircle),
321 mPattern(),
322 mStrokeOptions(aStrokeOptions),
323 mOptions(aOptions) {
324 StorePattern(mPattern, aPattern);
327 bool PlayEvent(Translator* aTranslator) const override;
329 template <class S>
330 void Record(S& aStream) const;
331 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
333 std::string GetName() const override { return "StrokeCircle"; }
335 private:
336 friend class RecordedEvent;
338 template <class S>
339 MOZ_IMPLICIT RecordedStrokeCircle(S& aStream);
341 Circle mCircle;
342 PatternStorage mPattern;
343 StrokeOptions mStrokeOptions;
344 DrawOptions mOptions;
347 class RecordedFill : public RecordedEventDerived<RecordedFill> {
348 public:
349 RecordedFill(ReferencePtr aPath, const Pattern& aPattern,
350 const DrawOptions& aOptions)
351 : RecordedEventDerived(FILL),
352 mPath(aPath),
353 mPattern(),
354 mOptions(aOptions) {
355 StorePattern(mPattern, aPattern);
358 bool PlayEvent(Translator* aTranslator) const override;
360 template <class S>
361 void Record(S& aStream) const;
362 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
364 std::string GetName() const override { return "Fill"; }
366 private:
367 friend class RecordedEvent;
369 template <class S>
370 MOZ_IMPLICIT RecordedFill(S& aStream);
372 ReferencePtr mPath;
373 PatternStorage mPattern;
374 DrawOptions mOptions;
377 class RecordedFillCircle : public RecordedEventDerived<RecordedFillCircle> {
378 public:
379 RecordedFillCircle(Circle aCircle, const Pattern& aPattern,
380 const DrawOptions& aOptions)
381 : RecordedEventDerived(FILLCIRCLE),
382 mCircle(aCircle),
383 mPattern(),
384 mOptions(aOptions) {
385 StorePattern(mPattern, aPattern);
388 bool PlayEvent(Translator* aTranslator) const override;
390 template <class S>
391 void Record(S& aStream) const;
392 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
394 std::string GetName() const override { return "FillCircle"; }
396 private:
397 friend class RecordedEvent;
399 template <class S>
400 MOZ_IMPLICIT RecordedFillCircle(S& aStream);
402 Circle mCircle;
403 PatternStorage mPattern;
404 DrawOptions mOptions;
407 class RecordedFillGlyphs : public RecordedEventDerived<RecordedFillGlyphs> {
408 public:
409 RecordedFillGlyphs(ReferencePtr aScaledFont, const Pattern& aPattern,
410 const DrawOptions& aOptions, const Glyph* aGlyphs,
411 uint32_t aNumGlyphs)
412 : RecordedEventDerived(FILLGLYPHS),
413 mScaledFont(aScaledFont),
414 mPattern(),
415 mOptions(aOptions) {
416 StorePattern(mPattern, aPattern);
417 mNumGlyphs = aNumGlyphs;
418 mGlyphs = new Glyph[aNumGlyphs];
419 memcpy(mGlyphs, aGlyphs, sizeof(Glyph) * aNumGlyphs);
421 virtual ~RecordedFillGlyphs();
423 bool PlayEvent(Translator* aTranslator) const override;
425 template <class S>
426 void Record(S& aStream) const;
427 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
429 std::string GetName() const override { return "FillGlyphs"; }
431 private:
432 friend class RecordedEvent;
434 template <class S>
435 MOZ_IMPLICIT RecordedFillGlyphs(S& aStream);
437 ReferencePtr mScaledFont;
438 PatternStorage mPattern;
439 DrawOptions mOptions;
440 Glyph* mGlyphs = nullptr;
441 uint32_t mNumGlyphs = 0;
444 class RecordedMask : public RecordedEventDerived<RecordedMask> {
445 public:
446 RecordedMask(const Pattern& aSource, const Pattern& aMask,
447 const DrawOptions& aOptions)
448 : RecordedEventDerived(MASK), mSource(), mMask(), mOptions(aOptions) {
449 StorePattern(mSource, aSource);
450 StorePattern(mMask, aMask);
453 bool PlayEvent(Translator* aTranslator) const override;
455 template <class S>
456 void Record(S& aStream) const;
457 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
459 std::string GetName() const override { return "Mask"; }
461 private:
462 friend class RecordedEvent;
464 template <class S>
465 MOZ_IMPLICIT RecordedMask(S& aStream);
467 PatternStorage mSource;
468 PatternStorage mMask;
469 DrawOptions mOptions;
472 class RecordedStroke : public RecordedEventDerived<RecordedStroke> {
473 public:
474 RecordedStroke(ReferencePtr aPath, const Pattern& aPattern,
475 const StrokeOptions& aStrokeOptions,
476 const DrawOptions& aOptions)
477 : RecordedEventDerived(STROKE),
478 mPath(aPath),
479 mPattern(),
480 mStrokeOptions(aStrokeOptions),
481 mOptions(aOptions) {
482 StorePattern(mPattern, aPattern);
485 bool PlayEvent(Translator* aTranslator) const override;
487 template <class S>
488 void Record(S& aStream) const;
489 virtual void OutputSimpleEventInfo(
490 std::stringstream& aStringStream) const override;
492 std::string GetName() const override { return "Stroke"; }
494 private:
495 friend class RecordedEvent;
497 template <class S>
498 MOZ_IMPLICIT RecordedStroke(S& aStream);
500 ReferencePtr mPath;
501 PatternStorage mPattern;
502 StrokeOptions mStrokeOptions;
503 DrawOptions mOptions;
506 class RecordedClearRect : public RecordedEventDerived<RecordedClearRect> {
507 public:
508 explicit RecordedClearRect(const Rect& aRect)
509 : RecordedEventDerived(CLEARRECT), mRect(aRect) {}
511 bool PlayEvent(Translator* aTranslator) const override;
513 template <class S>
514 void Record(S& aStream) const;
515 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
517 std::string GetName() const override { return "ClearRect"; }
519 private:
520 friend class RecordedEvent;
522 template <class S>
523 MOZ_IMPLICIT RecordedClearRect(S& aStream);
525 Rect mRect;
528 class RecordedCopySurface : public RecordedEventDerived<RecordedCopySurface> {
529 public:
530 RecordedCopySurface(ReferencePtr aSourceSurface, const IntRect& aSourceRect,
531 const IntPoint& aDest)
532 : RecordedEventDerived(COPYSURFACE),
533 mSourceSurface(aSourceSurface),
534 mSourceRect(aSourceRect),
535 mDest(aDest) {}
537 bool PlayEvent(Translator* aTranslator) const override;
539 template <class S>
540 void Record(S& aStream) const;
541 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
543 std::string GetName() const override { return "CopySurface"; }
545 private:
546 friend class RecordedEvent;
548 template <class S>
549 MOZ_IMPLICIT RecordedCopySurface(S& aStream);
551 ReferencePtr mSourceSurface;
552 IntRect mSourceRect;
553 IntPoint mDest;
556 class RecordedPushClip : public RecordedEventDerived<RecordedPushClip> {
557 public:
558 explicit RecordedPushClip(ReferencePtr aPath)
559 : RecordedEventDerived(PUSHCLIP), mPath(aPath) {}
561 bool PlayEvent(Translator* aTranslator) const override;
563 template <class S>
564 void Record(S& aStream) const;
565 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
567 std::string GetName() const override { return "PushClip"; }
569 private:
570 friend class RecordedEvent;
572 template <class S>
573 MOZ_IMPLICIT RecordedPushClip(S& aStream);
575 ReferencePtr mPath;
578 class RecordedPushClipRect : public RecordedEventDerived<RecordedPushClipRect> {
579 public:
580 explicit RecordedPushClipRect(const Rect& aRect)
581 : RecordedEventDerived(PUSHCLIPRECT), mRect(aRect) {}
583 bool PlayEvent(Translator* aTranslator) const override;
585 template <class S>
586 void Record(S& aStream) const;
587 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
589 std::string GetName() const override { return "PushClipRect"; }
591 private:
592 friend class RecordedEvent;
594 template <class S>
595 MOZ_IMPLICIT RecordedPushClipRect(S& aStream);
597 Rect mRect;
600 class RecordedPopClip : public RecordedEventDerived<RecordedPopClip> {
601 public:
602 MOZ_IMPLICIT RecordedPopClip() : RecordedEventDerived(POPCLIP) {}
604 bool PlayEvent(Translator* aTranslator) const override;
606 template <class S>
607 void Record(S& aStream) const;
608 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
610 std::string GetName() const override { return "PopClip"; }
612 private:
613 friend class RecordedEvent;
615 template <class S>
616 MOZ_IMPLICIT RecordedPopClip(S& aStream);
619 class RecordedPushLayer : public RecordedEventDerived<RecordedPushLayer> {
620 public:
621 RecordedPushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
622 const Matrix& aMaskTransform, const IntRect& aBounds,
623 bool aCopyBackground)
624 : RecordedEventDerived(PUSHLAYER),
625 mOpaque(aOpaque),
626 mOpacity(aOpacity),
627 mMask(aMask),
628 mMaskTransform(aMaskTransform),
629 mBounds(aBounds),
630 mCopyBackground(aCopyBackground) {}
632 bool PlayEvent(Translator* aTranslator) const override;
634 template <class S>
635 void Record(S& aStream) const;
636 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
638 std::string GetName() const override { return "PushLayer"; }
640 private:
641 friend class RecordedEvent;
643 template <class S>
644 MOZ_IMPLICIT RecordedPushLayer(S& aStream);
646 bool mOpaque;
647 Float mOpacity;
648 ReferencePtr mMask;
649 Matrix mMaskTransform;
650 IntRect mBounds;
651 bool mCopyBackground;
654 class RecordedPushLayerWithBlend
655 : public RecordedEventDerived<RecordedPushLayerWithBlend> {
656 public:
657 RecordedPushLayerWithBlend(bool aOpaque, Float aOpacity, SourceSurface* aMask,
658 const Matrix& aMaskTransform,
659 const IntRect& aBounds, bool aCopyBackground,
660 CompositionOp aCompositionOp)
661 : RecordedEventDerived(PUSHLAYERWITHBLEND),
662 mOpaque(aOpaque),
663 mOpacity(aOpacity),
664 mMask(aMask),
665 mMaskTransform(aMaskTransform),
666 mBounds(aBounds),
667 mCopyBackground(aCopyBackground),
668 mCompositionOp(aCompositionOp) {}
670 bool PlayEvent(Translator* aTranslator) const override;
672 template <class S>
673 void Record(S& aStream) const;
674 virtual void OutputSimpleEventInfo(
675 std::stringstream& aStringStream) const override;
677 std::string GetName() const override { return "PushLayerWithBlend"; }
679 private:
680 friend class RecordedEvent;
682 template <class S>
683 MOZ_IMPLICIT RecordedPushLayerWithBlend(S& aStream);
685 bool mOpaque;
686 Float mOpacity;
687 ReferencePtr mMask;
688 Matrix mMaskTransform;
689 IntRect mBounds;
690 bool mCopyBackground;
691 CompositionOp mCompositionOp;
694 class RecordedPopLayer : public RecordedEventDerived<RecordedPopLayer> {
695 public:
696 RecordedPopLayer() : RecordedEventDerived(POPLAYER) {}
698 bool PlayEvent(Translator* aTranslator) const override;
700 template <class S>
701 void Record(S& aStream) const;
702 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
704 std::string GetName() const override { return "PopLayer"; }
706 private:
707 friend class RecordedEvent;
709 template <class S>
710 MOZ_IMPLICIT RecordedPopLayer(S& aStream);
713 class RecordedSetTransform : public RecordedEventDerived<RecordedSetTransform> {
714 public:
715 explicit RecordedSetTransform(const Matrix& aTransform)
716 : RecordedEventDerived(SETTRANSFORM), mTransform(aTransform) {}
718 bool PlayEvent(Translator* aTranslator) const override;
720 template <class S>
721 void Record(S& aStream) const;
722 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
724 std::string GetName() const override { return "SetTransform"; }
726 Matrix mTransform;
728 private:
729 friend class RecordedEvent;
731 template <class S>
732 MOZ_IMPLICIT RecordedSetTransform(S& aStream);
735 class RecordedDrawSurface : public RecordedEventDerived<RecordedDrawSurface> {
736 public:
737 RecordedDrawSurface(ReferencePtr aRefSource, const Rect& aDest,
738 const Rect& aSource, const DrawSurfaceOptions& aDSOptions,
739 const DrawOptions& aOptions)
740 : RecordedEventDerived(DRAWSURFACE),
741 mRefSource(aRefSource),
742 mDest(aDest),
743 mSource(aSource),
744 mDSOptions(aDSOptions),
745 mOptions(aOptions) {}
747 bool PlayEvent(Translator* aTranslator) const override;
749 template <class S>
750 void Record(S& aStream) const;
751 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
753 std::string GetName() const override { return "DrawSurface"; }
755 private:
756 friend class RecordedEvent;
758 template <class S>
759 MOZ_IMPLICIT RecordedDrawSurface(S& aStream);
761 ReferencePtr mRefSource;
762 Rect mDest;
763 Rect mSource;
764 DrawSurfaceOptions mDSOptions;
765 DrawOptions mOptions;
768 class RecordedDrawDependentSurface
769 : public RecordedEventDerived<RecordedDrawDependentSurface> {
770 public:
771 RecordedDrawDependentSurface(uint64_t aId, const Rect& aDest)
772 : RecordedEventDerived(DRAWDEPENDENTSURFACE), mId(aId), mDest(aDest) {}
774 bool PlayEvent(Translator* aTranslator) const override;
776 template <class S>
777 void Record(S& aStream) const;
778 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
780 std::string GetName() const override { return "DrawDependentSurface"; }
782 private:
783 friend class RecordedEvent;
785 template <class S>
786 MOZ_IMPLICIT RecordedDrawDependentSurface(S& aStream);
788 uint64_t mId;
789 Rect mDest;
792 class RecordedDrawSurfaceWithShadow
793 : public RecordedEventDerived<RecordedDrawSurfaceWithShadow> {
794 public:
795 RecordedDrawSurfaceWithShadow(ReferencePtr aRefSource, const Point& aDest,
796 const ShadowOptions& aShadow, CompositionOp aOp)
797 : RecordedEventDerived(DRAWSURFACEWITHSHADOW),
798 mRefSource(aRefSource),
799 mDest(aDest),
800 mShadow(aShadow),
801 mOp(aOp) {}
803 bool PlayEvent(Translator* aTranslator) const override;
805 template <class S>
806 void Record(S& aStream) const;
807 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
809 std::string GetName() const override { return "DrawSurfaceWithShadow"; }
811 private:
812 friend class RecordedEvent;
814 template <class S>
815 MOZ_IMPLICIT RecordedDrawSurfaceWithShadow(S& aStream);
817 ReferencePtr mRefSource;
818 Point mDest;
819 ShadowOptions mShadow;
820 CompositionOp mOp;
823 class RecordedDrawShadow : public RecordedEventDerived<RecordedDrawShadow> {
824 public:
825 RecordedDrawShadow(ReferencePtr aPath, const Pattern& aPattern,
826 const ShadowOptions& aShadow, const DrawOptions& aOptions,
827 const StrokeOptions* aStrokeOptions)
828 : RecordedEventDerived(DRAWSHADOW),
829 mPath(aPath),
830 mPattern(),
831 mShadow(aShadow),
832 mOptions(aOptions),
833 mHasStrokeOptions(!!aStrokeOptions),
834 mStrokeOptions(aStrokeOptions ? *aStrokeOptions : StrokeOptions()) {
835 StorePattern(mPattern, aPattern);
838 bool PlayEvent(Translator* aTranslator) const override;
840 template <class S>
841 void Record(S& aStream) const;
842 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
844 std::string GetName() const override { return "DrawShadow"; }
846 private:
847 friend class RecordedEvent;
849 template <class S>
850 MOZ_IMPLICIT RecordedDrawShadow(S& aStream);
852 ReferencePtr mPath;
853 PatternStorage mPattern;
854 ShadowOptions mShadow;
855 DrawOptions mOptions;
856 bool mHasStrokeOptions;
857 StrokeOptions mStrokeOptions;
860 class RecordedDrawFilter : public RecordedEventDerived<RecordedDrawFilter> {
861 public:
862 RecordedDrawFilter(ReferencePtr aNode, const Rect& aSourceRect,
863 const Point& aDestPoint, const DrawOptions& aOptions)
864 : RecordedEventDerived(DRAWFILTER),
865 mNode(aNode),
866 mSourceRect(aSourceRect),
867 mDestPoint(aDestPoint),
868 mOptions(aOptions) {}
870 bool PlayEvent(Translator* aTranslator) const override;
872 template <class S>
873 void Record(S& aStream) const;
874 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
876 std::string GetName() const override { return "DrawFilter"; }
878 private:
879 friend class RecordedEvent;
881 template <class S>
882 MOZ_IMPLICIT RecordedDrawFilter(S& aStream);
884 ReferencePtr mNode;
885 Rect mSourceRect;
886 Point mDestPoint;
887 DrawOptions mOptions;
890 class RecordedPathCreation : public RecordedEventDerived<RecordedPathCreation> {
891 public:
892 MOZ_IMPLICIT RecordedPathCreation(PathRecording* aPath);
894 bool PlayEvent(Translator* aTranslator) const override;
896 template <class S>
897 void Record(S& aStream) const;
898 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
900 std::string GetName() const override { return "Path Creation"; }
902 private:
903 friend class RecordedEvent;
905 ReferencePtr mDT;
906 ReferencePtr mRefPtr;
907 FillRule mFillRule;
908 RefPtr<PathRecording> mPath;
909 UniquePtr<PathOps> mPathOps;
911 template <class S>
912 MOZ_IMPLICIT RecordedPathCreation(S& aStream);
915 class RecordedPathDestruction
916 : public RecordedEventDerived<RecordedPathDestruction> {
917 public:
918 MOZ_IMPLICIT RecordedPathDestruction(PathRecording* aPath)
919 : RecordedEventDerived(PATHDESTRUCTION), mRefPtr(aPath) {}
921 bool PlayEvent(Translator* aTranslator) const override;
923 template <class S>
924 void Record(S& aStream) const;
925 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
927 std::string GetName() const override { return "Path Destruction"; }
929 private:
930 friend class RecordedEvent;
932 ReferencePtr mRefPtr;
934 template <class S>
935 MOZ_IMPLICIT RecordedPathDestruction(S& aStream);
938 class RecordedSourceSurfaceCreation
939 : public RecordedEventDerived<RecordedSourceSurfaceCreation> {
940 public:
941 RecordedSourceSurfaceCreation(ReferencePtr aRefPtr, uint8_t* aData,
942 int32_t aStride, const IntSize& aSize,
943 SurfaceFormat aFormat)
944 : RecordedEventDerived(SOURCESURFACECREATION),
945 mRefPtr(aRefPtr),
946 mData(aData),
947 mStride(aStride),
948 mSize(aSize),
949 mFormat(aFormat),
950 mDataOwned(false) {}
952 ~RecordedSourceSurfaceCreation();
954 bool PlayEvent(Translator* aTranslator) const override;
956 template <class S>
957 void Record(S& aStream) const;
958 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
960 std::string GetName() const override { return "SourceSurface Creation"; }
962 private:
963 friend class RecordedEvent;
965 ReferencePtr mRefPtr;
966 uint8_t* mData = nullptr;
967 int32_t mStride;
968 IntSize mSize;
969 SurfaceFormat mFormat;
970 mutable bool mDataOwned;
972 template <class S>
973 MOZ_IMPLICIT RecordedSourceSurfaceCreation(S& aStream);
976 class RecordedSourceSurfaceDestruction
977 : public RecordedEventDerived<RecordedSourceSurfaceDestruction> {
978 public:
979 MOZ_IMPLICIT RecordedSourceSurfaceDestruction(ReferencePtr aRefPtr)
980 : RecordedEventDerived(SOURCESURFACEDESTRUCTION), mRefPtr(aRefPtr) {}
982 bool PlayEvent(Translator* aTranslator) const override;
984 template <class S>
985 void Record(S& aStream) const;
986 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
988 std::string GetName() const override { return "SourceSurface Destruction"; }
990 private:
991 friend class RecordedEvent;
993 ReferencePtr mRefPtr;
995 template <class S>
996 MOZ_IMPLICIT RecordedSourceSurfaceDestruction(S& aStream);
999 class RecordedOptimizeSourceSurface
1000 : public RecordedEventDerived<RecordedOptimizeSourceSurface> {
1001 public:
1002 RecordedOptimizeSourceSurface(ReferencePtr aSurface,
1003 ReferencePtr aOptimizedSurface)
1004 : RecordedEventDerived(OPTIMIZESOURCESURFACE),
1005 mSurface(aSurface),
1006 mOptimizedSurface(aOptimizedSurface) {}
1008 bool PlayEvent(Translator* aTranslator) const override;
1010 template <class S>
1011 void Record(S& aStream) const;
1012 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1014 std::string GetName() const override { return "OptimizeSourceSurface"; }
1016 private:
1017 friend class RecordedEvent;
1019 ReferencePtr mSurface;
1020 ReferencePtr mOptimizedSurface;
1022 template <class S>
1023 MOZ_IMPLICIT RecordedOptimizeSourceSurface(S& aStream);
1026 class RecordedExternalSurfaceCreation
1027 : public RecordedEventDerived<RecordedExternalSurfaceCreation> {
1028 public:
1029 RecordedExternalSurfaceCreation(ReferencePtr aRefPtr, const uint64_t aKey)
1030 : RecordedEventDerived(EXTERNALSURFACECREATION),
1031 mRefPtr(aRefPtr),
1032 mKey(aKey) {}
1034 ~RecordedExternalSurfaceCreation() = default;
1036 virtual bool PlayEvent(Translator* aTranslator) const;
1038 template <class S>
1039 void Record(S& aStream) const;
1040 virtual void OutputSimpleEventInfo(std::stringstream& aStringStream) const;
1042 virtual std::string GetName() const {
1043 return "SourceSurfaceSharedData Creation";
1046 private:
1047 friend class RecordedEvent;
1049 ReferencePtr mRefPtr;
1050 uint64_t mKey;
1052 template <class S>
1053 MOZ_IMPLICIT RecordedExternalSurfaceCreation(S& aStream);
1056 class RecordedFilterNodeCreation
1057 : public RecordedEventDerived<RecordedFilterNodeCreation> {
1058 public:
1059 RecordedFilterNodeCreation(ReferencePtr aRefPtr, FilterType aType)
1060 : RecordedEventDerived(FILTERNODECREATION),
1061 mRefPtr(aRefPtr),
1062 mType(aType) {}
1064 ~RecordedFilterNodeCreation();
1066 bool PlayEvent(Translator* aTranslator) const override;
1068 template <class S>
1069 void Record(S& aStream) const;
1070 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1072 std::string GetName() const override { return "FilterNode Creation"; }
1074 private:
1075 friend class RecordedEvent;
1077 ReferencePtr mRefPtr;
1078 FilterType mType;
1080 template <class S>
1081 MOZ_IMPLICIT RecordedFilterNodeCreation(S& aStream);
1084 class RecordedFilterNodeDestruction
1085 : public RecordedEventDerived<RecordedFilterNodeDestruction> {
1086 public:
1087 MOZ_IMPLICIT RecordedFilterNodeDestruction(ReferencePtr aRefPtr)
1088 : RecordedEventDerived(FILTERNODEDESTRUCTION), mRefPtr(aRefPtr) {}
1090 bool PlayEvent(Translator* aTranslator) const override;
1092 template <class S>
1093 void Record(S& aStream) const;
1094 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1096 std::string GetName() const override { return "FilterNode Destruction"; }
1098 private:
1099 friend class RecordedEvent;
1101 ReferencePtr mRefPtr;
1103 template <class S>
1104 MOZ_IMPLICIT RecordedFilterNodeDestruction(S& aStream);
1107 class RecordedGradientStopsCreation
1108 : public RecordedEventDerived<RecordedGradientStopsCreation> {
1109 public:
1110 RecordedGradientStopsCreation(ReferencePtr aRefPtr, GradientStop* aStops,
1111 uint32_t aNumStops, ExtendMode aExtendMode)
1112 : RecordedEventDerived(GRADIENTSTOPSCREATION),
1113 mRefPtr(aRefPtr),
1114 mStops(aStops),
1115 mNumStops(aNumStops),
1116 mExtendMode(aExtendMode),
1117 mDataOwned(false) {}
1119 ~RecordedGradientStopsCreation();
1121 bool PlayEvent(Translator* aTranslator) const override;
1123 template <class S>
1124 void Record(S& aStream) const;
1125 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1127 std::string GetName() const override { return "GradientStops Creation"; }
1129 private:
1130 friend class RecordedEvent;
1132 ReferencePtr mRefPtr;
1133 GradientStop* mStops = nullptr;
1134 uint32_t mNumStops = 0;
1135 ExtendMode mExtendMode;
1136 bool mDataOwned;
1138 template <class S>
1139 MOZ_IMPLICIT RecordedGradientStopsCreation(S& aStream);
1142 class RecordedGradientStopsDestruction
1143 : public RecordedEventDerived<RecordedGradientStopsDestruction> {
1144 public:
1145 MOZ_IMPLICIT RecordedGradientStopsDestruction(ReferencePtr aRefPtr)
1146 : RecordedEventDerived(GRADIENTSTOPSDESTRUCTION), mRefPtr(aRefPtr) {}
1148 bool PlayEvent(Translator* aTranslator) const override;
1150 template <class S>
1151 void Record(S& aStream) const;
1152 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1154 std::string GetName() const override { return "GradientStops Destruction"; }
1156 private:
1157 friend class RecordedEvent;
1159 ReferencePtr mRefPtr;
1161 template <class S>
1162 MOZ_IMPLICIT RecordedGradientStopsDestruction(S& aStream);
1165 class RecordedFlush : public RecordedEventDerived<RecordedFlush> {
1166 public:
1167 explicit RecordedFlush() : RecordedEventDerived(FLUSH) {}
1169 bool PlayEvent(Translator* aTranslator) const final;
1171 template <class S>
1172 void Record(S& aStream) const;
1173 virtual void OutputSimpleEventInfo(
1174 std::stringstream& aStringStream) const override;
1176 virtual std::string GetName() const override { return "Flush"; }
1178 private:
1179 friend class RecordedEvent;
1181 template <class S>
1182 MOZ_IMPLICIT RecordedFlush(S& aStream);
1185 class RecordedDetachAllSnapshots
1186 : public RecordedEventDerived<RecordedDetachAllSnapshots> {
1187 public:
1188 explicit RecordedDetachAllSnapshots()
1189 : RecordedEventDerived(DETACHALLSNAPSHOTS) {}
1191 bool PlayEvent(Translator* aTranslator) const final;
1193 template <class S>
1194 void Record(S& aStream) const;
1195 virtual void OutputSimpleEventInfo(
1196 std::stringstream& aStringStream) const override;
1198 virtual std::string GetName() const override { return "DetachAllSnapshots"; }
1200 private:
1201 friend class RecordedEvent;
1203 template <class S>
1204 MOZ_IMPLICIT RecordedDetachAllSnapshots(S& aStream);
1207 class RecordedSnapshot : public RecordedEventDerived<RecordedSnapshot> {
1208 public:
1209 explicit RecordedSnapshot(ReferencePtr aRefPtr)
1210 : RecordedEventDerived(SNAPSHOT), mRefPtr(aRefPtr) {}
1212 bool PlayEvent(Translator* aTranslator) const override;
1214 template <class S>
1215 void Record(S& aStream) const;
1216 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1218 std::string GetName() const override { return "Snapshot"; }
1220 private:
1221 friend class RecordedEvent;
1223 ReferencePtr mRefPtr;
1225 template <class S>
1226 MOZ_IMPLICIT RecordedSnapshot(S& aStream);
1229 class RecordedIntoLuminanceSource
1230 : public RecordedEventDerived<RecordedIntoLuminanceSource> {
1231 public:
1232 RecordedIntoLuminanceSource(ReferencePtr aRefPtr,
1233 LuminanceType aLuminanceType, float aOpacity)
1234 : RecordedEventDerived(INTOLUMINANCE),
1235 mRefPtr(aRefPtr),
1236 mLuminanceType(aLuminanceType),
1237 mOpacity(aOpacity) {}
1239 bool PlayEvent(Translator* aTranslator) const override;
1241 template <class S>
1242 void Record(S& aStream) const;
1243 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1245 std::string GetName() const override { return "IntoLuminanceSource"; }
1247 private:
1248 friend class RecordedEvent;
1250 ReferencePtr mRefPtr;
1251 LuminanceType mLuminanceType;
1252 float mOpacity;
1254 template <class S>
1255 MOZ_IMPLICIT RecordedIntoLuminanceSource(S& aStream);
1258 class RecordedFontData : public RecordedEventDerived<RecordedFontData> {
1259 public:
1260 static void FontDataProc(const uint8_t* aData, uint32_t aSize,
1261 uint32_t aIndex, void* aBaton) {
1262 auto recordedFontData = static_cast<RecordedFontData*>(aBaton);
1263 recordedFontData->SetFontData(aData, aSize, aIndex);
1266 explicit RecordedFontData(UnscaledFont* aUnscaledFont)
1267 : RecordedEventDerived(FONTDATA),
1268 mType(aUnscaledFont->GetType()),
1269 mFontDetails() {
1270 mGetFontFileDataSucceeded =
1271 aUnscaledFont->GetFontFileData(&FontDataProc, this) && mData;
1274 virtual ~RecordedFontData();
1276 bool IsValid() const { return mGetFontFileDataSucceeded; }
1278 bool PlayEvent(Translator* aTranslator) const override;
1280 template <class S>
1281 void Record(S& aStream) const;
1282 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1284 std::string GetName() const override { return "Font Data"; }
1286 void SetFontData(const uint8_t* aData, uint32_t aSize, uint32_t aIndex);
1288 bool GetFontDetails(RecordedFontDetails& fontDetails);
1290 private:
1291 friend class RecordedEvent;
1293 FontType mType;
1294 uint8_t* mData = nullptr;
1295 RecordedFontDetails mFontDetails;
1297 bool mGetFontFileDataSucceeded;
1299 template <class S>
1300 MOZ_IMPLICIT RecordedFontData(S& aStream);
1303 class RecordedFontDescriptor
1304 : public RecordedEventDerived<RecordedFontDescriptor> {
1305 public:
1306 static void FontDescCb(const uint8_t* aData, uint32_t aSize, uint32_t aIndex,
1307 void* aBaton) {
1308 auto recordedFontDesc = static_cast<RecordedFontDescriptor*>(aBaton);
1309 recordedFontDesc->SetFontDescriptor(aData, aSize, aIndex);
1312 explicit RecordedFontDescriptor(UnscaledFont* aUnscaledFont)
1313 : RecordedEventDerived(FONTDESC),
1314 mType(aUnscaledFont->GetType()),
1315 mIndex(0),
1316 mRefPtr(aUnscaledFont) {
1317 mHasDesc = aUnscaledFont->GetFontDescriptor(FontDescCb, this);
1320 virtual ~RecordedFontDescriptor();
1322 bool IsValid() const { return mHasDesc; }
1324 bool PlayEvent(Translator* aTranslator) const override;
1326 template <class S>
1327 void Record(S& aStream) const;
1328 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1330 std::string GetName() const override { return "Font Desc"; }
1332 private:
1333 friend class RecordedEvent;
1335 void SetFontDescriptor(const uint8_t* aData, uint32_t aSize, uint32_t aIndex);
1337 bool mHasDesc;
1339 FontType mType;
1340 std::vector<uint8_t> mData;
1341 uint32_t mIndex;
1342 ReferencePtr mRefPtr;
1344 template <class S>
1345 MOZ_IMPLICIT RecordedFontDescriptor(S& aStream);
1348 class RecordedUnscaledFontCreation
1349 : public RecordedEventDerived<RecordedUnscaledFontCreation> {
1350 public:
1351 static void FontInstanceDataProc(const uint8_t* aData, uint32_t aSize,
1352 void* aBaton) {
1353 auto recordedUnscaledFontCreation =
1354 static_cast<RecordedUnscaledFontCreation*>(aBaton);
1355 recordedUnscaledFontCreation->SetFontInstanceData(aData, aSize);
1358 RecordedUnscaledFontCreation(UnscaledFont* aUnscaledFont,
1359 RecordedFontDetails aFontDetails)
1360 : RecordedEventDerived(UNSCALEDFONTCREATION),
1361 mRefPtr(aUnscaledFont),
1362 mFontDataKey(aFontDetails.fontDataKey),
1363 mIndex(aFontDetails.index) {
1364 aUnscaledFont->GetFontInstanceData(FontInstanceDataProc, this);
1367 bool PlayEvent(Translator* aTranslator) const override;
1369 template <class S>
1370 void Record(S& aStream) const;
1371 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1373 std::string GetName() const override { return "UnscaledFont Creation"; }
1375 void SetFontInstanceData(const uint8_t* aData, uint32_t aSize);
1377 private:
1378 friend class RecordedEvent;
1380 ReferencePtr mRefPtr;
1381 uint64_t mFontDataKey;
1382 uint32_t mIndex;
1383 std::vector<uint8_t> mInstanceData;
1385 template <class S>
1386 MOZ_IMPLICIT RecordedUnscaledFontCreation(S& aStream);
1389 class RecordedUnscaledFontDestruction
1390 : public RecordedEventDerived<RecordedUnscaledFontDestruction> {
1391 public:
1392 MOZ_IMPLICIT RecordedUnscaledFontDestruction(ReferencePtr aRefPtr)
1393 : RecordedEventDerived(UNSCALEDFONTDESTRUCTION), mRefPtr(aRefPtr) {}
1395 bool PlayEvent(Translator* aTranslator) const override;
1396 template <class S>
1397 void Record(S& aStream) const;
1398 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1400 std::string GetName() const override { return "UnscaledFont Destruction"; }
1402 private:
1403 friend class RecordedEvent;
1405 ReferencePtr mRefPtr;
1407 template <class S>
1408 MOZ_IMPLICIT RecordedUnscaledFontDestruction(S& aStream);
1411 class RecordedScaledFontCreation
1412 : public RecordedEventDerived<RecordedScaledFontCreation> {
1413 public:
1414 static void FontInstanceDataProc(const uint8_t* aData, uint32_t aSize,
1415 const FontVariation* aVariations,
1416 uint32_t aNumVariations, void* aBaton) {
1417 auto recordedScaledFontCreation =
1418 static_cast<RecordedScaledFontCreation*>(aBaton);
1419 recordedScaledFontCreation->SetFontInstanceData(aData, aSize, aVariations,
1420 aNumVariations);
1423 RecordedScaledFontCreation(ScaledFont* aScaledFont,
1424 UnscaledFont* aUnscaledFont)
1425 : RecordedEventDerived(SCALEDFONTCREATION),
1426 mRefPtr(aScaledFont),
1427 mUnscaledFont(aUnscaledFont),
1428 mGlyphSize(aScaledFont->GetSize()) {
1429 aScaledFont->GetFontInstanceData(FontInstanceDataProc, this);
1432 bool PlayEvent(Translator* aTranslator) const override;
1434 template <class S>
1435 void Record(S& aStream) const;
1436 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1438 std::string GetName() const override { return "ScaledFont Creation"; }
1440 void SetFontInstanceData(const uint8_t* aData, uint32_t aSize,
1441 const FontVariation* aVariations,
1442 uint32_t aNumVariations);
1444 private:
1445 friend class RecordedEvent;
1447 ReferencePtr mRefPtr;
1448 ReferencePtr mUnscaledFont;
1449 Float mGlyphSize;
1450 std::vector<uint8_t> mInstanceData;
1451 std::vector<FontVariation> mVariations;
1453 template <class S>
1454 MOZ_IMPLICIT RecordedScaledFontCreation(S& aStream);
1457 class RecordedScaledFontDestruction
1458 : public RecordedEventDerived<RecordedScaledFontDestruction> {
1459 public:
1460 MOZ_IMPLICIT RecordedScaledFontDestruction(ReferencePtr aRefPtr)
1461 : RecordedEventDerived(SCALEDFONTDESTRUCTION), mRefPtr(aRefPtr) {}
1463 bool PlayEvent(Translator* aTranslator) const override;
1465 template <class S>
1466 void Record(S& aStream) const;
1467 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1469 std::string GetName() const override { return "ScaledFont Destruction"; }
1471 private:
1472 friend class RecordedEvent;
1474 ReferencePtr mRefPtr;
1476 template <class S>
1477 MOZ_IMPLICIT RecordedScaledFontDestruction(S& aStream);
1480 class RecordedMaskSurface : public RecordedEventDerived<RecordedMaskSurface> {
1481 public:
1482 RecordedMaskSurface(const Pattern& aPattern, ReferencePtr aRefMask,
1483 const Point& aOffset, const DrawOptions& aOptions)
1484 : RecordedEventDerived(MASKSURFACE),
1485 mPattern(),
1486 mRefMask(aRefMask),
1487 mOffset(aOffset),
1488 mOptions(aOptions) {
1489 StorePattern(mPattern, aPattern);
1492 bool PlayEvent(Translator* aTranslator) const override;
1494 template <class S>
1495 void Record(S& aStream) const;
1496 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1498 std::string GetName() const override { return "MaskSurface"; }
1500 private:
1501 friend class RecordedEvent;
1503 template <class S>
1504 MOZ_IMPLICIT RecordedMaskSurface(S& aStream);
1506 PatternStorage mPattern;
1507 ReferencePtr mRefMask;
1508 Point mOffset;
1509 DrawOptions mOptions;
1512 class RecordedFilterNodeSetAttribute
1513 : public RecordedEventDerived<RecordedFilterNodeSetAttribute> {
1514 public:
1515 enum ArgType {
1516 ARGTYPE_UINT32,
1517 ARGTYPE_BOOL,
1518 ARGTYPE_FLOAT,
1519 ARGTYPE_SIZE,
1520 ARGTYPE_INTSIZE,
1521 ARGTYPE_INTPOINT,
1522 ARGTYPE_RECT,
1523 ARGTYPE_INTRECT,
1524 ARGTYPE_POINT,
1525 ARGTYPE_MATRIX,
1526 ARGTYPE_MATRIX5X4,
1527 ARGTYPE_POINT3D,
1528 ARGTYPE_COLOR,
1529 ARGTYPE_FLOAT_ARRAY
1532 template <typename T>
1533 RecordedFilterNodeSetAttribute(FilterNode* aNode, uint32_t aIndex,
1534 T aArgument, ArgType aArgType)
1535 : RecordedEventDerived(FILTERNODESETATTRIBUTE),
1536 mNode(aNode),
1537 mIndex(aIndex),
1538 mArgType(aArgType) {
1539 mPayload.resize(sizeof(T));
1540 memcpy(&mPayload.front(), &aArgument, sizeof(T));
1543 RecordedFilterNodeSetAttribute(FilterNode* aNode, uint32_t aIndex,
1544 const Float* aFloat, uint32_t aSize)
1545 : RecordedEventDerived(FILTERNODESETATTRIBUTE),
1546 mNode(aNode),
1547 mIndex(aIndex),
1548 mArgType(ARGTYPE_FLOAT_ARRAY) {
1549 mPayload.resize(sizeof(Float) * aSize);
1550 memcpy(&mPayload.front(), aFloat, sizeof(Float) * aSize);
1553 bool PlayEvent(Translator* aTranslator) const override;
1554 template <class S>
1555 void Record(S& aStream) const;
1556 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1558 std::string GetName() const override { return "SetAttribute"; }
1560 private:
1561 friend class RecordedEvent;
1563 ReferencePtr mNode;
1565 uint32_t mIndex;
1566 ArgType mArgType;
1567 std::vector<uint8_t> mPayload;
1569 template <class S>
1570 MOZ_IMPLICIT RecordedFilterNodeSetAttribute(S& aStream);
1573 class RecordedFilterNodeSetInput
1574 : public RecordedEventDerived<RecordedFilterNodeSetInput> {
1575 public:
1576 RecordedFilterNodeSetInput(FilterNode* aNode, uint32_t aIndex,
1577 FilterNode* aInputNode)
1578 : RecordedEventDerived(FILTERNODESETINPUT),
1579 mNode(aNode),
1580 mIndex(aIndex),
1581 mInputFilter(aInputNode),
1582 mInputSurface(nullptr) {}
1584 RecordedFilterNodeSetInput(FilterNode* aNode, uint32_t aIndex,
1585 SourceSurface* aInputSurface)
1586 : RecordedEventDerived(FILTERNODESETINPUT),
1587 mNode(aNode),
1588 mIndex(aIndex),
1589 mInputFilter(nullptr),
1590 mInputSurface(aInputSurface) {}
1592 bool PlayEvent(Translator* aTranslator) const override;
1593 template <class S>
1594 void Record(S& aStream) const;
1595 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1597 std::string GetName() const override { return "SetInput"; }
1599 private:
1600 friend class RecordedEvent;
1602 ReferencePtr mNode;
1603 uint32_t mIndex;
1604 ReferencePtr mInputFilter;
1605 ReferencePtr mInputSurface;
1607 template <class S>
1608 MOZ_IMPLICIT RecordedFilterNodeSetInput(S& aStream);
1611 class RecordedLink : public RecordedEventDerived<RecordedLink> {
1612 public:
1613 RecordedLink(const char* aDestination, const Rect& aRect)
1614 : RecordedEventDerived(LINK), mDestination(aDestination), mRect(aRect) {}
1616 bool PlayEvent(Translator* aTranslator) const override;
1617 template <class S>
1618 void Record(S& aStream) const;
1619 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1621 std::string GetName() const override { return "Link"; }
1623 private:
1624 friend class RecordedEvent;
1626 std::string mDestination;
1627 Rect mRect;
1629 template <class S>
1630 MOZ_IMPLICIT RecordedLink(S& aStream);
1633 class RecordedDestination : public RecordedEventDerived<RecordedDestination> {
1634 public:
1635 RecordedDestination(const char* aDestination, const Point& aPoint)
1636 : RecordedEventDerived(DESTINATION),
1637 mDestination(aDestination),
1638 mPoint(aPoint) {}
1640 bool PlayEvent(Translator* aTranslator) const override;
1641 template <class S>
1642 void Record(S& aStream) const;
1643 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1645 std::string GetName() const override { return "Destination"; }
1647 private:
1648 friend class RecordedEvent;
1650 std::string mDestination;
1651 Point mPoint;
1653 template <class S>
1654 MOZ_IMPLICIT RecordedDestination(S& aStream);
1657 static std::string NameFromBackend(BackendType aType) {
1658 switch (aType) {
1659 case BackendType::NONE:
1660 return "None";
1661 case BackendType::DIRECT2D:
1662 return "Direct2D";
1663 default:
1664 return "Unknown";
1668 template <class S>
1669 void RecordedEvent::RecordPatternData(S& aStream,
1670 const PatternStorage& aPattern) const {
1671 WriteElement(aStream, aPattern.mType);
1673 switch (aPattern.mType) {
1674 case PatternType::COLOR: {
1675 WriteElement(aStream, *reinterpret_cast<const ColorPatternStorage*>(
1676 &aPattern.mStorage));
1677 return;
1679 case PatternType::LINEAR_GRADIENT: {
1680 WriteElement(aStream,
1681 *reinterpret_cast<const LinearGradientPatternStorage*>(
1682 &aPattern.mStorage));
1683 return;
1685 case PatternType::RADIAL_GRADIENT: {
1686 WriteElement(aStream,
1687 *reinterpret_cast<const RadialGradientPatternStorage*>(
1688 &aPattern.mStorage));
1689 return;
1691 case PatternType::CONIC_GRADIENT: {
1692 WriteElement(aStream,
1693 *reinterpret_cast<const ConicGradientPatternStorage*>(
1694 &aPattern.mStorage));
1695 return;
1697 case PatternType::SURFACE: {
1698 WriteElement(aStream, *reinterpret_cast<const SurfacePatternStorage*>(
1699 &aPattern.mStorage));
1700 return;
1702 default:
1703 return;
1707 template <class S>
1708 void RecordedEvent::ReadPatternData(S& aStream,
1709 PatternStorage& aPattern) const {
1710 ReadElementConstrained(aStream, aPattern.mType, PatternType::COLOR,
1711 kHighestPatternType);
1713 switch (aPattern.mType) {
1714 case PatternType::COLOR: {
1715 ReadElement(aStream,
1716 *reinterpret_cast<ColorPatternStorage*>(&aPattern.mStorage));
1717 return;
1719 case PatternType::LINEAR_GRADIENT: {
1720 ReadElement(aStream, *reinterpret_cast<LinearGradientPatternStorage*>(
1721 &aPattern.mStorage));
1722 return;
1724 case PatternType::RADIAL_GRADIENT: {
1725 ReadElement(aStream, *reinterpret_cast<RadialGradientPatternStorage*>(
1726 &aPattern.mStorage));
1727 return;
1729 case PatternType::CONIC_GRADIENT: {
1730 ReadElement(aStream, *reinterpret_cast<ConicGradientPatternStorage*>(
1731 &aPattern.mStorage));
1732 return;
1734 case PatternType::SURFACE: {
1735 SurfacePatternStorage* sps =
1736 reinterpret_cast<SurfacePatternStorage*>(&aPattern.mStorage);
1737 ReadElement(aStream, *sps);
1738 if (sps->mExtend < ExtendMode::CLAMP ||
1739 sps->mExtend > ExtendMode::REFLECT) {
1740 aStream.SetIsBad();
1741 return;
1744 if (sps->mSamplingFilter < SamplingFilter::GOOD ||
1745 sps->mSamplingFilter >= SamplingFilter::SENTINEL) {
1746 aStream.SetIsBad();
1748 return;
1750 default:
1751 return;
1755 inline void RecordedEvent::StorePattern(PatternStorage& aDestination,
1756 const Pattern& aSource) const {
1757 aDestination.mType = aSource.GetType();
1759 switch (aSource.GetType()) {
1760 case PatternType::COLOR: {
1761 reinterpret_cast<ColorPatternStorage*>(&aDestination.mStorage)->mColor =
1762 static_cast<const ColorPattern*>(&aSource)->mColor;
1763 return;
1765 case PatternType::LINEAR_GRADIENT: {
1766 LinearGradientPatternStorage* store =
1767 reinterpret_cast<LinearGradientPatternStorage*>(
1768 &aDestination.mStorage);
1769 const LinearGradientPattern* pat =
1770 static_cast<const LinearGradientPattern*>(&aSource);
1771 store->mBegin = pat->mBegin;
1772 store->mEnd = pat->mEnd;
1773 store->mMatrix = pat->mMatrix;
1774 store->mStops = pat->mStops.get();
1775 return;
1777 case PatternType::RADIAL_GRADIENT: {
1778 RadialGradientPatternStorage* store =
1779 reinterpret_cast<RadialGradientPatternStorage*>(
1780 &aDestination.mStorage);
1781 const RadialGradientPattern* pat =
1782 static_cast<const RadialGradientPattern*>(&aSource);
1783 store->mCenter1 = pat->mCenter1;
1784 store->mCenter2 = pat->mCenter2;
1785 store->mRadius1 = pat->mRadius1;
1786 store->mRadius2 = pat->mRadius2;
1787 store->mMatrix = pat->mMatrix;
1788 store->mStops = pat->mStops.get();
1789 return;
1791 case PatternType::CONIC_GRADIENT: {
1792 ConicGradientPatternStorage* store =
1793 reinterpret_cast<ConicGradientPatternStorage*>(
1794 &aDestination.mStorage);
1795 const ConicGradientPattern* pat =
1796 static_cast<const ConicGradientPattern*>(&aSource);
1797 store->mCenter = pat->mCenter;
1798 store->mAngle = pat->mAngle;
1799 store->mStartOffset = pat->mStartOffset;
1800 store->mEndOffset = pat->mEndOffset;
1801 store->mMatrix = pat->mMatrix;
1802 store->mStops = pat->mStops.get();
1803 return;
1805 case PatternType::SURFACE: {
1806 SurfacePatternStorage* store =
1807 reinterpret_cast<SurfacePatternStorage*>(&aDestination.mStorage);
1808 const SurfacePattern* pat = static_cast<const SurfacePattern*>(&aSource);
1809 store->mExtend = pat->mExtendMode;
1810 store->mSamplingFilter = pat->mSamplingFilter;
1811 store->mMatrix = pat->mMatrix;
1812 store->mSurface = pat->mSurface;
1813 store->mSamplingRect = pat->mSamplingRect;
1814 return;
1819 template <class S>
1820 void RecordedEvent::RecordStrokeOptions(
1821 S& aStream, const StrokeOptions& aStrokeOptions) const {
1822 JoinStyle joinStyle = aStrokeOptions.mLineJoin;
1823 CapStyle capStyle = aStrokeOptions.mLineCap;
1825 WriteElement(aStream, uint64_t(aStrokeOptions.mDashLength));
1826 WriteElement(aStream, aStrokeOptions.mLineWidth);
1827 WriteElement(aStream, aStrokeOptions.mMiterLimit);
1828 WriteElement(aStream, joinStyle);
1829 WriteElement(aStream, capStyle);
1831 if (!aStrokeOptions.mDashPattern) {
1832 return;
1835 WriteElement(aStream, aStrokeOptions.mDashOffset);
1836 aStream.write((char*)aStrokeOptions.mDashPattern,
1837 sizeof(Float) * aStrokeOptions.mDashLength);
1840 template <class S>
1841 void RecordedEvent::ReadStrokeOptions(S& aStream,
1842 StrokeOptions& aStrokeOptions) {
1843 uint64_t dashLength;
1844 JoinStyle joinStyle;
1845 CapStyle capStyle;
1847 ReadElement(aStream, dashLength);
1848 ReadElement(aStream, aStrokeOptions.mLineWidth);
1849 ReadElement(aStream, aStrokeOptions.mMiterLimit);
1850 ReadElementConstrained(aStream, joinStyle, JoinStyle::BEVEL,
1851 JoinStyle::MITER_OR_BEVEL);
1852 ReadElementConstrained(aStream, capStyle, CapStyle::BUTT, CapStyle::SQUARE);
1853 // On 32 bit we truncate the value of dashLength.
1854 // See also bug 811850 for history.
1855 aStrokeOptions.mDashLength = size_t(dashLength);
1856 aStrokeOptions.mLineJoin = joinStyle;
1857 aStrokeOptions.mLineCap = capStyle;
1859 if (!aStrokeOptions.mDashLength || !aStream.good()) {
1860 return;
1863 ReadElement(aStream, aStrokeOptions.mDashOffset);
1865 mDashPatternStorage.resize(aStrokeOptions.mDashLength);
1866 aStrokeOptions.mDashPattern = &mDashPatternStorage.front();
1867 aStream.read((char*)aStrokeOptions.mDashPattern,
1868 sizeof(Float) * aStrokeOptions.mDashLength);
1871 template <class S>
1872 static void ReadDrawOptions(S& aStream, DrawOptions& aDrawOptions) {
1873 ReadElement(aStream, aDrawOptions);
1874 if (aDrawOptions.mAntialiasMode < AntialiasMode::NONE ||
1875 aDrawOptions.mAntialiasMode > AntialiasMode::DEFAULT) {
1876 aStream.SetIsBad();
1877 return;
1880 if (aDrawOptions.mCompositionOp < CompositionOp::OP_CLEAR ||
1881 aDrawOptions.mCompositionOp > CompositionOp::OP_COUNT) {
1882 aStream.SetIsBad();
1886 template <class S>
1887 static void ReadDrawSurfaceOptions(S& aStream,
1888 DrawSurfaceOptions& aDrawSurfaceOptions) {
1889 ReadElement(aStream, aDrawSurfaceOptions);
1890 if (aDrawSurfaceOptions.mSamplingFilter < SamplingFilter::GOOD ||
1891 aDrawSurfaceOptions.mSamplingFilter >= SamplingFilter::SENTINEL) {
1892 aStream.SetIsBad();
1893 return;
1896 if (aDrawSurfaceOptions.mSamplingBounds < SamplingBounds::UNBOUNDED ||
1897 aDrawSurfaceOptions.mSamplingBounds > SamplingBounds::BOUNDED) {
1898 aStream.SetIsBad();
1902 inline void RecordedEvent::OutputSimplePatternInfo(
1903 const PatternStorage& aStorage, std::stringstream& aOutput) const {
1904 switch (aStorage.mType) {
1905 case PatternType::COLOR: {
1906 const DeviceColor color =
1907 reinterpret_cast<const ColorPatternStorage*>(&aStorage.mStorage)
1908 ->mColor;
1909 aOutput << "DeviceColor: (" << color.r << ", " << color.g << ", "
1910 << color.b << ", " << color.a << ")";
1911 return;
1913 case PatternType::LINEAR_GRADIENT: {
1914 const LinearGradientPatternStorage* store =
1915 reinterpret_cast<const LinearGradientPatternStorage*>(
1916 &aStorage.mStorage);
1918 aOutput << "LinearGradient (" << store->mBegin.x << ", "
1919 << store->mBegin.y << ") - (" << store->mEnd.x << ", "
1920 << store->mEnd.y << ") Stops: " << store->mStops;
1921 return;
1923 case PatternType::RADIAL_GRADIENT: {
1924 const RadialGradientPatternStorage* store =
1925 reinterpret_cast<const RadialGradientPatternStorage*>(
1926 &aStorage.mStorage);
1927 aOutput << "RadialGradient (Center 1: (" << store->mCenter1.x << ", "
1928 << store->mCenter2.y << ") Radius 2: " << store->mRadius2;
1929 return;
1931 case PatternType::CONIC_GRADIENT: {
1932 const ConicGradientPatternStorage* store =
1933 reinterpret_cast<const ConicGradientPatternStorage*>(
1934 &aStorage.mStorage);
1935 aOutput << "ConicGradient (Center: (" << store->mCenter.x << ", "
1936 << store->mCenter.y << ") Angle: " << store->mAngle
1937 << " Range:" << store->mStartOffset << " - " << store->mEndOffset;
1938 return;
1940 case PatternType::SURFACE: {
1941 const SurfacePatternStorage* store =
1942 reinterpret_cast<const SurfacePatternStorage*>(&aStorage.mStorage);
1943 aOutput << "Surface (0x" << store->mSurface << ")";
1944 return;
1949 inline bool RecordedDrawTargetCreation::PlayEvent(
1950 Translator* aTranslator) const {
1951 RefPtr<DrawTarget> newDT =
1952 aTranslator->CreateDrawTarget(mRefPtr, mRect.Size(), mFormat);
1954 // If we couldn't create a DrawTarget this will probably cause us to crash
1955 // with nullptr later in the playback, so return false to abort.
1956 if (!newDT) {
1957 return false;
1960 if (mHasExistingData) {
1961 Rect dataRect(0, 0, mExistingData->GetSize().width,
1962 mExistingData->GetSize().height);
1963 newDT->DrawSurface(mExistingData, dataRect, dataRect);
1966 return true;
1969 template <class S>
1970 void RecordedDrawTargetCreation::Record(S& aStream) const {
1971 WriteElement(aStream, mRefPtr);
1972 WriteElement(aStream, mBackendType);
1973 WriteElement(aStream, mRect);
1974 WriteElement(aStream, mFormat);
1975 WriteElement(aStream, mHasExistingData);
1977 if (mHasExistingData) {
1978 MOZ_ASSERT(mExistingData);
1979 MOZ_ASSERT(mExistingData->GetSize() == mRect.Size());
1980 RefPtr<DataSourceSurface> dataSurf = mExistingData->GetDataSurface();
1982 DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ);
1983 for (int y = 0; y < mRect.height; y++) {
1984 aStream.write((const char*)map.GetData() + y * map.GetStride(),
1985 BytesPerPixel(mFormat) * mRect.width);
1990 template <class S>
1991 RecordedDrawTargetCreation::RecordedDrawTargetCreation(S& aStream)
1992 : RecordedEventDerived(DRAWTARGETCREATION), mExistingData(nullptr) {
1993 ReadElement(aStream, mRefPtr);
1994 ReadElementConstrained(aStream, mBackendType, BackendType::NONE,
1995 BackendType::WEBRENDER_TEXT);
1996 ReadElement(aStream, mRect);
1997 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
1998 SurfaceFormat::UNKNOWN);
1999 ReadElement(aStream, mHasExistingData);
2001 if (mHasExistingData) {
2002 RefPtr<DataSourceSurface> dataSurf =
2003 Factory::CreateDataSourceSurface(mRect.Size(), mFormat);
2004 if (!dataSurf) {
2005 gfxWarning()
2006 << "RecordedDrawTargetCreation had to reset mHasExistingData";
2007 mHasExistingData = false;
2008 return;
2011 DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ);
2012 for (int y = 0; y < mRect.height; y++) {
2013 aStream.read((char*)map.GetData() + y * map.GetStride(),
2014 BytesPerPixel(mFormat) * mRect.width);
2016 mExistingData = dataSurf;
2020 inline void RecordedDrawTargetCreation::OutputSimpleEventInfo(
2021 std::stringstream& aStringStream) const {
2022 aStringStream << "[" << mRefPtr << "] DrawTarget Creation (Type: "
2023 << NameFromBackend(mBackendType) << ", Size: " << mRect.width
2024 << "x" << mRect.height << ")";
2027 inline bool RecordedDrawTargetDestruction::PlayEvent(
2028 Translator* aTranslator) const {
2029 aTranslator->RemoveDrawTarget(mRefPtr);
2030 return true;
2033 template <class S>
2034 void RecordedDrawTargetDestruction::Record(S& aStream) const {
2035 WriteElement(aStream, mRefPtr);
2038 template <class S>
2039 RecordedDrawTargetDestruction::RecordedDrawTargetDestruction(S& aStream)
2040 : RecordedEventDerived(DRAWTARGETDESTRUCTION) {
2041 ReadElement(aStream, mRefPtr);
2044 inline void RecordedDrawTargetDestruction::OutputSimpleEventInfo(
2045 std::stringstream& aStringStream) const {
2046 aStringStream << "[" << mRefPtr << "] DrawTarget Destruction";
2049 inline bool RecordedSetCurrentDrawTarget::PlayEvent(
2050 Translator* aTranslator) const {
2051 return aTranslator->SetCurrentDrawTarget(mRefPtr);
2054 template <class S>
2055 void RecordedSetCurrentDrawTarget::Record(S& aStream) const {
2056 WriteElement(aStream, mRefPtr);
2059 template <class S>
2060 RecordedSetCurrentDrawTarget::RecordedSetCurrentDrawTarget(S& aStream)
2061 : RecordedEventDerived(SETCURRENTDRAWTARGET) {
2062 ReadElement(aStream, mRefPtr);
2065 inline void RecordedSetCurrentDrawTarget::OutputSimpleEventInfo(
2066 std::stringstream& aStringStream) const {
2067 aStringStream << "[" << mRefPtr << "] SetCurrentDrawTarget";
2070 inline bool RecordedCreateSimilarDrawTarget::PlayEvent(
2071 Translator* aTranslator) const {
2072 DrawTarget* drawTarget = aTranslator->GetCurrentDrawTarget();
2073 if (!drawTarget) {
2074 return false;
2077 RefPtr<DrawTarget> newDT =
2078 drawTarget->CreateSimilarDrawTarget(mSize, mFormat);
2080 // If we couldn't create a DrawTarget this will probably cause us to crash
2081 // with nullptr later in the playback, so return false to abort.
2082 if (!newDT) {
2083 return false;
2086 aTranslator->AddDrawTarget(mRefPtr, newDT);
2087 return true;
2090 template <class S>
2091 void RecordedCreateSimilarDrawTarget::Record(S& aStream) const {
2092 WriteElement(aStream, mRefPtr);
2093 WriteElement(aStream, mSize);
2094 WriteElement(aStream, mFormat);
2097 template <class S>
2098 RecordedCreateSimilarDrawTarget::RecordedCreateSimilarDrawTarget(S& aStream)
2099 : RecordedEventDerived(CREATESIMILARDRAWTARGET) {
2100 ReadElement(aStream, mRefPtr);
2101 ReadElement(aStream, mSize);
2102 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2103 SurfaceFormat::UNKNOWN);
2106 inline void RecordedCreateSimilarDrawTarget::OutputSimpleEventInfo(
2107 std::stringstream& aStringStream) const {
2108 aStringStream << "[" << mRefPtr
2109 << "] CreateSimilarDrawTarget (Size: " << mSize.width << "x"
2110 << mSize.height << ")";
2113 inline bool RecordedCreateDrawTargetForFilter::PlayEvent(
2114 Translator* aTranslator) const {
2115 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2116 if (!dt) {
2117 return false;
2120 IntRect baseRect = dt->GetRect();
2122 auto maxRect = IntRect(IntPoint(0, 0), mMaxSize);
2124 auto clone = dt->GetTransform();
2125 bool invertible = clone.Invert();
2126 // mSourceRect is in filter space. The filter outputs from mSourceRect need
2127 // to be drawn at mDestPoint in user space.
2128 Rect userSpaceSource = Rect(mDestPoint, mSourceRect.Size());
2129 if (invertible) {
2130 // Try to reduce the source rect so that it's not much bigger
2131 // than the draw target. The result is not minimal. Examples
2132 // are left as an exercise for the reader.
2133 auto destRect = IntRectToRect(baseRect);
2134 Rect userSpaceBounds = clone.TransformBounds(destRect);
2135 userSpaceSource = userSpaceSource.Intersect(userSpaceBounds);
2138 // Compute how much we moved the top-left of the source rect by, and use that
2139 // to compute the new dest point, and move our intersected source rect back
2140 // into the (new) filter space.
2141 Point shift = userSpaceSource.TopLeft() - mDestPoint;
2142 Rect filterSpaceSource =
2143 Rect(mSourceRect.TopLeft() + shift, userSpaceSource.Size());
2145 baseRect = RoundedOut(filterSpaceSource);
2146 FilterNode* filter = aTranslator->LookupFilterNode(mFilter);
2147 if (!filter) {
2148 return false;
2151 IntRect transformedRect = filter->MapRectToSource(
2152 baseRect, maxRect, aTranslator->LookupFilterNode(mSource));
2154 // Intersect with maxRect to make sure we didn't end up with something bigger
2155 transformedRect = transformedRect.Intersect(maxRect);
2157 // If we end up with an empty rect make it 1x1 so that things don't break.
2158 if (transformedRect.IsEmpty()) {
2159 transformedRect = IntRect(0, 0, 1, 1);
2162 RefPtr<DrawTarget> newDT =
2163 dt->CreateSimilarDrawTarget(transformedRect.Size(), mFormat);
2164 if (!newDT) {
2165 return false;
2167 newDT =
2168 gfx::Factory::CreateOffsetDrawTarget(newDT, transformedRect.TopLeft());
2170 // If we couldn't create a DrawTarget this will probably cause us to crash
2171 // with nullptr later in the playback, so return false to abort.
2172 if (!newDT) {
2173 return false;
2176 aTranslator->AddDrawTarget(mRefPtr, newDT);
2177 return true;
2180 inline bool RecordedCreateClippedDrawTarget::PlayEvent(
2181 Translator* aTranslator) const {
2182 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2183 if (!dt) {
2184 return false;
2187 RefPtr<DrawTarget> newDT = dt->CreateClippedDrawTarget(mBounds, mFormat);
2189 // If we couldn't create a DrawTarget this will probably cause us to crash
2190 // with nullptr later in the playback, so return false to abort.
2191 if (!newDT) {
2192 return false;
2195 aTranslator->AddDrawTarget(mRefPtr, newDT);
2196 return true;
2199 template <class S>
2200 void RecordedCreateClippedDrawTarget::Record(S& aStream) const {
2201 WriteElement(aStream, mRefPtr);
2202 WriteElement(aStream, mBounds);
2203 WriteElement(aStream, mFormat);
2206 template <class S>
2207 RecordedCreateClippedDrawTarget::RecordedCreateClippedDrawTarget(S& aStream)
2208 : RecordedEventDerived(CREATECLIPPEDDRAWTARGET) {
2209 ReadElement(aStream, mRefPtr);
2210 ReadElement(aStream, mBounds);
2211 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2212 SurfaceFormat::UNKNOWN);
2215 inline void RecordedCreateClippedDrawTarget::OutputSimpleEventInfo(
2216 std::stringstream& aStringStream) const {
2217 aStringStream << "[" << mRefPtr << "] CreateClippedDrawTarget ()";
2220 template <class S>
2221 void RecordedCreateDrawTargetForFilter::Record(S& aStream) const {
2222 WriteElement(aStream, mRefPtr);
2223 WriteElement(aStream, mMaxSize);
2224 WriteElement(aStream, mFormat);
2225 WriteElement(aStream, mFilter);
2226 WriteElement(aStream, mSource);
2227 WriteElement(aStream, mSourceRect);
2228 WriteElement(aStream, mDestPoint);
2231 template <class S>
2232 RecordedCreateDrawTargetForFilter::RecordedCreateDrawTargetForFilter(S& aStream)
2233 : RecordedEventDerived(CREATEDRAWTARGETFORFILTER) {
2234 ReadElement(aStream, mRefPtr);
2235 ReadElement(aStream, mMaxSize);
2236 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2237 SurfaceFormat::UNKNOWN);
2238 ReadElement(aStream, mFilter);
2239 ReadElement(aStream, mSource);
2240 ReadElement(aStream, mSourceRect);
2241 ReadElement(aStream, mDestPoint);
2244 inline void RecordedCreateDrawTargetForFilter::OutputSimpleEventInfo(
2245 std::stringstream& aStringStream) const {
2246 aStringStream << "[" << mRefPtr << "] CreateDrawTargetForFilter ()";
2249 struct GenericPattern {
2250 GenericPattern(const PatternStorage& aStorage, Translator* aTranslator)
2251 : mPattern(nullptr), mTranslator(aTranslator) {
2252 mStorage = const_cast<PatternStorage*>(&aStorage);
2255 ~GenericPattern() {
2256 if (mPattern) {
2257 mPattern->~Pattern();
2261 operator Pattern*() {
2262 switch (mStorage->mType) {
2263 case PatternType::COLOR:
2264 return new (mColPat) ColorPattern(
2265 reinterpret_cast<ColorPatternStorage*>(&mStorage->mStorage)
2266 ->mColor);
2267 case PatternType::SURFACE: {
2268 SurfacePatternStorage* storage =
2269 reinterpret_cast<SurfacePatternStorage*>(&mStorage->mStorage);
2270 mPattern = new (mSurfPat)
2271 SurfacePattern(mTranslator->LookupSourceSurface(storage->mSurface),
2272 storage->mExtend, storage->mMatrix,
2273 storage->mSamplingFilter, storage->mSamplingRect);
2274 return mPattern;
2276 case PatternType::LINEAR_GRADIENT: {
2277 LinearGradientPatternStorage* storage =
2278 reinterpret_cast<LinearGradientPatternStorage*>(
2279 &mStorage->mStorage);
2280 mPattern = new (mLinGradPat) LinearGradientPattern(
2281 storage->mBegin, storage->mEnd,
2282 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2283 : nullptr,
2284 storage->mMatrix);
2285 return mPattern;
2287 case PatternType::RADIAL_GRADIENT: {
2288 RadialGradientPatternStorage* storage =
2289 reinterpret_cast<RadialGradientPatternStorage*>(
2290 &mStorage->mStorage);
2291 mPattern = new (mRadGradPat) RadialGradientPattern(
2292 storage->mCenter1, storage->mCenter2, storage->mRadius1,
2293 storage->mRadius2,
2294 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2295 : nullptr,
2296 storage->mMatrix);
2297 return mPattern;
2299 case PatternType::CONIC_GRADIENT: {
2300 ConicGradientPatternStorage* storage =
2301 reinterpret_cast<ConicGradientPatternStorage*>(&mStorage->mStorage);
2302 mPattern = new (mConGradPat) ConicGradientPattern(
2303 storage->mCenter, storage->mAngle, storage->mStartOffset,
2304 storage->mEndOffset,
2305 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2306 : nullptr,
2307 storage->mMatrix);
2308 return mPattern;
2310 default:
2311 return new (mColPat) ColorPattern(DeviceColor());
2314 return mPattern;
2317 union {
2318 char mColPat[sizeof(ColorPattern)];
2319 char mLinGradPat[sizeof(LinearGradientPattern)];
2320 char mRadGradPat[sizeof(RadialGradientPattern)];
2321 char mConGradPat[sizeof(ConicGradientPattern)];
2322 char mSurfPat[sizeof(SurfacePattern)];
2325 PatternStorage* mStorage;
2326 Pattern* mPattern;
2327 Translator* mTranslator;
2330 inline bool RecordedFillRect::PlayEvent(Translator* aTranslator) const {
2331 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2332 if (!dt) {
2333 return false;
2336 dt->FillRect(mRect, *GenericPattern(mPattern, aTranslator), mOptions);
2337 return true;
2340 template <class S>
2341 void RecordedFillRect::Record(S& aStream) const {
2342 WriteElement(aStream, mRect);
2343 WriteElement(aStream, mOptions);
2344 RecordPatternData(aStream, mPattern);
2347 template <class S>
2348 RecordedFillRect::RecordedFillRect(S& aStream)
2349 : RecordedEventDerived(FILLRECT) {
2350 ReadElement(aStream, mRect);
2351 ReadDrawOptions(aStream, mOptions);
2352 ReadPatternData(aStream, mPattern);
2355 inline void RecordedFillRect::OutputSimpleEventInfo(
2356 std::stringstream& aStringStream) const {
2357 aStringStream << "FillRect (" << mRect.X() << ", " << mRect.Y() << " - "
2358 << mRect.Width() << " x " << mRect.Height() << ") ";
2359 OutputSimplePatternInfo(mPattern, aStringStream);
2362 inline bool RecordedStrokeRect::PlayEvent(Translator* aTranslator) const {
2363 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2364 if (!dt) {
2365 return false;
2368 dt->StrokeRect(mRect, *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2369 mOptions);
2370 return true;
2373 template <class S>
2374 void RecordedStrokeRect::Record(S& aStream) const {
2375 WriteElement(aStream, mRect);
2376 WriteElement(aStream, mOptions);
2377 RecordPatternData(aStream, mPattern);
2378 RecordStrokeOptions(aStream, mStrokeOptions);
2381 template <class S>
2382 RecordedStrokeRect::RecordedStrokeRect(S& aStream)
2383 : RecordedEventDerived(STROKERECT) {
2384 ReadElement(aStream, mRect);
2385 ReadDrawOptions(aStream, mOptions);
2386 ReadPatternData(aStream, mPattern);
2387 ReadStrokeOptions(aStream, mStrokeOptions);
2390 inline void RecordedStrokeRect::OutputSimpleEventInfo(
2391 std::stringstream& aStringStream) const {
2392 aStringStream << "StrokeRect (" << mRect.X() << ", " << mRect.Y() << " - "
2393 << mRect.Width() << " x " << mRect.Height()
2394 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2395 OutputSimplePatternInfo(mPattern, aStringStream);
2398 inline bool RecordedStrokeLine::PlayEvent(Translator* aTranslator) const {
2399 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2400 if (!dt) {
2401 return false;
2404 dt->StrokeLine(mBegin, mEnd, *GenericPattern(mPattern, aTranslator),
2405 mStrokeOptions, mOptions);
2406 return true;
2409 template <class S>
2410 void RecordedStrokeLine::Record(S& aStream) const {
2411 WriteElement(aStream, mBegin);
2412 WriteElement(aStream, mEnd);
2413 WriteElement(aStream, mOptions);
2414 RecordPatternData(aStream, mPattern);
2415 RecordStrokeOptions(aStream, mStrokeOptions);
2418 template <class S>
2419 RecordedStrokeLine::RecordedStrokeLine(S& aStream)
2420 : RecordedEventDerived(STROKELINE) {
2421 ReadElement(aStream, mBegin);
2422 ReadElement(aStream, mEnd);
2423 ReadDrawOptions(aStream, mOptions);
2424 ReadPatternData(aStream, mPattern);
2425 ReadStrokeOptions(aStream, mStrokeOptions);
2428 inline void RecordedStrokeLine::OutputSimpleEventInfo(
2429 std::stringstream& aStringStream) const {
2430 aStringStream << "StrokeLine (" << mBegin.x << ", " << mBegin.y << " - "
2431 << mEnd.x << ", " << mEnd.y
2432 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2433 OutputSimplePatternInfo(mPattern, aStringStream);
2436 inline bool RecordedStrokeCircle::PlayEvent(Translator* aTranslator) const {
2437 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2438 if (!dt) {
2439 return false;
2442 dt->StrokeCircle(mCircle.origin, mCircle.radius,
2443 *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2444 mOptions);
2445 return true;
2448 template <class S>
2449 void RecordedStrokeCircle::Record(S& aStream) const {
2450 WriteElement(aStream, mCircle);
2451 WriteElement(aStream, mOptions);
2452 RecordPatternData(aStream, mPattern);
2453 RecordStrokeOptions(aStream, mStrokeOptions);
2456 template <class S>
2457 RecordedStrokeCircle::RecordedStrokeCircle(S& aStream)
2458 : RecordedEventDerived(STROKECIRCLE) {
2459 ReadElement(aStream, mCircle);
2460 ReadDrawOptions(aStream, mOptions);
2461 ReadPatternData(aStream, mPattern);
2462 ReadStrokeOptions(aStream, mStrokeOptions);
2465 inline void RecordedStrokeCircle::OutputSimpleEventInfo(
2466 std::stringstream& aStringStream) const {
2467 aStringStream << "StrokeCircle (" << mCircle.origin.x << ", "
2468 << mCircle.origin.y << " - " << mCircle.radius
2469 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2470 OutputSimplePatternInfo(mPattern, aStringStream);
2473 inline bool RecordedFill::PlayEvent(Translator* aTranslator) const {
2474 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2475 if (!dt) {
2476 return false;
2479 dt->Fill(aTranslator->LookupPath(mPath),
2480 *GenericPattern(mPattern, aTranslator), mOptions);
2481 return true;
2484 template <class S>
2485 RecordedFill::RecordedFill(S& aStream) : RecordedEventDerived(FILL) {
2486 ReadElement(aStream, mPath);
2487 ReadDrawOptions(aStream, mOptions);
2488 ReadPatternData(aStream, mPattern);
2491 template <class S>
2492 void RecordedFill::Record(S& aStream) const {
2493 WriteElement(aStream, mPath);
2494 WriteElement(aStream, mOptions);
2495 RecordPatternData(aStream, mPattern);
2498 inline void RecordedFill::OutputSimpleEventInfo(
2499 std::stringstream& aStringStream) const {
2500 aStringStream << "Fill (" << mPath << ") ";
2501 OutputSimplePatternInfo(mPattern, aStringStream);
2504 inline bool RecordedFillCircle::PlayEvent(Translator* aTranslator) const {
2505 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2506 if (!dt) {
2507 return false;
2510 dt->FillCircle(mCircle.origin, mCircle.radius,
2511 *GenericPattern(mPattern, aTranslator), mOptions);
2512 return true;
2515 template <class S>
2516 void RecordedFillCircle::Record(S& aStream) const {
2517 WriteElement(aStream, mCircle);
2518 WriteElement(aStream, mOptions);
2519 RecordPatternData(aStream, mPattern);
2522 template <class S>
2523 RecordedFillCircle::RecordedFillCircle(S& aStream)
2524 : RecordedEventDerived(FILLCIRCLE) {
2525 ReadElement(aStream, mCircle);
2526 ReadDrawOptions(aStream, mOptions);
2527 ReadPatternData(aStream, mPattern);
2530 inline void RecordedFillCircle::OutputSimpleEventInfo(
2531 std::stringstream& aStringStream) const {
2532 aStringStream << "StrokeCircle (" << mCircle.origin.x << ", "
2533 << mCircle.origin.y << " - " << mCircle.radius << ")";
2534 OutputSimplePatternInfo(mPattern, aStringStream);
2537 inline RecordedFillGlyphs::~RecordedFillGlyphs() { delete[] mGlyphs; }
2539 inline bool RecordedFillGlyphs::PlayEvent(Translator* aTranslator) const {
2540 if (mNumGlyphs > 0 && !mGlyphs) {
2541 // Glyph allocation failed
2542 return false;
2545 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2546 if (!dt) {
2547 return false;
2550 ScaledFont* scaledFont = aTranslator->LookupScaledFont(mScaledFont);
2551 if (!scaledFont) {
2552 return false;
2555 GlyphBuffer buffer;
2556 buffer.mGlyphs = mGlyphs;
2557 buffer.mNumGlyphs = mNumGlyphs;
2558 dt->FillGlyphs(scaledFont, buffer, *GenericPattern(mPattern, aTranslator),
2559 mOptions);
2560 return true;
2563 template <class S>
2564 RecordedFillGlyphs::RecordedFillGlyphs(S& aStream)
2565 : RecordedEventDerived(FILLGLYPHS) {
2566 ReadElement(aStream, mScaledFont);
2567 ReadDrawOptions(aStream, mOptions);
2568 ReadPatternData(aStream, mPattern);
2569 ReadElement(aStream, mNumGlyphs);
2570 if (!aStream.good() || mNumGlyphs <= 0) {
2571 return;
2574 mGlyphs = new (fallible) Glyph[mNumGlyphs];
2575 if (!mGlyphs) {
2576 gfxCriticalNote << "RecordedFillGlyphs failed to allocate glyphs of size "
2577 << mNumGlyphs;
2578 aStream.SetIsBad();
2579 } else {
2580 aStream.read((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
2584 template <class S>
2585 void RecordedFillGlyphs::Record(S& aStream) const {
2586 WriteElement(aStream, mScaledFont);
2587 WriteElement(aStream, mOptions);
2588 RecordPatternData(aStream, mPattern);
2589 WriteElement(aStream, mNumGlyphs);
2590 aStream.write((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
2593 inline void RecordedFillGlyphs::OutputSimpleEventInfo(
2594 std::stringstream& aStringStream) const {
2595 aStringStream << "FillGlyphs (" << mScaledFont << ") ";
2596 OutputSimplePatternInfo(mPattern, aStringStream);
2599 inline bool RecordedMask::PlayEvent(Translator* aTranslator) const {
2600 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2601 if (!dt) {
2602 return false;
2605 dt->Mask(*GenericPattern(mSource, aTranslator),
2606 *GenericPattern(mMask, aTranslator), mOptions);
2607 return true;
2610 template <class S>
2611 RecordedMask::RecordedMask(S& aStream) : RecordedEventDerived(MASK) {
2612 ReadDrawOptions(aStream, mOptions);
2613 ReadPatternData(aStream, mSource);
2614 ReadPatternData(aStream, mMask);
2617 template <class S>
2618 void RecordedMask::Record(S& aStream) const {
2619 WriteElement(aStream, mOptions);
2620 RecordPatternData(aStream, mSource);
2621 RecordPatternData(aStream, mMask);
2624 inline void RecordedMask::OutputSimpleEventInfo(
2625 std::stringstream& aStringStream) const {
2626 aStringStream << "Mask (Source: ";
2627 OutputSimplePatternInfo(mSource, aStringStream);
2628 aStringStream << " Mask: ";
2629 OutputSimplePatternInfo(mMask, aStringStream);
2632 inline bool RecordedStroke::PlayEvent(Translator* aTranslator) const {
2633 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2634 if (!dt) {
2635 return false;
2638 Path* path = aTranslator->LookupPath(mPath);
2639 if (!path) {
2640 return false;
2643 dt->Stroke(path, *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2644 mOptions);
2645 return true;
2648 template <class S>
2649 void RecordedStroke::Record(S& aStream) const {
2650 WriteElement(aStream, mPath);
2651 WriteElement(aStream, mOptions);
2652 RecordPatternData(aStream, mPattern);
2653 RecordStrokeOptions(aStream, mStrokeOptions);
2656 template <class S>
2657 RecordedStroke::RecordedStroke(S& aStream) : RecordedEventDerived(STROKE) {
2658 ReadElement(aStream, mPath);
2659 ReadDrawOptions(aStream, mOptions);
2660 ReadPatternData(aStream, mPattern);
2661 ReadStrokeOptions(aStream, mStrokeOptions);
2664 inline void RecordedStroke::OutputSimpleEventInfo(
2665 std::stringstream& aStringStream) const {
2666 aStringStream << "Stroke (" << mPath
2667 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2668 OutputSimplePatternInfo(mPattern, aStringStream);
2671 inline bool RecordedClearRect::PlayEvent(Translator* aTranslator) const {
2672 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2673 if (!dt) {
2674 return false;
2677 dt->ClearRect(mRect);
2678 return true;
2681 template <class S>
2682 void RecordedClearRect::Record(S& aStream) const {
2683 WriteElement(aStream, mRect);
2686 template <class S>
2687 RecordedClearRect::RecordedClearRect(S& aStream)
2688 : RecordedEventDerived(CLEARRECT) {
2689 ReadElement(aStream, mRect);
2692 inline void RecordedClearRect::OutputSimpleEventInfo(
2693 std::stringstream& aStringStream) const {
2694 aStringStream << "ClearRect (" << mRect.X() << ", " << mRect.Y() << " - "
2695 << mRect.Width() << " x " << mRect.Height() << ") ";
2698 inline bool RecordedCopySurface::PlayEvent(Translator* aTranslator) const {
2699 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2700 if (!dt) {
2701 return false;
2704 SourceSurface* surface = aTranslator->LookupSourceSurface(mSourceSurface);
2705 if (!surface) {
2706 return false;
2709 dt->CopySurface(surface, mSourceRect, mDest);
2710 return true;
2713 template <class S>
2714 void RecordedCopySurface::Record(S& aStream) const {
2715 WriteElement(aStream, mSourceSurface);
2716 WriteElement(aStream, mSourceRect);
2717 WriteElement(aStream, mDest);
2720 template <class S>
2721 RecordedCopySurface::RecordedCopySurface(S& aStream)
2722 : RecordedEventDerived(COPYSURFACE) {
2723 ReadElement(aStream, mSourceSurface);
2724 ReadElement(aStream, mSourceRect);
2725 ReadElement(aStream, mDest);
2728 inline void RecordedCopySurface::OutputSimpleEventInfo(
2729 std::stringstream& aStringStream) const {
2730 aStringStream << "CopySurface (" << mSourceSurface << ")";
2733 inline bool RecordedPushClip::PlayEvent(Translator* aTranslator) const {
2734 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2735 if (!dt) {
2736 return false;
2739 Path* path = aTranslator->LookupPath(mPath);
2740 if (!path) {
2741 return false;
2744 dt->PushClip(path);
2745 return true;
2748 template <class S>
2749 void RecordedPushClip::Record(S& aStream) const {
2750 WriteElement(aStream, mPath);
2753 template <class S>
2754 RecordedPushClip::RecordedPushClip(S& aStream)
2755 : RecordedEventDerived(PUSHCLIP) {
2756 ReadElement(aStream, mPath);
2759 inline void RecordedPushClip::OutputSimpleEventInfo(
2760 std::stringstream& aStringStream) const {
2761 aStringStream << "PushClip (" << mPath << ") ";
2764 inline bool RecordedPushClipRect::PlayEvent(Translator* aTranslator) const {
2765 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2766 if (!dt) {
2767 return false;
2770 dt->PushClipRect(mRect);
2771 return true;
2774 template <class S>
2775 void RecordedPushClipRect::Record(S& aStream) const {
2776 WriteElement(aStream, mRect);
2779 template <class S>
2780 RecordedPushClipRect::RecordedPushClipRect(S& aStream)
2781 : RecordedEventDerived(PUSHCLIPRECT) {
2782 ReadElement(aStream, mRect);
2785 inline void RecordedPushClipRect::OutputSimpleEventInfo(
2786 std::stringstream& aStringStream) const {
2787 aStringStream << "PushClipRect (" << mRect.X() << ", " << mRect.Y() << " - "
2788 << mRect.Width() << " x " << mRect.Height() << ") ";
2791 inline bool RecordedPopClip::PlayEvent(Translator* aTranslator) const {
2792 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2793 if (!dt) {
2794 return false;
2797 dt->PopClip();
2798 return true;
2801 template <class S>
2802 void RecordedPopClip::Record(S& aStream) const {}
2804 template <class S>
2805 RecordedPopClip::RecordedPopClip(S& aStream) : RecordedEventDerived(POPCLIP) {}
2807 inline void RecordedPopClip::OutputSimpleEventInfo(
2808 std::stringstream& aStringStream) const {
2809 aStringStream << "PopClip";
2812 inline bool RecordedPushLayer::PlayEvent(Translator* aTranslator) const {
2813 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2814 if (!dt) {
2815 return false;
2818 SourceSurface* mask =
2819 mMask ? aTranslator->LookupSourceSurface(mMask) : nullptr;
2820 dt->PushLayer(mOpaque, mOpacity, mask, mMaskTransform, mBounds,
2821 mCopyBackground);
2822 return true;
2825 template <class S>
2826 void RecordedPushLayer::Record(S& aStream) const {
2827 WriteElement(aStream, mOpaque);
2828 WriteElement(aStream, mOpacity);
2829 WriteElement(aStream, mMask);
2830 WriteElement(aStream, mMaskTransform);
2831 WriteElement(aStream, mBounds);
2832 WriteElement(aStream, mCopyBackground);
2835 template <class S>
2836 RecordedPushLayer::RecordedPushLayer(S& aStream)
2837 : RecordedEventDerived(PUSHLAYER) {
2838 ReadElement(aStream, mOpaque);
2839 ReadElement(aStream, mOpacity);
2840 ReadElement(aStream, mMask);
2841 ReadElement(aStream, mMaskTransform);
2842 ReadElement(aStream, mBounds);
2843 ReadElement(aStream, mCopyBackground);
2846 inline void RecordedPushLayer::OutputSimpleEventInfo(
2847 std::stringstream& aStringStream) const {
2848 aStringStream << "PushPLayer (Opaque=" << mOpaque << ", Opacity=" << mOpacity
2849 << ", Mask Ref=" << mMask << ") ";
2852 inline bool RecordedPushLayerWithBlend::PlayEvent(
2853 Translator* aTranslator) const {
2854 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2855 if (!dt) {
2856 return false;
2859 SourceSurface* mask =
2860 mMask ? aTranslator->LookupSourceSurface(mMask) : nullptr;
2861 dt->PushLayerWithBlend(mOpaque, mOpacity, mask, mMaskTransform, mBounds,
2862 mCopyBackground, mCompositionOp);
2863 return true;
2866 template <class S>
2867 void RecordedPushLayerWithBlend::Record(S& aStream) const {
2868 WriteElement(aStream, mOpaque);
2869 WriteElement(aStream, mOpacity);
2870 WriteElement(aStream, mMask);
2871 WriteElement(aStream, mMaskTransform);
2872 WriteElement(aStream, mBounds);
2873 WriteElement(aStream, mCopyBackground);
2874 WriteElement(aStream, mCompositionOp);
2877 template <class S>
2878 RecordedPushLayerWithBlend::RecordedPushLayerWithBlend(S& aStream)
2879 : RecordedEventDerived(PUSHLAYERWITHBLEND) {
2880 ReadElement(aStream, mOpaque);
2881 ReadElement(aStream, mOpacity);
2882 ReadElement(aStream, mMask);
2883 ReadElement(aStream, mMaskTransform);
2884 ReadElement(aStream, mBounds);
2885 ReadElement(aStream, mCopyBackground);
2886 ReadElementConstrained(aStream, mCompositionOp, CompositionOp::OP_OVER,
2887 CompositionOp::OP_COUNT);
2890 inline void RecordedPushLayerWithBlend::OutputSimpleEventInfo(
2891 std::stringstream& aStringStream) const {
2892 aStringStream << "PushLayerWithBlend (Opaque=" << mOpaque
2893 << ", Opacity=" << mOpacity << ", Mask Ref=" << mMask << ") ";
2896 inline bool RecordedPopLayer::PlayEvent(Translator* aTranslator) const {
2897 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2898 if (!dt) {
2899 return false;
2902 dt->PopLayer();
2903 return true;
2906 template <class S>
2907 void RecordedPopLayer::Record(S& aStream) const {}
2909 template <class S>
2910 RecordedPopLayer::RecordedPopLayer(S& aStream)
2911 : RecordedEventDerived(POPLAYER) {}
2913 inline void RecordedPopLayer::OutputSimpleEventInfo(
2914 std::stringstream& aStringStream) const {
2915 aStringStream << "PopLayer";
2918 inline bool RecordedSetTransform::PlayEvent(Translator* aTranslator) const {
2919 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2920 if (!dt) {
2921 return false;
2924 // If we're drawing to the reference DT, then we need to manually apply
2925 // its initial transform, otherwise we'll just clobber it with only the
2926 // the transform that was visible to the code doing the recording.
2927 if (dt == aTranslator->GetReferenceDrawTarget()) {
2928 dt->SetTransform(mTransform *
2929 aTranslator->GetReferenceDrawTargetTransform());
2930 } else {
2931 dt->SetTransform(mTransform);
2934 return true;
2937 template <class S>
2938 void RecordedSetTransform::Record(S& aStream) const {
2939 WriteElement(aStream, mTransform);
2942 template <class S>
2943 RecordedSetTransform::RecordedSetTransform(S& aStream)
2944 : RecordedEventDerived(SETTRANSFORM) {
2945 ReadElement(aStream, mTransform);
2948 inline void RecordedSetTransform::OutputSimpleEventInfo(
2949 std::stringstream& aStringStream) const {
2950 aStringStream << "SetTransform [ " << mTransform._11 << " " << mTransform._12
2951 << " ; " << mTransform._21 << " " << mTransform._22 << " ; "
2952 << mTransform._31 << " " << mTransform._32 << " ]";
2955 inline bool RecordedDrawSurface::PlayEvent(Translator* aTranslator) const {
2956 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2957 if (!dt) {
2958 return false;
2961 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefSource);
2962 if (!surface) {
2963 return false;
2966 dt->DrawSurface(surface, mDest, mSource, mDSOptions, mOptions);
2967 return true;
2970 template <class S>
2971 void RecordedDrawSurface::Record(S& aStream) const {
2972 WriteElement(aStream, mRefSource);
2973 WriteElement(aStream, mDest);
2974 WriteElement(aStream, mSource);
2975 WriteElement(aStream, mDSOptions);
2976 WriteElement(aStream, mOptions);
2979 template <class S>
2980 RecordedDrawSurface::RecordedDrawSurface(S& aStream)
2981 : RecordedEventDerived(DRAWSURFACE) {
2982 ReadElement(aStream, mRefSource);
2983 ReadElement(aStream, mDest);
2984 ReadElement(aStream, mSource);
2985 ReadDrawSurfaceOptions(aStream, mDSOptions);
2986 ReadDrawOptions(aStream, mOptions);
2989 inline void RecordedDrawSurface::OutputSimpleEventInfo(
2990 std::stringstream& aStringStream) const {
2991 aStringStream << "DrawSurface (" << mRefSource << ")";
2994 inline bool RecordedDrawDependentSurface::PlayEvent(
2995 Translator* aTranslator) const {
2996 aTranslator->DrawDependentSurface(mId, mDest);
2997 return true;
3000 template <class S>
3001 void RecordedDrawDependentSurface::Record(S& aStream) const {
3002 WriteElement(aStream, mId);
3003 WriteElement(aStream, mDest);
3006 template <class S>
3007 RecordedDrawDependentSurface::RecordedDrawDependentSurface(S& aStream)
3008 : RecordedEventDerived(DRAWDEPENDENTSURFACE) {
3009 ReadElement(aStream, mId);
3010 ReadElement(aStream, mDest);
3013 inline void RecordedDrawDependentSurface::OutputSimpleEventInfo(
3014 std::stringstream& aStringStream) const {
3015 aStringStream << "DrawDependentSurface (" << mId << ")";
3018 inline bool RecordedDrawFilter::PlayEvent(Translator* aTranslator) const {
3019 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3020 if (!dt) {
3021 return false;
3024 FilterNode* filter = aTranslator->LookupFilterNode(mNode);
3025 if (!filter) {
3026 return false;
3029 dt->DrawFilter(filter, mSourceRect, mDestPoint, mOptions);
3030 return true;
3033 template <class S>
3034 void RecordedDrawFilter::Record(S& aStream) const {
3035 WriteElement(aStream, mNode);
3036 WriteElement(aStream, mSourceRect);
3037 WriteElement(aStream, mDestPoint);
3038 WriteElement(aStream, mOptions);
3041 template <class S>
3042 RecordedDrawFilter::RecordedDrawFilter(S& aStream)
3043 : RecordedEventDerived(DRAWFILTER) {
3044 ReadElement(aStream, mNode);
3045 ReadElement(aStream, mSourceRect);
3046 ReadElement(aStream, mDestPoint);
3047 ReadDrawOptions(aStream, mOptions);
3050 inline void RecordedDrawFilter::OutputSimpleEventInfo(
3051 std::stringstream& aStringStream) const {
3052 aStringStream << "DrawFilter (" << mNode << ")";
3055 inline bool RecordedDrawSurfaceWithShadow::PlayEvent(
3056 Translator* aTranslator) const {
3057 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3058 if (!dt) {
3059 return false;
3062 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefSource);
3063 if (!surface) {
3064 return false;
3067 dt->DrawSurfaceWithShadow(surface, mDest, mShadow, mOp);
3068 return true;
3071 template <class S>
3072 void RecordedDrawSurfaceWithShadow::Record(S& aStream) const {
3073 WriteElement(aStream, mRefSource);
3074 WriteElement(aStream, mDest);
3075 WriteElement(aStream, mShadow);
3076 WriteElement(aStream, mOp);
3079 template <class S>
3080 RecordedDrawSurfaceWithShadow::RecordedDrawSurfaceWithShadow(S& aStream)
3081 : RecordedEventDerived(DRAWSURFACEWITHSHADOW) {
3082 ReadElement(aStream, mRefSource);
3083 ReadElement(aStream, mDest);
3084 ReadElement(aStream, mShadow);
3085 ReadElementConstrained(aStream, mOp, CompositionOp::OP_OVER,
3086 CompositionOp::OP_COUNT);
3089 inline void RecordedDrawSurfaceWithShadow::OutputSimpleEventInfo(
3090 std::stringstream& aStringStream) const {
3091 aStringStream << "DrawSurfaceWithShadow (" << mRefSource << ") DeviceColor: ("
3092 << mShadow.mColor.r << ", " << mShadow.mColor.g << ", "
3093 << mShadow.mColor.b << ", " << mShadow.mColor.a << ")";
3096 inline bool RecordedDrawShadow::PlayEvent(Translator* aTranslator) const {
3097 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3098 if (!dt) {
3099 return false;
3102 Path* path = aTranslator->LookupPath(mPath);
3103 if (!path) {
3104 return false;
3107 dt->DrawShadow(path, *GenericPattern(mPattern, aTranslator), mShadow,
3108 mOptions, mHasStrokeOptions ? &mStrokeOptions : nullptr);
3109 return true;
3112 template <class S>
3113 void RecordedDrawShadow::Record(S& aStream) const {
3114 WriteElement(aStream, mPath);
3115 RecordPatternData(aStream, mPattern);
3116 WriteElement(aStream, mShadow);
3117 WriteElement(aStream, mOptions);
3118 WriteElement(aStream, mHasStrokeOptions);
3119 if (mHasStrokeOptions) {
3120 RecordStrokeOptions(aStream, mStrokeOptions);
3124 template <class S>
3125 RecordedDrawShadow::RecordedDrawShadow(S& aStream)
3126 : RecordedEventDerived(DRAWSHADOW) {
3127 ReadElement(aStream, mPath);
3128 ReadPatternData(aStream, mPattern);
3129 ReadElement(aStream, mShadow);
3130 ReadDrawOptions(aStream, mOptions);
3131 ReadElement(aStream, mHasStrokeOptions);
3132 if (mHasStrokeOptions) {
3133 ReadStrokeOptions(aStream, mStrokeOptions);
3137 inline void RecordedDrawShadow::OutputSimpleEventInfo(
3138 std::stringstream& aStringStream) const {
3139 aStringStream << "DrawShadow (" << mPath << ") DeviceColor: ("
3140 << mShadow.mColor.r << ", " << mShadow.mColor.g << ", "
3141 << mShadow.mColor.b << ", " << mShadow.mColor.a << ")";
3144 inline RecordedPathCreation::RecordedPathCreation(PathRecording* aPath)
3145 : RecordedEventDerived(PATHCREATION),
3146 mRefPtr(aPath),
3147 mFillRule(aPath->mFillRule),
3148 mPath(aPath) {}
3150 inline bool RecordedPathCreation::PlayEvent(Translator* aTranslator) const {
3151 DrawTarget* drawTarget = aTranslator->GetCurrentDrawTarget();
3152 if (!drawTarget) {
3153 return false;
3156 RefPtr<PathBuilder> builder = drawTarget->CreatePathBuilder(mFillRule);
3157 if (!mPathOps->CheckedStreamToSink(*builder)) {
3158 return false;
3161 RefPtr<Path> path = builder->Finish();
3162 aTranslator->AddPath(mRefPtr, path);
3163 return true;
3166 template <class S>
3167 void RecordedPathCreation::Record(S& aStream) const {
3168 WriteElement(aStream, mRefPtr);
3169 WriteElement(aStream, mFillRule);
3170 mPath->mPathOps.Record(aStream);
3173 template <class S>
3174 RecordedPathCreation::RecordedPathCreation(S& aStream)
3175 : RecordedEventDerived(PATHCREATION) {
3176 ReadElement(aStream, mRefPtr);
3177 ReadElementConstrained(aStream, mFillRule, FillRule::FILL_WINDING,
3178 FillRule::FILL_EVEN_ODD);
3179 mPathOps = MakeUnique<PathOps>(aStream);
3182 inline void RecordedPathCreation::OutputSimpleEventInfo(
3183 std::stringstream& aStringStream) const {
3184 size_t numberOfOps =
3185 mPath ? mPath->mPathOps.NumberOfOps() : mPathOps->NumberOfOps();
3186 aStringStream << "[" << mRefPtr << "] Path created (OpCount: " << numberOfOps
3187 << ")";
3189 inline bool RecordedPathDestruction::PlayEvent(Translator* aTranslator) const {
3190 aTranslator->RemovePath(mRefPtr);
3191 return true;
3194 template <class S>
3195 void RecordedPathDestruction::Record(S& aStream) const {
3196 WriteElement(aStream, mRefPtr);
3199 template <class S>
3200 RecordedPathDestruction::RecordedPathDestruction(S& aStream)
3201 : RecordedEventDerived(PATHDESTRUCTION) {
3202 ReadElement(aStream, mRefPtr);
3205 inline void RecordedPathDestruction::OutputSimpleEventInfo(
3206 std::stringstream& aStringStream) const {
3207 aStringStream << "[" << mRefPtr << "] Path Destroyed";
3210 inline RecordedSourceSurfaceCreation::~RecordedSourceSurfaceCreation() {
3211 if (mDataOwned) {
3212 delete[] mData;
3216 inline bool RecordedSourceSurfaceCreation::PlayEvent(
3217 Translator* aTranslator) const {
3218 if (!mData) {
3219 return false;
3222 RefPtr<SourceSurface> src = Factory::CreateWrappingDataSourceSurface(
3223 mData, mSize.width * BytesPerPixel(mFormat), mSize, mFormat,
3224 [](void* aClosure) { delete[] static_cast<uint8_t*>(aClosure); }, mData);
3225 if (src) {
3226 mDataOwned = false;
3229 aTranslator->AddSourceSurface(mRefPtr, src);
3230 return true;
3233 template <class S>
3234 void RecordedSourceSurfaceCreation::Record(S& aStream) const {
3235 WriteElement(aStream, mRefPtr);
3236 WriteElement(aStream, mSize);
3237 WriteElement(aStream, mFormat);
3238 MOZ_ASSERT(mData);
3239 size_t dataFormatWidth = BytesPerPixel(mFormat) * mSize.width;
3240 const char* endSrc = (const char*)(mData + (mSize.height * mStride));
3241 for (const char* src = (const char*)mData; src < endSrc; src += mStride) {
3242 aStream.write(src, dataFormatWidth);
3246 template <class S>
3247 RecordedSourceSurfaceCreation::RecordedSourceSurfaceCreation(S& aStream)
3248 : RecordedEventDerived(SOURCESURFACECREATION), mDataOwned(true) {
3249 ReadElement(aStream, mRefPtr);
3250 ReadElement(aStream, mSize);
3251 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
3252 SurfaceFormat::UNKNOWN);
3254 if (!Factory::AllowedSurfaceSize(mSize)) {
3255 gfxCriticalNote << "RecordedSourceSurfaceCreation read invalid size "
3256 << mSize;
3257 aStream.SetIsBad();
3260 if (!aStream.good()) {
3261 return;
3264 size_t size = 0;
3265 if (mSize.width >= 0 && mSize.height >= 0) {
3266 size = size_t(mSize.width) * size_t(mSize.height) * BytesPerPixel(mFormat);
3267 mData = new (fallible) uint8_t[size];
3269 if (!mData) {
3270 gfxCriticalNote
3271 << "RecordedSourceSurfaceCreation failed to allocate data of size "
3272 << size;
3273 aStream.SetIsBad();
3274 } else {
3275 aStream.read((char*)mData, size);
3279 inline void RecordedSourceSurfaceCreation::OutputSimpleEventInfo(
3280 std::stringstream& aStringStream) const {
3281 aStringStream << "[" << mRefPtr
3282 << "] SourceSurface created (Size: " << mSize.width << "x"
3283 << mSize.height << ")";
3286 inline bool RecordedSourceSurfaceDestruction::PlayEvent(
3287 Translator* aTranslator) const {
3288 aTranslator->RemoveSourceSurface(mRefPtr);
3289 return true;
3292 template <class S>
3293 void RecordedSourceSurfaceDestruction::Record(S& aStream) const {
3294 WriteElement(aStream, mRefPtr);
3297 template <class S>
3298 RecordedSourceSurfaceDestruction::RecordedSourceSurfaceDestruction(S& aStream)
3299 : RecordedEventDerived(SOURCESURFACEDESTRUCTION) {
3300 ReadElement(aStream, mRefPtr);
3303 inline void RecordedSourceSurfaceDestruction::OutputSimpleEventInfo(
3304 std::stringstream& aStringStream) const {
3305 aStringStream << "[" << mRefPtr << "] SourceSurface Destroyed";
3308 inline bool RecordedOptimizeSourceSurface::PlayEvent(
3309 Translator* aTranslator) const {
3310 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3311 if (!dt) {
3312 return false;
3315 SourceSurface* surface = aTranslator->LookupSourceSurface(mSurface);
3316 if (!surface) {
3317 return false;
3320 RefPtr<SourceSurface> optimizedSurface = dt->OptimizeSourceSurface(surface);
3321 aTranslator->AddSourceSurface(mOptimizedSurface, optimizedSurface);
3322 return true;
3325 template <class S>
3326 void RecordedOptimizeSourceSurface::Record(S& aStream) const {
3327 WriteElement(aStream, mSurface);
3328 WriteElement(aStream, mOptimizedSurface);
3331 template <class S>
3332 RecordedOptimizeSourceSurface::RecordedOptimizeSourceSurface(S& aStream)
3333 : RecordedEventDerived(OPTIMIZESOURCESURFACE) {
3334 ReadElement(aStream, mSurface);
3335 ReadElement(aStream, mOptimizedSurface);
3338 inline void RecordedOptimizeSourceSurface::OutputSimpleEventInfo(
3339 std::stringstream& aStringStream) const {
3340 aStringStream << "[" << mSurface << "] Surface Optimized";
3343 inline bool RecordedExternalSurfaceCreation::PlayEvent(
3344 Translator* aTranslator) const {
3345 RefPtr<SourceSurface> surface = aTranslator->LookupExternalSurface(mKey);
3346 if (!surface) {
3347 return false;
3350 aTranslator->AddSourceSurface(mRefPtr, surface);
3351 return true;
3354 template <class S>
3355 void RecordedExternalSurfaceCreation::Record(S& aStream) const {
3356 WriteElement(aStream, mRefPtr);
3357 WriteElement(aStream, mKey);
3360 template <class S>
3361 RecordedExternalSurfaceCreation::RecordedExternalSurfaceCreation(S& aStream)
3362 : RecordedEventDerived(EXTERNALSURFACECREATION) {
3363 ReadElement(aStream, mRefPtr);
3364 ReadElement(aStream, mKey);
3367 inline void RecordedExternalSurfaceCreation::OutputSimpleEventInfo(
3368 std::stringstream& aStringStream) const {
3369 aStringStream << "[" << mRefPtr
3370 << "] SourceSurfaceSharedData created (Key: " << mKey << ")";
3373 inline RecordedFilterNodeCreation::~RecordedFilterNodeCreation() = default;
3375 inline bool RecordedFilterNodeCreation::PlayEvent(
3376 Translator* aTranslator) const {
3377 DrawTarget* drawTarget = aTranslator->GetCurrentDrawTarget();
3378 if (!drawTarget) {
3379 return false;
3382 RefPtr<FilterNode> node = drawTarget->CreateFilter(mType);
3383 aTranslator->AddFilterNode(mRefPtr, node);
3384 return true;
3387 template <class S>
3388 void RecordedFilterNodeCreation::Record(S& aStream) const {
3389 WriteElement(aStream, mRefPtr);
3390 WriteElement(aStream, mType);
3393 template <class S>
3394 RecordedFilterNodeCreation::RecordedFilterNodeCreation(S& aStream)
3395 : RecordedEventDerived(FILTERNODECREATION) {
3396 ReadElement(aStream, mRefPtr);
3397 ReadElementConstrained(aStream, mType, FilterType::BLEND,
3398 FilterType::OPACITY);
3401 inline void RecordedFilterNodeCreation::OutputSimpleEventInfo(
3402 std::stringstream& aStringStream) const {
3403 aStringStream << "CreateFilter [" << mRefPtr
3404 << "] FilterNode created (Type: " << int(mType) << ")";
3407 inline bool RecordedFilterNodeDestruction::PlayEvent(
3408 Translator* aTranslator) const {
3409 aTranslator->RemoveFilterNode(mRefPtr);
3410 return true;
3413 template <class S>
3414 void RecordedFilterNodeDestruction::Record(S& aStream) const {
3415 WriteElement(aStream, mRefPtr);
3418 template <class S>
3419 RecordedFilterNodeDestruction::RecordedFilterNodeDestruction(S& aStream)
3420 : RecordedEventDerived(FILTERNODEDESTRUCTION) {
3421 ReadElement(aStream, mRefPtr);
3424 inline void RecordedFilterNodeDestruction::OutputSimpleEventInfo(
3425 std::stringstream& aStringStream) const {
3426 aStringStream << "[" << mRefPtr << "] FilterNode Destroyed";
3429 inline RecordedGradientStopsCreation::~RecordedGradientStopsCreation() {
3430 if (mDataOwned) {
3431 delete[] mStops;
3435 inline bool RecordedGradientStopsCreation::PlayEvent(
3436 Translator* aTranslator) const {
3437 if (mNumStops > 0 && !mStops) {
3438 // Stops allocation failed
3439 return false;
3442 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3443 if (!dt) {
3444 return false;
3447 RefPtr<GradientStops> src =
3448 aTranslator->GetOrCreateGradientStops(dt, mStops, mNumStops, mExtendMode);
3449 aTranslator->AddGradientStops(mRefPtr, src);
3450 return true;
3453 template <class S>
3454 void RecordedGradientStopsCreation::Record(S& aStream) const {
3455 WriteElement(aStream, mRefPtr);
3456 WriteElement(aStream, mExtendMode);
3457 WriteElement(aStream, mNumStops);
3458 aStream.write((const char*)mStops, mNumStops * sizeof(GradientStop));
3461 template <class S>
3462 RecordedGradientStopsCreation::RecordedGradientStopsCreation(S& aStream)
3463 : RecordedEventDerived(GRADIENTSTOPSCREATION), mDataOwned(true) {
3464 ReadElement(aStream, mRefPtr);
3465 ReadElementConstrained(aStream, mExtendMode, ExtendMode::CLAMP,
3466 ExtendMode::REFLECT);
3467 ReadElement(aStream, mNumStops);
3468 if (!aStream.good() || mNumStops <= 0) {
3469 return;
3472 mStops = new (fallible) GradientStop[mNumStops];
3473 if (!mStops) {
3474 gfxCriticalNote
3475 << "RecordedGradientStopsCreation failed to allocate stops of size "
3476 << mNumStops;
3477 aStream.SetIsBad();
3478 } else {
3479 aStream.read((char*)mStops, mNumStops * sizeof(GradientStop));
3483 inline void RecordedGradientStopsCreation::OutputSimpleEventInfo(
3484 std::stringstream& aStringStream) const {
3485 aStringStream << "[" << mRefPtr
3486 << "] GradientStops created (Stops: " << mNumStops << ")";
3489 inline bool RecordedGradientStopsDestruction::PlayEvent(
3490 Translator* aTranslator) const {
3491 aTranslator->RemoveGradientStops(mRefPtr);
3492 return true;
3495 template <class S>
3496 void RecordedGradientStopsDestruction::Record(S& aStream) const {
3497 WriteElement(aStream, mRefPtr);
3500 template <class S>
3501 RecordedGradientStopsDestruction::RecordedGradientStopsDestruction(S& aStream)
3502 : RecordedEventDerived(GRADIENTSTOPSDESTRUCTION) {
3503 ReadElement(aStream, mRefPtr);
3506 inline void RecordedGradientStopsDestruction::OutputSimpleEventInfo(
3507 std::stringstream& aStringStream) const {
3508 aStringStream << "[" << mRefPtr << "] GradientStops Destroyed";
3511 inline bool RecordedIntoLuminanceSource::PlayEvent(
3512 Translator* aTranslator) const {
3513 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3514 if (!dt) {
3515 return false;
3518 RefPtr<SourceSurface> src = dt->IntoLuminanceSource(mLuminanceType, mOpacity);
3519 aTranslator->AddSourceSurface(mRefPtr, src);
3520 return true;
3523 template <class S>
3524 void RecordedIntoLuminanceSource::Record(S& aStream) const {
3525 WriteElement(aStream, mRefPtr);
3526 WriteElement(aStream, mLuminanceType);
3527 WriteElement(aStream, mOpacity);
3530 template <class S>
3531 RecordedIntoLuminanceSource::RecordedIntoLuminanceSource(S& aStream)
3532 : RecordedEventDerived(INTOLUMINANCE) {
3533 ReadElement(aStream, mRefPtr);
3534 ReadElementConstrained(aStream, mLuminanceType, LuminanceType::LUMINANCE,
3535 LuminanceType::LINEARRGB);
3536 ReadElement(aStream, mOpacity);
3539 inline void RecordedIntoLuminanceSource::OutputSimpleEventInfo(
3540 std::stringstream& aStringStream) const {
3541 aStringStream << "[" << mRefPtr << "] Into Luminance Source";
3544 inline bool RecordedFlush::PlayEvent(Translator* aTranslator) const {
3545 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3546 if (!dt) {
3547 return false;
3550 dt->Flush();
3551 return true;
3554 template <class S>
3555 void RecordedFlush::Record(S& aStream) const {}
3557 template <class S>
3558 RecordedFlush::RecordedFlush(S& aStream) : RecordedEventDerived(FLUSH) {}
3560 inline void RecordedFlush::OutputSimpleEventInfo(
3561 std::stringstream& aStringStream) const {
3562 aStringStream << "Flush";
3565 inline bool RecordedDetachAllSnapshots::PlayEvent(
3566 Translator* aTranslator) const {
3567 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3568 if (!dt) {
3569 return false;
3572 dt->DetachAllSnapshots();
3573 return true;
3576 template <class S>
3577 void RecordedDetachAllSnapshots::Record(S& aStream) const {}
3579 template <class S>
3580 RecordedDetachAllSnapshots::RecordedDetachAllSnapshots(S& aStream)
3581 : RecordedEventDerived(DETACHALLSNAPSHOTS) {}
3583 inline void RecordedDetachAllSnapshots::OutputSimpleEventInfo(
3584 std::stringstream& aStringStream) const {
3585 aStringStream << "DetachAllSnapshots";
3588 inline bool RecordedSnapshot::PlayEvent(Translator* aTranslator) const {
3589 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3590 if (!dt) {
3591 return false;
3594 RefPtr<SourceSurface> src = dt->Snapshot();
3595 aTranslator->AddSourceSurface(mRefPtr, src);
3596 return true;
3599 template <class S>
3600 void RecordedSnapshot::Record(S& aStream) const {
3601 WriteElement(aStream, mRefPtr);
3604 template <class S>
3605 RecordedSnapshot::RecordedSnapshot(S& aStream)
3606 : RecordedEventDerived(SNAPSHOT) {
3607 ReadElement(aStream, mRefPtr);
3610 inline void RecordedSnapshot::OutputSimpleEventInfo(
3611 std::stringstream& aStringStream) const {
3612 aStringStream << "[" << mRefPtr << "] Snapshot Created";
3615 inline RecordedFontData::~RecordedFontData() { delete[] mData; }
3617 inline bool RecordedFontData::PlayEvent(Translator* aTranslator) const {
3618 if (!mData) {
3619 return false;
3622 RefPtr<NativeFontResource> fontResource = Factory::CreateNativeFontResource(
3623 mData, mFontDetails.size, mType, aTranslator->GetFontContext());
3624 if (!fontResource) {
3625 return false;
3628 aTranslator->AddNativeFontResource(mFontDetails.fontDataKey, fontResource);
3629 return true;
3632 template <class S>
3633 void RecordedFontData::Record(S& aStream) const {
3634 MOZ_ASSERT(mGetFontFileDataSucceeded);
3636 WriteElement(aStream, mType);
3637 WriteElement(aStream, mFontDetails.fontDataKey);
3638 if (!mData) {
3639 WriteElement(aStream, 0);
3640 } else {
3641 WriteElement(aStream, mFontDetails.size);
3642 aStream.write((const char*)mData, mFontDetails.size);
3646 inline void RecordedFontData::OutputSimpleEventInfo(
3647 std::stringstream& aStringStream) const {
3648 aStringStream << "Font Data of size " << mFontDetails.size;
3651 inline void RecordedFontData::SetFontData(const uint8_t* aData, uint32_t aSize,
3652 uint32_t aIndex) {
3653 mData = new (fallible) uint8_t[aSize];
3654 if (!mData) {
3655 gfxCriticalNote
3656 << "RecordedFontData failed to allocate data for recording of size "
3657 << aSize;
3658 } else {
3659 memcpy(mData, aData, aSize);
3661 mFontDetails.fontDataKey = SFNTData::GetUniqueKey(aData, aSize, 0, nullptr);
3662 mFontDetails.size = aSize;
3663 mFontDetails.index = aIndex;
3666 inline bool RecordedFontData::GetFontDetails(RecordedFontDetails& fontDetails) {
3667 if (!mGetFontFileDataSucceeded) {
3668 return false;
3671 fontDetails.fontDataKey = mFontDetails.fontDataKey;
3672 fontDetails.size = mFontDetails.size;
3673 fontDetails.index = mFontDetails.index;
3674 return true;
3677 template <class S>
3678 RecordedFontData::RecordedFontData(S& aStream)
3679 : RecordedEventDerived(FONTDATA), mType(FontType::UNKNOWN) {
3680 ReadElementConstrained(aStream, mType, FontType::DWRITE, FontType::UNKNOWN);
3681 ReadElement(aStream, mFontDetails.fontDataKey);
3682 ReadElement(aStream, mFontDetails.size);
3683 if (!mFontDetails.size || !aStream.good()) {
3684 return;
3687 mData = new (fallible) uint8_t[mFontDetails.size];
3688 if (!mData) {
3689 gfxCriticalNote
3690 << "RecordedFontData failed to allocate data for playback of size "
3691 << mFontDetails.size;
3692 aStream.SetIsBad();
3693 } else {
3694 aStream.read((char*)mData, mFontDetails.size);
3698 inline RecordedFontDescriptor::~RecordedFontDescriptor() = default;
3700 inline bool RecordedFontDescriptor::PlayEvent(Translator* aTranslator) const {
3701 RefPtr<UnscaledFont> font = Factory::CreateUnscaledFontFromFontDescriptor(
3702 mType, mData.data(), mData.size(), mIndex);
3703 if (!font) {
3704 gfxDevCrash(LogReason::InvalidFont)
3705 << "Failed creating UnscaledFont of type " << int(mType)
3706 << " from font descriptor";
3707 return false;
3710 aTranslator->AddUnscaledFont(mRefPtr, font);
3711 return true;
3714 template <class S>
3715 void RecordedFontDescriptor::Record(S& aStream) const {
3716 MOZ_ASSERT(mHasDesc);
3717 WriteElement(aStream, mType);
3718 WriteElement(aStream, mRefPtr);
3719 WriteElement(aStream, mIndex);
3720 WriteElement(aStream, (size_t)mData.size());
3721 if (mData.size()) {
3722 aStream.write((char*)mData.data(), mData.size());
3726 inline void RecordedFontDescriptor::OutputSimpleEventInfo(
3727 std::stringstream& aStringStream) const {
3728 aStringStream << "[" << mRefPtr << "] Font Descriptor";
3731 inline void RecordedFontDescriptor::SetFontDescriptor(const uint8_t* aData,
3732 uint32_t aSize,
3733 uint32_t aIndex) {
3734 mData.assign(aData, aData + aSize);
3735 mIndex = aIndex;
3738 template <class S>
3739 RecordedFontDescriptor::RecordedFontDescriptor(S& aStream)
3740 : RecordedEventDerived(FONTDESC) {
3741 ReadElementConstrained(aStream, mType, FontType::DWRITE, FontType::UNKNOWN);
3742 ReadElement(aStream, mRefPtr);
3743 ReadElement(aStream, mIndex);
3745 size_t size;
3746 ReadElement(aStream, size);
3747 if (!aStream.good()) {
3748 return;
3750 if (size) {
3751 mData.resize(size);
3752 aStream.read((char*)mData.data(), size);
3756 inline bool RecordedUnscaledFontCreation::PlayEvent(
3757 Translator* aTranslator) const {
3758 NativeFontResource* fontResource =
3759 aTranslator->LookupNativeFontResource(mFontDataKey);
3760 if (!fontResource) {
3761 gfxDevCrash(LogReason::NativeFontResourceNotFound)
3762 << "NativeFontResource lookup failed for key |" << hexa(mFontDataKey)
3763 << "|.";
3764 return false;
3767 RefPtr<UnscaledFont> unscaledFont = fontResource->CreateUnscaledFont(
3768 mIndex, mInstanceData.data(), mInstanceData.size());
3769 aTranslator->AddUnscaledFont(mRefPtr, unscaledFont);
3770 return true;
3773 template <class S>
3774 void RecordedUnscaledFontCreation::Record(S& aStream) const {
3775 WriteElement(aStream, mRefPtr);
3776 WriteElement(aStream, mFontDataKey);
3777 WriteElement(aStream, mIndex);
3778 WriteElement(aStream, (size_t)mInstanceData.size());
3779 if (mInstanceData.size()) {
3780 aStream.write((char*)mInstanceData.data(), mInstanceData.size());
3784 inline void RecordedUnscaledFontCreation::OutputSimpleEventInfo(
3785 std::stringstream& aStringStream) const {
3786 aStringStream << "[" << mRefPtr << "] UnscaledFont Created";
3789 inline void RecordedUnscaledFontCreation::SetFontInstanceData(
3790 const uint8_t* aData, uint32_t aSize) {
3791 if (aSize) {
3792 mInstanceData.assign(aData, aData + aSize);
3796 template <class S>
3797 RecordedUnscaledFontCreation::RecordedUnscaledFontCreation(S& aStream)
3798 : RecordedEventDerived(UNSCALEDFONTCREATION) {
3799 ReadElement(aStream, mRefPtr);
3800 ReadElement(aStream, mFontDataKey);
3801 ReadElement(aStream, mIndex);
3803 size_t size;
3804 ReadElement(aStream, size);
3805 if (!aStream.good()) {
3806 return;
3808 if (size) {
3809 mInstanceData.resize(size);
3810 aStream.read((char*)mInstanceData.data(), size);
3814 inline bool RecordedUnscaledFontDestruction::PlayEvent(
3815 Translator* aTranslator) const {
3816 aTranslator->RemoveUnscaledFont(mRefPtr);
3817 return true;
3820 template <class S>
3821 void RecordedUnscaledFontDestruction::Record(S& aStream) const {
3822 WriteElement(aStream, mRefPtr);
3825 template <class S>
3826 RecordedUnscaledFontDestruction::RecordedUnscaledFontDestruction(S& aStream)
3827 : RecordedEventDerived(UNSCALEDFONTDESTRUCTION) {
3828 ReadElement(aStream, mRefPtr);
3831 inline void RecordedUnscaledFontDestruction::OutputSimpleEventInfo(
3832 std::stringstream& aStringStream) const {
3833 aStringStream << "[" << mRefPtr << "] UnscaledFont Destroyed";
3836 inline bool RecordedScaledFontCreation::PlayEvent(
3837 Translator* aTranslator) const {
3838 UnscaledFont* unscaledFont = aTranslator->LookupUnscaledFont(mUnscaledFont);
3839 if (!unscaledFont) {
3840 gfxDevCrash(LogReason::UnscaledFontNotFound)
3841 << "UnscaledFont lookup failed for key |" << hexa(mUnscaledFont)
3842 << "|.";
3843 return false;
3846 RefPtr<ScaledFont> scaledFont = unscaledFont->CreateScaledFont(
3847 mGlyphSize, mInstanceData.data(), mInstanceData.size(),
3848 mVariations.data(), mVariations.size());
3850 aTranslator->AddScaledFont(mRefPtr, scaledFont);
3851 return true;
3854 template <class S>
3855 void RecordedScaledFontCreation::Record(S& aStream) const {
3856 WriteElement(aStream, mRefPtr);
3857 WriteElement(aStream, mUnscaledFont);
3858 WriteElement(aStream, mGlyphSize);
3859 WriteElement(aStream, (size_t)mInstanceData.size());
3860 if (mInstanceData.size()) {
3861 aStream.write((char*)mInstanceData.data(), mInstanceData.size());
3863 WriteElement(aStream, (size_t)mVariations.size());
3864 if (mVariations.size()) {
3865 aStream.write((char*)mVariations.data(),
3866 sizeof(FontVariation) * mVariations.size());
3870 inline void RecordedScaledFontCreation::OutputSimpleEventInfo(
3871 std::stringstream& aStringStream) const {
3872 aStringStream << "[" << mRefPtr << "] ScaledFont Created";
3875 inline void RecordedScaledFontCreation::SetFontInstanceData(
3876 const uint8_t* aData, uint32_t aSize, const FontVariation* aVariations,
3877 uint32_t aNumVariations) {
3878 if (aSize) {
3879 mInstanceData.assign(aData, aData + aSize);
3881 if (aNumVariations) {
3882 mVariations.assign(aVariations, aVariations + aNumVariations);
3886 template <class S>
3887 RecordedScaledFontCreation::RecordedScaledFontCreation(S& aStream)
3888 : RecordedEventDerived(SCALEDFONTCREATION) {
3889 ReadElement(aStream, mRefPtr);
3890 ReadElement(aStream, mUnscaledFont);
3891 ReadElement(aStream, mGlyphSize);
3893 size_t size;
3894 ReadElement(aStream, size);
3895 if (!aStream.good()) {
3896 return;
3898 if (size) {
3899 mInstanceData.resize(size);
3900 aStream.read((char*)mInstanceData.data(), size);
3903 size_t numVariations;
3904 ReadElement(aStream, numVariations);
3905 if (!aStream.good()) {
3906 return;
3908 if (numVariations) {
3909 mVariations.resize(numVariations);
3910 aStream.read((char*)mVariations.data(),
3911 sizeof(FontVariation) * numVariations);
3915 inline bool RecordedScaledFontDestruction::PlayEvent(
3916 Translator* aTranslator) const {
3917 aTranslator->RemoveScaledFont(mRefPtr);
3918 return true;
3921 template <class S>
3922 void RecordedScaledFontDestruction::Record(S& aStream) const {
3923 WriteElement(aStream, mRefPtr);
3926 template <class S>
3927 RecordedScaledFontDestruction::RecordedScaledFontDestruction(S& aStream)
3928 : RecordedEventDerived(SCALEDFONTDESTRUCTION) {
3929 ReadElement(aStream, mRefPtr);
3932 inline void RecordedScaledFontDestruction::OutputSimpleEventInfo(
3933 std::stringstream& aStringStream) const {
3934 aStringStream << "[" << mRefPtr << "] ScaledFont Destroyed";
3937 inline bool RecordedMaskSurface::PlayEvent(Translator* aTranslator) const {
3938 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3939 if (!dt) {
3940 return false;
3943 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefMask);
3944 if (!surface) {
3945 return false;
3948 dt->MaskSurface(*GenericPattern(mPattern, aTranslator), surface, mOffset,
3949 mOptions);
3950 return true;
3953 template <class S>
3954 void RecordedMaskSurface::Record(S& aStream) const {
3955 RecordPatternData(aStream, mPattern);
3956 WriteElement(aStream, mRefMask);
3957 WriteElement(aStream, mOffset);
3958 WriteElement(aStream, mOptions);
3961 template <class S>
3962 RecordedMaskSurface::RecordedMaskSurface(S& aStream)
3963 : RecordedEventDerived(MASKSURFACE) {
3964 ReadPatternData(aStream, mPattern);
3965 ReadElement(aStream, mRefMask);
3966 ReadElement(aStream, mOffset);
3967 ReadDrawOptions(aStream, mOptions);
3970 inline void RecordedMaskSurface::OutputSimpleEventInfo(
3971 std::stringstream& aStringStream) const {
3972 aStringStream << "MaskSurface (" << mRefMask << ") Offset: (" << mOffset.x
3973 << "x" << mOffset.y << ") Pattern: ";
3974 OutputSimplePatternInfo(mPattern, aStringStream);
3977 template <typename T>
3978 void ReplaySetAttribute(FilterNode* aNode, uint32_t aIndex, T aValue) {
3979 aNode->SetAttribute(aIndex, aValue);
3982 inline bool RecordedFilterNodeSetAttribute::PlayEvent(
3983 Translator* aTranslator) const {
3984 FilterNode* node = aTranslator->LookupFilterNode(mNode);
3985 if (!node) {
3986 return false;
3989 #define REPLAY_SET_ATTRIBUTE(type, argtype) \
3990 case ARGTYPE_##argtype: \
3991 ReplaySetAttribute(node, mIndex, *(type*)&mPayload.front()); \
3992 break
3994 switch (mArgType) {
3995 REPLAY_SET_ATTRIBUTE(bool, BOOL);
3996 REPLAY_SET_ATTRIBUTE(uint32_t, UINT32);
3997 REPLAY_SET_ATTRIBUTE(Float, FLOAT);
3998 REPLAY_SET_ATTRIBUTE(Size, SIZE);
3999 REPLAY_SET_ATTRIBUTE(IntSize, INTSIZE);
4000 REPLAY_SET_ATTRIBUTE(IntPoint, INTPOINT);
4001 REPLAY_SET_ATTRIBUTE(Rect, RECT);
4002 REPLAY_SET_ATTRIBUTE(IntRect, INTRECT);
4003 REPLAY_SET_ATTRIBUTE(Point, POINT);
4004 REPLAY_SET_ATTRIBUTE(Matrix, MATRIX);
4005 REPLAY_SET_ATTRIBUTE(Matrix5x4, MATRIX5X4);
4006 REPLAY_SET_ATTRIBUTE(Point3D, POINT3D);
4007 REPLAY_SET_ATTRIBUTE(DeviceColor, COLOR);
4008 case ARGTYPE_FLOAT_ARRAY:
4009 node->SetAttribute(mIndex,
4010 reinterpret_cast<const Float*>(&mPayload.front()),
4011 mPayload.size() / sizeof(Float));
4012 break;
4015 return true;
4018 template <class S>
4019 void RecordedFilterNodeSetAttribute::Record(S& aStream) const {
4020 WriteElement(aStream, mNode);
4021 WriteElement(aStream, mIndex);
4022 WriteElement(aStream, mArgType);
4023 WriteElement(aStream, uint64_t(mPayload.size()));
4024 aStream.write((const char*)&mPayload.front(), mPayload.size());
4027 template <class S>
4028 RecordedFilterNodeSetAttribute::RecordedFilterNodeSetAttribute(S& aStream)
4029 : RecordedEventDerived(FILTERNODESETATTRIBUTE) {
4030 ReadElement(aStream, mNode);
4031 ReadElement(aStream, mIndex);
4032 ReadElementConstrained(aStream, mArgType, ArgType::ARGTYPE_UINT32,
4033 ArgType::ARGTYPE_FLOAT_ARRAY);
4034 uint64_t size;
4035 ReadElement(aStream, size);
4036 if (!aStream.good()) {
4037 return;
4040 mPayload.resize(size_t(size));
4041 aStream.read((char*)&mPayload.front(), size);
4044 inline void RecordedFilterNodeSetAttribute::OutputSimpleEventInfo(
4045 std::stringstream& aStringStream) const {
4046 aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ")";
4049 inline bool RecordedFilterNodeSetInput::PlayEvent(
4050 Translator* aTranslator) const {
4051 FilterNode* node = aTranslator->LookupFilterNode(mNode);
4052 if (!node) {
4053 return false;
4056 if (mInputFilter) {
4057 node->SetInput(mIndex, aTranslator->LookupFilterNode(mInputFilter));
4058 } else {
4059 node->SetInput(mIndex, aTranslator->LookupSourceSurface(mInputSurface));
4062 return true;
4065 template <class S>
4066 void RecordedFilterNodeSetInput::Record(S& aStream) const {
4067 WriteElement(aStream, mNode);
4068 WriteElement(aStream, mIndex);
4069 WriteElement(aStream, mInputFilter);
4070 WriteElement(aStream, mInputSurface);
4073 template <class S>
4074 RecordedFilterNodeSetInput::RecordedFilterNodeSetInput(S& aStream)
4075 : RecordedEventDerived(FILTERNODESETINPUT) {
4076 ReadElement(aStream, mNode);
4077 ReadElement(aStream, mIndex);
4078 ReadElement(aStream, mInputFilter);
4079 ReadElement(aStream, mInputSurface);
4082 inline void RecordedFilterNodeSetInput::OutputSimpleEventInfo(
4083 std::stringstream& aStringStream) const {
4084 aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ", ";
4086 if (mInputFilter) {
4087 aStringStream << "Filter: " << mInputFilter;
4088 } else {
4089 aStringStream << "Surface: " << mInputSurface;
4092 aStringStream << ")";
4095 inline bool RecordedLink::PlayEvent(Translator* aTranslator) const {
4096 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
4097 if (!dt) {
4098 return false;
4100 dt->Link(mDestination.c_str(), mRect);
4101 return true;
4104 template <class S>
4105 void RecordedLink::Record(S& aStream) const {
4106 WriteElement(aStream, mRect);
4107 uint32_t len = mDestination.length();
4108 WriteElement(aStream, len);
4109 if (len) {
4110 aStream.write(mDestination.data(), len);
4114 template <class S>
4115 RecordedLink::RecordedLink(S& aStream) : RecordedEventDerived(LINK) {
4116 ReadElement(aStream, mRect);
4117 uint32_t len;
4118 ReadElement(aStream, len);
4119 mDestination.resize(size_t(len));
4120 if (len && aStream.good()) {
4121 aStream.read(&mDestination.front(), len);
4125 inline void RecordedLink::OutputSimpleEventInfo(
4126 std::stringstream& aStringStream) const {
4127 aStringStream << "Link [" << mDestination << " @ " << mRect << "]";
4130 inline bool RecordedDestination::PlayEvent(Translator* aTranslator) const {
4131 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
4132 if (!dt) {
4133 return false;
4135 dt->Destination(mDestination.c_str(), mPoint);
4136 return true;
4139 template <class S>
4140 void RecordedDestination::Record(S& aStream) const {
4141 WriteElement(aStream, mPoint);
4142 uint32_t len = mDestination.length();
4143 WriteElement(aStream, len);
4144 if (len) {
4145 aStream.write(mDestination.data(), len);
4149 template <class S>
4150 RecordedDestination::RecordedDestination(S& aStream)
4151 : RecordedEventDerived(DESTINATION) {
4152 ReadElement(aStream, mPoint);
4153 uint32_t len;
4154 ReadElement(aStream, len);
4155 mDestination.resize(size_t(len));
4156 if (len && aStream.good()) {
4157 aStream.read(&mDestination.front(), len);
4161 inline void RecordedDestination::OutputSimpleEventInfo(
4162 std::stringstream& aStringStream) const {
4163 aStringStream << "Destination [" << mDestination << " @ " << mPoint << "]";
4166 #define FOR_EACH_EVENT(f) \
4167 f(DRAWTARGETCREATION, RecordedDrawTargetCreation); \
4168 f(DRAWTARGETDESTRUCTION, RecordedDrawTargetDestruction); \
4169 f(SETCURRENTDRAWTARGET, RecordedSetCurrentDrawTarget); \
4170 f(FILLRECT, RecordedFillRect); \
4171 f(STROKERECT, RecordedStrokeRect); \
4172 f(STROKELINE, RecordedStrokeLine); \
4173 f(STROKECIRCLE, RecordedStrokeCircle); \
4174 f(CLEARRECT, RecordedClearRect); \
4175 f(COPYSURFACE, RecordedCopySurface); \
4176 f(SETTRANSFORM, RecordedSetTransform); \
4177 f(PUSHCLIPRECT, RecordedPushClipRect); \
4178 f(PUSHCLIP, RecordedPushClip); \
4179 f(POPCLIP, RecordedPopClip); \
4180 f(FILL, RecordedFill); \
4181 f(FILLCIRCLE, RecordedFillCircle); \
4182 f(FILLGLYPHS, RecordedFillGlyphs); \
4183 f(MASK, RecordedMask); \
4184 f(STROKE, RecordedStroke); \
4185 f(DRAWSURFACE, RecordedDrawSurface); \
4186 f(DRAWDEPENDENTSURFACE, RecordedDrawDependentSurface); \
4187 f(DRAWSURFACEWITHSHADOW, RecordedDrawSurfaceWithShadow); \
4188 f(DRAWSHADOW, RecordedDrawShadow); \
4189 f(DRAWFILTER, RecordedDrawFilter); \
4190 f(PATHCREATION, RecordedPathCreation); \
4191 f(PATHDESTRUCTION, RecordedPathDestruction); \
4192 f(SOURCESURFACECREATION, RecordedSourceSurfaceCreation); \
4193 f(SOURCESURFACEDESTRUCTION, RecordedSourceSurfaceDestruction); \
4194 f(FILTERNODECREATION, RecordedFilterNodeCreation); \
4195 f(FILTERNODEDESTRUCTION, RecordedFilterNodeDestruction); \
4196 f(GRADIENTSTOPSCREATION, RecordedGradientStopsCreation); \
4197 f(GRADIENTSTOPSDESTRUCTION, RecordedGradientStopsDestruction); \
4198 f(SNAPSHOT, RecordedSnapshot); \
4199 f(SCALEDFONTCREATION, RecordedScaledFontCreation); \
4200 f(SCALEDFONTDESTRUCTION, RecordedScaledFontDestruction); \
4201 f(MASKSURFACE, RecordedMaskSurface); \
4202 f(FILTERNODESETATTRIBUTE, RecordedFilterNodeSetAttribute); \
4203 f(FILTERNODESETINPUT, RecordedFilterNodeSetInput); \
4204 f(CREATESIMILARDRAWTARGET, RecordedCreateSimilarDrawTarget); \
4205 f(CREATECLIPPEDDRAWTARGET, RecordedCreateClippedDrawTarget); \
4206 f(CREATEDRAWTARGETFORFILTER, RecordedCreateDrawTargetForFilter); \
4207 f(FONTDATA, RecordedFontData); \
4208 f(FONTDESC, RecordedFontDescriptor); \
4209 f(PUSHLAYER, RecordedPushLayer); \
4210 f(PUSHLAYERWITHBLEND, RecordedPushLayerWithBlend); \
4211 f(POPLAYER, RecordedPopLayer); \
4212 f(UNSCALEDFONTCREATION, RecordedUnscaledFontCreation); \
4213 f(UNSCALEDFONTDESTRUCTION, RecordedUnscaledFontDestruction); \
4214 f(INTOLUMINANCE, RecordedIntoLuminanceSource); \
4215 f(EXTERNALSURFACECREATION, RecordedExternalSurfaceCreation); \
4216 f(FLUSH, RecordedFlush); \
4217 f(DETACHALLSNAPSHOTS, RecordedDetachAllSnapshots); \
4218 f(OPTIMIZESOURCESURFACE, RecordedOptimizeSourceSurface); \
4219 f(LINK, RecordedLink); \
4220 f(DESTINATION, RecordedDestination);
4222 #define DO_WITH_EVENT_TYPE(_typeenum, _class) \
4223 case _typeenum: { \
4224 auto e = _class(aStream); \
4225 return aAction(&e); \
4228 template <class S>
4229 bool RecordedEvent::DoWithEvent(
4230 S& aStream, EventType aType,
4231 const std::function<bool(RecordedEvent*)>& aAction) {
4232 switch (aType) {
4233 FOR_EACH_EVENT(DO_WITH_EVENT_TYPE)
4234 default:
4235 return false;
4239 } // namespace gfx
4240 } // namespace mozilla
4242 #endif