no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / gfx / 2d / RecordedEventImpl.h
bloba880536bf8304c73d657e51c808a3dbd6fa28fdd
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 template <class Derived>
408 class RecordedDrawGlyphs : public RecordedEventDerived<Derived> {
409 public:
410 RecordedDrawGlyphs(RecordedEvent::EventType aType, ReferencePtr aScaledFont,
411 const Pattern& aPattern, const DrawOptions& aOptions,
412 const Glyph* aGlyphs, uint32_t aNumGlyphs)
413 : RecordedEventDerived<Derived>(aType),
414 mScaledFont(aScaledFont),
415 mPattern(),
416 mOptions(aOptions) {
417 this->StorePattern(mPattern, aPattern);
418 mNumGlyphs = aNumGlyphs;
419 mGlyphs = new Glyph[aNumGlyphs];
420 memcpy(mGlyphs, aGlyphs, sizeof(Glyph) * aNumGlyphs);
422 virtual ~RecordedDrawGlyphs();
424 bool PlayEvent(Translator* aTranslator) const override;
426 template <class S>
427 void Record(S& aStream) const;
428 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
430 protected:
431 friend class RecordedEvent;
433 template <class S>
434 RecordedDrawGlyphs(RecordedEvent::EventType aType, S& aStream);
436 virtual void DrawGlyphs(DrawTarget* aDT, ScaledFont* aScaledFont,
437 const GlyphBuffer& aBuffer,
438 const Pattern& aPattern) const = 0;
440 ReferencePtr mScaledFont;
441 PatternStorage mPattern;
442 DrawOptions mOptions;
443 Glyph* mGlyphs = nullptr;
444 uint32_t mNumGlyphs = 0;
447 class RecordedFillGlyphs : public RecordedDrawGlyphs<RecordedFillGlyphs> {
448 public:
449 RecordedFillGlyphs(ReferencePtr aScaledFont, const Pattern& aPattern,
450 const DrawOptions& aOptions, const Glyph* aGlyphs,
451 uint32_t aNumGlyphs)
452 : RecordedDrawGlyphs(FILLGLYPHS, aScaledFont, aPattern, aOptions, aGlyphs,
453 aNumGlyphs) {}
455 std::string GetName() const override { return "FillGlyphs"; }
457 private:
458 friend class RecordedEvent;
460 template <class S>
461 MOZ_IMPLICIT RecordedFillGlyphs(S& aStream)
462 : RecordedDrawGlyphs(FILLGLYPHS, aStream) {}
464 void DrawGlyphs(DrawTarget* aDT, ScaledFont* aScaledFont,
465 const GlyphBuffer& aBuffer,
466 const Pattern& aPattern) const override {
467 aDT->FillGlyphs(aScaledFont, aBuffer, aPattern, mOptions);
471 class RecordedStrokeGlyphs : public RecordedDrawGlyphs<RecordedStrokeGlyphs> {
472 public:
473 RecordedStrokeGlyphs(ReferencePtr aScaledFont, const Pattern& aPattern,
474 const StrokeOptions& aStrokeOptions,
475 const DrawOptions& aOptions, const Glyph* aGlyphs,
476 uint32_t aNumGlyphs)
477 : RecordedDrawGlyphs(STROKEGLYPHS, aScaledFont, aPattern, aOptions,
478 aGlyphs, aNumGlyphs),
479 mStrokeOptions(aStrokeOptions) {}
481 std::string GetName() const override { return "StrokeGlyphs"; }
483 template <class S>
484 void Record(S& aStream) const {
485 RecordedDrawGlyphs::Record(aStream);
486 RecordStrokeOptions(aStream, mStrokeOptions);
489 private:
490 friend class RecordedEvent;
492 template <class S>
493 MOZ_IMPLICIT RecordedStrokeGlyphs(S& aStream)
494 : RecordedDrawGlyphs(STROKEGLYPHS, aStream) {
495 ReadStrokeOptions(aStream, mStrokeOptions);
498 void DrawGlyphs(DrawTarget* aDT, ScaledFont* aScaledFont,
499 const GlyphBuffer& aBuffer,
500 const Pattern& aPattern) const override {
501 aDT->StrokeGlyphs(aScaledFont, aBuffer, aPattern, mStrokeOptions, mOptions);
504 StrokeOptions mStrokeOptions;
507 class RecordedMask : public RecordedEventDerived<RecordedMask> {
508 public:
509 RecordedMask(const Pattern& aSource, const Pattern& aMask,
510 const DrawOptions& aOptions)
511 : RecordedEventDerived(MASK), mSource(), mMask(), mOptions(aOptions) {
512 StorePattern(mSource, aSource);
513 StorePattern(mMask, aMask);
516 bool PlayEvent(Translator* aTranslator) const override;
518 template <class S>
519 void Record(S& aStream) const;
520 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
522 std::string GetName() const override { return "Mask"; }
524 private:
525 friend class RecordedEvent;
527 template <class S>
528 MOZ_IMPLICIT RecordedMask(S& aStream);
530 PatternStorage mSource;
531 PatternStorage mMask;
532 DrawOptions mOptions;
535 class RecordedStroke : public RecordedEventDerived<RecordedStroke> {
536 public:
537 RecordedStroke(ReferencePtr aPath, const Pattern& aPattern,
538 const StrokeOptions& aStrokeOptions,
539 const DrawOptions& aOptions)
540 : RecordedEventDerived(STROKE),
541 mPath(aPath),
542 mPattern(),
543 mStrokeOptions(aStrokeOptions),
544 mOptions(aOptions) {
545 StorePattern(mPattern, aPattern);
548 bool PlayEvent(Translator* aTranslator) const override;
550 template <class S>
551 void Record(S& aStream) const;
552 virtual void OutputSimpleEventInfo(
553 std::stringstream& aStringStream) const override;
555 std::string GetName() const override { return "Stroke"; }
557 private:
558 friend class RecordedEvent;
560 template <class S>
561 MOZ_IMPLICIT RecordedStroke(S& aStream);
563 ReferencePtr mPath;
564 PatternStorage mPattern;
565 StrokeOptions mStrokeOptions;
566 DrawOptions mOptions;
569 class RecordedClearRect : public RecordedEventDerived<RecordedClearRect> {
570 public:
571 explicit RecordedClearRect(const Rect& aRect)
572 : RecordedEventDerived(CLEARRECT), mRect(aRect) {}
574 bool PlayEvent(Translator* aTranslator) const override;
576 template <class S>
577 void Record(S& aStream) const;
578 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
580 std::string GetName() const override { return "ClearRect"; }
582 private:
583 friend class RecordedEvent;
585 template <class S>
586 MOZ_IMPLICIT RecordedClearRect(S& aStream);
588 Rect mRect;
591 class RecordedCopySurface : public RecordedEventDerived<RecordedCopySurface> {
592 public:
593 RecordedCopySurface(ReferencePtr aSourceSurface, const IntRect& aSourceRect,
594 const IntPoint& aDest)
595 : RecordedEventDerived(COPYSURFACE),
596 mSourceSurface(aSourceSurface),
597 mSourceRect(aSourceRect),
598 mDest(aDest) {}
600 bool PlayEvent(Translator* aTranslator) const override;
602 template <class S>
603 void Record(S& aStream) const;
604 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
606 std::string GetName() const override { return "CopySurface"; }
608 private:
609 friend class RecordedEvent;
611 template <class S>
612 MOZ_IMPLICIT RecordedCopySurface(S& aStream);
614 ReferencePtr mSourceSurface;
615 IntRect mSourceRect;
616 IntPoint mDest;
619 class RecordedPushClip : public RecordedEventDerived<RecordedPushClip> {
620 public:
621 explicit RecordedPushClip(ReferencePtr aPath)
622 : RecordedEventDerived(PUSHCLIP), mPath(aPath) {}
624 bool PlayEvent(Translator* aTranslator) const override;
626 template <class S>
627 void Record(S& aStream) const;
628 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
630 std::string GetName() const override { return "PushClip"; }
632 private:
633 friend class RecordedEvent;
635 template <class S>
636 MOZ_IMPLICIT RecordedPushClip(S& aStream);
638 ReferencePtr mPath;
641 class RecordedPushClipRect : public RecordedEventDerived<RecordedPushClipRect> {
642 public:
643 explicit RecordedPushClipRect(const Rect& aRect)
644 : RecordedEventDerived(PUSHCLIPRECT), mRect(aRect) {}
646 bool PlayEvent(Translator* aTranslator) const override;
648 template <class S>
649 void Record(S& aStream) const;
650 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
652 std::string GetName() const override { return "PushClipRect"; }
654 private:
655 friend class RecordedEvent;
657 template <class S>
658 MOZ_IMPLICIT RecordedPushClipRect(S& aStream);
660 Rect mRect;
663 class RecordedPopClip : public RecordedEventDerived<RecordedPopClip> {
664 public:
665 MOZ_IMPLICIT RecordedPopClip() : RecordedEventDerived(POPCLIP) {}
667 bool PlayEvent(Translator* aTranslator) const override;
669 template <class S>
670 void Record(S& aStream) const;
671 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
673 std::string GetName() const override { return "PopClip"; }
675 private:
676 friend class RecordedEvent;
678 template <class S>
679 MOZ_IMPLICIT RecordedPopClip(S& aStream);
682 class RecordedPushLayer : public RecordedEventDerived<RecordedPushLayer> {
683 public:
684 RecordedPushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
685 const Matrix& aMaskTransform, const IntRect& aBounds,
686 bool aCopyBackground)
687 : RecordedEventDerived(PUSHLAYER),
688 mOpaque(aOpaque),
689 mOpacity(aOpacity),
690 mMask(aMask),
691 mMaskTransform(aMaskTransform),
692 mBounds(aBounds),
693 mCopyBackground(aCopyBackground) {}
695 bool PlayEvent(Translator* aTranslator) const override;
697 template <class S>
698 void Record(S& aStream) const;
699 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
701 std::string GetName() const override { return "PushLayer"; }
703 private:
704 friend class RecordedEvent;
706 template <class S>
707 MOZ_IMPLICIT RecordedPushLayer(S& aStream);
709 bool mOpaque;
710 Float mOpacity;
711 ReferencePtr mMask;
712 Matrix mMaskTransform;
713 IntRect mBounds;
714 bool mCopyBackground;
717 class RecordedPushLayerWithBlend
718 : public RecordedEventDerived<RecordedPushLayerWithBlend> {
719 public:
720 RecordedPushLayerWithBlend(bool aOpaque, Float aOpacity, SourceSurface* aMask,
721 const Matrix& aMaskTransform,
722 const IntRect& aBounds, bool aCopyBackground,
723 CompositionOp aCompositionOp)
724 : RecordedEventDerived(PUSHLAYERWITHBLEND),
725 mOpaque(aOpaque),
726 mOpacity(aOpacity),
727 mMask(aMask),
728 mMaskTransform(aMaskTransform),
729 mBounds(aBounds),
730 mCopyBackground(aCopyBackground),
731 mCompositionOp(aCompositionOp) {}
733 bool PlayEvent(Translator* aTranslator) const override;
735 template <class S>
736 void Record(S& aStream) const;
737 virtual void OutputSimpleEventInfo(
738 std::stringstream& aStringStream) const override;
740 std::string GetName() const override { return "PushLayerWithBlend"; }
742 private:
743 friend class RecordedEvent;
745 template <class S>
746 MOZ_IMPLICIT RecordedPushLayerWithBlend(S& aStream);
748 bool mOpaque;
749 Float mOpacity;
750 ReferencePtr mMask;
751 Matrix mMaskTransform;
752 IntRect mBounds;
753 bool mCopyBackground;
754 CompositionOp mCompositionOp;
757 class RecordedPopLayer : public RecordedEventDerived<RecordedPopLayer> {
758 public:
759 RecordedPopLayer() : RecordedEventDerived(POPLAYER) {}
761 bool PlayEvent(Translator* aTranslator) const override;
763 template <class S>
764 void Record(S& aStream) const;
765 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
767 std::string GetName() const override { return "PopLayer"; }
769 private:
770 friend class RecordedEvent;
772 template <class S>
773 MOZ_IMPLICIT RecordedPopLayer(S& aStream);
776 class RecordedSetPermitSubpixelAA
777 : public RecordedEventDerived<RecordedSetPermitSubpixelAA> {
778 public:
779 explicit RecordedSetPermitSubpixelAA(bool aPermitSubpixelAA)
780 : RecordedEventDerived(SETPERMITSUBPIXELAA),
781 mPermitSubpixelAA(aPermitSubpixelAA) {}
783 bool PlayEvent(Translator* aTranslator) const override;
785 template <class S>
786 void Record(S& aStream) const;
787 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
789 std::string GetName() const override { return "SetPermitSubpixelAA"; }
791 private:
792 friend class RecordedEvent;
794 template <class S>
795 MOZ_IMPLICIT RecordedSetPermitSubpixelAA(S& aStream);
797 bool mPermitSubpixelAA = false;
800 class RecordedSetTransform : public RecordedEventDerived<RecordedSetTransform> {
801 public:
802 explicit RecordedSetTransform(const Matrix& aTransform)
803 : RecordedEventDerived(SETTRANSFORM), mTransform(aTransform) {}
805 bool PlayEvent(Translator* aTranslator) const override;
807 template <class S>
808 void Record(S& aStream) const;
809 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
811 std::string GetName() const override { return "SetTransform"; }
813 Matrix mTransform;
815 private:
816 friend class RecordedEvent;
818 template <class S>
819 MOZ_IMPLICIT RecordedSetTransform(S& aStream);
822 class RecordedDrawSurface : public RecordedEventDerived<RecordedDrawSurface> {
823 public:
824 RecordedDrawSurface(ReferencePtr aRefSource, const Rect& aDest,
825 const Rect& aSource, const DrawSurfaceOptions& aDSOptions,
826 const DrawOptions& aOptions)
827 : RecordedEventDerived(DRAWSURFACE),
828 mRefSource(aRefSource),
829 mDest(aDest),
830 mSource(aSource),
831 mDSOptions(aDSOptions),
832 mOptions(aOptions) {}
834 bool PlayEvent(Translator* aTranslator) const override;
836 template <class S>
837 void Record(S& aStream) const;
838 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
840 std::string GetName() const override { return "DrawSurface"; }
842 private:
843 friend class RecordedEvent;
845 template <class S>
846 MOZ_IMPLICIT RecordedDrawSurface(S& aStream);
848 ReferencePtr mRefSource;
849 Rect mDest;
850 Rect mSource;
851 DrawSurfaceOptions mDSOptions;
852 DrawOptions mOptions;
855 class RecordedDrawDependentSurface
856 : public RecordedEventDerived<RecordedDrawDependentSurface> {
857 public:
858 RecordedDrawDependentSurface(uint64_t aId, const Rect& aDest)
859 : RecordedEventDerived(DRAWDEPENDENTSURFACE), mId(aId), mDest(aDest) {}
861 bool PlayEvent(Translator* aTranslator) const override;
863 template <class S>
864 void Record(S& aStream) const;
865 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
867 std::string GetName() const override { return "DrawDependentSurface"; }
869 private:
870 friend class RecordedEvent;
872 template <class S>
873 MOZ_IMPLICIT RecordedDrawDependentSurface(S& aStream);
875 uint64_t mId;
876 Rect mDest;
879 class RecordedDrawSurfaceWithShadow
880 : public RecordedEventDerived<RecordedDrawSurfaceWithShadow> {
881 public:
882 RecordedDrawSurfaceWithShadow(ReferencePtr aRefSource, const Point& aDest,
883 const ShadowOptions& aShadow, CompositionOp aOp)
884 : RecordedEventDerived(DRAWSURFACEWITHSHADOW),
885 mRefSource(aRefSource),
886 mDest(aDest),
887 mShadow(aShadow),
888 mOp(aOp) {}
890 bool PlayEvent(Translator* aTranslator) const override;
892 template <class S>
893 void Record(S& aStream) const;
894 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
896 std::string GetName() const override { return "DrawSurfaceWithShadow"; }
898 private:
899 friend class RecordedEvent;
901 template <class S>
902 MOZ_IMPLICIT RecordedDrawSurfaceWithShadow(S& aStream);
904 ReferencePtr mRefSource;
905 Point mDest;
906 ShadowOptions mShadow;
907 CompositionOp mOp;
910 class RecordedDrawShadow : public RecordedEventDerived<RecordedDrawShadow> {
911 public:
912 RecordedDrawShadow(ReferencePtr aPath, const Pattern& aPattern,
913 const ShadowOptions& aShadow, const DrawOptions& aOptions,
914 const StrokeOptions* aStrokeOptions)
915 : RecordedEventDerived(DRAWSHADOW),
916 mPath(aPath),
917 mPattern(),
918 mShadow(aShadow),
919 mOptions(aOptions),
920 mHasStrokeOptions(!!aStrokeOptions),
921 mStrokeOptions(aStrokeOptions ? *aStrokeOptions : StrokeOptions()) {
922 StorePattern(mPattern, aPattern);
925 bool PlayEvent(Translator* aTranslator) const override;
927 template <class S>
928 void Record(S& aStream) const;
929 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
931 std::string GetName() const override { return "DrawShadow"; }
933 private:
934 friend class RecordedEvent;
936 template <class S>
937 MOZ_IMPLICIT RecordedDrawShadow(S& aStream);
939 ReferencePtr mPath;
940 PatternStorage mPattern;
941 ShadowOptions mShadow;
942 DrawOptions mOptions;
943 bool mHasStrokeOptions;
944 StrokeOptions mStrokeOptions;
947 class RecordedDrawFilter : public RecordedEventDerived<RecordedDrawFilter> {
948 public:
949 RecordedDrawFilter(ReferencePtr aNode, const Rect& aSourceRect,
950 const Point& aDestPoint, const DrawOptions& aOptions)
951 : RecordedEventDerived(DRAWFILTER),
952 mNode(aNode),
953 mSourceRect(aSourceRect),
954 mDestPoint(aDestPoint),
955 mOptions(aOptions) {}
957 bool PlayEvent(Translator* aTranslator) const override;
959 template <class S>
960 void Record(S& aStream) const;
961 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
963 std::string GetName() const override { return "DrawFilter"; }
965 private:
966 friend class RecordedEvent;
968 template <class S>
969 MOZ_IMPLICIT RecordedDrawFilter(S& aStream);
971 ReferencePtr mNode;
972 Rect mSourceRect;
973 Point mDestPoint;
974 DrawOptions mOptions;
977 class RecordedPathCreation : public RecordedEventDerived<RecordedPathCreation> {
978 public:
979 MOZ_IMPLICIT RecordedPathCreation(PathRecording* aPath);
981 bool PlayEvent(Translator* aTranslator) const override;
983 template <class S>
984 void Record(S& aStream) const;
985 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
987 std::string GetName() const override { return "Path Creation"; }
989 private:
990 friend class RecordedEvent;
992 ReferencePtr mDT;
993 ReferencePtr mRefPtr;
994 FillRule mFillRule;
995 RefPtr<PathRecording> mPath;
996 UniquePtr<PathOps> mPathOps;
998 template <class S>
999 MOZ_IMPLICIT RecordedPathCreation(S& aStream);
1002 class RecordedPathDestruction
1003 : public RecordedEventDerived<RecordedPathDestruction> {
1004 public:
1005 MOZ_IMPLICIT RecordedPathDestruction(PathRecording* aPath)
1006 : RecordedEventDerived(PATHDESTRUCTION), mRefPtr(aPath) {}
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 "Path Destruction"; }
1016 private:
1017 friend class RecordedEvent;
1019 ReferencePtr mRefPtr;
1021 template <class S>
1022 MOZ_IMPLICIT RecordedPathDestruction(S& aStream);
1025 class RecordedSourceSurfaceCreation
1026 : public RecordedEventDerived<RecordedSourceSurfaceCreation> {
1027 public:
1028 RecordedSourceSurfaceCreation(ReferencePtr aRefPtr, uint8_t* aData,
1029 int32_t aStride, const IntSize& aSize,
1030 SurfaceFormat aFormat)
1031 : RecordedEventDerived(SOURCESURFACECREATION),
1032 mRefPtr(aRefPtr),
1033 mData(aData),
1034 mStride(aStride),
1035 mSize(aSize),
1036 mFormat(aFormat),
1037 mDataOwned(false) {}
1039 ~RecordedSourceSurfaceCreation();
1041 bool PlayEvent(Translator* aTranslator) const override;
1043 template <class S>
1044 void Record(S& aStream) const;
1045 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1047 std::string GetName() const override { return "SourceSurface Creation"; }
1049 private:
1050 friend class RecordedEvent;
1052 ReferencePtr mRefPtr;
1053 uint8_t* mData = nullptr;
1054 int32_t mStride;
1055 IntSize mSize;
1056 SurfaceFormat mFormat;
1057 mutable bool mDataOwned;
1059 template <class S>
1060 MOZ_IMPLICIT RecordedSourceSurfaceCreation(S& aStream);
1063 class RecordedSourceSurfaceDestruction
1064 : public RecordedEventDerived<RecordedSourceSurfaceDestruction> {
1065 public:
1066 MOZ_IMPLICIT RecordedSourceSurfaceDestruction(ReferencePtr aRefPtr)
1067 : RecordedEventDerived(SOURCESURFACEDESTRUCTION), mRefPtr(aRefPtr) {}
1069 bool PlayEvent(Translator* aTranslator) const override;
1071 template <class S>
1072 void Record(S& aStream) const;
1073 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1075 std::string GetName() const override { return "SourceSurface Destruction"; }
1077 private:
1078 friend class RecordedEvent;
1080 ReferencePtr mRefPtr;
1082 template <class S>
1083 MOZ_IMPLICIT RecordedSourceSurfaceDestruction(S& aStream);
1086 class RecordedOptimizeSourceSurface
1087 : public RecordedEventDerived<RecordedOptimizeSourceSurface> {
1088 public:
1089 RecordedOptimizeSourceSurface(ReferencePtr aSurface,
1090 ReferencePtr aOptimizedSurface)
1091 : RecordedEventDerived(OPTIMIZESOURCESURFACE),
1092 mSurface(aSurface),
1093 mOptimizedSurface(aOptimizedSurface) {}
1095 bool PlayEvent(Translator* aTranslator) const override;
1097 template <class S>
1098 void Record(S& aStream) const;
1099 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1101 std::string GetName() const override { return "OptimizeSourceSurface"; }
1103 private:
1104 friend class RecordedEvent;
1106 ReferencePtr mSurface;
1107 ReferencePtr mOptimizedSurface;
1109 template <class S>
1110 MOZ_IMPLICIT RecordedOptimizeSourceSurface(S& aStream);
1113 class RecordedExternalSurfaceCreation
1114 : public RecordedEventDerived<RecordedExternalSurfaceCreation> {
1115 public:
1116 RecordedExternalSurfaceCreation(ReferencePtr aRefPtr, const uint64_t aKey)
1117 : RecordedEventDerived(EXTERNALSURFACECREATION),
1118 mRefPtr(aRefPtr),
1119 mKey(aKey) {}
1121 ~RecordedExternalSurfaceCreation() = default;
1123 virtual bool PlayEvent(Translator* aTranslator) const;
1125 template <class S>
1126 void Record(S& aStream) const;
1127 virtual void OutputSimpleEventInfo(std::stringstream& aStringStream) const;
1129 virtual std::string GetName() const {
1130 return "SourceSurfaceSharedData Creation";
1133 private:
1134 friend class RecordedEvent;
1136 ReferencePtr mRefPtr;
1137 uint64_t mKey;
1139 template <class S>
1140 MOZ_IMPLICIT RecordedExternalSurfaceCreation(S& aStream);
1143 class RecordedFilterNodeCreation
1144 : public RecordedEventDerived<RecordedFilterNodeCreation> {
1145 public:
1146 RecordedFilterNodeCreation(ReferencePtr aRefPtr, FilterType aType)
1147 : RecordedEventDerived(FILTERNODECREATION),
1148 mRefPtr(aRefPtr),
1149 mType(aType) {}
1151 ~RecordedFilterNodeCreation();
1153 bool PlayEvent(Translator* aTranslator) const override;
1155 template <class S>
1156 void Record(S& aStream) const;
1157 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1159 std::string GetName() const override { return "FilterNode Creation"; }
1161 private:
1162 friend class RecordedEvent;
1164 ReferencePtr mRefPtr;
1165 FilterType mType;
1167 template <class S>
1168 MOZ_IMPLICIT RecordedFilterNodeCreation(S& aStream);
1171 class RecordedFilterNodeDestruction
1172 : public RecordedEventDerived<RecordedFilterNodeDestruction> {
1173 public:
1174 MOZ_IMPLICIT RecordedFilterNodeDestruction(ReferencePtr aRefPtr)
1175 : RecordedEventDerived(FILTERNODEDESTRUCTION), mRefPtr(aRefPtr) {}
1177 bool PlayEvent(Translator* aTranslator) const override;
1179 template <class S>
1180 void Record(S& aStream) const;
1181 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1183 std::string GetName() const override { return "FilterNode Destruction"; }
1185 private:
1186 friend class RecordedEvent;
1188 ReferencePtr mRefPtr;
1190 template <class S>
1191 MOZ_IMPLICIT RecordedFilterNodeDestruction(S& aStream);
1194 class RecordedGradientStopsCreation
1195 : public RecordedEventDerived<RecordedGradientStopsCreation> {
1196 public:
1197 RecordedGradientStopsCreation(ReferencePtr aRefPtr, GradientStop* aStops,
1198 uint32_t aNumStops, ExtendMode aExtendMode)
1199 : RecordedEventDerived(GRADIENTSTOPSCREATION),
1200 mRefPtr(aRefPtr),
1201 mStops(aStops),
1202 mNumStops(aNumStops),
1203 mExtendMode(aExtendMode),
1204 mDataOwned(false) {}
1206 ~RecordedGradientStopsCreation();
1208 bool PlayEvent(Translator* aTranslator) const override;
1210 template <class S>
1211 void Record(S& aStream) const;
1212 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1214 std::string GetName() const override { return "GradientStops Creation"; }
1216 private:
1217 friend class RecordedEvent;
1219 ReferencePtr mRefPtr;
1220 GradientStop* mStops = nullptr;
1221 uint32_t mNumStops = 0;
1222 ExtendMode mExtendMode;
1223 bool mDataOwned;
1225 template <class S>
1226 MOZ_IMPLICIT RecordedGradientStopsCreation(S& aStream);
1229 class RecordedGradientStopsDestruction
1230 : public RecordedEventDerived<RecordedGradientStopsDestruction> {
1231 public:
1232 MOZ_IMPLICIT RecordedGradientStopsDestruction(ReferencePtr aRefPtr)
1233 : RecordedEventDerived(GRADIENTSTOPSDESTRUCTION), mRefPtr(aRefPtr) {}
1235 bool PlayEvent(Translator* aTranslator) const override;
1237 template <class S>
1238 void Record(S& aStream) const;
1239 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1241 std::string GetName() const override { return "GradientStops Destruction"; }
1243 private:
1244 friend class RecordedEvent;
1246 ReferencePtr mRefPtr;
1248 template <class S>
1249 MOZ_IMPLICIT RecordedGradientStopsDestruction(S& aStream);
1252 class RecordedFlush : public RecordedEventDerived<RecordedFlush> {
1253 public:
1254 explicit RecordedFlush() : RecordedEventDerived(FLUSH) {}
1256 bool PlayEvent(Translator* aTranslator) const final;
1258 template <class S>
1259 void Record(S& aStream) const;
1260 virtual void OutputSimpleEventInfo(
1261 std::stringstream& aStringStream) const override;
1263 virtual std::string GetName() const override { return "Flush"; }
1265 private:
1266 friend class RecordedEvent;
1268 template <class S>
1269 MOZ_IMPLICIT RecordedFlush(S& aStream);
1272 class RecordedDetachAllSnapshots
1273 : public RecordedEventDerived<RecordedDetachAllSnapshots> {
1274 public:
1275 explicit RecordedDetachAllSnapshots()
1276 : RecordedEventDerived(DETACHALLSNAPSHOTS) {}
1278 bool PlayEvent(Translator* aTranslator) const final;
1280 template <class S>
1281 void Record(S& aStream) const;
1282 virtual void OutputSimpleEventInfo(
1283 std::stringstream& aStringStream) const override;
1285 virtual std::string GetName() const override { return "DetachAllSnapshots"; }
1287 private:
1288 friend class RecordedEvent;
1290 template <class S>
1291 MOZ_IMPLICIT RecordedDetachAllSnapshots(S& aStream);
1294 class RecordedSnapshot : public RecordedEventDerived<RecordedSnapshot> {
1295 public:
1296 explicit RecordedSnapshot(ReferencePtr aRefPtr)
1297 : RecordedEventDerived(SNAPSHOT), mRefPtr(aRefPtr) {}
1299 bool PlayEvent(Translator* aTranslator) const override;
1301 template <class S>
1302 void Record(S& aStream) const;
1303 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1305 std::string GetName() const override { return "Snapshot"; }
1307 private:
1308 friend class RecordedEvent;
1310 ReferencePtr mRefPtr;
1312 template <class S>
1313 MOZ_IMPLICIT RecordedSnapshot(S& aStream);
1316 class RecordedIntoLuminanceSource
1317 : public RecordedEventDerived<RecordedIntoLuminanceSource> {
1318 public:
1319 RecordedIntoLuminanceSource(ReferencePtr aRefPtr,
1320 LuminanceType aLuminanceType, float aOpacity)
1321 : RecordedEventDerived(INTOLUMINANCE),
1322 mRefPtr(aRefPtr),
1323 mLuminanceType(aLuminanceType),
1324 mOpacity(aOpacity) {}
1326 bool PlayEvent(Translator* aTranslator) const override;
1328 template <class S>
1329 void Record(S& aStream) const;
1330 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1332 std::string GetName() const override { return "IntoLuminanceSource"; }
1334 private:
1335 friend class RecordedEvent;
1337 ReferencePtr mRefPtr;
1338 LuminanceType mLuminanceType;
1339 float mOpacity;
1341 template <class S>
1342 MOZ_IMPLICIT RecordedIntoLuminanceSource(S& aStream);
1345 class RecordedExtractSubrect
1346 : public RecordedEventDerived<RecordedExtractSubrect> {
1347 public:
1348 RecordedExtractSubrect(ReferencePtr aRefPtr, ReferencePtr aSourceSurface,
1349 const IntRect& aSubrect)
1350 : RecordedEventDerived(EXTRACTSUBRECT),
1351 mRefPtr(aRefPtr),
1352 mSourceSurface(aSourceSurface),
1353 mSubrect(aSubrect) {}
1355 bool PlayEvent(Translator* aTranslator) const override;
1357 template <class S>
1358 void Record(S& aStream) const;
1359 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1361 std::string GetName() const override { return "ExtractSubrect"; }
1363 private:
1364 friend class RecordedEvent;
1366 ReferencePtr mRefPtr;
1367 ReferencePtr mSourceSurface;
1368 IntRect mSubrect;
1370 template <class S>
1371 MOZ_IMPLICIT RecordedExtractSubrect(S& aStream);
1374 class RecordedFontData : public RecordedEventDerived<RecordedFontData> {
1375 public:
1376 static void FontDataProc(const uint8_t* aData, uint32_t aSize,
1377 uint32_t aIndex, void* aBaton) {
1378 auto recordedFontData = static_cast<RecordedFontData*>(aBaton);
1379 recordedFontData->SetFontData(aData, aSize, aIndex);
1382 explicit RecordedFontData(UnscaledFont* aUnscaledFont)
1383 : RecordedEventDerived(FONTDATA),
1384 mType(aUnscaledFont->GetType()),
1385 mFontDetails() {
1386 mGetFontFileDataSucceeded =
1387 aUnscaledFont->GetFontFileData(&FontDataProc, this) && mData;
1390 virtual ~RecordedFontData();
1392 bool IsValid() const { return mGetFontFileDataSucceeded; }
1394 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 "Font Data"; }
1402 void SetFontData(const uint8_t* aData, uint32_t aSize, uint32_t aIndex);
1404 bool GetFontDetails(RecordedFontDetails& fontDetails);
1406 private:
1407 friend class RecordedEvent;
1409 FontType mType;
1410 uint8_t* mData = nullptr;
1411 RecordedFontDetails mFontDetails;
1413 bool mGetFontFileDataSucceeded;
1415 template <class S>
1416 MOZ_IMPLICIT RecordedFontData(S& aStream);
1419 class RecordedFontDescriptor
1420 : public RecordedEventDerived<RecordedFontDescriptor> {
1421 public:
1422 static void FontDescCb(const uint8_t* aData, uint32_t aSize, uint32_t aIndex,
1423 void* aBaton) {
1424 auto recordedFontDesc = static_cast<RecordedFontDescriptor*>(aBaton);
1425 recordedFontDesc->SetFontDescriptor(aData, aSize, aIndex);
1428 explicit RecordedFontDescriptor(UnscaledFont* aUnscaledFont)
1429 : RecordedEventDerived(FONTDESC),
1430 mType(aUnscaledFont->GetType()),
1431 mIndex(0),
1432 mRefPtr(aUnscaledFont) {
1433 mHasDesc = aUnscaledFont->GetFontDescriptor(FontDescCb, this);
1436 virtual ~RecordedFontDescriptor();
1438 bool IsValid() const { return mHasDesc; }
1440 bool PlayEvent(Translator* aTranslator) const override;
1442 template <class S>
1443 void Record(S& aStream) const;
1444 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1446 std::string GetName() const override { return "Font Desc"; }
1448 private:
1449 friend class RecordedEvent;
1451 void SetFontDescriptor(const uint8_t* aData, uint32_t aSize, uint32_t aIndex);
1453 bool mHasDesc;
1455 FontType mType;
1456 std::vector<uint8_t> mData;
1457 uint32_t mIndex;
1458 ReferencePtr mRefPtr;
1460 template <class S>
1461 MOZ_IMPLICIT RecordedFontDescriptor(S& aStream);
1464 class RecordedUnscaledFontCreation
1465 : public RecordedEventDerived<RecordedUnscaledFontCreation> {
1466 public:
1467 static void FontInstanceDataProc(const uint8_t* aData, uint32_t aSize,
1468 void* aBaton) {
1469 auto recordedUnscaledFontCreation =
1470 static_cast<RecordedUnscaledFontCreation*>(aBaton);
1471 recordedUnscaledFontCreation->SetFontInstanceData(aData, aSize);
1474 RecordedUnscaledFontCreation(UnscaledFont* aUnscaledFont,
1475 RecordedFontDetails aFontDetails)
1476 : RecordedEventDerived(UNSCALEDFONTCREATION),
1477 mRefPtr(aUnscaledFont),
1478 mFontDataKey(aFontDetails.fontDataKey),
1479 mIndex(aFontDetails.index) {
1480 aUnscaledFont->GetFontInstanceData(FontInstanceDataProc, this);
1483 bool PlayEvent(Translator* aTranslator) const override;
1485 template <class S>
1486 void Record(S& aStream) const;
1487 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1489 std::string GetName() const override { return "UnscaledFont Creation"; }
1491 void SetFontInstanceData(const uint8_t* aData, uint32_t aSize);
1493 private:
1494 friend class RecordedEvent;
1496 ReferencePtr mRefPtr;
1497 uint64_t mFontDataKey;
1498 uint32_t mIndex;
1499 std::vector<uint8_t> mInstanceData;
1501 template <class S>
1502 MOZ_IMPLICIT RecordedUnscaledFontCreation(S& aStream);
1505 class RecordedUnscaledFontDestruction
1506 : public RecordedEventDerived<RecordedUnscaledFontDestruction> {
1507 public:
1508 MOZ_IMPLICIT RecordedUnscaledFontDestruction(ReferencePtr aRefPtr)
1509 : RecordedEventDerived(UNSCALEDFONTDESTRUCTION), mRefPtr(aRefPtr) {}
1511 bool PlayEvent(Translator* aTranslator) const override;
1512 template <class S>
1513 void Record(S& aStream) const;
1514 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1516 std::string GetName() const override { return "UnscaledFont Destruction"; }
1518 private:
1519 friend class RecordedEvent;
1521 ReferencePtr mRefPtr;
1523 template <class S>
1524 MOZ_IMPLICIT RecordedUnscaledFontDestruction(S& aStream);
1527 class RecordedScaledFontCreation
1528 : public RecordedEventDerived<RecordedScaledFontCreation> {
1529 public:
1530 static void FontInstanceDataProc(const uint8_t* aData, uint32_t aSize,
1531 const FontVariation* aVariations,
1532 uint32_t aNumVariations, void* aBaton) {
1533 auto recordedScaledFontCreation =
1534 static_cast<RecordedScaledFontCreation*>(aBaton);
1535 recordedScaledFontCreation->SetFontInstanceData(aData, aSize, aVariations,
1536 aNumVariations);
1539 RecordedScaledFontCreation(ScaledFont* aScaledFont,
1540 UnscaledFont* aUnscaledFont)
1541 : RecordedEventDerived(SCALEDFONTCREATION),
1542 mRefPtr(aScaledFont),
1543 mUnscaledFont(aUnscaledFont),
1544 mGlyphSize(aScaledFont->GetSize()) {
1545 aScaledFont->GetFontInstanceData(FontInstanceDataProc, this);
1548 bool PlayEvent(Translator* aTranslator) const override;
1550 template <class S>
1551 void Record(S& aStream) const;
1552 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1554 std::string GetName() const override { return "ScaledFont Creation"; }
1556 void SetFontInstanceData(const uint8_t* aData, uint32_t aSize,
1557 const FontVariation* aVariations,
1558 uint32_t aNumVariations);
1560 private:
1561 friend class RecordedEvent;
1563 ReferencePtr mRefPtr;
1564 ReferencePtr mUnscaledFont;
1565 Float mGlyphSize;
1566 std::vector<uint8_t> mInstanceData;
1567 std::vector<FontVariation> mVariations;
1569 template <class S>
1570 MOZ_IMPLICIT RecordedScaledFontCreation(S& aStream);
1573 class RecordedScaledFontDestruction
1574 : public RecordedEventDerived<RecordedScaledFontDestruction> {
1575 public:
1576 MOZ_IMPLICIT RecordedScaledFontDestruction(ReferencePtr aRefPtr)
1577 : RecordedEventDerived(SCALEDFONTDESTRUCTION), mRefPtr(aRefPtr) {}
1579 bool PlayEvent(Translator* aTranslator) const override;
1581 template <class S>
1582 void Record(S& aStream) const;
1583 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1585 std::string GetName() const override { return "ScaledFont Destruction"; }
1587 private:
1588 friend class RecordedEvent;
1590 ReferencePtr mRefPtr;
1592 template <class S>
1593 MOZ_IMPLICIT RecordedScaledFontDestruction(S& aStream);
1596 class RecordedMaskSurface : public RecordedEventDerived<RecordedMaskSurface> {
1597 public:
1598 RecordedMaskSurface(const Pattern& aPattern, ReferencePtr aRefMask,
1599 const Point& aOffset, const DrawOptions& aOptions)
1600 : RecordedEventDerived(MASKSURFACE),
1601 mPattern(),
1602 mRefMask(aRefMask),
1603 mOffset(aOffset),
1604 mOptions(aOptions) {
1605 StorePattern(mPattern, aPattern);
1608 bool PlayEvent(Translator* aTranslator) const override;
1610 template <class S>
1611 void Record(S& aStream) const;
1612 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1614 std::string GetName() const override { return "MaskSurface"; }
1616 private:
1617 friend class RecordedEvent;
1619 template <class S>
1620 MOZ_IMPLICIT RecordedMaskSurface(S& aStream);
1622 PatternStorage mPattern;
1623 ReferencePtr mRefMask;
1624 Point mOffset;
1625 DrawOptions mOptions;
1628 class RecordedFilterNodeSetAttribute
1629 : public RecordedEventDerived<RecordedFilterNodeSetAttribute> {
1630 public:
1631 enum ArgType {
1632 ARGTYPE_UINT32,
1633 ARGTYPE_BOOL,
1634 ARGTYPE_FLOAT,
1635 ARGTYPE_SIZE,
1636 ARGTYPE_INTSIZE,
1637 ARGTYPE_INTPOINT,
1638 ARGTYPE_RECT,
1639 ARGTYPE_INTRECT,
1640 ARGTYPE_POINT,
1641 ARGTYPE_MATRIX,
1642 ARGTYPE_MATRIX5X4,
1643 ARGTYPE_POINT3D,
1644 ARGTYPE_COLOR,
1645 ARGTYPE_FLOAT_ARRAY
1648 template <typename T>
1649 RecordedFilterNodeSetAttribute(FilterNode* aNode, uint32_t aIndex,
1650 T aArgument, ArgType aArgType)
1651 : RecordedEventDerived(FILTERNODESETATTRIBUTE),
1652 mNode(aNode),
1653 mIndex(aIndex),
1654 mArgType(aArgType) {
1655 mPayload.resize(sizeof(T));
1656 memcpy(&mPayload.front(), &aArgument, sizeof(T));
1659 RecordedFilterNodeSetAttribute(FilterNode* aNode, uint32_t aIndex,
1660 const Float* aFloat, uint32_t aSize)
1661 : RecordedEventDerived(FILTERNODESETATTRIBUTE),
1662 mNode(aNode),
1663 mIndex(aIndex),
1664 mArgType(ARGTYPE_FLOAT_ARRAY) {
1665 mPayload.resize(sizeof(Float) * aSize);
1666 memcpy(&mPayload.front(), aFloat, sizeof(Float) * aSize);
1669 bool PlayEvent(Translator* aTranslator) const override;
1670 template <class S>
1671 void Record(S& aStream) const;
1672 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1674 std::string GetName() const override { return "SetAttribute"; }
1676 private:
1677 friend class RecordedEvent;
1679 ReferencePtr mNode;
1681 uint32_t mIndex;
1682 ArgType mArgType;
1683 std::vector<uint8_t> mPayload;
1685 template <class S>
1686 MOZ_IMPLICIT RecordedFilterNodeSetAttribute(S& aStream);
1689 class RecordedFilterNodeSetInput
1690 : public RecordedEventDerived<RecordedFilterNodeSetInput> {
1691 public:
1692 RecordedFilterNodeSetInput(FilterNode* aNode, uint32_t aIndex,
1693 FilterNode* aInputNode)
1694 : RecordedEventDerived(FILTERNODESETINPUT),
1695 mNode(aNode),
1696 mIndex(aIndex),
1697 mInputFilter(aInputNode),
1698 mInputSurface(nullptr) {}
1700 RecordedFilterNodeSetInput(FilterNode* aNode, uint32_t aIndex,
1701 SourceSurface* aInputSurface)
1702 : RecordedEventDerived(FILTERNODESETINPUT),
1703 mNode(aNode),
1704 mIndex(aIndex),
1705 mInputFilter(nullptr),
1706 mInputSurface(aInputSurface) {}
1708 bool PlayEvent(Translator* aTranslator) const override;
1709 template <class S>
1710 void Record(S& aStream) const;
1711 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1713 std::string GetName() const override { return "SetInput"; }
1715 private:
1716 friend class RecordedEvent;
1718 ReferencePtr mNode;
1719 uint32_t mIndex;
1720 ReferencePtr mInputFilter;
1721 ReferencePtr mInputSurface;
1723 template <class S>
1724 MOZ_IMPLICIT RecordedFilterNodeSetInput(S& aStream);
1727 class RecordedLink : public RecordedEventDerived<RecordedLink> {
1728 public:
1729 RecordedLink(const char* aDestination, const Rect& aRect)
1730 : RecordedEventDerived(LINK), mDestination(aDestination), mRect(aRect) {}
1732 bool PlayEvent(Translator* aTranslator) const override;
1733 template <class S>
1734 void Record(S& aStream) const;
1735 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1737 std::string GetName() const override { return "Link"; }
1739 private:
1740 friend class RecordedEvent;
1742 std::string mDestination;
1743 Rect mRect;
1745 template <class S>
1746 MOZ_IMPLICIT RecordedLink(S& aStream);
1749 class RecordedDestination : public RecordedEventDerived<RecordedDestination> {
1750 public:
1751 RecordedDestination(const char* aDestination, const Point& aPoint)
1752 : RecordedEventDerived(DESTINATION),
1753 mDestination(aDestination),
1754 mPoint(aPoint) {}
1756 bool PlayEvent(Translator* aTranslator) const override;
1757 template <class S>
1758 void Record(S& aStream) const;
1759 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1761 std::string GetName() const override { return "Destination"; }
1763 private:
1764 friend class RecordedEvent;
1766 std::string mDestination;
1767 Point mPoint;
1769 template <class S>
1770 MOZ_IMPLICIT RecordedDestination(S& aStream);
1773 static std::string NameFromBackend(BackendType aType) {
1774 switch (aType) {
1775 case BackendType::NONE:
1776 return "None";
1777 case BackendType::DIRECT2D:
1778 return "Direct2D";
1779 default:
1780 return "Unknown";
1784 template <class S>
1785 void RecordedEvent::RecordPatternData(S& aStream,
1786 const PatternStorage& aPattern) const {
1787 WriteElement(aStream, aPattern.mType);
1789 switch (aPattern.mType) {
1790 case PatternType::COLOR: {
1791 WriteElement(aStream, *reinterpret_cast<const ColorPatternStorage*>(
1792 &aPattern.mStorage));
1793 return;
1795 case PatternType::LINEAR_GRADIENT: {
1796 WriteElement(aStream,
1797 *reinterpret_cast<const LinearGradientPatternStorage*>(
1798 &aPattern.mStorage));
1799 return;
1801 case PatternType::RADIAL_GRADIENT: {
1802 WriteElement(aStream,
1803 *reinterpret_cast<const RadialGradientPatternStorage*>(
1804 &aPattern.mStorage));
1805 return;
1807 case PatternType::CONIC_GRADIENT: {
1808 WriteElement(aStream,
1809 *reinterpret_cast<const ConicGradientPatternStorage*>(
1810 &aPattern.mStorage));
1811 return;
1813 case PatternType::SURFACE: {
1814 WriteElement(aStream, *reinterpret_cast<const SurfacePatternStorage*>(
1815 &aPattern.mStorage));
1816 return;
1818 default:
1819 return;
1823 template <class S>
1824 void RecordedEvent::ReadPatternData(S& aStream,
1825 PatternStorage& aPattern) const {
1826 ReadElementConstrained(aStream, aPattern.mType, PatternType::COLOR,
1827 kHighestPatternType);
1829 switch (aPattern.mType) {
1830 case PatternType::COLOR: {
1831 ReadElement(aStream,
1832 *reinterpret_cast<ColorPatternStorage*>(&aPattern.mStorage));
1833 return;
1835 case PatternType::LINEAR_GRADIENT: {
1836 ReadElement(aStream, *reinterpret_cast<LinearGradientPatternStorage*>(
1837 &aPattern.mStorage));
1838 return;
1840 case PatternType::RADIAL_GRADIENT: {
1841 ReadElement(aStream, *reinterpret_cast<RadialGradientPatternStorage*>(
1842 &aPattern.mStorage));
1843 return;
1845 case PatternType::CONIC_GRADIENT: {
1846 ReadElement(aStream, *reinterpret_cast<ConicGradientPatternStorage*>(
1847 &aPattern.mStorage));
1848 return;
1850 case PatternType::SURFACE: {
1851 SurfacePatternStorage* sps =
1852 reinterpret_cast<SurfacePatternStorage*>(&aPattern.mStorage);
1853 ReadElement(aStream, *sps);
1854 if (sps->mExtend < ExtendMode::CLAMP ||
1855 sps->mExtend > ExtendMode::REFLECT) {
1856 aStream.SetIsBad();
1857 return;
1860 if (sps->mSamplingFilter < SamplingFilter::GOOD ||
1861 sps->mSamplingFilter >= SamplingFilter::SENTINEL) {
1862 aStream.SetIsBad();
1864 return;
1866 default:
1867 return;
1871 inline void RecordedEvent::StorePattern(PatternStorage& aDestination,
1872 const Pattern& aSource) const {
1873 aDestination.mType = aSource.GetType();
1875 switch (aSource.GetType()) {
1876 case PatternType::COLOR: {
1877 reinterpret_cast<ColorPatternStorage*>(&aDestination.mStorage)->mColor =
1878 static_cast<const ColorPattern*>(&aSource)->mColor;
1879 return;
1881 case PatternType::LINEAR_GRADIENT: {
1882 LinearGradientPatternStorage* store =
1883 reinterpret_cast<LinearGradientPatternStorage*>(
1884 &aDestination.mStorage);
1885 const LinearGradientPattern* pat =
1886 static_cast<const LinearGradientPattern*>(&aSource);
1887 store->mBegin = pat->mBegin;
1888 store->mEnd = pat->mEnd;
1889 store->mMatrix = pat->mMatrix;
1890 store->mStops = pat->mStops.get();
1891 return;
1893 case PatternType::RADIAL_GRADIENT: {
1894 RadialGradientPatternStorage* store =
1895 reinterpret_cast<RadialGradientPatternStorage*>(
1896 &aDestination.mStorage);
1897 const RadialGradientPattern* pat =
1898 static_cast<const RadialGradientPattern*>(&aSource);
1899 store->mCenter1 = pat->mCenter1;
1900 store->mCenter2 = pat->mCenter2;
1901 store->mRadius1 = pat->mRadius1;
1902 store->mRadius2 = pat->mRadius2;
1903 store->mMatrix = pat->mMatrix;
1904 store->mStops = pat->mStops.get();
1905 return;
1907 case PatternType::CONIC_GRADIENT: {
1908 ConicGradientPatternStorage* store =
1909 reinterpret_cast<ConicGradientPatternStorage*>(
1910 &aDestination.mStorage);
1911 const ConicGradientPattern* pat =
1912 static_cast<const ConicGradientPattern*>(&aSource);
1913 store->mCenter = pat->mCenter;
1914 store->mAngle = pat->mAngle;
1915 store->mStartOffset = pat->mStartOffset;
1916 store->mEndOffset = pat->mEndOffset;
1917 store->mMatrix = pat->mMatrix;
1918 store->mStops = pat->mStops.get();
1919 return;
1921 case PatternType::SURFACE: {
1922 SurfacePatternStorage* store =
1923 reinterpret_cast<SurfacePatternStorage*>(&aDestination.mStorage);
1924 const SurfacePattern* pat = static_cast<const SurfacePattern*>(&aSource);
1925 store->mExtend = pat->mExtendMode;
1926 store->mSamplingFilter = pat->mSamplingFilter;
1927 store->mMatrix = pat->mMatrix;
1928 store->mSurface = pat->mSurface;
1929 store->mSamplingRect = pat->mSamplingRect;
1930 return;
1935 template <class S>
1936 void RecordedEvent::RecordStrokeOptions(
1937 S& aStream, const StrokeOptions& aStrokeOptions) const {
1938 JoinStyle joinStyle = aStrokeOptions.mLineJoin;
1939 CapStyle capStyle = aStrokeOptions.mLineCap;
1941 WriteElement(aStream, uint64_t(aStrokeOptions.mDashLength));
1942 WriteElement(aStream, aStrokeOptions.mLineWidth);
1943 WriteElement(aStream, aStrokeOptions.mMiterLimit);
1944 WriteElement(aStream, joinStyle);
1945 WriteElement(aStream, capStyle);
1947 if (!aStrokeOptions.mDashPattern) {
1948 return;
1951 WriteElement(aStream, aStrokeOptions.mDashOffset);
1952 aStream.write((char*)aStrokeOptions.mDashPattern,
1953 sizeof(Float) * aStrokeOptions.mDashLength);
1956 template <class S>
1957 void RecordedEvent::ReadStrokeOptions(S& aStream,
1958 StrokeOptions& aStrokeOptions) {
1959 uint64_t dashLength;
1960 JoinStyle joinStyle;
1961 CapStyle capStyle;
1963 ReadElement(aStream, dashLength);
1964 ReadElement(aStream, aStrokeOptions.mLineWidth);
1965 ReadElement(aStream, aStrokeOptions.mMiterLimit);
1966 ReadElementConstrained(aStream, joinStyle, JoinStyle::BEVEL,
1967 JoinStyle::MITER_OR_BEVEL);
1968 ReadElementConstrained(aStream, capStyle, CapStyle::BUTT, CapStyle::SQUARE);
1969 // On 32 bit we truncate the value of dashLength.
1970 // See also bug 811850 for history.
1971 aStrokeOptions.mDashLength = size_t(dashLength);
1972 aStrokeOptions.mLineJoin = joinStyle;
1973 aStrokeOptions.mLineCap = capStyle;
1975 if (!aStrokeOptions.mDashLength || !aStream.good()) {
1976 return;
1979 ReadElement(aStream, aStrokeOptions.mDashOffset);
1981 mDashPatternStorage.resize(aStrokeOptions.mDashLength);
1982 aStrokeOptions.mDashPattern = &mDashPatternStorage.front();
1983 aStream.read((char*)aStrokeOptions.mDashPattern,
1984 sizeof(Float) * aStrokeOptions.mDashLength);
1987 template <class S>
1988 static void ReadDrawOptions(S& aStream, DrawOptions& aDrawOptions) {
1989 ReadElement(aStream, aDrawOptions);
1990 if (aDrawOptions.mAntialiasMode < AntialiasMode::NONE ||
1991 aDrawOptions.mAntialiasMode > AntialiasMode::DEFAULT) {
1992 aStream.SetIsBad();
1993 return;
1996 if (aDrawOptions.mCompositionOp < CompositionOp::OP_CLEAR ||
1997 aDrawOptions.mCompositionOp > CompositionOp::OP_COUNT) {
1998 aStream.SetIsBad();
2002 template <class S>
2003 static void ReadDrawSurfaceOptions(S& aStream,
2004 DrawSurfaceOptions& aDrawSurfaceOptions) {
2005 ReadElement(aStream, aDrawSurfaceOptions);
2006 if (aDrawSurfaceOptions.mSamplingFilter < SamplingFilter::GOOD ||
2007 aDrawSurfaceOptions.mSamplingFilter >= SamplingFilter::SENTINEL) {
2008 aStream.SetIsBad();
2009 return;
2012 if (aDrawSurfaceOptions.mSamplingBounds < SamplingBounds::UNBOUNDED ||
2013 aDrawSurfaceOptions.mSamplingBounds > SamplingBounds::BOUNDED) {
2014 aStream.SetIsBad();
2018 inline void RecordedEvent::OutputSimplePatternInfo(
2019 const PatternStorage& aStorage, std::stringstream& aOutput) const {
2020 switch (aStorage.mType) {
2021 case PatternType::COLOR: {
2022 const DeviceColor color =
2023 reinterpret_cast<const ColorPatternStorage*>(&aStorage.mStorage)
2024 ->mColor;
2025 aOutput << "DeviceColor: (" << color.r << ", " << color.g << ", "
2026 << color.b << ", " << color.a << ")";
2027 return;
2029 case PatternType::LINEAR_GRADIENT: {
2030 const LinearGradientPatternStorage* store =
2031 reinterpret_cast<const LinearGradientPatternStorage*>(
2032 &aStorage.mStorage);
2034 aOutput << "LinearGradient (" << store->mBegin.x << ", "
2035 << store->mBegin.y << ") - (" << store->mEnd.x << ", "
2036 << store->mEnd.y << ") Stops: " << store->mStops;
2037 return;
2039 case PatternType::RADIAL_GRADIENT: {
2040 const RadialGradientPatternStorage* store =
2041 reinterpret_cast<const RadialGradientPatternStorage*>(
2042 &aStorage.mStorage);
2043 aOutput << "RadialGradient (Center 1: (" << store->mCenter1.x << ", "
2044 << store->mCenter2.y << ") Radius 2: " << store->mRadius2;
2045 return;
2047 case PatternType::CONIC_GRADIENT: {
2048 const ConicGradientPatternStorage* store =
2049 reinterpret_cast<const ConicGradientPatternStorage*>(
2050 &aStorage.mStorage);
2051 aOutput << "ConicGradient (Center: (" << store->mCenter.x << ", "
2052 << store->mCenter.y << ") Angle: " << store->mAngle
2053 << " Range:" << store->mStartOffset << " - " << store->mEndOffset;
2054 return;
2056 case PatternType::SURFACE: {
2057 const SurfacePatternStorage* store =
2058 reinterpret_cast<const SurfacePatternStorage*>(&aStorage.mStorage);
2059 aOutput << "Surface (0x" << store->mSurface << ")";
2060 return;
2065 inline bool RecordedDrawTargetCreation::PlayEvent(
2066 Translator* aTranslator) const {
2067 RefPtr<DrawTarget> newDT =
2068 aTranslator->CreateDrawTarget(mRefPtr, mRect.Size(), mFormat);
2070 // If we couldn't create a DrawTarget this will probably cause us to crash
2071 // with nullptr later in the playback, so return false to abort.
2072 if (!newDT) {
2073 return false;
2076 if (mHasExistingData) {
2077 Rect dataRect(0, 0, mExistingData->GetSize().width,
2078 mExistingData->GetSize().height);
2079 newDT->DrawSurface(mExistingData, dataRect, dataRect);
2082 return true;
2085 template <class S>
2086 void RecordedDrawTargetCreation::Record(S& aStream) const {
2087 WriteElement(aStream, mRefPtr);
2088 WriteElement(aStream, mBackendType);
2089 WriteElement(aStream, mRect);
2090 WriteElement(aStream, mFormat);
2091 WriteElement(aStream, mHasExistingData);
2093 if (mHasExistingData) {
2094 MOZ_ASSERT(mExistingData);
2095 MOZ_ASSERT(mExistingData->GetSize() == mRect.Size());
2096 RefPtr<DataSourceSurface> dataSurf = mExistingData->GetDataSurface();
2098 DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ);
2099 for (int y = 0; y < mRect.height; y++) {
2100 aStream.write((const char*)map.GetData() + y * map.GetStride(),
2101 BytesPerPixel(mFormat) * mRect.width);
2106 template <class S>
2107 RecordedDrawTargetCreation::RecordedDrawTargetCreation(S& aStream)
2108 : RecordedEventDerived(DRAWTARGETCREATION), mExistingData(nullptr) {
2109 ReadElement(aStream, mRefPtr);
2110 ReadElementConstrained(aStream, mBackendType, BackendType::NONE,
2111 BackendType::WEBRENDER_TEXT);
2112 ReadElement(aStream, mRect);
2113 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2114 SurfaceFormat::UNKNOWN);
2115 ReadElement(aStream, mHasExistingData);
2117 if (mHasExistingData) {
2118 RefPtr<DataSourceSurface> dataSurf =
2119 Factory::CreateDataSourceSurface(mRect.Size(), mFormat);
2120 if (!dataSurf) {
2121 gfxWarning()
2122 << "RecordedDrawTargetCreation had to reset mHasExistingData";
2123 mHasExistingData = false;
2124 return;
2127 DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ);
2128 for (int y = 0; y < mRect.height; y++) {
2129 aStream.read((char*)map.GetData() + y * map.GetStride(),
2130 BytesPerPixel(mFormat) * mRect.width);
2132 mExistingData = dataSurf;
2136 inline void RecordedDrawTargetCreation::OutputSimpleEventInfo(
2137 std::stringstream& aStringStream) const {
2138 aStringStream << "[" << mRefPtr << "] DrawTarget Creation (Type: "
2139 << NameFromBackend(mBackendType) << ", Size: " << mRect.width
2140 << "x" << mRect.height << ")";
2143 inline bool RecordedDrawTargetDestruction::PlayEvent(
2144 Translator* aTranslator) const {
2145 aTranslator->RemoveDrawTarget(mRefPtr);
2146 return true;
2149 template <class S>
2150 void RecordedDrawTargetDestruction::Record(S& aStream) const {
2151 WriteElement(aStream, mRefPtr);
2154 template <class S>
2155 RecordedDrawTargetDestruction::RecordedDrawTargetDestruction(S& aStream)
2156 : RecordedEventDerived(DRAWTARGETDESTRUCTION) {
2157 ReadElement(aStream, mRefPtr);
2160 inline void RecordedDrawTargetDestruction::OutputSimpleEventInfo(
2161 std::stringstream& aStringStream) const {
2162 aStringStream << "[" << mRefPtr << "] DrawTarget Destruction";
2165 inline bool RecordedSetCurrentDrawTarget::PlayEvent(
2166 Translator* aTranslator) const {
2167 return aTranslator->SetCurrentDrawTarget(mRefPtr);
2170 template <class S>
2171 void RecordedSetCurrentDrawTarget::Record(S& aStream) const {
2172 WriteElement(aStream, mRefPtr);
2175 template <class S>
2176 RecordedSetCurrentDrawTarget::RecordedSetCurrentDrawTarget(S& aStream)
2177 : RecordedEventDerived(SETCURRENTDRAWTARGET) {
2178 ReadElement(aStream, mRefPtr);
2181 inline void RecordedSetCurrentDrawTarget::OutputSimpleEventInfo(
2182 std::stringstream& aStringStream) const {
2183 aStringStream << "[" << mRefPtr << "] SetCurrentDrawTarget";
2186 inline bool RecordedCreateSimilarDrawTarget::PlayEvent(
2187 Translator* aTranslator) const {
2188 DrawTarget* drawTarget = aTranslator->GetCurrentDrawTarget();
2189 if (!drawTarget) {
2190 return false;
2193 RefPtr<DrawTarget> newDT =
2194 drawTarget->CreateSimilarDrawTarget(mSize, mFormat);
2196 // If we couldn't create a DrawTarget this will probably cause us to crash
2197 // with nullptr later in the playback, so return false to abort.
2198 if (!newDT) {
2199 return false;
2202 aTranslator->AddDrawTarget(mRefPtr, newDT);
2203 return true;
2206 template <class S>
2207 void RecordedCreateSimilarDrawTarget::Record(S& aStream) const {
2208 WriteElement(aStream, mRefPtr);
2209 WriteElement(aStream, mSize);
2210 WriteElement(aStream, mFormat);
2213 template <class S>
2214 RecordedCreateSimilarDrawTarget::RecordedCreateSimilarDrawTarget(S& aStream)
2215 : RecordedEventDerived(CREATESIMILARDRAWTARGET) {
2216 ReadElement(aStream, mRefPtr);
2217 ReadElement(aStream, mSize);
2218 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2219 SurfaceFormat::UNKNOWN);
2222 inline void RecordedCreateSimilarDrawTarget::OutputSimpleEventInfo(
2223 std::stringstream& aStringStream) const {
2224 aStringStream << "[" << mRefPtr
2225 << "] CreateSimilarDrawTarget (Size: " << mSize.width << "x"
2226 << mSize.height << ")";
2229 inline bool RecordedCreateDrawTargetForFilter::PlayEvent(
2230 Translator* aTranslator) const {
2231 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2232 if (!dt) {
2233 return false;
2236 IntRect baseRect = dt->GetRect();
2238 auto maxRect = IntRect(IntPoint(0, 0), mMaxSize);
2240 auto clone = dt->GetTransform();
2241 bool invertible = clone.Invert();
2242 // mSourceRect is in filter space. The filter outputs from mSourceRect need
2243 // to be drawn at mDestPoint in user space.
2244 Rect userSpaceSource = Rect(mDestPoint, mSourceRect.Size());
2245 if (invertible) {
2246 // Try to reduce the source rect so that it's not much bigger
2247 // than the draw target. The result is not minimal. Examples
2248 // are left as an exercise for the reader.
2249 auto destRect = IntRectToRect(baseRect);
2250 Rect userSpaceBounds = clone.TransformBounds(destRect);
2251 userSpaceSource = userSpaceSource.Intersect(userSpaceBounds);
2254 // Compute how much we moved the top-left of the source rect by, and use that
2255 // to compute the new dest point, and move our intersected source rect back
2256 // into the (new) filter space.
2257 Point shift = userSpaceSource.TopLeft() - mDestPoint;
2258 Rect filterSpaceSource =
2259 Rect(mSourceRect.TopLeft() + shift, userSpaceSource.Size());
2261 baseRect = RoundedOut(filterSpaceSource);
2262 FilterNode* filter = aTranslator->LookupFilterNode(mFilter);
2263 if (!filter) {
2264 return false;
2267 IntRect transformedRect = filter->MapRectToSource(
2268 baseRect, maxRect, aTranslator->LookupFilterNode(mSource));
2270 // Intersect with maxRect to make sure we didn't end up with something bigger
2271 transformedRect = transformedRect.Intersect(maxRect);
2273 // If we end up with an empty rect make it 1x1 so that things don't break.
2274 if (transformedRect.IsEmpty()) {
2275 transformedRect = IntRect(0, 0, 1, 1);
2278 RefPtr<DrawTarget> newDT =
2279 dt->CreateSimilarDrawTarget(transformedRect.Size(), mFormat);
2280 if (!newDT) {
2281 return false;
2283 newDT =
2284 gfx::Factory::CreateOffsetDrawTarget(newDT, transformedRect.TopLeft());
2286 // If we couldn't create a DrawTarget this will probably cause us to crash
2287 // with nullptr later in the playback, so return false to abort.
2288 if (!newDT) {
2289 return false;
2292 aTranslator->AddDrawTarget(mRefPtr, newDT);
2293 return true;
2296 inline bool RecordedCreateClippedDrawTarget::PlayEvent(
2297 Translator* aTranslator) const {
2298 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2299 if (!dt) {
2300 return false;
2303 RefPtr<DrawTarget> newDT = dt->CreateClippedDrawTarget(mBounds, mFormat);
2305 // If we couldn't create a DrawTarget this will probably cause us to crash
2306 // with nullptr later in the playback, so return false to abort.
2307 if (!newDT) {
2308 return false;
2311 aTranslator->AddDrawTarget(mRefPtr, newDT);
2312 return true;
2315 template <class S>
2316 void RecordedCreateClippedDrawTarget::Record(S& aStream) const {
2317 WriteElement(aStream, mRefPtr);
2318 WriteElement(aStream, mBounds);
2319 WriteElement(aStream, mFormat);
2322 template <class S>
2323 RecordedCreateClippedDrawTarget::RecordedCreateClippedDrawTarget(S& aStream)
2324 : RecordedEventDerived(CREATECLIPPEDDRAWTARGET) {
2325 ReadElement(aStream, mRefPtr);
2326 ReadElement(aStream, mBounds);
2327 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2328 SurfaceFormat::UNKNOWN);
2331 inline void RecordedCreateClippedDrawTarget::OutputSimpleEventInfo(
2332 std::stringstream& aStringStream) const {
2333 aStringStream << "[" << mRefPtr << "] CreateClippedDrawTarget ()";
2336 template <class S>
2337 void RecordedCreateDrawTargetForFilter::Record(S& aStream) const {
2338 WriteElement(aStream, mRefPtr);
2339 WriteElement(aStream, mMaxSize);
2340 WriteElement(aStream, mFormat);
2341 WriteElement(aStream, mFilter);
2342 WriteElement(aStream, mSource);
2343 WriteElement(aStream, mSourceRect);
2344 WriteElement(aStream, mDestPoint);
2347 template <class S>
2348 RecordedCreateDrawTargetForFilter::RecordedCreateDrawTargetForFilter(S& aStream)
2349 : RecordedEventDerived(CREATEDRAWTARGETFORFILTER) {
2350 ReadElement(aStream, mRefPtr);
2351 ReadElement(aStream, mMaxSize);
2352 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2353 SurfaceFormat::UNKNOWN);
2354 ReadElement(aStream, mFilter);
2355 ReadElement(aStream, mSource);
2356 ReadElement(aStream, mSourceRect);
2357 ReadElement(aStream, mDestPoint);
2360 inline void RecordedCreateDrawTargetForFilter::OutputSimpleEventInfo(
2361 std::stringstream& aStringStream) const {
2362 aStringStream << "[" << mRefPtr << "] CreateDrawTargetForFilter ()";
2365 struct GenericPattern {
2366 GenericPattern(const PatternStorage& aStorage, Translator* aTranslator)
2367 : mPattern(nullptr), mTranslator(aTranslator) {
2368 mStorage = const_cast<PatternStorage*>(&aStorage);
2371 ~GenericPattern() {
2372 if (mPattern) {
2373 mPattern->~Pattern();
2377 operator Pattern*() {
2378 switch (mStorage->mType) {
2379 case PatternType::COLOR:
2380 return new (mColPat) ColorPattern(
2381 reinterpret_cast<ColorPatternStorage*>(&mStorage->mStorage)
2382 ->mColor);
2383 case PatternType::SURFACE: {
2384 SurfacePatternStorage* storage =
2385 reinterpret_cast<SurfacePatternStorage*>(&mStorage->mStorage);
2386 mPattern = new (mSurfPat)
2387 SurfacePattern(mTranslator->LookupSourceSurface(storage->mSurface),
2388 storage->mExtend, storage->mMatrix,
2389 storage->mSamplingFilter, storage->mSamplingRect);
2390 return mPattern;
2392 case PatternType::LINEAR_GRADIENT: {
2393 LinearGradientPatternStorage* storage =
2394 reinterpret_cast<LinearGradientPatternStorage*>(
2395 &mStorage->mStorage);
2396 mPattern = new (mLinGradPat) LinearGradientPattern(
2397 storage->mBegin, storage->mEnd,
2398 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2399 : nullptr,
2400 storage->mMatrix);
2401 return mPattern;
2403 case PatternType::RADIAL_GRADIENT: {
2404 RadialGradientPatternStorage* storage =
2405 reinterpret_cast<RadialGradientPatternStorage*>(
2406 &mStorage->mStorage);
2407 mPattern = new (mRadGradPat) RadialGradientPattern(
2408 storage->mCenter1, storage->mCenter2, storage->mRadius1,
2409 storage->mRadius2,
2410 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2411 : nullptr,
2412 storage->mMatrix);
2413 return mPattern;
2415 case PatternType::CONIC_GRADIENT: {
2416 ConicGradientPatternStorage* storage =
2417 reinterpret_cast<ConicGradientPatternStorage*>(&mStorage->mStorage);
2418 mPattern = new (mConGradPat) ConicGradientPattern(
2419 storage->mCenter, storage->mAngle, storage->mStartOffset,
2420 storage->mEndOffset,
2421 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2422 : nullptr,
2423 storage->mMatrix);
2424 return mPattern;
2426 default:
2427 return new (mColPat) ColorPattern(DeviceColor());
2430 return mPattern;
2433 union {
2434 char mColPat[sizeof(ColorPattern)];
2435 char mLinGradPat[sizeof(LinearGradientPattern)];
2436 char mRadGradPat[sizeof(RadialGradientPattern)];
2437 char mConGradPat[sizeof(ConicGradientPattern)];
2438 char mSurfPat[sizeof(SurfacePattern)];
2441 PatternStorage* mStorage;
2442 Pattern* mPattern;
2443 Translator* mTranslator;
2446 inline bool RecordedFillRect::PlayEvent(Translator* aTranslator) const {
2447 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2448 if (!dt) {
2449 return false;
2452 dt->FillRect(mRect, *GenericPattern(mPattern, aTranslator), mOptions);
2453 return true;
2456 template <class S>
2457 void RecordedFillRect::Record(S& aStream) const {
2458 WriteElement(aStream, mRect);
2459 WriteElement(aStream, mOptions);
2460 RecordPatternData(aStream, mPattern);
2463 template <class S>
2464 RecordedFillRect::RecordedFillRect(S& aStream)
2465 : RecordedEventDerived(FILLRECT) {
2466 ReadElement(aStream, mRect);
2467 ReadDrawOptions(aStream, mOptions);
2468 ReadPatternData(aStream, mPattern);
2471 inline void RecordedFillRect::OutputSimpleEventInfo(
2472 std::stringstream& aStringStream) const {
2473 aStringStream << "FillRect (" << mRect.X() << ", " << mRect.Y() << " - "
2474 << mRect.Width() << " x " << mRect.Height() << ") ";
2475 OutputSimplePatternInfo(mPattern, aStringStream);
2478 inline bool RecordedStrokeRect::PlayEvent(Translator* aTranslator) const {
2479 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2480 if (!dt) {
2481 return false;
2484 dt->StrokeRect(mRect, *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2485 mOptions);
2486 return true;
2489 template <class S>
2490 void RecordedStrokeRect::Record(S& aStream) const {
2491 WriteElement(aStream, mRect);
2492 WriteElement(aStream, mOptions);
2493 RecordPatternData(aStream, mPattern);
2494 RecordStrokeOptions(aStream, mStrokeOptions);
2497 template <class S>
2498 RecordedStrokeRect::RecordedStrokeRect(S& aStream)
2499 : RecordedEventDerived(STROKERECT) {
2500 ReadElement(aStream, mRect);
2501 ReadDrawOptions(aStream, mOptions);
2502 ReadPatternData(aStream, mPattern);
2503 ReadStrokeOptions(aStream, mStrokeOptions);
2506 inline void RecordedStrokeRect::OutputSimpleEventInfo(
2507 std::stringstream& aStringStream) const {
2508 aStringStream << "StrokeRect (" << mRect.X() << ", " << mRect.Y() << " - "
2509 << mRect.Width() << " x " << mRect.Height()
2510 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2511 OutputSimplePatternInfo(mPattern, aStringStream);
2514 inline bool RecordedStrokeLine::PlayEvent(Translator* aTranslator) const {
2515 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2516 if (!dt) {
2517 return false;
2520 dt->StrokeLine(mBegin, mEnd, *GenericPattern(mPattern, aTranslator),
2521 mStrokeOptions, mOptions);
2522 return true;
2525 template <class S>
2526 void RecordedStrokeLine::Record(S& aStream) const {
2527 WriteElement(aStream, mBegin);
2528 WriteElement(aStream, mEnd);
2529 WriteElement(aStream, mOptions);
2530 RecordPatternData(aStream, mPattern);
2531 RecordStrokeOptions(aStream, mStrokeOptions);
2534 template <class S>
2535 RecordedStrokeLine::RecordedStrokeLine(S& aStream)
2536 : RecordedEventDerived(STROKELINE) {
2537 ReadElement(aStream, mBegin);
2538 ReadElement(aStream, mEnd);
2539 ReadDrawOptions(aStream, mOptions);
2540 ReadPatternData(aStream, mPattern);
2541 ReadStrokeOptions(aStream, mStrokeOptions);
2544 inline void RecordedStrokeLine::OutputSimpleEventInfo(
2545 std::stringstream& aStringStream) const {
2546 aStringStream << "StrokeLine (" << mBegin.x << ", " << mBegin.y << " - "
2547 << mEnd.x << ", " << mEnd.y
2548 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2549 OutputSimplePatternInfo(mPattern, aStringStream);
2552 inline bool RecordedStrokeCircle::PlayEvent(Translator* aTranslator) const {
2553 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2554 if (!dt) {
2555 return false;
2558 dt->StrokeCircle(mCircle.origin, mCircle.radius,
2559 *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2560 mOptions);
2561 return true;
2564 template <class S>
2565 void RecordedStrokeCircle::Record(S& aStream) const {
2566 WriteElement(aStream, mCircle);
2567 WriteElement(aStream, mOptions);
2568 RecordPatternData(aStream, mPattern);
2569 RecordStrokeOptions(aStream, mStrokeOptions);
2572 template <class S>
2573 RecordedStrokeCircle::RecordedStrokeCircle(S& aStream)
2574 : RecordedEventDerived(STROKECIRCLE) {
2575 ReadElement(aStream, mCircle);
2576 ReadDrawOptions(aStream, mOptions);
2577 ReadPatternData(aStream, mPattern);
2578 ReadStrokeOptions(aStream, mStrokeOptions);
2581 inline void RecordedStrokeCircle::OutputSimpleEventInfo(
2582 std::stringstream& aStringStream) const {
2583 aStringStream << "StrokeCircle (" << mCircle.origin.x << ", "
2584 << mCircle.origin.y << " - " << mCircle.radius
2585 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2586 OutputSimplePatternInfo(mPattern, aStringStream);
2589 inline bool RecordedFill::PlayEvent(Translator* aTranslator) const {
2590 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2591 if (!dt) {
2592 return false;
2595 dt->Fill(aTranslator->LookupPath(mPath),
2596 *GenericPattern(mPattern, aTranslator), mOptions);
2597 return true;
2600 template <class S>
2601 RecordedFill::RecordedFill(S& aStream) : RecordedEventDerived(FILL) {
2602 ReadElement(aStream, mPath);
2603 ReadDrawOptions(aStream, mOptions);
2604 ReadPatternData(aStream, mPattern);
2607 template <class S>
2608 void RecordedFill::Record(S& aStream) const {
2609 WriteElement(aStream, mPath);
2610 WriteElement(aStream, mOptions);
2611 RecordPatternData(aStream, mPattern);
2614 inline void RecordedFill::OutputSimpleEventInfo(
2615 std::stringstream& aStringStream) const {
2616 aStringStream << "Fill (" << mPath << ") ";
2617 OutputSimplePatternInfo(mPattern, aStringStream);
2620 inline bool RecordedFillCircle::PlayEvent(Translator* aTranslator) const {
2621 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2622 if (!dt) {
2623 return false;
2626 dt->FillCircle(mCircle.origin, mCircle.radius,
2627 *GenericPattern(mPattern, aTranslator), mOptions);
2628 return true;
2631 template <class S>
2632 void RecordedFillCircle::Record(S& aStream) const {
2633 WriteElement(aStream, mCircle);
2634 WriteElement(aStream, mOptions);
2635 RecordPatternData(aStream, mPattern);
2638 template <class S>
2639 RecordedFillCircle::RecordedFillCircle(S& aStream)
2640 : RecordedEventDerived(FILLCIRCLE) {
2641 ReadElement(aStream, mCircle);
2642 ReadDrawOptions(aStream, mOptions);
2643 ReadPatternData(aStream, mPattern);
2646 inline void RecordedFillCircle::OutputSimpleEventInfo(
2647 std::stringstream& aStringStream) const {
2648 aStringStream << "FillCircle (" << mCircle.origin.x << ", "
2649 << mCircle.origin.y << " - " << mCircle.radius << ")";
2650 OutputSimplePatternInfo(mPattern, aStringStream);
2653 template <class T>
2654 inline RecordedDrawGlyphs<T>::~RecordedDrawGlyphs() {
2655 delete[] mGlyphs;
2658 template <class T>
2659 inline bool RecordedDrawGlyphs<T>::PlayEvent(Translator* aTranslator) const {
2660 if (mNumGlyphs > 0 && !mGlyphs) {
2661 // Glyph allocation failed
2662 return false;
2665 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2666 if (!dt) {
2667 return false;
2670 ScaledFont* scaledFont = aTranslator->LookupScaledFont(mScaledFont);
2671 if (!scaledFont) {
2672 return false;
2675 GlyphBuffer buffer;
2676 buffer.mGlyphs = mGlyphs;
2677 buffer.mNumGlyphs = mNumGlyphs;
2678 DrawGlyphs(dt, scaledFont, buffer, *GenericPattern(mPattern, aTranslator));
2679 return true;
2682 template <class T>
2683 template <class S>
2684 RecordedDrawGlyphs<T>::RecordedDrawGlyphs(RecordedEvent::EventType aType,
2685 S& aStream)
2686 : RecordedEventDerived<T>(aType) {
2687 ReadElement(aStream, mScaledFont);
2688 ReadDrawOptions(aStream, mOptions);
2689 this->ReadPatternData(aStream, mPattern);
2690 ReadElement(aStream, mNumGlyphs);
2691 if (!aStream.good() || mNumGlyphs <= 0) {
2692 return;
2695 mGlyphs = new (fallible) Glyph[mNumGlyphs];
2696 if (!mGlyphs) {
2697 gfxCriticalNote << "RecordedDrawGlyphs failed to allocate glyphs of size "
2698 << mNumGlyphs;
2699 aStream.SetIsBad();
2700 } else {
2701 aStream.read((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
2705 template <class T>
2706 template <class S>
2707 void RecordedDrawGlyphs<T>::Record(S& aStream) const {
2708 WriteElement(aStream, mScaledFont);
2709 WriteElement(aStream, mOptions);
2710 this->RecordPatternData(aStream, mPattern);
2711 WriteElement(aStream, mNumGlyphs);
2712 aStream.write((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
2715 template <class T>
2716 inline void RecordedDrawGlyphs<T>::OutputSimpleEventInfo(
2717 std::stringstream& aStringStream) const {
2718 aStringStream << this->GetName() << " (" << mScaledFont << ") ";
2719 this->OutputSimplePatternInfo(mPattern, aStringStream);
2722 inline bool RecordedMask::PlayEvent(Translator* aTranslator) const {
2723 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2724 if (!dt) {
2725 return false;
2728 dt->Mask(*GenericPattern(mSource, aTranslator),
2729 *GenericPattern(mMask, aTranslator), mOptions);
2730 return true;
2733 template <class S>
2734 RecordedMask::RecordedMask(S& aStream) : RecordedEventDerived(MASK) {
2735 ReadDrawOptions(aStream, mOptions);
2736 ReadPatternData(aStream, mSource);
2737 ReadPatternData(aStream, mMask);
2740 template <class S>
2741 void RecordedMask::Record(S& aStream) const {
2742 WriteElement(aStream, mOptions);
2743 RecordPatternData(aStream, mSource);
2744 RecordPatternData(aStream, mMask);
2747 inline void RecordedMask::OutputSimpleEventInfo(
2748 std::stringstream& aStringStream) const {
2749 aStringStream << "Mask (Source: ";
2750 OutputSimplePatternInfo(mSource, aStringStream);
2751 aStringStream << " Mask: ";
2752 OutputSimplePatternInfo(mMask, aStringStream);
2755 inline bool RecordedStroke::PlayEvent(Translator* aTranslator) const {
2756 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2757 if (!dt) {
2758 return false;
2761 Path* path = aTranslator->LookupPath(mPath);
2762 if (!path) {
2763 return false;
2766 dt->Stroke(path, *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2767 mOptions);
2768 return true;
2771 template <class S>
2772 void RecordedStroke::Record(S& aStream) const {
2773 WriteElement(aStream, mPath);
2774 WriteElement(aStream, mOptions);
2775 RecordPatternData(aStream, mPattern);
2776 RecordStrokeOptions(aStream, mStrokeOptions);
2779 template <class S>
2780 RecordedStroke::RecordedStroke(S& aStream) : RecordedEventDerived(STROKE) {
2781 ReadElement(aStream, mPath);
2782 ReadDrawOptions(aStream, mOptions);
2783 ReadPatternData(aStream, mPattern);
2784 ReadStrokeOptions(aStream, mStrokeOptions);
2787 inline void RecordedStroke::OutputSimpleEventInfo(
2788 std::stringstream& aStringStream) const {
2789 aStringStream << "Stroke (" << mPath
2790 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2791 OutputSimplePatternInfo(mPattern, aStringStream);
2794 inline bool RecordedClearRect::PlayEvent(Translator* aTranslator) const {
2795 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2796 if (!dt) {
2797 return false;
2800 dt->ClearRect(mRect);
2801 return true;
2804 template <class S>
2805 void RecordedClearRect::Record(S& aStream) const {
2806 WriteElement(aStream, mRect);
2809 template <class S>
2810 RecordedClearRect::RecordedClearRect(S& aStream)
2811 : RecordedEventDerived(CLEARRECT) {
2812 ReadElement(aStream, mRect);
2815 inline void RecordedClearRect::OutputSimpleEventInfo(
2816 std::stringstream& aStringStream) const {
2817 aStringStream << "ClearRect (" << mRect.X() << ", " << mRect.Y() << " - "
2818 << mRect.Width() << " x " << mRect.Height() << ") ";
2821 inline bool RecordedCopySurface::PlayEvent(Translator* aTranslator) const {
2822 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2823 if (!dt) {
2824 return false;
2827 SourceSurface* surface = aTranslator->LookupSourceSurface(mSourceSurface);
2828 if (!surface) {
2829 return false;
2832 dt->CopySurface(surface, mSourceRect, mDest);
2833 return true;
2836 template <class S>
2837 void RecordedCopySurface::Record(S& aStream) const {
2838 WriteElement(aStream, mSourceSurface);
2839 WriteElement(aStream, mSourceRect);
2840 WriteElement(aStream, mDest);
2843 template <class S>
2844 RecordedCopySurface::RecordedCopySurface(S& aStream)
2845 : RecordedEventDerived(COPYSURFACE) {
2846 ReadElement(aStream, mSourceSurface);
2847 ReadElement(aStream, mSourceRect);
2848 ReadElement(aStream, mDest);
2851 inline void RecordedCopySurface::OutputSimpleEventInfo(
2852 std::stringstream& aStringStream) const {
2853 aStringStream << "CopySurface (" << mSourceSurface << ")";
2856 inline bool RecordedPushClip::PlayEvent(Translator* aTranslator) const {
2857 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2858 if (!dt) {
2859 return false;
2862 Path* path = aTranslator->LookupPath(mPath);
2863 if (!path) {
2864 return false;
2867 dt->PushClip(path);
2868 return true;
2871 template <class S>
2872 void RecordedPushClip::Record(S& aStream) const {
2873 WriteElement(aStream, mPath);
2876 template <class S>
2877 RecordedPushClip::RecordedPushClip(S& aStream)
2878 : RecordedEventDerived(PUSHCLIP) {
2879 ReadElement(aStream, mPath);
2882 inline void RecordedPushClip::OutputSimpleEventInfo(
2883 std::stringstream& aStringStream) const {
2884 aStringStream << "PushClip (" << mPath << ") ";
2887 inline bool RecordedPushClipRect::PlayEvent(Translator* aTranslator) const {
2888 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2889 if (!dt) {
2890 return false;
2893 dt->PushClipRect(mRect);
2894 return true;
2897 template <class S>
2898 void RecordedPushClipRect::Record(S& aStream) const {
2899 WriteElement(aStream, mRect);
2902 template <class S>
2903 RecordedPushClipRect::RecordedPushClipRect(S& aStream)
2904 : RecordedEventDerived(PUSHCLIPRECT) {
2905 ReadElement(aStream, mRect);
2908 inline void RecordedPushClipRect::OutputSimpleEventInfo(
2909 std::stringstream& aStringStream) const {
2910 aStringStream << "PushClipRect (" << mRect.X() << ", " << mRect.Y() << " - "
2911 << mRect.Width() << " x " << mRect.Height() << ") ";
2914 inline bool RecordedPopClip::PlayEvent(Translator* aTranslator) const {
2915 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2916 if (!dt) {
2917 return false;
2920 dt->PopClip();
2921 return true;
2924 template <class S>
2925 void RecordedPopClip::Record(S& aStream) const {}
2927 template <class S>
2928 RecordedPopClip::RecordedPopClip(S& aStream) : RecordedEventDerived(POPCLIP) {}
2930 inline void RecordedPopClip::OutputSimpleEventInfo(
2931 std::stringstream& aStringStream) const {
2932 aStringStream << "PopClip";
2935 inline bool RecordedPushLayer::PlayEvent(Translator* aTranslator) const {
2936 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2937 if (!dt) {
2938 return false;
2941 SourceSurface* mask =
2942 mMask ? aTranslator->LookupSourceSurface(mMask) : nullptr;
2943 dt->PushLayer(mOpaque, mOpacity, mask, mMaskTransform, mBounds,
2944 mCopyBackground);
2945 return true;
2948 template <class S>
2949 void RecordedPushLayer::Record(S& aStream) const {
2950 WriteElement(aStream, mOpaque);
2951 WriteElement(aStream, mOpacity);
2952 WriteElement(aStream, mMask);
2953 WriteElement(aStream, mMaskTransform);
2954 WriteElement(aStream, mBounds);
2955 WriteElement(aStream, mCopyBackground);
2958 template <class S>
2959 RecordedPushLayer::RecordedPushLayer(S& aStream)
2960 : RecordedEventDerived(PUSHLAYER) {
2961 ReadElement(aStream, mOpaque);
2962 ReadElement(aStream, mOpacity);
2963 ReadElement(aStream, mMask);
2964 ReadElement(aStream, mMaskTransform);
2965 ReadElement(aStream, mBounds);
2966 ReadElement(aStream, mCopyBackground);
2969 inline void RecordedPushLayer::OutputSimpleEventInfo(
2970 std::stringstream& aStringStream) const {
2971 aStringStream << "PushPLayer (Opaque=" << mOpaque << ", Opacity=" << mOpacity
2972 << ", Mask Ref=" << mMask << ") ";
2975 inline bool RecordedPushLayerWithBlend::PlayEvent(
2976 Translator* aTranslator) const {
2977 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2978 if (!dt) {
2979 return false;
2982 SourceSurface* mask =
2983 mMask ? aTranslator->LookupSourceSurface(mMask) : nullptr;
2984 dt->PushLayerWithBlend(mOpaque, mOpacity, mask, mMaskTransform, mBounds,
2985 mCopyBackground, mCompositionOp);
2986 return true;
2989 template <class S>
2990 void RecordedPushLayerWithBlend::Record(S& aStream) const {
2991 WriteElement(aStream, mOpaque);
2992 WriteElement(aStream, mOpacity);
2993 WriteElement(aStream, mMask);
2994 WriteElement(aStream, mMaskTransform);
2995 WriteElement(aStream, mBounds);
2996 WriteElement(aStream, mCopyBackground);
2997 WriteElement(aStream, mCompositionOp);
3000 template <class S>
3001 RecordedPushLayerWithBlend::RecordedPushLayerWithBlend(S& aStream)
3002 : RecordedEventDerived(PUSHLAYERWITHBLEND) {
3003 ReadElement(aStream, mOpaque);
3004 ReadElement(aStream, mOpacity);
3005 ReadElement(aStream, mMask);
3006 ReadElement(aStream, mMaskTransform);
3007 ReadElement(aStream, mBounds);
3008 ReadElement(aStream, mCopyBackground);
3009 ReadElementConstrained(aStream, mCompositionOp, CompositionOp::OP_OVER,
3010 CompositionOp::OP_COUNT);
3013 inline void RecordedPushLayerWithBlend::OutputSimpleEventInfo(
3014 std::stringstream& aStringStream) const {
3015 aStringStream << "PushLayerWithBlend (Opaque=" << mOpaque
3016 << ", Opacity=" << mOpacity << ", Mask Ref=" << mMask << ") ";
3019 inline bool RecordedPopLayer::PlayEvent(Translator* aTranslator) const {
3020 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3021 if (!dt) {
3022 return false;
3025 dt->PopLayer();
3026 return true;
3029 template <class S>
3030 void RecordedPopLayer::Record(S& aStream) const {}
3032 template <class S>
3033 RecordedPopLayer::RecordedPopLayer(S& aStream)
3034 : RecordedEventDerived(POPLAYER) {}
3036 inline void RecordedPopLayer::OutputSimpleEventInfo(
3037 std::stringstream& aStringStream) const {
3038 aStringStream << "PopLayer";
3041 inline bool RecordedSetPermitSubpixelAA::PlayEvent(
3042 Translator* aTranslator) const {
3043 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3044 if (!dt) {
3045 return false;
3048 dt->SetPermitSubpixelAA(mPermitSubpixelAA);
3049 return true;
3052 template <class S>
3053 void RecordedSetPermitSubpixelAA::Record(S& aStream) const {
3054 WriteElement(aStream, mPermitSubpixelAA);
3057 template <class S>
3058 RecordedSetPermitSubpixelAA::RecordedSetPermitSubpixelAA(S& aStream)
3059 : RecordedEventDerived(SETPERMITSUBPIXELAA) {
3060 ReadElement(aStream, mPermitSubpixelAA);
3063 inline void RecordedSetPermitSubpixelAA::OutputSimpleEventInfo(
3064 std::stringstream& aStringStream) const {
3065 aStringStream << "SetPermitSubpixelAA (" << mPermitSubpixelAA << ")";
3068 inline bool RecordedSetTransform::PlayEvent(Translator* aTranslator) const {
3069 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3070 if (!dt) {
3071 return false;
3074 // If we're drawing to the reference DT, then we need to manually apply
3075 // its initial transform, otherwise we'll just clobber it with only the
3076 // the transform that was visible to the code doing the recording.
3077 if (dt == aTranslator->GetReferenceDrawTarget()) {
3078 dt->SetTransform(mTransform *
3079 aTranslator->GetReferenceDrawTargetTransform());
3080 } else {
3081 dt->SetTransform(mTransform);
3084 return true;
3087 template <class S>
3088 void RecordedSetTransform::Record(S& aStream) const {
3089 WriteElement(aStream, mTransform);
3092 template <class S>
3093 RecordedSetTransform::RecordedSetTransform(S& aStream)
3094 : RecordedEventDerived(SETTRANSFORM) {
3095 ReadElement(aStream, mTransform);
3098 inline void RecordedSetTransform::OutputSimpleEventInfo(
3099 std::stringstream& aStringStream) const {
3100 aStringStream << "SetTransform [ " << mTransform._11 << " " << mTransform._12
3101 << " ; " << mTransform._21 << " " << mTransform._22 << " ; "
3102 << mTransform._31 << " " << mTransform._32 << " ]";
3105 inline bool RecordedDrawSurface::PlayEvent(Translator* aTranslator) const {
3106 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3107 if (!dt) {
3108 return false;
3111 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefSource);
3112 if (!surface) {
3113 return false;
3116 dt->DrawSurface(surface, mDest, mSource, mDSOptions, mOptions);
3117 return true;
3120 template <class S>
3121 void RecordedDrawSurface::Record(S& aStream) const {
3122 WriteElement(aStream, mRefSource);
3123 WriteElement(aStream, mDest);
3124 WriteElement(aStream, mSource);
3125 WriteElement(aStream, mDSOptions);
3126 WriteElement(aStream, mOptions);
3129 template <class S>
3130 RecordedDrawSurface::RecordedDrawSurface(S& aStream)
3131 : RecordedEventDerived(DRAWSURFACE) {
3132 ReadElement(aStream, mRefSource);
3133 ReadElement(aStream, mDest);
3134 ReadElement(aStream, mSource);
3135 ReadDrawSurfaceOptions(aStream, mDSOptions);
3136 ReadDrawOptions(aStream, mOptions);
3139 inline void RecordedDrawSurface::OutputSimpleEventInfo(
3140 std::stringstream& aStringStream) const {
3141 aStringStream << "DrawSurface (" << mRefSource << ")";
3144 inline bool RecordedDrawDependentSurface::PlayEvent(
3145 Translator* aTranslator) const {
3146 aTranslator->DrawDependentSurface(mId, mDest);
3147 return true;
3150 template <class S>
3151 void RecordedDrawDependentSurface::Record(S& aStream) const {
3152 WriteElement(aStream, mId);
3153 WriteElement(aStream, mDest);
3156 template <class S>
3157 RecordedDrawDependentSurface::RecordedDrawDependentSurface(S& aStream)
3158 : RecordedEventDerived(DRAWDEPENDENTSURFACE) {
3159 ReadElement(aStream, mId);
3160 ReadElement(aStream, mDest);
3163 inline void RecordedDrawDependentSurface::OutputSimpleEventInfo(
3164 std::stringstream& aStringStream) const {
3165 aStringStream << "DrawDependentSurface (" << mId << ")";
3168 inline bool RecordedDrawFilter::PlayEvent(Translator* aTranslator) const {
3169 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3170 if (!dt) {
3171 return false;
3174 FilterNode* filter = aTranslator->LookupFilterNode(mNode);
3175 if (!filter) {
3176 return false;
3179 dt->DrawFilter(filter, mSourceRect, mDestPoint, mOptions);
3180 return true;
3183 template <class S>
3184 void RecordedDrawFilter::Record(S& aStream) const {
3185 WriteElement(aStream, mNode);
3186 WriteElement(aStream, mSourceRect);
3187 WriteElement(aStream, mDestPoint);
3188 WriteElement(aStream, mOptions);
3191 template <class S>
3192 RecordedDrawFilter::RecordedDrawFilter(S& aStream)
3193 : RecordedEventDerived(DRAWFILTER) {
3194 ReadElement(aStream, mNode);
3195 ReadElement(aStream, mSourceRect);
3196 ReadElement(aStream, mDestPoint);
3197 ReadDrawOptions(aStream, mOptions);
3200 inline void RecordedDrawFilter::OutputSimpleEventInfo(
3201 std::stringstream& aStringStream) const {
3202 aStringStream << "DrawFilter (" << mNode << ")";
3205 inline bool RecordedDrawSurfaceWithShadow::PlayEvent(
3206 Translator* aTranslator) const {
3207 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3208 if (!dt) {
3209 return false;
3212 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefSource);
3213 if (!surface) {
3214 return false;
3217 dt->DrawSurfaceWithShadow(surface, mDest, mShadow, mOp);
3218 return true;
3221 template <class S>
3222 void RecordedDrawSurfaceWithShadow::Record(S& aStream) const {
3223 WriteElement(aStream, mRefSource);
3224 WriteElement(aStream, mDest);
3225 WriteElement(aStream, mShadow);
3226 WriteElement(aStream, mOp);
3229 template <class S>
3230 RecordedDrawSurfaceWithShadow::RecordedDrawSurfaceWithShadow(S& aStream)
3231 : RecordedEventDerived(DRAWSURFACEWITHSHADOW) {
3232 ReadElement(aStream, mRefSource);
3233 ReadElement(aStream, mDest);
3234 ReadElement(aStream, mShadow);
3235 ReadElementConstrained(aStream, mOp, CompositionOp::OP_OVER,
3236 CompositionOp::OP_COUNT);
3239 inline void RecordedDrawSurfaceWithShadow::OutputSimpleEventInfo(
3240 std::stringstream& aStringStream) const {
3241 aStringStream << "DrawSurfaceWithShadow (" << mRefSource << ") DeviceColor: ("
3242 << mShadow.mColor.r << ", " << mShadow.mColor.g << ", "
3243 << mShadow.mColor.b << ", " << mShadow.mColor.a << ")";
3246 inline bool RecordedDrawShadow::PlayEvent(Translator* aTranslator) const {
3247 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3248 if (!dt) {
3249 return false;
3252 Path* path = aTranslator->LookupPath(mPath);
3253 if (!path) {
3254 return false;
3257 dt->DrawShadow(path, *GenericPattern(mPattern, aTranslator), mShadow,
3258 mOptions, mHasStrokeOptions ? &mStrokeOptions : nullptr);
3259 return true;
3262 template <class S>
3263 void RecordedDrawShadow::Record(S& aStream) const {
3264 WriteElement(aStream, mPath);
3265 RecordPatternData(aStream, mPattern);
3266 WriteElement(aStream, mShadow);
3267 WriteElement(aStream, mOptions);
3268 WriteElement(aStream, mHasStrokeOptions);
3269 if (mHasStrokeOptions) {
3270 RecordStrokeOptions(aStream, mStrokeOptions);
3274 template <class S>
3275 RecordedDrawShadow::RecordedDrawShadow(S& aStream)
3276 : RecordedEventDerived(DRAWSHADOW) {
3277 ReadElement(aStream, mPath);
3278 ReadPatternData(aStream, mPattern);
3279 ReadElement(aStream, mShadow);
3280 ReadDrawOptions(aStream, mOptions);
3281 ReadElement(aStream, mHasStrokeOptions);
3282 if (mHasStrokeOptions) {
3283 ReadStrokeOptions(aStream, mStrokeOptions);
3287 inline void RecordedDrawShadow::OutputSimpleEventInfo(
3288 std::stringstream& aStringStream) const {
3289 aStringStream << "DrawShadow (" << mPath << ") DeviceColor: ("
3290 << mShadow.mColor.r << ", " << mShadow.mColor.g << ", "
3291 << mShadow.mColor.b << ", " << mShadow.mColor.a << ")";
3294 inline RecordedPathCreation::RecordedPathCreation(PathRecording* aPath)
3295 : RecordedEventDerived(PATHCREATION),
3296 mRefPtr(aPath),
3297 mFillRule(aPath->mFillRule),
3298 mPath(aPath) {}
3300 inline bool RecordedPathCreation::PlayEvent(Translator* aTranslator) const {
3301 DrawTarget* drawTarget = aTranslator->GetCurrentDrawTarget();
3302 if (!drawTarget) {
3303 return false;
3306 RefPtr<PathBuilder> builder = drawTarget->CreatePathBuilder(mFillRule);
3307 if (!mPathOps->CheckedStreamToSink(*builder)) {
3308 return false;
3311 RefPtr<Path> path = builder->Finish();
3312 aTranslator->AddPath(mRefPtr, path);
3313 return true;
3316 template <class S>
3317 void RecordedPathCreation::Record(S& aStream) const {
3318 WriteElement(aStream, mRefPtr);
3319 WriteElement(aStream, mFillRule);
3320 mPath->mPathOps.Record(aStream);
3323 template <class S>
3324 RecordedPathCreation::RecordedPathCreation(S& aStream)
3325 : RecordedEventDerived(PATHCREATION) {
3326 ReadElement(aStream, mRefPtr);
3327 ReadElementConstrained(aStream, mFillRule, FillRule::FILL_WINDING,
3328 FillRule::FILL_EVEN_ODD);
3329 mPathOps = MakeUnique<PathOps>(aStream);
3332 inline void RecordedPathCreation::OutputSimpleEventInfo(
3333 std::stringstream& aStringStream) const {
3334 size_t numberOfOps =
3335 mPath ? mPath->mPathOps.NumberOfOps() : mPathOps->NumberOfOps();
3336 aStringStream << "[" << mRefPtr << "] Path created (OpCount: " << numberOfOps
3337 << ")";
3339 inline bool RecordedPathDestruction::PlayEvent(Translator* aTranslator) const {
3340 aTranslator->RemovePath(mRefPtr);
3341 return true;
3344 template <class S>
3345 void RecordedPathDestruction::Record(S& aStream) const {
3346 WriteElement(aStream, mRefPtr);
3349 template <class S>
3350 RecordedPathDestruction::RecordedPathDestruction(S& aStream)
3351 : RecordedEventDerived(PATHDESTRUCTION) {
3352 ReadElement(aStream, mRefPtr);
3355 inline void RecordedPathDestruction::OutputSimpleEventInfo(
3356 std::stringstream& aStringStream) const {
3357 aStringStream << "[" << mRefPtr << "] Path Destroyed";
3360 inline RecordedSourceSurfaceCreation::~RecordedSourceSurfaceCreation() {
3361 if (mDataOwned) {
3362 delete[] mData;
3366 inline bool RecordedSourceSurfaceCreation::PlayEvent(
3367 Translator* aTranslator) const {
3368 if (!mData) {
3369 return false;
3372 RefPtr<SourceSurface> src = Factory::CreateWrappingDataSourceSurface(
3373 mData, mSize.width * BytesPerPixel(mFormat), mSize, mFormat,
3374 [](void* aClosure) { delete[] static_cast<uint8_t*>(aClosure); }, mData);
3375 if (src) {
3376 mDataOwned = false;
3379 aTranslator->AddSourceSurface(mRefPtr, src);
3380 return true;
3383 template <class S>
3384 void RecordedSourceSurfaceCreation::Record(S& aStream) const {
3385 WriteElement(aStream, mRefPtr);
3386 WriteElement(aStream, mSize);
3387 WriteElement(aStream, mFormat);
3388 MOZ_ASSERT(mData);
3389 size_t dataFormatWidth = BytesPerPixel(mFormat) * mSize.width;
3390 const char* endSrc = (const char*)(mData + (mSize.height * mStride));
3391 for (const char* src = (const char*)mData; src < endSrc; src += mStride) {
3392 aStream.write(src, dataFormatWidth);
3396 template <class S>
3397 RecordedSourceSurfaceCreation::RecordedSourceSurfaceCreation(S& aStream)
3398 : RecordedEventDerived(SOURCESURFACECREATION), mDataOwned(true) {
3399 ReadElement(aStream, mRefPtr);
3400 ReadElement(aStream, mSize);
3401 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
3402 SurfaceFormat::UNKNOWN);
3404 if (!Factory::AllowedSurfaceSize(mSize)) {
3405 gfxCriticalNote << "RecordedSourceSurfaceCreation read invalid size "
3406 << mSize;
3407 aStream.SetIsBad();
3410 if (!aStream.good()) {
3411 return;
3414 size_t size = 0;
3415 if (mSize.width >= 0 && mSize.height >= 0) {
3416 size = size_t(mSize.width) * size_t(mSize.height) * BytesPerPixel(mFormat);
3417 mData = new (fallible) uint8_t[size];
3419 if (!mData) {
3420 gfxCriticalNote
3421 << "RecordedSourceSurfaceCreation failed to allocate data of size "
3422 << size;
3423 aStream.SetIsBad();
3424 } else {
3425 aStream.read((char*)mData, size);
3429 inline void RecordedSourceSurfaceCreation::OutputSimpleEventInfo(
3430 std::stringstream& aStringStream) const {
3431 aStringStream << "[" << mRefPtr
3432 << "] SourceSurface created (Size: " << mSize.width << "x"
3433 << mSize.height << ")";
3436 inline bool RecordedSourceSurfaceDestruction::PlayEvent(
3437 Translator* aTranslator) const {
3438 aTranslator->RemoveSourceSurface(mRefPtr);
3439 return true;
3442 template <class S>
3443 void RecordedSourceSurfaceDestruction::Record(S& aStream) const {
3444 WriteElement(aStream, mRefPtr);
3447 template <class S>
3448 RecordedSourceSurfaceDestruction::RecordedSourceSurfaceDestruction(S& aStream)
3449 : RecordedEventDerived(SOURCESURFACEDESTRUCTION) {
3450 ReadElement(aStream, mRefPtr);
3453 inline void RecordedSourceSurfaceDestruction::OutputSimpleEventInfo(
3454 std::stringstream& aStringStream) const {
3455 aStringStream << "[" << mRefPtr << "] SourceSurface Destroyed";
3458 inline bool RecordedOptimizeSourceSurface::PlayEvent(
3459 Translator* aTranslator) const {
3460 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3461 if (!dt) {
3462 return false;
3465 SourceSurface* surface = aTranslator->LookupSourceSurface(mSurface);
3466 if (!surface) {
3467 return false;
3470 RefPtr<SourceSurface> optimizedSurface = dt->OptimizeSourceSurface(surface);
3471 aTranslator->AddSourceSurface(mOptimizedSurface, optimizedSurface);
3472 return true;
3475 template <class S>
3476 void RecordedOptimizeSourceSurface::Record(S& aStream) const {
3477 WriteElement(aStream, mSurface);
3478 WriteElement(aStream, mOptimizedSurface);
3481 template <class S>
3482 RecordedOptimizeSourceSurface::RecordedOptimizeSourceSurface(S& aStream)
3483 : RecordedEventDerived(OPTIMIZESOURCESURFACE) {
3484 ReadElement(aStream, mSurface);
3485 ReadElement(aStream, mOptimizedSurface);
3488 inline void RecordedOptimizeSourceSurface::OutputSimpleEventInfo(
3489 std::stringstream& aStringStream) const {
3490 aStringStream << "[" << mSurface << "] Surface Optimized";
3493 inline bool RecordedExternalSurfaceCreation::PlayEvent(
3494 Translator* aTranslator) const {
3495 RefPtr<SourceSurface> surface = aTranslator->LookupExternalSurface(mKey);
3496 if (!surface) {
3497 return false;
3500 aTranslator->AddSourceSurface(mRefPtr, surface);
3501 return true;
3504 template <class S>
3505 void RecordedExternalSurfaceCreation::Record(S& aStream) const {
3506 WriteElement(aStream, mRefPtr);
3507 WriteElement(aStream, mKey);
3510 template <class S>
3511 RecordedExternalSurfaceCreation::RecordedExternalSurfaceCreation(S& aStream)
3512 : RecordedEventDerived(EXTERNALSURFACECREATION) {
3513 ReadElement(aStream, mRefPtr);
3514 ReadElement(aStream, mKey);
3517 inline void RecordedExternalSurfaceCreation::OutputSimpleEventInfo(
3518 std::stringstream& aStringStream) const {
3519 aStringStream << "[" << mRefPtr
3520 << "] SourceSurfaceSharedData created (Key: " << mKey << ")";
3523 inline RecordedFilterNodeCreation::~RecordedFilterNodeCreation() = default;
3525 inline bool RecordedFilterNodeCreation::PlayEvent(
3526 Translator* aTranslator) const {
3527 DrawTarget* drawTarget = aTranslator->GetCurrentDrawTarget();
3528 if (!drawTarget) {
3529 return false;
3532 RefPtr<FilterNode> node = drawTarget->CreateFilter(mType);
3533 aTranslator->AddFilterNode(mRefPtr, node);
3534 return true;
3537 template <class S>
3538 void RecordedFilterNodeCreation::Record(S& aStream) const {
3539 WriteElement(aStream, mRefPtr);
3540 WriteElement(aStream, mType);
3543 template <class S>
3544 RecordedFilterNodeCreation::RecordedFilterNodeCreation(S& aStream)
3545 : RecordedEventDerived(FILTERNODECREATION) {
3546 ReadElement(aStream, mRefPtr);
3547 ReadElementConstrained(aStream, mType, FilterType::BLEND,
3548 FilterType::OPACITY);
3551 inline void RecordedFilterNodeCreation::OutputSimpleEventInfo(
3552 std::stringstream& aStringStream) const {
3553 aStringStream << "CreateFilter [" << mRefPtr
3554 << "] FilterNode created (Type: " << int(mType) << ")";
3557 inline bool RecordedFilterNodeDestruction::PlayEvent(
3558 Translator* aTranslator) const {
3559 aTranslator->RemoveFilterNode(mRefPtr);
3560 return true;
3563 template <class S>
3564 void RecordedFilterNodeDestruction::Record(S& aStream) const {
3565 WriteElement(aStream, mRefPtr);
3568 template <class S>
3569 RecordedFilterNodeDestruction::RecordedFilterNodeDestruction(S& aStream)
3570 : RecordedEventDerived(FILTERNODEDESTRUCTION) {
3571 ReadElement(aStream, mRefPtr);
3574 inline void RecordedFilterNodeDestruction::OutputSimpleEventInfo(
3575 std::stringstream& aStringStream) const {
3576 aStringStream << "[" << mRefPtr << "] FilterNode Destroyed";
3579 inline RecordedGradientStopsCreation::~RecordedGradientStopsCreation() {
3580 if (mDataOwned) {
3581 delete[] mStops;
3585 inline bool RecordedGradientStopsCreation::PlayEvent(
3586 Translator* aTranslator) const {
3587 if (mNumStops > 0 && !mStops) {
3588 // Stops allocation failed
3589 return false;
3592 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3593 if (!dt) {
3594 return false;
3597 RefPtr<GradientStops> src =
3598 aTranslator->GetOrCreateGradientStops(dt, mStops, mNumStops, mExtendMode);
3599 aTranslator->AddGradientStops(mRefPtr, src);
3600 return true;
3603 template <class S>
3604 void RecordedGradientStopsCreation::Record(S& aStream) const {
3605 WriteElement(aStream, mRefPtr);
3606 WriteElement(aStream, mExtendMode);
3607 WriteElement(aStream, mNumStops);
3608 aStream.write((const char*)mStops, mNumStops * sizeof(GradientStop));
3611 template <class S>
3612 RecordedGradientStopsCreation::RecordedGradientStopsCreation(S& aStream)
3613 : RecordedEventDerived(GRADIENTSTOPSCREATION), mDataOwned(true) {
3614 ReadElement(aStream, mRefPtr);
3615 ReadElementConstrained(aStream, mExtendMode, ExtendMode::CLAMP,
3616 ExtendMode::REFLECT);
3617 ReadElement(aStream, mNumStops);
3618 if (!aStream.good() || mNumStops <= 0) {
3619 return;
3622 mStops = new (fallible) GradientStop[mNumStops];
3623 if (!mStops) {
3624 gfxCriticalNote
3625 << "RecordedGradientStopsCreation failed to allocate stops of size "
3626 << mNumStops;
3627 aStream.SetIsBad();
3628 } else {
3629 aStream.read((char*)mStops, mNumStops * sizeof(GradientStop));
3633 inline void RecordedGradientStopsCreation::OutputSimpleEventInfo(
3634 std::stringstream& aStringStream) const {
3635 aStringStream << "[" << mRefPtr
3636 << "] GradientStops created (Stops: " << mNumStops << ")";
3639 inline bool RecordedGradientStopsDestruction::PlayEvent(
3640 Translator* aTranslator) const {
3641 aTranslator->RemoveGradientStops(mRefPtr);
3642 return true;
3645 template <class S>
3646 void RecordedGradientStopsDestruction::Record(S& aStream) const {
3647 WriteElement(aStream, mRefPtr);
3650 template <class S>
3651 RecordedGradientStopsDestruction::RecordedGradientStopsDestruction(S& aStream)
3652 : RecordedEventDerived(GRADIENTSTOPSDESTRUCTION) {
3653 ReadElement(aStream, mRefPtr);
3656 inline void RecordedGradientStopsDestruction::OutputSimpleEventInfo(
3657 std::stringstream& aStringStream) const {
3658 aStringStream << "[" << mRefPtr << "] GradientStops Destroyed";
3661 inline bool RecordedIntoLuminanceSource::PlayEvent(
3662 Translator* aTranslator) const {
3663 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3664 if (!dt) {
3665 return false;
3668 RefPtr<SourceSurface> src = dt->IntoLuminanceSource(mLuminanceType, mOpacity);
3669 aTranslator->AddSourceSurface(mRefPtr, src);
3670 return true;
3673 template <class S>
3674 void RecordedIntoLuminanceSource::Record(S& aStream) const {
3675 WriteElement(aStream, mRefPtr);
3676 WriteElement(aStream, mLuminanceType);
3677 WriteElement(aStream, mOpacity);
3680 template <class S>
3681 RecordedIntoLuminanceSource::RecordedIntoLuminanceSource(S& aStream)
3682 : RecordedEventDerived(INTOLUMINANCE) {
3683 ReadElement(aStream, mRefPtr);
3684 ReadElementConstrained(aStream, mLuminanceType, LuminanceType::LUMINANCE,
3685 LuminanceType::LINEARRGB);
3686 ReadElement(aStream, mOpacity);
3689 inline void RecordedIntoLuminanceSource::OutputSimpleEventInfo(
3690 std::stringstream& aStringStream) const {
3691 aStringStream << "[" << mRefPtr << "] Into Luminance Source";
3694 inline bool RecordedExtractSubrect::PlayEvent(Translator* aTranslator) const {
3695 SourceSurface* sourceSurf = aTranslator->LookupSourceSurface(mSourceSurface);
3696 if (!sourceSurf) {
3697 return false;
3700 RefPtr<SourceSurface> subSurf = sourceSurf->ExtractSubrect(mSubrect);
3701 if (!subSurf) {
3702 RefPtr<DrawTarget> dt =
3703 aTranslator->GetReferenceDrawTarget()->CreateSimilarDrawTarget(
3704 mSubrect.Size(), sourceSurf->GetFormat());
3705 if (dt) {
3706 dt->CopySurface(sourceSurf, mSubrect, IntPoint());
3707 subSurf = dt->Snapshot();
3710 if (!subSurf) {
3711 return false;
3714 aTranslator->AddSourceSurface(mRefPtr, subSurf);
3715 return true;
3718 template <class S>
3719 void RecordedExtractSubrect::Record(S& aStream) const {
3720 WriteElement(aStream, mRefPtr);
3721 WriteElement(aStream, mSourceSurface);
3722 WriteElement(aStream, mSubrect);
3725 template <class S>
3726 RecordedExtractSubrect::RecordedExtractSubrect(S& aStream)
3727 : RecordedEventDerived(EXTRACTSUBRECT) {
3728 ReadElement(aStream, mRefPtr);
3729 ReadElement(aStream, mSourceSurface);
3730 ReadElement(aStream, mSubrect);
3733 inline void RecordedExtractSubrect::OutputSimpleEventInfo(
3734 std::stringstream& aStringStream) const {
3735 aStringStream << "[" << mRefPtr << "] Exract Subrect";
3738 inline bool RecordedFlush::PlayEvent(Translator* aTranslator) const {
3739 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3740 if (!dt) {
3741 return false;
3744 dt->Flush();
3745 return true;
3748 template <class S>
3749 void RecordedFlush::Record(S& aStream) const {}
3751 template <class S>
3752 RecordedFlush::RecordedFlush(S& aStream) : RecordedEventDerived(FLUSH) {}
3754 inline void RecordedFlush::OutputSimpleEventInfo(
3755 std::stringstream& aStringStream) const {
3756 aStringStream << "Flush";
3759 inline bool RecordedDetachAllSnapshots::PlayEvent(
3760 Translator* aTranslator) const {
3761 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3762 if (!dt) {
3763 return false;
3766 dt->DetachAllSnapshots();
3767 return true;
3770 template <class S>
3771 void RecordedDetachAllSnapshots::Record(S& aStream) const {}
3773 template <class S>
3774 RecordedDetachAllSnapshots::RecordedDetachAllSnapshots(S& aStream)
3775 : RecordedEventDerived(DETACHALLSNAPSHOTS) {}
3777 inline void RecordedDetachAllSnapshots::OutputSimpleEventInfo(
3778 std::stringstream& aStringStream) const {
3779 aStringStream << "DetachAllSnapshots";
3782 inline bool RecordedSnapshot::PlayEvent(Translator* aTranslator) const {
3783 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3784 if (!dt) {
3785 return false;
3788 RefPtr<SourceSurface> src = dt->Snapshot();
3789 aTranslator->AddSourceSurface(mRefPtr, src);
3790 return true;
3793 template <class S>
3794 void RecordedSnapshot::Record(S& aStream) const {
3795 WriteElement(aStream, mRefPtr);
3798 template <class S>
3799 RecordedSnapshot::RecordedSnapshot(S& aStream)
3800 : RecordedEventDerived(SNAPSHOT) {
3801 ReadElement(aStream, mRefPtr);
3804 inline void RecordedSnapshot::OutputSimpleEventInfo(
3805 std::stringstream& aStringStream) const {
3806 aStringStream << "[" << mRefPtr << "] Snapshot Created";
3809 inline RecordedFontData::~RecordedFontData() { delete[] mData; }
3811 inline bool RecordedFontData::PlayEvent(Translator* aTranslator) const {
3812 if (!mData) {
3813 return false;
3816 RefPtr<NativeFontResource> fontResource = Factory::CreateNativeFontResource(
3817 mData, mFontDetails.size, mType, aTranslator->GetFontContext());
3818 if (!fontResource) {
3819 return false;
3822 aTranslator->AddNativeFontResource(mFontDetails.fontDataKey, fontResource);
3823 return true;
3826 template <class S>
3827 void RecordedFontData::Record(S& aStream) const {
3828 MOZ_ASSERT(mGetFontFileDataSucceeded);
3830 WriteElement(aStream, mType);
3831 WriteElement(aStream, mFontDetails.fontDataKey);
3832 if (!mData) {
3833 WriteElement(aStream, 0);
3834 } else {
3835 WriteElement(aStream, mFontDetails.size);
3836 aStream.write((const char*)mData, mFontDetails.size);
3840 inline void RecordedFontData::OutputSimpleEventInfo(
3841 std::stringstream& aStringStream) const {
3842 aStringStream << "Font Data of size " << mFontDetails.size;
3845 inline void RecordedFontData::SetFontData(const uint8_t* aData, uint32_t aSize,
3846 uint32_t aIndex) {
3847 mData = new (fallible) uint8_t[aSize];
3848 if (!mData) {
3849 gfxCriticalNote
3850 << "RecordedFontData failed to allocate data for recording of size "
3851 << aSize;
3852 } else {
3853 memcpy(mData, aData, aSize);
3855 mFontDetails.fontDataKey = SFNTData::GetUniqueKey(aData, aSize, 0, nullptr);
3856 mFontDetails.size = aSize;
3857 mFontDetails.index = aIndex;
3860 inline bool RecordedFontData::GetFontDetails(RecordedFontDetails& fontDetails) {
3861 if (!mGetFontFileDataSucceeded) {
3862 return false;
3865 fontDetails.fontDataKey = mFontDetails.fontDataKey;
3866 fontDetails.size = mFontDetails.size;
3867 fontDetails.index = mFontDetails.index;
3868 return true;
3871 template <class S>
3872 RecordedFontData::RecordedFontData(S& aStream)
3873 : RecordedEventDerived(FONTDATA), mType(FontType::UNKNOWN) {
3874 ReadElementConstrained(aStream, mType, FontType::DWRITE, FontType::UNKNOWN);
3875 ReadElement(aStream, mFontDetails.fontDataKey);
3876 ReadElement(aStream, mFontDetails.size);
3877 if (!mFontDetails.size || !aStream.good()) {
3878 return;
3881 mData = new (fallible) uint8_t[mFontDetails.size];
3882 if (!mData) {
3883 gfxCriticalNote
3884 << "RecordedFontData failed to allocate data for playback of size "
3885 << mFontDetails.size;
3886 aStream.SetIsBad();
3887 } else {
3888 aStream.read((char*)mData, mFontDetails.size);
3892 inline RecordedFontDescriptor::~RecordedFontDescriptor() = default;
3894 inline bool RecordedFontDescriptor::PlayEvent(Translator* aTranslator) const {
3895 RefPtr<UnscaledFont> font = Factory::CreateUnscaledFontFromFontDescriptor(
3896 mType, mData.data(), mData.size(), mIndex);
3897 if (!font) {
3898 gfxDevCrash(LogReason::InvalidFont)
3899 << "Failed creating UnscaledFont of type " << int(mType)
3900 << " from font descriptor";
3901 return false;
3904 aTranslator->AddUnscaledFont(mRefPtr, font);
3905 return true;
3908 template <class S>
3909 void RecordedFontDescriptor::Record(S& aStream) const {
3910 MOZ_ASSERT(mHasDesc);
3911 WriteElement(aStream, mType);
3912 WriteElement(aStream, mRefPtr);
3913 WriteElement(aStream, mIndex);
3914 WriteElement(aStream, (size_t)mData.size());
3915 if (mData.size()) {
3916 aStream.write((char*)mData.data(), mData.size());
3920 inline void RecordedFontDescriptor::OutputSimpleEventInfo(
3921 std::stringstream& aStringStream) const {
3922 aStringStream << "[" << mRefPtr << "] Font Descriptor";
3925 inline void RecordedFontDescriptor::SetFontDescriptor(const uint8_t* aData,
3926 uint32_t aSize,
3927 uint32_t aIndex) {
3928 mData.assign(aData, aData + aSize);
3929 mIndex = aIndex;
3932 template <class S>
3933 RecordedFontDescriptor::RecordedFontDescriptor(S& aStream)
3934 : RecordedEventDerived(FONTDESC) {
3935 ReadElementConstrained(aStream, mType, FontType::DWRITE, FontType::UNKNOWN);
3936 ReadElement(aStream, mRefPtr);
3937 ReadElement(aStream, mIndex);
3939 size_t size;
3940 ReadElement(aStream, size);
3941 if (!aStream.good()) {
3942 return;
3944 if (size) {
3945 mData.resize(size);
3946 aStream.read((char*)mData.data(), size);
3950 inline bool RecordedUnscaledFontCreation::PlayEvent(
3951 Translator* aTranslator) const {
3952 NativeFontResource* fontResource =
3953 aTranslator->LookupNativeFontResource(mFontDataKey);
3954 if (!fontResource) {
3955 gfxDevCrash(LogReason::NativeFontResourceNotFound)
3956 << "NativeFontResource lookup failed for key |" << hexa(mFontDataKey)
3957 << "|.";
3958 return false;
3961 RefPtr<UnscaledFont> unscaledFont = fontResource->CreateUnscaledFont(
3962 mIndex, mInstanceData.data(), mInstanceData.size());
3963 aTranslator->AddUnscaledFont(mRefPtr, unscaledFont);
3964 return true;
3967 template <class S>
3968 void RecordedUnscaledFontCreation::Record(S& aStream) const {
3969 WriteElement(aStream, mRefPtr);
3970 WriteElement(aStream, mFontDataKey);
3971 WriteElement(aStream, mIndex);
3972 WriteElement(aStream, (size_t)mInstanceData.size());
3973 if (mInstanceData.size()) {
3974 aStream.write((char*)mInstanceData.data(), mInstanceData.size());
3978 inline void RecordedUnscaledFontCreation::OutputSimpleEventInfo(
3979 std::stringstream& aStringStream) const {
3980 aStringStream << "[" << mRefPtr << "] UnscaledFont Created";
3983 inline void RecordedUnscaledFontCreation::SetFontInstanceData(
3984 const uint8_t* aData, uint32_t aSize) {
3985 if (aSize) {
3986 mInstanceData.assign(aData, aData + aSize);
3990 template <class S>
3991 RecordedUnscaledFontCreation::RecordedUnscaledFontCreation(S& aStream)
3992 : RecordedEventDerived(UNSCALEDFONTCREATION) {
3993 ReadElement(aStream, mRefPtr);
3994 ReadElement(aStream, mFontDataKey);
3995 ReadElement(aStream, mIndex);
3997 size_t size;
3998 ReadElement(aStream, size);
3999 if (!aStream.good()) {
4000 return;
4002 if (size) {
4003 mInstanceData.resize(size);
4004 aStream.read((char*)mInstanceData.data(), size);
4008 inline bool RecordedUnscaledFontDestruction::PlayEvent(
4009 Translator* aTranslator) const {
4010 aTranslator->RemoveUnscaledFont(mRefPtr);
4011 return true;
4014 template <class S>
4015 void RecordedUnscaledFontDestruction::Record(S& aStream) const {
4016 WriteElement(aStream, mRefPtr);
4019 template <class S>
4020 RecordedUnscaledFontDestruction::RecordedUnscaledFontDestruction(S& aStream)
4021 : RecordedEventDerived(UNSCALEDFONTDESTRUCTION) {
4022 ReadElement(aStream, mRefPtr);
4025 inline void RecordedUnscaledFontDestruction::OutputSimpleEventInfo(
4026 std::stringstream& aStringStream) const {
4027 aStringStream << "[" << mRefPtr << "] UnscaledFont Destroyed";
4030 inline bool RecordedScaledFontCreation::PlayEvent(
4031 Translator* aTranslator) const {
4032 UnscaledFont* unscaledFont = aTranslator->LookupUnscaledFont(mUnscaledFont);
4033 if (!unscaledFont) {
4034 gfxDevCrash(LogReason::UnscaledFontNotFound)
4035 << "UnscaledFont lookup failed for key |" << hexa(mUnscaledFont)
4036 << "|.";
4037 return false;
4040 RefPtr<ScaledFont> scaledFont = unscaledFont->CreateScaledFont(
4041 mGlyphSize, mInstanceData.data(), mInstanceData.size(),
4042 mVariations.data(), mVariations.size());
4044 aTranslator->AddScaledFont(mRefPtr, scaledFont);
4045 return true;
4048 template <class S>
4049 void RecordedScaledFontCreation::Record(S& aStream) const {
4050 WriteElement(aStream, mRefPtr);
4051 WriteElement(aStream, mUnscaledFont);
4052 WriteElement(aStream, mGlyphSize);
4053 WriteElement(aStream, (size_t)mInstanceData.size());
4054 if (mInstanceData.size()) {
4055 aStream.write((char*)mInstanceData.data(), mInstanceData.size());
4057 WriteElement(aStream, (size_t)mVariations.size());
4058 if (mVariations.size()) {
4059 aStream.write((char*)mVariations.data(),
4060 sizeof(FontVariation) * mVariations.size());
4064 inline void RecordedScaledFontCreation::OutputSimpleEventInfo(
4065 std::stringstream& aStringStream) const {
4066 aStringStream << "[" << mRefPtr << "] ScaledFont Created";
4069 inline void RecordedScaledFontCreation::SetFontInstanceData(
4070 const uint8_t* aData, uint32_t aSize, const FontVariation* aVariations,
4071 uint32_t aNumVariations) {
4072 if (aSize) {
4073 mInstanceData.assign(aData, aData + aSize);
4075 if (aNumVariations) {
4076 mVariations.assign(aVariations, aVariations + aNumVariations);
4080 template <class S>
4081 RecordedScaledFontCreation::RecordedScaledFontCreation(S& aStream)
4082 : RecordedEventDerived(SCALEDFONTCREATION) {
4083 ReadElement(aStream, mRefPtr);
4084 ReadElement(aStream, mUnscaledFont);
4085 ReadElement(aStream, mGlyphSize);
4087 size_t size;
4088 ReadElement(aStream, size);
4089 if (!aStream.good()) {
4090 return;
4092 if (size) {
4093 mInstanceData.resize(size);
4094 aStream.read((char*)mInstanceData.data(), size);
4097 size_t numVariations;
4098 ReadElement(aStream, numVariations);
4099 if (!aStream.good()) {
4100 return;
4102 if (numVariations) {
4103 mVariations.resize(numVariations);
4104 aStream.read((char*)mVariations.data(),
4105 sizeof(FontVariation) * numVariations);
4109 inline bool RecordedScaledFontDestruction::PlayEvent(
4110 Translator* aTranslator) const {
4111 aTranslator->RemoveScaledFont(mRefPtr);
4112 return true;
4115 template <class S>
4116 void RecordedScaledFontDestruction::Record(S& aStream) const {
4117 WriteElement(aStream, mRefPtr);
4120 template <class S>
4121 RecordedScaledFontDestruction::RecordedScaledFontDestruction(S& aStream)
4122 : RecordedEventDerived(SCALEDFONTDESTRUCTION) {
4123 ReadElement(aStream, mRefPtr);
4126 inline void RecordedScaledFontDestruction::OutputSimpleEventInfo(
4127 std::stringstream& aStringStream) const {
4128 aStringStream << "[" << mRefPtr << "] ScaledFont Destroyed";
4131 inline bool RecordedMaskSurface::PlayEvent(Translator* aTranslator) const {
4132 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
4133 if (!dt) {
4134 return false;
4137 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefMask);
4138 if (!surface) {
4139 return false;
4142 dt->MaskSurface(*GenericPattern(mPattern, aTranslator), surface, mOffset,
4143 mOptions);
4144 return true;
4147 template <class S>
4148 void RecordedMaskSurface::Record(S& aStream) const {
4149 RecordPatternData(aStream, mPattern);
4150 WriteElement(aStream, mRefMask);
4151 WriteElement(aStream, mOffset);
4152 WriteElement(aStream, mOptions);
4155 template <class S>
4156 RecordedMaskSurface::RecordedMaskSurface(S& aStream)
4157 : RecordedEventDerived(MASKSURFACE) {
4158 ReadPatternData(aStream, mPattern);
4159 ReadElement(aStream, mRefMask);
4160 ReadElement(aStream, mOffset);
4161 ReadDrawOptions(aStream, mOptions);
4164 inline void RecordedMaskSurface::OutputSimpleEventInfo(
4165 std::stringstream& aStringStream) const {
4166 aStringStream << "MaskSurface (" << mRefMask << ") Offset: (" << mOffset.x
4167 << "x" << mOffset.y << ") Pattern: ";
4168 OutputSimplePatternInfo(mPattern, aStringStream);
4171 template <typename T>
4172 void ReplaySetAttribute(FilterNode* aNode, uint32_t aIndex, T aValue) {
4173 aNode->SetAttribute(aIndex, aValue);
4176 inline bool RecordedFilterNodeSetAttribute::PlayEvent(
4177 Translator* aTranslator) const {
4178 FilterNode* node = aTranslator->LookupFilterNode(mNode);
4179 if (!node) {
4180 return false;
4183 #define REPLAY_SET_ATTRIBUTE(type, argtype) \
4184 case ARGTYPE_##argtype: \
4185 ReplaySetAttribute(node, mIndex, *(type*)&mPayload.front()); \
4186 break
4188 switch (mArgType) {
4189 REPLAY_SET_ATTRIBUTE(bool, BOOL);
4190 REPLAY_SET_ATTRIBUTE(uint32_t, UINT32);
4191 REPLAY_SET_ATTRIBUTE(Float, FLOAT);
4192 REPLAY_SET_ATTRIBUTE(Size, SIZE);
4193 REPLAY_SET_ATTRIBUTE(IntSize, INTSIZE);
4194 REPLAY_SET_ATTRIBUTE(IntPoint, INTPOINT);
4195 REPLAY_SET_ATTRIBUTE(Rect, RECT);
4196 REPLAY_SET_ATTRIBUTE(IntRect, INTRECT);
4197 REPLAY_SET_ATTRIBUTE(Point, POINT);
4198 REPLAY_SET_ATTRIBUTE(Matrix, MATRIX);
4199 REPLAY_SET_ATTRIBUTE(Matrix5x4, MATRIX5X4);
4200 REPLAY_SET_ATTRIBUTE(Point3D, POINT3D);
4201 REPLAY_SET_ATTRIBUTE(DeviceColor, COLOR);
4202 case ARGTYPE_FLOAT_ARRAY:
4203 node->SetAttribute(mIndex,
4204 reinterpret_cast<const Float*>(&mPayload.front()),
4205 mPayload.size() / sizeof(Float));
4206 break;
4209 return true;
4212 template <class S>
4213 void RecordedFilterNodeSetAttribute::Record(S& aStream) const {
4214 WriteElement(aStream, mNode);
4215 WriteElement(aStream, mIndex);
4216 WriteElement(aStream, mArgType);
4217 WriteElement(aStream, uint64_t(mPayload.size()));
4218 aStream.write((const char*)&mPayload.front(), mPayload.size());
4221 template <class S>
4222 RecordedFilterNodeSetAttribute::RecordedFilterNodeSetAttribute(S& aStream)
4223 : RecordedEventDerived(FILTERNODESETATTRIBUTE) {
4224 ReadElement(aStream, mNode);
4225 ReadElement(aStream, mIndex);
4226 ReadElementConstrained(aStream, mArgType, ArgType::ARGTYPE_UINT32,
4227 ArgType::ARGTYPE_FLOAT_ARRAY);
4228 uint64_t size;
4229 ReadElement(aStream, size);
4230 if (!aStream.good()) {
4231 return;
4234 mPayload.resize(size_t(size));
4235 aStream.read((char*)&mPayload.front(), size);
4238 inline void RecordedFilterNodeSetAttribute::OutputSimpleEventInfo(
4239 std::stringstream& aStringStream) const {
4240 aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ")";
4243 inline bool RecordedFilterNodeSetInput::PlayEvent(
4244 Translator* aTranslator) const {
4245 FilterNode* node = aTranslator->LookupFilterNode(mNode);
4246 if (!node) {
4247 return false;
4250 if (mInputFilter) {
4251 node->SetInput(mIndex, aTranslator->LookupFilterNode(mInputFilter));
4252 } else {
4253 node->SetInput(mIndex, aTranslator->LookupSourceSurface(mInputSurface));
4256 return true;
4259 template <class S>
4260 void RecordedFilterNodeSetInput::Record(S& aStream) const {
4261 WriteElement(aStream, mNode);
4262 WriteElement(aStream, mIndex);
4263 WriteElement(aStream, mInputFilter);
4264 WriteElement(aStream, mInputSurface);
4267 template <class S>
4268 RecordedFilterNodeSetInput::RecordedFilterNodeSetInput(S& aStream)
4269 : RecordedEventDerived(FILTERNODESETINPUT) {
4270 ReadElement(aStream, mNode);
4271 ReadElement(aStream, mIndex);
4272 ReadElement(aStream, mInputFilter);
4273 ReadElement(aStream, mInputSurface);
4276 inline void RecordedFilterNodeSetInput::OutputSimpleEventInfo(
4277 std::stringstream& aStringStream) const {
4278 aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ", ";
4280 if (mInputFilter) {
4281 aStringStream << "Filter: " << mInputFilter;
4282 } else {
4283 aStringStream << "Surface: " << mInputSurface;
4286 aStringStream << ")";
4289 inline bool RecordedLink::PlayEvent(Translator* aTranslator) const {
4290 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
4291 if (!dt) {
4292 return false;
4294 dt->Link(mDestination.c_str(), mRect);
4295 return true;
4298 template <class S>
4299 void RecordedLink::Record(S& aStream) const {
4300 WriteElement(aStream, mRect);
4301 uint32_t len = mDestination.length();
4302 WriteElement(aStream, len);
4303 if (len) {
4304 aStream.write(mDestination.data(), len);
4308 template <class S>
4309 RecordedLink::RecordedLink(S& aStream) : RecordedEventDerived(LINK) {
4310 ReadElement(aStream, mRect);
4311 uint32_t len;
4312 ReadElement(aStream, len);
4313 mDestination.resize(size_t(len));
4314 if (len && aStream.good()) {
4315 aStream.read(&mDestination.front(), len);
4319 inline void RecordedLink::OutputSimpleEventInfo(
4320 std::stringstream& aStringStream) const {
4321 aStringStream << "Link [" << mDestination << " @ " << mRect << "]";
4324 inline bool RecordedDestination::PlayEvent(Translator* aTranslator) const {
4325 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
4326 if (!dt) {
4327 return false;
4329 dt->Destination(mDestination.c_str(), mPoint);
4330 return true;
4333 template <class S>
4334 void RecordedDestination::Record(S& aStream) const {
4335 WriteElement(aStream, mPoint);
4336 uint32_t len = mDestination.length();
4337 WriteElement(aStream, len);
4338 if (len) {
4339 aStream.write(mDestination.data(), len);
4343 template <class S>
4344 RecordedDestination::RecordedDestination(S& aStream)
4345 : RecordedEventDerived(DESTINATION) {
4346 ReadElement(aStream, mPoint);
4347 uint32_t len;
4348 ReadElement(aStream, len);
4349 mDestination.resize(size_t(len));
4350 if (len && aStream.good()) {
4351 aStream.read(&mDestination.front(), len);
4355 inline void RecordedDestination::OutputSimpleEventInfo(
4356 std::stringstream& aStringStream) const {
4357 aStringStream << "Destination [" << mDestination << " @ " << mPoint << "]";
4360 #define FOR_EACH_EVENT(f) \
4361 f(DRAWTARGETCREATION, RecordedDrawTargetCreation); \
4362 f(DRAWTARGETDESTRUCTION, RecordedDrawTargetDestruction); \
4363 f(SETCURRENTDRAWTARGET, RecordedSetCurrentDrawTarget); \
4364 f(FILLRECT, RecordedFillRect); \
4365 f(STROKERECT, RecordedStrokeRect); \
4366 f(STROKELINE, RecordedStrokeLine); \
4367 f(STROKECIRCLE, RecordedStrokeCircle); \
4368 f(CLEARRECT, RecordedClearRect); \
4369 f(COPYSURFACE, RecordedCopySurface); \
4370 f(SETPERMITSUBPIXELAA, RecordedSetPermitSubpixelAA); \
4371 f(SETTRANSFORM, RecordedSetTransform); \
4372 f(PUSHCLIPRECT, RecordedPushClipRect); \
4373 f(PUSHCLIP, RecordedPushClip); \
4374 f(POPCLIP, RecordedPopClip); \
4375 f(FILL, RecordedFill); \
4376 f(FILLCIRCLE, RecordedFillCircle); \
4377 f(FILLGLYPHS, RecordedFillGlyphs); \
4378 f(STROKEGLYPHS, RecordedStrokeGlyphs); \
4379 f(MASK, RecordedMask); \
4380 f(STROKE, RecordedStroke); \
4381 f(DRAWSURFACE, RecordedDrawSurface); \
4382 f(DRAWDEPENDENTSURFACE, RecordedDrawDependentSurface); \
4383 f(DRAWSURFACEWITHSHADOW, RecordedDrawSurfaceWithShadow); \
4384 f(DRAWSHADOW, RecordedDrawShadow); \
4385 f(DRAWFILTER, RecordedDrawFilter); \
4386 f(PATHCREATION, RecordedPathCreation); \
4387 f(PATHDESTRUCTION, RecordedPathDestruction); \
4388 f(SOURCESURFACECREATION, RecordedSourceSurfaceCreation); \
4389 f(SOURCESURFACEDESTRUCTION, RecordedSourceSurfaceDestruction); \
4390 f(FILTERNODECREATION, RecordedFilterNodeCreation); \
4391 f(FILTERNODEDESTRUCTION, RecordedFilterNodeDestruction); \
4392 f(GRADIENTSTOPSCREATION, RecordedGradientStopsCreation); \
4393 f(GRADIENTSTOPSDESTRUCTION, RecordedGradientStopsDestruction); \
4394 f(SNAPSHOT, RecordedSnapshot); \
4395 f(SCALEDFONTCREATION, RecordedScaledFontCreation); \
4396 f(SCALEDFONTDESTRUCTION, RecordedScaledFontDestruction); \
4397 f(MASKSURFACE, RecordedMaskSurface); \
4398 f(FILTERNODESETATTRIBUTE, RecordedFilterNodeSetAttribute); \
4399 f(FILTERNODESETINPUT, RecordedFilterNodeSetInput); \
4400 f(CREATESIMILARDRAWTARGET, RecordedCreateSimilarDrawTarget); \
4401 f(CREATECLIPPEDDRAWTARGET, RecordedCreateClippedDrawTarget); \
4402 f(CREATEDRAWTARGETFORFILTER, RecordedCreateDrawTargetForFilter); \
4403 f(FONTDATA, RecordedFontData); \
4404 f(FONTDESC, RecordedFontDescriptor); \
4405 f(PUSHLAYER, RecordedPushLayer); \
4406 f(PUSHLAYERWITHBLEND, RecordedPushLayerWithBlend); \
4407 f(POPLAYER, RecordedPopLayer); \
4408 f(UNSCALEDFONTCREATION, RecordedUnscaledFontCreation); \
4409 f(UNSCALEDFONTDESTRUCTION, RecordedUnscaledFontDestruction); \
4410 f(INTOLUMINANCE, RecordedIntoLuminanceSource); \
4411 f(EXTRACTSUBRECT, RecordedExtractSubrect); \
4412 f(EXTERNALSURFACECREATION, RecordedExternalSurfaceCreation); \
4413 f(FLUSH, RecordedFlush); \
4414 f(DETACHALLSNAPSHOTS, RecordedDetachAllSnapshots); \
4415 f(OPTIMIZESOURCESURFACE, RecordedOptimizeSourceSurface); \
4416 f(LINK, RecordedLink); \
4417 f(DESTINATION, RecordedDestination);
4419 #define DO_WITH_EVENT_TYPE(_typeenum, _class) \
4420 case _typeenum: { \
4421 auto e = _class(aStream); \
4422 return aAction(&e); \
4425 template <class S>
4426 bool RecordedEvent::DoWithEvent(
4427 S& aStream, EventType aType,
4428 const std::function<bool(RecordedEvent*)>& aAction) {
4429 switch (aType) {
4430 FOR_EACH_EVENT(DO_WITH_EVENT_TYPE)
4431 default:
4432 return false;
4436 } // namespace gfx
4437 } // namespace mozilla
4439 #endif