Bug 1890689 accumulate input in LargerReceiverBlockSizeThanDesiredBuffering GTest...
[gecko.git] / gfx / 2d / RecordedEventImpl.h
blob1d8a275c63f13852059993652b47612ec43b8b6c
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 #include "mozilla/layers/LayersSurfaces.h"
22 namespace mozilla {
23 namespace gfx {
25 class RecordedDrawTargetCreation
26 : public RecordedEventDerived<RecordedDrawTargetCreation> {
27 public:
28 RecordedDrawTargetCreation(ReferencePtr aRefPtr, BackendType aType,
29 const IntRect& aRect, SurfaceFormat aFormat,
30 bool aHasExistingData = false,
31 SourceSurface* aExistingData = nullptr)
32 : RecordedEventDerived(DRAWTARGETCREATION),
33 mRefPtr(aRefPtr),
34 mBackendType(aType),
35 mRect(aRect),
36 mFormat(aFormat),
37 mHasExistingData(aHasExistingData),
38 mExistingData(aExistingData) {}
40 bool PlayEvent(Translator* aTranslator) const override;
42 template <class S>
43 void Record(S& aStream) const;
44 virtual void OutputSimpleEventInfo(
45 std::stringstream& aStringStream) const override;
47 std::string GetName() const override { return "DrawTarget Creation"; }
49 ReferencePtr mRefPtr;
50 BackendType mBackendType;
51 IntRect mRect;
52 SurfaceFormat mFormat;
53 bool mHasExistingData = false;
54 RefPtr<SourceSurface> mExistingData;
56 private:
57 friend class RecordedEvent;
59 template <class S>
60 MOZ_IMPLICIT RecordedDrawTargetCreation(S& aStream);
63 class RecordedDrawTargetDestruction
64 : public RecordedEventDerived<RecordedDrawTargetDestruction> {
65 public:
66 MOZ_IMPLICIT RecordedDrawTargetDestruction(ReferencePtr aRefPtr)
67 : RecordedEventDerived(DRAWTARGETDESTRUCTION),
68 mRefPtr(aRefPtr),
69 mBackendType(BackendType::NONE) {}
71 bool PlayEvent(Translator* aTranslator) const override;
73 template <class S>
74 void Record(S& aStream) const;
75 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
77 std::string GetName() const override { return "DrawTarget Destruction"; }
79 ReferencePtr mRefPtr;
81 BackendType mBackendType;
83 private:
84 friend class RecordedEvent;
86 template <class S>
87 MOZ_IMPLICIT RecordedDrawTargetDestruction(S& aStream);
90 class RecordedSetCurrentDrawTarget
91 : public RecordedEventDerived<RecordedSetCurrentDrawTarget> {
92 public:
93 MOZ_IMPLICIT RecordedSetCurrentDrawTarget(ReferencePtr aRefPtr)
94 : RecordedEventDerived(SETCURRENTDRAWTARGET), mRefPtr(aRefPtr) {}
96 bool PlayEvent(Translator* aTranslator) const override;
98 template <class S>
99 void Record(S& aStream) const;
100 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
102 std::string GetName() const override { return "SetCurrentDrawTarget"; }
104 ReferencePtr mRefPtr;
106 private:
107 friend class RecordedEvent;
109 template <class S>
110 MOZ_IMPLICIT RecordedSetCurrentDrawTarget(S& aStream);
113 class RecordedCreateSimilarDrawTarget
114 : public RecordedEventDerived<RecordedCreateSimilarDrawTarget> {
115 public:
116 RecordedCreateSimilarDrawTarget(ReferencePtr aRefPtr, const IntSize& aSize,
117 SurfaceFormat aFormat)
118 : RecordedEventDerived(CREATESIMILARDRAWTARGET),
119 mRefPtr(aRefPtr),
120 mSize(aSize),
121 mFormat(aFormat) {}
123 bool PlayEvent(Translator* aTranslator) const override;
125 template <class S>
126 void Record(S& aStream) const;
127 virtual void OutputSimpleEventInfo(
128 std::stringstream& aStringStream) const override;
130 std::string GetName() const override { return "CreateSimilarDrawTarget"; }
132 ReferencePtr mRefPtr;
133 IntSize mSize;
134 SurfaceFormat mFormat;
136 private:
137 friend class RecordedEvent;
139 template <class S>
140 MOZ_IMPLICIT RecordedCreateSimilarDrawTarget(S& aStream);
143 class RecordedCreateClippedDrawTarget
144 : public RecordedEventDerived<RecordedCreateClippedDrawTarget> {
145 public:
146 RecordedCreateClippedDrawTarget(ReferencePtr aRefPtr, const Rect& aBounds,
147 SurfaceFormat aFormat)
148 : RecordedEventDerived(CREATECLIPPEDDRAWTARGET),
149 mRefPtr(aRefPtr),
150 mBounds(aBounds),
151 mFormat(aFormat) {}
153 bool PlayEvent(Translator* aTranslator) const override;
155 template <class S>
156 void Record(S& aStream) const;
157 virtual void OutputSimpleEventInfo(
158 std::stringstream& aStringStream) const override;
160 std::string GetName() const override { return "CreateClippedDrawTarget"; }
162 ReferencePtr mRefPtr;
163 Rect mBounds;
164 SurfaceFormat mFormat;
166 private:
167 friend class RecordedEvent;
169 template <class S>
170 MOZ_IMPLICIT RecordedCreateClippedDrawTarget(S& aStream);
173 class RecordedCreateDrawTargetForFilter
174 : public RecordedEventDerived<RecordedCreateDrawTargetForFilter> {
175 public:
176 RecordedCreateDrawTargetForFilter(ReferencePtr aRefPtr,
177 const IntSize& aMaxSize,
178 SurfaceFormat aFormat, FilterNode* aFilter,
179 FilterNode* aSource,
180 const Rect& aSourceRect,
181 const Point& aDestPoint)
182 : RecordedEventDerived(CREATEDRAWTARGETFORFILTER),
183 mRefPtr(aRefPtr),
184 mMaxSize(aMaxSize),
185 mFormat(aFormat),
186 mFilter(aFilter),
187 mSource(aSource),
188 mSourceRect(aSourceRect),
189 mDestPoint(aDestPoint) {}
191 bool PlayEvent(Translator* aTranslator) const override;
193 template <class S>
194 void Record(S& aStream) const;
195 virtual void OutputSimpleEventInfo(
196 std::stringstream& aStringStream) const override;
198 std::string GetName() const override {
199 return "CreateSimilarDrawTargetForFilter";
202 ReferencePtr mRefPtr;
203 IntSize mMaxSize;
204 SurfaceFormat mFormat;
205 ReferencePtr mFilter;
206 ReferencePtr mSource;
207 Rect mSourceRect;
208 Point mDestPoint;
210 private:
211 friend class RecordedEvent;
213 template <class S>
214 MOZ_IMPLICIT RecordedCreateDrawTargetForFilter(S& aStream);
217 class RecordedFillRect : public RecordedEventDerived<RecordedFillRect> {
218 public:
219 RecordedFillRect(const Rect& aRect, const Pattern& aPattern,
220 const DrawOptions& aOptions)
221 : RecordedEventDerived(FILLRECT),
222 mRect(aRect),
223 mPattern(),
224 mOptions(aOptions) {
225 StorePattern(mPattern, aPattern);
228 bool PlayEvent(Translator* aTranslator) const override;
230 template <class S>
231 void Record(S& aStream) const;
232 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
234 std::string GetName() const override { return "FillRect"; }
236 private:
237 friend class RecordedEvent;
239 template <class S>
240 MOZ_IMPLICIT RecordedFillRect(S& aStream);
242 Rect mRect;
243 PatternStorage mPattern;
244 DrawOptions mOptions;
247 class RecordedStrokeRect : public RecordedEventDerived<RecordedStrokeRect> {
248 public:
249 RecordedStrokeRect(const Rect& aRect, const Pattern& aPattern,
250 const StrokeOptions& aStrokeOptions,
251 const DrawOptions& aOptions)
252 : RecordedEventDerived(STROKERECT),
253 mRect(aRect),
254 mPattern(),
255 mStrokeOptions(aStrokeOptions),
256 mOptions(aOptions) {
257 StorePattern(mPattern, aPattern);
260 bool PlayEvent(Translator* aTranslator) const override;
262 template <class S>
263 void Record(S& aStream) const;
264 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
266 std::string GetName() const override { return "StrokeRect"; }
268 private:
269 friend class RecordedEvent;
271 template <class S>
272 MOZ_IMPLICIT RecordedStrokeRect(S& aStream);
274 Rect mRect;
275 PatternStorage mPattern;
276 StrokeOptions mStrokeOptions;
277 DrawOptions mOptions;
280 class RecordedStrokeLine : public RecordedEventDerived<RecordedStrokeLine> {
281 public:
282 RecordedStrokeLine(const Point& aBegin, const Point& aEnd,
283 const Pattern& aPattern,
284 const StrokeOptions& aStrokeOptions,
285 const DrawOptions& aOptions)
286 : RecordedEventDerived(STROKELINE),
287 mBegin(aBegin),
288 mEnd(aEnd),
289 mPattern(),
290 mStrokeOptions(aStrokeOptions),
291 mOptions(aOptions) {
292 StorePattern(mPattern, aPattern);
295 bool PlayEvent(Translator* aTranslator) const override;
297 template <class S>
298 void Record(S& aStream) const;
299 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
301 std::string GetName() const override { return "StrokeLine"; }
303 private:
304 friend class RecordedEvent;
306 template <class S>
307 MOZ_IMPLICIT RecordedStrokeLine(S& aStream);
309 Point mBegin;
310 Point mEnd;
311 PatternStorage mPattern;
312 StrokeOptions mStrokeOptions;
313 DrawOptions mOptions;
316 class RecordedStrokeCircle : public RecordedEventDerived<RecordedStrokeCircle> {
317 public:
318 RecordedStrokeCircle(Circle aCircle, const Pattern& aPattern,
319 const StrokeOptions& aStrokeOptions,
320 const DrawOptions& aOptions)
321 : RecordedEventDerived(STROKECIRCLE),
322 mCircle(aCircle),
323 mPattern(),
324 mStrokeOptions(aStrokeOptions),
325 mOptions(aOptions) {
326 StorePattern(mPattern, aPattern);
329 bool PlayEvent(Translator* aTranslator) const override;
331 template <class S>
332 void Record(S& aStream) const;
333 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
335 std::string GetName() const override { return "StrokeCircle"; }
337 private:
338 friend class RecordedEvent;
340 template <class S>
341 MOZ_IMPLICIT RecordedStrokeCircle(S& aStream);
343 Circle mCircle;
344 PatternStorage mPattern;
345 StrokeOptions mStrokeOptions;
346 DrawOptions mOptions;
349 class RecordedFill : public RecordedEventDerived<RecordedFill> {
350 public:
351 RecordedFill(ReferencePtr aPath, const Pattern& aPattern,
352 const DrawOptions& aOptions)
353 : RecordedEventDerived(FILL),
354 mPath(aPath),
355 mPattern(),
356 mOptions(aOptions) {
357 StorePattern(mPattern, aPattern);
360 bool PlayEvent(Translator* aTranslator) const override;
362 template <class S>
363 void Record(S& aStream) const;
364 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
366 std::string GetName() const override { return "Fill"; }
368 private:
369 friend class RecordedEvent;
371 template <class S>
372 MOZ_IMPLICIT RecordedFill(S& aStream);
374 ReferencePtr mPath;
375 PatternStorage mPattern;
376 DrawOptions mOptions;
379 class RecordedFillCircle : public RecordedEventDerived<RecordedFillCircle> {
380 public:
381 RecordedFillCircle(Circle aCircle, const Pattern& aPattern,
382 const DrawOptions& aOptions)
383 : RecordedEventDerived(FILLCIRCLE),
384 mCircle(aCircle),
385 mPattern(),
386 mOptions(aOptions) {
387 StorePattern(mPattern, aPattern);
390 bool PlayEvent(Translator* aTranslator) const override;
392 template <class S>
393 void Record(S& aStream) const;
394 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
396 std::string GetName() const override { return "FillCircle"; }
398 private:
399 friend class RecordedEvent;
401 template <class S>
402 MOZ_IMPLICIT RecordedFillCircle(S& aStream);
404 Circle mCircle;
405 PatternStorage mPattern;
406 DrawOptions mOptions;
409 template <class Derived>
410 class RecordedDrawGlyphs : public RecordedEventDerived<Derived> {
411 public:
412 RecordedDrawGlyphs(RecordedEvent::EventType aType, ReferencePtr aScaledFont,
413 const Pattern& aPattern, const DrawOptions& aOptions,
414 const Glyph* aGlyphs, uint32_t aNumGlyphs)
415 : RecordedEventDerived<Derived>(aType),
416 mScaledFont(aScaledFont),
417 mPattern(),
418 mOptions(aOptions) {
419 this->StorePattern(mPattern, aPattern);
420 mNumGlyphs = aNumGlyphs;
421 mGlyphs = new Glyph[aNumGlyphs];
422 memcpy(mGlyphs, aGlyphs, sizeof(Glyph) * aNumGlyphs);
424 virtual ~RecordedDrawGlyphs();
426 bool PlayEvent(Translator* aTranslator) const override;
428 template <class S>
429 void Record(S& aStream) const;
430 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
432 protected:
433 friend class RecordedEvent;
435 template <class S>
436 RecordedDrawGlyphs(RecordedEvent::EventType aType, S& aStream);
438 virtual void DrawGlyphs(DrawTarget* aDT, ScaledFont* aScaledFont,
439 const GlyphBuffer& aBuffer,
440 const Pattern& aPattern) const = 0;
442 ReferencePtr mScaledFont;
443 PatternStorage mPattern;
444 DrawOptions mOptions;
445 Glyph* mGlyphs = nullptr;
446 uint32_t mNumGlyphs = 0;
449 class RecordedFillGlyphs : public RecordedDrawGlyphs<RecordedFillGlyphs> {
450 public:
451 RecordedFillGlyphs(ReferencePtr aScaledFont, const Pattern& aPattern,
452 const DrawOptions& aOptions, const Glyph* aGlyphs,
453 uint32_t aNumGlyphs)
454 : RecordedDrawGlyphs(FILLGLYPHS, aScaledFont, aPattern, aOptions, aGlyphs,
455 aNumGlyphs) {}
457 std::string GetName() const override { return "FillGlyphs"; }
459 private:
460 friend class RecordedEvent;
462 template <class S>
463 MOZ_IMPLICIT RecordedFillGlyphs(S& aStream)
464 : RecordedDrawGlyphs(FILLGLYPHS, aStream) {}
466 void DrawGlyphs(DrawTarget* aDT, ScaledFont* aScaledFont,
467 const GlyphBuffer& aBuffer,
468 const Pattern& aPattern) const override {
469 aDT->FillGlyphs(aScaledFont, aBuffer, aPattern, mOptions);
473 class RecordedStrokeGlyphs : public RecordedDrawGlyphs<RecordedStrokeGlyphs> {
474 public:
475 RecordedStrokeGlyphs(ReferencePtr aScaledFont, const Pattern& aPattern,
476 const StrokeOptions& aStrokeOptions,
477 const DrawOptions& aOptions, const Glyph* aGlyphs,
478 uint32_t aNumGlyphs)
479 : RecordedDrawGlyphs(STROKEGLYPHS, aScaledFont, aPattern, aOptions,
480 aGlyphs, aNumGlyphs),
481 mStrokeOptions(aStrokeOptions) {}
483 std::string GetName() const override { return "StrokeGlyphs"; }
485 template <class S>
486 void Record(S& aStream) const {
487 RecordedDrawGlyphs::Record(aStream);
488 RecordStrokeOptions(aStream, mStrokeOptions);
491 private:
492 friend class RecordedEvent;
494 template <class S>
495 MOZ_IMPLICIT RecordedStrokeGlyphs(S& aStream)
496 : RecordedDrawGlyphs(STROKEGLYPHS, aStream) {
497 ReadStrokeOptions(aStream, mStrokeOptions);
500 void DrawGlyphs(DrawTarget* aDT, ScaledFont* aScaledFont,
501 const GlyphBuffer& aBuffer,
502 const Pattern& aPattern) const override {
503 aDT->StrokeGlyphs(aScaledFont, aBuffer, aPattern, mStrokeOptions, mOptions);
506 StrokeOptions mStrokeOptions;
509 class RecordedMask : public RecordedEventDerived<RecordedMask> {
510 public:
511 RecordedMask(const Pattern& aSource, const Pattern& aMask,
512 const DrawOptions& aOptions)
513 : RecordedEventDerived(MASK), mSource(), mMask(), mOptions(aOptions) {
514 StorePattern(mSource, aSource);
515 StorePattern(mMask, aMask);
518 bool PlayEvent(Translator* aTranslator) const override;
520 template <class S>
521 void Record(S& aStream) const;
522 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
524 std::string GetName() const override { return "Mask"; }
526 private:
527 friend class RecordedEvent;
529 template <class S>
530 MOZ_IMPLICIT RecordedMask(S& aStream);
532 PatternStorage mSource;
533 PatternStorage mMask;
534 DrawOptions mOptions;
537 class RecordedStroke : public RecordedEventDerived<RecordedStroke> {
538 public:
539 RecordedStroke(ReferencePtr aPath, const Pattern& aPattern,
540 const StrokeOptions& aStrokeOptions,
541 const DrawOptions& aOptions)
542 : RecordedEventDerived(STROKE),
543 mPath(aPath),
544 mPattern(),
545 mStrokeOptions(aStrokeOptions),
546 mOptions(aOptions) {
547 StorePattern(mPattern, aPattern);
550 bool PlayEvent(Translator* aTranslator) const override;
552 template <class S>
553 void Record(S& aStream) const;
554 virtual void OutputSimpleEventInfo(
555 std::stringstream& aStringStream) const override;
557 std::string GetName() const override { return "Stroke"; }
559 private:
560 friend class RecordedEvent;
562 template <class S>
563 MOZ_IMPLICIT RecordedStroke(S& aStream);
565 ReferencePtr mPath;
566 PatternStorage mPattern;
567 StrokeOptions mStrokeOptions;
568 DrawOptions mOptions;
571 class RecordedClearRect : public RecordedEventDerived<RecordedClearRect> {
572 public:
573 explicit RecordedClearRect(const Rect& aRect)
574 : RecordedEventDerived(CLEARRECT), mRect(aRect) {}
576 bool PlayEvent(Translator* aTranslator) const override;
578 template <class S>
579 void Record(S& aStream) const;
580 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
582 std::string GetName() const override { return "ClearRect"; }
584 private:
585 friend class RecordedEvent;
587 template <class S>
588 MOZ_IMPLICIT RecordedClearRect(S& aStream);
590 Rect mRect;
593 class RecordedCopySurface : public RecordedEventDerived<RecordedCopySurface> {
594 public:
595 RecordedCopySurface(ReferencePtr aSourceSurface, const IntRect& aSourceRect,
596 const IntPoint& aDest)
597 : RecordedEventDerived(COPYSURFACE),
598 mSourceSurface(aSourceSurface),
599 mSourceRect(aSourceRect),
600 mDest(aDest) {}
602 bool PlayEvent(Translator* aTranslator) const override;
604 template <class S>
605 void Record(S& aStream) const;
606 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
608 std::string GetName() const override { return "CopySurface"; }
610 private:
611 friend class RecordedEvent;
613 template <class S>
614 MOZ_IMPLICIT RecordedCopySurface(S& aStream);
616 ReferencePtr mSourceSurface;
617 IntRect mSourceRect;
618 IntPoint mDest;
621 class RecordedPushClip : public RecordedEventDerived<RecordedPushClip> {
622 public:
623 explicit RecordedPushClip(ReferencePtr aPath)
624 : RecordedEventDerived(PUSHCLIP), mPath(aPath) {}
626 bool PlayEvent(Translator* aTranslator) const override;
628 template <class S>
629 void Record(S& aStream) const;
630 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
632 std::string GetName() const override { return "PushClip"; }
634 private:
635 friend class RecordedEvent;
637 template <class S>
638 MOZ_IMPLICIT RecordedPushClip(S& aStream);
640 ReferencePtr mPath;
643 class RecordedPushClipRect : public RecordedEventDerived<RecordedPushClipRect> {
644 public:
645 explicit RecordedPushClipRect(const Rect& aRect)
646 : RecordedEventDerived(PUSHCLIPRECT), mRect(aRect) {}
648 bool PlayEvent(Translator* aTranslator) const override;
650 template <class S>
651 void Record(S& aStream) const;
652 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
654 std::string GetName() const override { return "PushClipRect"; }
656 private:
657 friend class RecordedEvent;
659 template <class S>
660 MOZ_IMPLICIT RecordedPushClipRect(S& aStream);
662 Rect mRect;
665 class RecordedPopClip : public RecordedEventDerived<RecordedPopClip> {
666 public:
667 MOZ_IMPLICIT RecordedPopClip() : RecordedEventDerived(POPCLIP) {}
669 bool PlayEvent(Translator* aTranslator) const override;
671 template <class S>
672 void Record(S& aStream) const;
673 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
675 std::string GetName() const override { return "PopClip"; }
677 private:
678 friend class RecordedEvent;
680 template <class S>
681 MOZ_IMPLICIT RecordedPopClip(S& aStream);
684 class RecordedPushLayer : public RecordedEventDerived<RecordedPushLayer> {
685 public:
686 RecordedPushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
687 const Matrix& aMaskTransform, const IntRect& aBounds,
688 bool aCopyBackground)
689 : RecordedEventDerived(PUSHLAYER),
690 mOpaque(aOpaque),
691 mOpacity(aOpacity),
692 mMask(aMask),
693 mMaskTransform(aMaskTransform),
694 mBounds(aBounds),
695 mCopyBackground(aCopyBackground) {}
697 bool PlayEvent(Translator* aTranslator) const override;
699 template <class S>
700 void Record(S& aStream) const;
701 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
703 std::string GetName() const override { return "PushLayer"; }
705 private:
706 friend class RecordedEvent;
708 template <class S>
709 MOZ_IMPLICIT RecordedPushLayer(S& aStream);
711 bool mOpaque;
712 Float mOpacity;
713 ReferencePtr mMask;
714 Matrix mMaskTransform;
715 IntRect mBounds;
716 bool mCopyBackground;
719 class RecordedPushLayerWithBlend
720 : public RecordedEventDerived<RecordedPushLayerWithBlend> {
721 public:
722 RecordedPushLayerWithBlend(bool aOpaque, Float aOpacity, SourceSurface* aMask,
723 const Matrix& aMaskTransform,
724 const IntRect& aBounds, bool aCopyBackground,
725 CompositionOp aCompositionOp)
726 : RecordedEventDerived(PUSHLAYERWITHBLEND),
727 mOpaque(aOpaque),
728 mOpacity(aOpacity),
729 mMask(aMask),
730 mMaskTransform(aMaskTransform),
731 mBounds(aBounds),
732 mCopyBackground(aCopyBackground),
733 mCompositionOp(aCompositionOp) {}
735 bool PlayEvent(Translator* aTranslator) const override;
737 template <class S>
738 void Record(S& aStream) const;
739 virtual void OutputSimpleEventInfo(
740 std::stringstream& aStringStream) const override;
742 std::string GetName() const override { return "PushLayerWithBlend"; }
744 private:
745 friend class RecordedEvent;
747 template <class S>
748 MOZ_IMPLICIT RecordedPushLayerWithBlend(S& aStream);
750 bool mOpaque;
751 Float mOpacity;
752 ReferencePtr mMask;
753 Matrix mMaskTransform;
754 IntRect mBounds;
755 bool mCopyBackground;
756 CompositionOp mCompositionOp;
759 class RecordedPopLayer : public RecordedEventDerived<RecordedPopLayer> {
760 public:
761 RecordedPopLayer() : RecordedEventDerived(POPLAYER) {}
763 bool PlayEvent(Translator* aTranslator) const override;
765 template <class S>
766 void Record(S& aStream) const;
767 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
769 std::string GetName() const override { return "PopLayer"; }
771 private:
772 friend class RecordedEvent;
774 template <class S>
775 MOZ_IMPLICIT RecordedPopLayer(S& aStream);
778 class RecordedSetPermitSubpixelAA
779 : public RecordedEventDerived<RecordedSetPermitSubpixelAA> {
780 public:
781 explicit RecordedSetPermitSubpixelAA(bool aPermitSubpixelAA)
782 : RecordedEventDerived(SETPERMITSUBPIXELAA),
783 mPermitSubpixelAA(aPermitSubpixelAA) {}
785 bool PlayEvent(Translator* aTranslator) const override;
787 template <class S>
788 void Record(S& aStream) const;
789 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
791 std::string GetName() const override { return "SetPermitSubpixelAA"; }
793 private:
794 friend class RecordedEvent;
796 template <class S>
797 MOZ_IMPLICIT RecordedSetPermitSubpixelAA(S& aStream);
799 bool mPermitSubpixelAA = false;
802 class RecordedSetTransform : public RecordedEventDerived<RecordedSetTransform> {
803 public:
804 explicit RecordedSetTransform(const Matrix& aTransform)
805 : RecordedEventDerived(SETTRANSFORM), mTransform(aTransform) {}
807 bool PlayEvent(Translator* aTranslator) const override;
809 template <class S>
810 void Record(S& aStream) const;
811 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
813 std::string GetName() const override { return "SetTransform"; }
815 Matrix mTransform;
817 private:
818 friend class RecordedEvent;
820 template <class S>
821 MOZ_IMPLICIT RecordedSetTransform(S& aStream);
824 class RecordedDrawSurface : public RecordedEventDerived<RecordedDrawSurface> {
825 public:
826 RecordedDrawSurface(ReferencePtr aRefSource, const Rect& aDest,
827 const Rect& aSource, const DrawSurfaceOptions& aDSOptions,
828 const DrawOptions& aOptions)
829 : RecordedEventDerived(DRAWSURFACE),
830 mRefSource(aRefSource),
831 mDest(aDest),
832 mSource(aSource),
833 mDSOptions(aDSOptions),
834 mOptions(aOptions) {}
836 bool PlayEvent(Translator* aTranslator) const override;
838 template <class S>
839 void Record(S& aStream) const;
840 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
842 std::string GetName() const override { return "DrawSurface"; }
844 private:
845 friend class RecordedEvent;
847 template <class S>
848 MOZ_IMPLICIT RecordedDrawSurface(S& aStream);
850 ReferencePtr mRefSource;
851 Rect mDest;
852 Rect mSource;
853 DrawSurfaceOptions mDSOptions;
854 DrawOptions mOptions;
857 class RecordedDrawSurfaceDescriptor
858 : public RecordedEventDerived<RecordedDrawSurfaceDescriptor> {
859 public:
860 RecordedDrawSurfaceDescriptor(const layers::SurfaceDescriptor& aDesc,
861 const Rect& aDest, const Rect& aSource,
862 const DrawSurfaceOptions& aDSOptions,
863 const DrawOptions& aOptions)
864 : RecordedEventDerived(DRAWSURFACEDESCRIPTOR),
865 mDesc(aDesc),
866 mDest(aDest),
867 mSource(aSource),
868 mDSOptions(aDSOptions),
869 mOptions(aOptions) {}
871 bool PlayEvent(Translator* aTranslator) const override;
873 template <class S>
874 void Record(S& aStream) const;
875 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
877 std::string GetName() const override { return "DrawSurfaceDescriptor"; }
879 private:
880 friend class RecordedEvent;
882 template <class S>
883 MOZ_IMPLICIT RecordedDrawSurfaceDescriptor(S& aStream);
885 layers::SurfaceDescriptor mDesc;
886 Rect mDest;
887 Rect mSource;
888 DrawSurfaceOptions mDSOptions;
889 DrawOptions mOptions;
892 class RecordedDrawDependentSurface
893 : public RecordedEventDerived<RecordedDrawDependentSurface> {
894 public:
895 RecordedDrawDependentSurface(uint64_t aId, const Rect& aDest)
896 : RecordedEventDerived(DRAWDEPENDENTSURFACE), mId(aId), mDest(aDest) {}
898 bool PlayEvent(Translator* aTranslator) const override;
900 template <class S>
901 void Record(S& aStream) const;
902 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
904 std::string GetName() const override { return "DrawDependentSurface"; }
906 private:
907 friend class RecordedEvent;
909 template <class S>
910 MOZ_IMPLICIT RecordedDrawDependentSurface(S& aStream);
912 uint64_t mId;
913 Rect mDest;
916 class RecordedDrawSurfaceWithShadow
917 : public RecordedEventDerived<RecordedDrawSurfaceWithShadow> {
918 public:
919 RecordedDrawSurfaceWithShadow(ReferencePtr aRefSource, const Point& aDest,
920 const ShadowOptions& aShadow, CompositionOp aOp)
921 : RecordedEventDerived(DRAWSURFACEWITHSHADOW),
922 mRefSource(aRefSource),
923 mDest(aDest),
924 mShadow(aShadow),
925 mOp(aOp) {}
927 bool PlayEvent(Translator* aTranslator) const override;
929 template <class S>
930 void Record(S& aStream) const;
931 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
933 std::string GetName() const override { return "DrawSurfaceWithShadow"; }
935 private:
936 friend class RecordedEvent;
938 template <class S>
939 MOZ_IMPLICIT RecordedDrawSurfaceWithShadow(S& aStream);
941 ReferencePtr mRefSource;
942 Point mDest;
943 ShadowOptions mShadow;
944 CompositionOp mOp;
947 class RecordedDrawShadow : public RecordedEventDerived<RecordedDrawShadow> {
948 public:
949 RecordedDrawShadow(ReferencePtr aPath, const Pattern& aPattern,
950 const ShadowOptions& aShadow, const DrawOptions& aOptions,
951 const StrokeOptions* aStrokeOptions)
952 : RecordedEventDerived(DRAWSHADOW),
953 mPath(aPath),
954 mPattern(),
955 mShadow(aShadow),
956 mOptions(aOptions),
957 mHasStrokeOptions(!!aStrokeOptions),
958 mStrokeOptions(aStrokeOptions ? *aStrokeOptions : StrokeOptions()) {
959 StorePattern(mPattern, aPattern);
962 bool PlayEvent(Translator* aTranslator) const override;
964 template <class S>
965 void Record(S& aStream) const;
966 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
968 std::string GetName() const override { return "DrawShadow"; }
970 private:
971 friend class RecordedEvent;
973 template <class S>
974 MOZ_IMPLICIT RecordedDrawShadow(S& aStream);
976 ReferencePtr mPath;
977 PatternStorage mPattern;
978 ShadowOptions mShadow;
979 DrawOptions mOptions;
980 bool mHasStrokeOptions;
981 StrokeOptions mStrokeOptions;
984 class RecordedDrawFilter : public RecordedEventDerived<RecordedDrawFilter> {
985 public:
986 RecordedDrawFilter(ReferencePtr aNode, const Rect& aSourceRect,
987 const Point& aDestPoint, const DrawOptions& aOptions)
988 : RecordedEventDerived(DRAWFILTER),
989 mNode(aNode),
990 mSourceRect(aSourceRect),
991 mDestPoint(aDestPoint),
992 mOptions(aOptions) {}
994 bool PlayEvent(Translator* aTranslator) const override;
996 template <class S>
997 void Record(S& aStream) const;
998 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1000 std::string GetName() const override { return "DrawFilter"; }
1002 private:
1003 friend class RecordedEvent;
1005 template <class S>
1006 MOZ_IMPLICIT RecordedDrawFilter(S& aStream);
1008 ReferencePtr mNode;
1009 Rect mSourceRect;
1010 Point mDestPoint;
1011 DrawOptions mOptions;
1014 class RecordedPathCreation : public RecordedEventDerived<RecordedPathCreation> {
1015 public:
1016 MOZ_IMPLICIT RecordedPathCreation(PathRecording* aPath);
1018 bool PlayEvent(Translator* aTranslator) const override;
1020 template <class S>
1021 void Record(S& aStream) const;
1022 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1024 std::string GetName() const override { return "Path Creation"; }
1026 private:
1027 friend class RecordedEvent;
1029 ReferencePtr mDT;
1030 ReferencePtr mRefPtr;
1031 FillRule mFillRule;
1032 RefPtr<PathRecording> mPath;
1033 UniquePtr<PathOps> mPathOps;
1035 template <class S>
1036 MOZ_IMPLICIT RecordedPathCreation(S& aStream);
1039 class RecordedPathDestruction
1040 : public RecordedEventDerived<RecordedPathDestruction> {
1041 public:
1042 MOZ_IMPLICIT RecordedPathDestruction(PathRecording* aPath)
1043 : RecordedEventDerived(PATHDESTRUCTION), mRefPtr(aPath) {}
1045 bool PlayEvent(Translator* aTranslator) const override;
1047 template <class S>
1048 void Record(S& aStream) const;
1049 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1051 std::string GetName() const override { return "Path Destruction"; }
1053 private:
1054 friend class RecordedEvent;
1056 ReferencePtr mRefPtr;
1058 template <class S>
1059 MOZ_IMPLICIT RecordedPathDestruction(S& aStream);
1062 class RecordedSourceSurfaceCreation
1063 : public RecordedEventDerived<RecordedSourceSurfaceCreation> {
1064 public:
1065 RecordedSourceSurfaceCreation(ReferencePtr aRefPtr, uint8_t* aData,
1066 int32_t aStride, const IntSize& aSize,
1067 SurfaceFormat aFormat)
1068 : RecordedEventDerived(SOURCESURFACECREATION),
1069 mRefPtr(aRefPtr),
1070 mData(aData),
1071 mStride(aStride),
1072 mSize(aSize),
1073 mFormat(aFormat),
1074 mDataOwned(false) {}
1076 ~RecordedSourceSurfaceCreation();
1078 bool PlayEvent(Translator* aTranslator) const override;
1080 template <class S>
1081 void Record(S& aStream) const;
1082 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1084 std::string GetName() const override { return "SourceSurface Creation"; }
1086 private:
1087 friend class RecordedEvent;
1089 ReferencePtr mRefPtr;
1090 uint8_t* mData = nullptr;
1091 int32_t mStride;
1092 IntSize mSize;
1093 SurfaceFormat mFormat;
1094 mutable bool mDataOwned;
1096 template <class S>
1097 MOZ_IMPLICIT RecordedSourceSurfaceCreation(S& aStream);
1100 class RecordedSourceSurfaceDestruction
1101 : public RecordedEventDerived<RecordedSourceSurfaceDestruction> {
1102 public:
1103 MOZ_IMPLICIT RecordedSourceSurfaceDestruction(ReferencePtr aRefPtr)
1104 : RecordedEventDerived(SOURCESURFACEDESTRUCTION), mRefPtr(aRefPtr) {}
1106 bool PlayEvent(Translator* aTranslator) const override;
1108 template <class S>
1109 void Record(S& aStream) const;
1110 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1112 std::string GetName() const override { return "SourceSurface Destruction"; }
1114 private:
1115 friend class RecordedEvent;
1117 ReferencePtr mRefPtr;
1119 template <class S>
1120 MOZ_IMPLICIT RecordedSourceSurfaceDestruction(S& aStream);
1123 class RecordedOptimizeSourceSurface
1124 : public RecordedEventDerived<RecordedOptimizeSourceSurface> {
1125 public:
1126 RecordedOptimizeSourceSurface(ReferencePtr aSurface,
1127 ReferencePtr aOptimizedSurface)
1128 : RecordedEventDerived(OPTIMIZESOURCESURFACE),
1129 mSurface(aSurface),
1130 mOptimizedSurface(aOptimizedSurface) {}
1132 bool PlayEvent(Translator* aTranslator) const override;
1134 template <class S>
1135 void Record(S& aStream) const;
1136 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1138 std::string GetName() const override { return "OptimizeSourceSurface"; }
1140 private:
1141 friend class RecordedEvent;
1143 ReferencePtr mSurface;
1144 ReferencePtr mOptimizedSurface;
1146 template <class S>
1147 MOZ_IMPLICIT RecordedOptimizeSourceSurface(S& aStream);
1150 class RecordedExternalSurfaceCreation
1151 : public RecordedEventDerived<RecordedExternalSurfaceCreation> {
1152 public:
1153 RecordedExternalSurfaceCreation(ReferencePtr aRefPtr, const uint64_t aKey)
1154 : RecordedEventDerived(EXTERNALSURFACECREATION),
1155 mRefPtr(aRefPtr),
1156 mKey(aKey) {}
1158 ~RecordedExternalSurfaceCreation() = default;
1160 virtual bool PlayEvent(Translator* aTranslator) const;
1162 template <class S>
1163 void Record(S& aStream) const;
1164 virtual void OutputSimpleEventInfo(std::stringstream& aStringStream) const;
1166 virtual std::string GetName() const {
1167 return "SourceSurfaceSharedData Creation";
1170 private:
1171 friend class RecordedEvent;
1173 ReferencePtr mRefPtr;
1174 uint64_t mKey;
1176 template <class S>
1177 MOZ_IMPLICIT RecordedExternalSurfaceCreation(S& aStream);
1180 class RecordedFilterNodeCreation
1181 : public RecordedEventDerived<RecordedFilterNodeCreation> {
1182 public:
1183 RecordedFilterNodeCreation(ReferencePtr aRefPtr, FilterType aType)
1184 : RecordedEventDerived(FILTERNODECREATION),
1185 mRefPtr(aRefPtr),
1186 mType(aType) {}
1188 ~RecordedFilterNodeCreation();
1190 bool PlayEvent(Translator* aTranslator) const override;
1192 template <class S>
1193 void Record(S& aStream) const;
1194 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1196 std::string GetName() const override { return "FilterNode Creation"; }
1198 private:
1199 friend class RecordedEvent;
1201 ReferencePtr mRefPtr;
1202 FilterType mType;
1204 template <class S>
1205 MOZ_IMPLICIT RecordedFilterNodeCreation(S& aStream);
1208 class RecordedFilterNodeDestruction
1209 : public RecordedEventDerived<RecordedFilterNodeDestruction> {
1210 public:
1211 MOZ_IMPLICIT RecordedFilterNodeDestruction(ReferencePtr aRefPtr)
1212 : RecordedEventDerived(FILTERNODEDESTRUCTION), mRefPtr(aRefPtr) {}
1214 bool PlayEvent(Translator* aTranslator) const override;
1216 template <class S>
1217 void Record(S& aStream) const;
1218 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1220 std::string GetName() const override { return "FilterNode Destruction"; }
1222 private:
1223 friend class RecordedEvent;
1225 ReferencePtr mRefPtr;
1227 template <class S>
1228 MOZ_IMPLICIT RecordedFilterNodeDestruction(S& aStream);
1231 class RecordedGradientStopsCreation
1232 : public RecordedEventDerived<RecordedGradientStopsCreation> {
1233 public:
1234 RecordedGradientStopsCreation(ReferencePtr aRefPtr, GradientStop* aStops,
1235 uint32_t aNumStops, ExtendMode aExtendMode)
1236 : RecordedEventDerived(GRADIENTSTOPSCREATION),
1237 mRefPtr(aRefPtr),
1238 mStops(aStops),
1239 mNumStops(aNumStops),
1240 mExtendMode(aExtendMode),
1241 mDataOwned(false) {}
1243 ~RecordedGradientStopsCreation();
1245 bool PlayEvent(Translator* aTranslator) const override;
1247 template <class S>
1248 void Record(S& aStream) const;
1249 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1251 std::string GetName() const override { return "GradientStops Creation"; }
1253 private:
1254 friend class RecordedEvent;
1256 ReferencePtr mRefPtr;
1257 GradientStop* mStops = nullptr;
1258 uint32_t mNumStops = 0;
1259 ExtendMode mExtendMode;
1260 bool mDataOwned;
1262 template <class S>
1263 MOZ_IMPLICIT RecordedGradientStopsCreation(S& aStream);
1266 class RecordedGradientStopsDestruction
1267 : public RecordedEventDerived<RecordedGradientStopsDestruction> {
1268 public:
1269 MOZ_IMPLICIT RecordedGradientStopsDestruction(ReferencePtr aRefPtr)
1270 : RecordedEventDerived(GRADIENTSTOPSDESTRUCTION), mRefPtr(aRefPtr) {}
1272 bool PlayEvent(Translator* aTranslator) const override;
1274 template <class S>
1275 void Record(S& aStream) const;
1276 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1278 std::string GetName() const override { return "GradientStops Destruction"; }
1280 private:
1281 friend class RecordedEvent;
1283 ReferencePtr mRefPtr;
1285 template <class S>
1286 MOZ_IMPLICIT RecordedGradientStopsDestruction(S& aStream);
1289 class RecordedFlush : public RecordedEventDerived<RecordedFlush> {
1290 public:
1291 explicit RecordedFlush() : RecordedEventDerived(FLUSH) {}
1293 bool PlayEvent(Translator* aTranslator) const final;
1295 template <class S>
1296 void Record(S& aStream) const;
1297 virtual void OutputSimpleEventInfo(
1298 std::stringstream& aStringStream) const override;
1300 virtual std::string GetName() const override { return "Flush"; }
1302 private:
1303 friend class RecordedEvent;
1305 template <class S>
1306 MOZ_IMPLICIT RecordedFlush(S& aStream);
1309 class RecordedDetachAllSnapshots
1310 : public RecordedEventDerived<RecordedDetachAllSnapshots> {
1311 public:
1312 explicit RecordedDetachAllSnapshots()
1313 : RecordedEventDerived(DETACHALLSNAPSHOTS) {}
1315 bool PlayEvent(Translator* aTranslator) const final;
1317 template <class S>
1318 void Record(S& aStream) const;
1319 virtual void OutputSimpleEventInfo(
1320 std::stringstream& aStringStream) const override;
1322 virtual std::string GetName() const override { return "DetachAllSnapshots"; }
1324 private:
1325 friend class RecordedEvent;
1327 template <class S>
1328 MOZ_IMPLICIT RecordedDetachAllSnapshots(S& aStream);
1331 class RecordedSnapshot : public RecordedEventDerived<RecordedSnapshot> {
1332 public:
1333 explicit RecordedSnapshot(ReferencePtr aRefPtr)
1334 : RecordedEventDerived(SNAPSHOT), mRefPtr(aRefPtr) {}
1336 bool PlayEvent(Translator* aTranslator) const override;
1338 template <class S>
1339 void Record(S& aStream) const;
1340 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1342 std::string GetName() const override { return "Snapshot"; }
1344 private:
1345 friend class RecordedEvent;
1347 ReferencePtr mRefPtr;
1349 template <class S>
1350 MOZ_IMPLICIT RecordedSnapshot(S& aStream);
1353 class RecordedIntoLuminanceSource
1354 : public RecordedEventDerived<RecordedIntoLuminanceSource> {
1355 public:
1356 RecordedIntoLuminanceSource(ReferencePtr aRefPtr,
1357 LuminanceType aLuminanceType, float aOpacity)
1358 : RecordedEventDerived(INTOLUMINANCE),
1359 mRefPtr(aRefPtr),
1360 mLuminanceType(aLuminanceType),
1361 mOpacity(aOpacity) {}
1363 bool PlayEvent(Translator* aTranslator) const override;
1365 template <class S>
1366 void Record(S& aStream) const;
1367 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1369 std::string GetName() const override { return "IntoLuminanceSource"; }
1371 private:
1372 friend class RecordedEvent;
1374 ReferencePtr mRefPtr;
1375 LuminanceType mLuminanceType;
1376 float mOpacity;
1378 template <class S>
1379 MOZ_IMPLICIT RecordedIntoLuminanceSource(S& aStream);
1382 class RecordedExtractSubrect
1383 : public RecordedEventDerived<RecordedExtractSubrect> {
1384 public:
1385 RecordedExtractSubrect(ReferencePtr aRefPtr, ReferencePtr aSourceSurface,
1386 const IntRect& aSubrect)
1387 : RecordedEventDerived(EXTRACTSUBRECT),
1388 mRefPtr(aRefPtr),
1389 mSourceSurface(aSourceSurface),
1390 mSubrect(aSubrect) {}
1392 bool PlayEvent(Translator* aTranslator) const override;
1394 template <class S>
1395 void Record(S& aStream) const;
1396 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1398 std::string GetName() const override { return "ExtractSubrect"; }
1400 private:
1401 friend class RecordedEvent;
1403 ReferencePtr mRefPtr;
1404 ReferencePtr mSourceSurface;
1405 IntRect mSubrect;
1407 template <class S>
1408 MOZ_IMPLICIT RecordedExtractSubrect(S& aStream);
1411 class RecordedFontData : public RecordedEventDerived<RecordedFontData> {
1412 public:
1413 static void FontDataProc(const uint8_t* aData, uint32_t aSize,
1414 uint32_t aIndex, void* aBaton) {
1415 auto recordedFontData = static_cast<RecordedFontData*>(aBaton);
1416 recordedFontData->SetFontData(aData, aSize, aIndex);
1419 explicit RecordedFontData(UnscaledFont* aUnscaledFont)
1420 : RecordedEventDerived(FONTDATA),
1421 mType(aUnscaledFont->GetType()),
1422 mFontDetails() {
1423 mGetFontFileDataSucceeded =
1424 aUnscaledFont->GetFontFileData(&FontDataProc, this) && mData;
1427 virtual ~RecordedFontData();
1429 bool IsValid() const { return mGetFontFileDataSucceeded; }
1431 bool PlayEvent(Translator* aTranslator) const override;
1433 template <class S>
1434 void Record(S& aStream) const;
1435 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1437 std::string GetName() const override { return "Font Data"; }
1439 void SetFontData(const uint8_t* aData, uint32_t aSize, uint32_t aIndex);
1441 bool GetFontDetails(RecordedFontDetails& fontDetails);
1443 private:
1444 friend class RecordedEvent;
1446 FontType mType;
1447 uint8_t* mData = nullptr;
1448 RecordedFontDetails mFontDetails;
1450 bool mGetFontFileDataSucceeded;
1452 template <class S>
1453 MOZ_IMPLICIT RecordedFontData(S& aStream);
1456 class RecordedFontDescriptor
1457 : public RecordedEventDerived<RecordedFontDescriptor> {
1458 public:
1459 static void FontDescCb(const uint8_t* aData, uint32_t aSize, uint32_t aIndex,
1460 void* aBaton) {
1461 auto recordedFontDesc = static_cast<RecordedFontDescriptor*>(aBaton);
1462 recordedFontDesc->SetFontDescriptor(aData, aSize, aIndex);
1465 explicit RecordedFontDescriptor(UnscaledFont* aUnscaledFont)
1466 : RecordedEventDerived(FONTDESC),
1467 mType(aUnscaledFont->GetType()),
1468 mIndex(0),
1469 mRefPtr(aUnscaledFont) {
1470 mHasDesc = aUnscaledFont->GetFontDescriptor(FontDescCb, this);
1473 virtual ~RecordedFontDescriptor();
1475 bool IsValid() const { return mHasDesc; }
1477 bool PlayEvent(Translator* aTranslator) const override;
1479 template <class S>
1480 void Record(S& aStream) const;
1481 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1483 std::string GetName() const override { return "Font Desc"; }
1485 private:
1486 friend class RecordedEvent;
1488 void SetFontDescriptor(const uint8_t* aData, uint32_t aSize, uint32_t aIndex);
1490 bool mHasDesc;
1492 FontType mType;
1493 std::vector<uint8_t> mData;
1494 uint32_t mIndex;
1495 ReferencePtr mRefPtr;
1497 template <class S>
1498 MOZ_IMPLICIT RecordedFontDescriptor(S& aStream);
1501 class RecordedUnscaledFontCreation
1502 : public RecordedEventDerived<RecordedUnscaledFontCreation> {
1503 public:
1504 static void FontInstanceDataProc(const uint8_t* aData, uint32_t aSize,
1505 void* aBaton) {
1506 auto recordedUnscaledFontCreation =
1507 static_cast<RecordedUnscaledFontCreation*>(aBaton);
1508 recordedUnscaledFontCreation->SetFontInstanceData(aData, aSize);
1511 RecordedUnscaledFontCreation(UnscaledFont* aUnscaledFont,
1512 RecordedFontDetails aFontDetails)
1513 : RecordedEventDerived(UNSCALEDFONTCREATION),
1514 mRefPtr(aUnscaledFont),
1515 mFontDataKey(aFontDetails.fontDataKey),
1516 mIndex(aFontDetails.index) {
1517 aUnscaledFont->GetFontInstanceData(FontInstanceDataProc, this);
1520 bool PlayEvent(Translator* aTranslator) const override;
1522 template <class S>
1523 void Record(S& aStream) const;
1524 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1526 std::string GetName() const override { return "UnscaledFont Creation"; }
1528 void SetFontInstanceData(const uint8_t* aData, uint32_t aSize);
1530 private:
1531 friend class RecordedEvent;
1533 ReferencePtr mRefPtr;
1534 uint64_t mFontDataKey;
1535 uint32_t mIndex;
1536 std::vector<uint8_t> mInstanceData;
1538 template <class S>
1539 MOZ_IMPLICIT RecordedUnscaledFontCreation(S& aStream);
1542 class RecordedUnscaledFontDestruction
1543 : public RecordedEventDerived<RecordedUnscaledFontDestruction> {
1544 public:
1545 MOZ_IMPLICIT RecordedUnscaledFontDestruction(ReferencePtr aRefPtr)
1546 : RecordedEventDerived(UNSCALEDFONTDESTRUCTION), mRefPtr(aRefPtr) {}
1548 bool PlayEvent(Translator* aTranslator) const override;
1549 template <class S>
1550 void Record(S& aStream) const;
1551 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1553 std::string GetName() const override { return "UnscaledFont Destruction"; }
1555 private:
1556 friend class RecordedEvent;
1558 ReferencePtr mRefPtr;
1560 template <class S>
1561 MOZ_IMPLICIT RecordedUnscaledFontDestruction(S& aStream);
1564 class RecordedScaledFontCreation
1565 : public RecordedEventDerived<RecordedScaledFontCreation> {
1566 public:
1567 static void FontInstanceDataProc(const uint8_t* aData, uint32_t aSize,
1568 const FontVariation* aVariations,
1569 uint32_t aNumVariations, void* aBaton) {
1570 auto recordedScaledFontCreation =
1571 static_cast<RecordedScaledFontCreation*>(aBaton);
1572 recordedScaledFontCreation->SetFontInstanceData(aData, aSize, aVariations,
1573 aNumVariations);
1576 RecordedScaledFontCreation(ScaledFont* aScaledFont,
1577 UnscaledFont* aUnscaledFont)
1578 : RecordedEventDerived(SCALEDFONTCREATION),
1579 mRefPtr(aScaledFont),
1580 mUnscaledFont(aUnscaledFont),
1581 mGlyphSize(aScaledFont->GetSize()) {
1582 aScaledFont->GetFontInstanceData(FontInstanceDataProc, this);
1585 bool PlayEvent(Translator* aTranslator) const override;
1587 template <class S>
1588 void Record(S& aStream) const;
1589 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1591 std::string GetName() const override { return "ScaledFont Creation"; }
1593 void SetFontInstanceData(const uint8_t* aData, uint32_t aSize,
1594 const FontVariation* aVariations,
1595 uint32_t aNumVariations);
1597 private:
1598 friend class RecordedEvent;
1600 ReferencePtr mRefPtr;
1601 ReferencePtr mUnscaledFont;
1602 Float mGlyphSize;
1603 std::vector<uint8_t> mInstanceData;
1604 std::vector<FontVariation> mVariations;
1606 template <class S>
1607 MOZ_IMPLICIT RecordedScaledFontCreation(S& aStream);
1610 class RecordedScaledFontDestruction
1611 : public RecordedEventDerived<RecordedScaledFontDestruction> {
1612 public:
1613 MOZ_IMPLICIT RecordedScaledFontDestruction(ReferencePtr aRefPtr)
1614 : RecordedEventDerived(SCALEDFONTDESTRUCTION), mRefPtr(aRefPtr) {}
1616 bool PlayEvent(Translator* aTranslator) const override;
1618 template <class S>
1619 void Record(S& aStream) const;
1620 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1622 std::string GetName() const override { return "ScaledFont Destruction"; }
1624 private:
1625 friend class RecordedEvent;
1627 ReferencePtr mRefPtr;
1629 template <class S>
1630 MOZ_IMPLICIT RecordedScaledFontDestruction(S& aStream);
1633 class RecordedMaskSurface : public RecordedEventDerived<RecordedMaskSurface> {
1634 public:
1635 RecordedMaskSurface(const Pattern& aPattern, ReferencePtr aRefMask,
1636 const Point& aOffset, const DrawOptions& aOptions)
1637 : RecordedEventDerived(MASKSURFACE),
1638 mPattern(),
1639 mRefMask(aRefMask),
1640 mOffset(aOffset),
1641 mOptions(aOptions) {
1642 StorePattern(mPattern, aPattern);
1645 bool PlayEvent(Translator* aTranslator) const override;
1647 template <class S>
1648 void Record(S& aStream) const;
1649 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1651 std::string GetName() const override { return "MaskSurface"; }
1653 private:
1654 friend class RecordedEvent;
1656 template <class S>
1657 MOZ_IMPLICIT RecordedMaskSurface(S& aStream);
1659 PatternStorage mPattern;
1660 ReferencePtr mRefMask;
1661 Point mOffset;
1662 DrawOptions mOptions;
1665 class RecordedFilterNodeSetAttribute
1666 : public RecordedEventDerived<RecordedFilterNodeSetAttribute> {
1667 public:
1668 enum ArgType {
1669 ARGTYPE_UINT32,
1670 ARGTYPE_BOOL,
1671 ARGTYPE_FLOAT,
1672 ARGTYPE_SIZE,
1673 ARGTYPE_INTSIZE,
1674 ARGTYPE_INTPOINT,
1675 ARGTYPE_RECT,
1676 ARGTYPE_INTRECT,
1677 ARGTYPE_POINT,
1678 ARGTYPE_MATRIX,
1679 ARGTYPE_MATRIX5X4,
1680 ARGTYPE_POINT3D,
1681 ARGTYPE_COLOR,
1682 ARGTYPE_FLOAT_ARRAY
1685 template <typename T>
1686 RecordedFilterNodeSetAttribute(FilterNode* aNode, uint32_t aIndex,
1687 T aArgument, ArgType aArgType)
1688 : RecordedEventDerived(FILTERNODESETATTRIBUTE),
1689 mNode(aNode),
1690 mIndex(aIndex),
1691 mArgType(aArgType) {
1692 mPayload.resize(sizeof(T));
1693 memcpy(&mPayload.front(), &aArgument, sizeof(T));
1696 RecordedFilterNodeSetAttribute(FilterNode* aNode, uint32_t aIndex,
1697 const Float* aFloat, uint32_t aSize)
1698 : RecordedEventDerived(FILTERNODESETATTRIBUTE),
1699 mNode(aNode),
1700 mIndex(aIndex),
1701 mArgType(ARGTYPE_FLOAT_ARRAY) {
1702 mPayload.resize(sizeof(Float) * aSize);
1703 memcpy(&mPayload.front(), aFloat, sizeof(Float) * aSize);
1706 bool PlayEvent(Translator* aTranslator) const override;
1707 template <class S>
1708 void Record(S& aStream) const;
1709 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1711 std::string GetName() const override { return "SetAttribute"; }
1713 private:
1714 friend class RecordedEvent;
1716 ReferencePtr mNode;
1718 uint32_t mIndex;
1719 ArgType mArgType;
1720 std::vector<uint8_t> mPayload;
1722 template <class S>
1723 MOZ_IMPLICIT RecordedFilterNodeSetAttribute(S& aStream);
1726 class RecordedFilterNodeSetInput
1727 : public RecordedEventDerived<RecordedFilterNodeSetInput> {
1728 public:
1729 RecordedFilterNodeSetInput(FilterNode* aNode, uint32_t aIndex,
1730 FilterNode* aInputNode)
1731 : RecordedEventDerived(FILTERNODESETINPUT),
1732 mNode(aNode),
1733 mIndex(aIndex),
1734 mInputFilter(aInputNode),
1735 mInputSurface(nullptr) {}
1737 RecordedFilterNodeSetInput(FilterNode* aNode, uint32_t aIndex,
1738 SourceSurface* aInputSurface)
1739 : RecordedEventDerived(FILTERNODESETINPUT),
1740 mNode(aNode),
1741 mIndex(aIndex),
1742 mInputFilter(nullptr),
1743 mInputSurface(aInputSurface) {}
1745 bool PlayEvent(Translator* aTranslator) const override;
1746 template <class S>
1747 void Record(S& aStream) const;
1748 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1750 std::string GetName() const override { return "SetInput"; }
1752 private:
1753 friend class RecordedEvent;
1755 ReferencePtr mNode;
1756 uint32_t mIndex;
1757 ReferencePtr mInputFilter;
1758 ReferencePtr mInputSurface;
1760 template <class S>
1761 MOZ_IMPLICIT RecordedFilterNodeSetInput(S& aStream);
1764 class RecordedLink : public RecordedEventDerived<RecordedLink> {
1765 public:
1766 RecordedLink(const char* aDestination, const Rect& aRect)
1767 : RecordedEventDerived(LINK), mDestination(aDestination), mRect(aRect) {}
1769 bool PlayEvent(Translator* aTranslator) const override;
1770 template <class S>
1771 void Record(S& aStream) const;
1772 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1774 std::string GetName() const override { return "Link"; }
1776 private:
1777 friend class RecordedEvent;
1779 std::string mDestination;
1780 Rect mRect;
1782 template <class S>
1783 MOZ_IMPLICIT RecordedLink(S& aStream);
1786 class RecordedDestination : public RecordedEventDerived<RecordedDestination> {
1787 public:
1788 RecordedDestination(const char* aDestination, const Point& aPoint)
1789 : RecordedEventDerived(DESTINATION),
1790 mDestination(aDestination),
1791 mPoint(aPoint) {}
1793 bool PlayEvent(Translator* aTranslator) const override;
1794 template <class S>
1795 void Record(S& aStream) const;
1796 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1798 std::string GetName() const override { return "Destination"; }
1800 private:
1801 friend class RecordedEvent;
1803 std::string mDestination;
1804 Point mPoint;
1806 template <class S>
1807 MOZ_IMPLICIT RecordedDestination(S& aStream);
1810 static std::string NameFromBackend(BackendType aType) {
1811 switch (aType) {
1812 case BackendType::NONE:
1813 return "None";
1814 case BackendType::DIRECT2D:
1815 return "Direct2D";
1816 default:
1817 return "Unknown";
1821 template <class S>
1822 void RecordedEvent::RecordPatternData(S& aStream,
1823 const PatternStorage& aPattern) const {
1824 WriteElement(aStream, aPattern.mType);
1826 switch (aPattern.mType) {
1827 case PatternType::COLOR: {
1828 WriteElement(aStream, *reinterpret_cast<const ColorPatternStorage*>(
1829 &aPattern.mStorage));
1830 return;
1832 case PatternType::LINEAR_GRADIENT: {
1833 WriteElement(aStream,
1834 *reinterpret_cast<const LinearGradientPatternStorage*>(
1835 &aPattern.mStorage));
1836 return;
1838 case PatternType::RADIAL_GRADIENT: {
1839 WriteElement(aStream,
1840 *reinterpret_cast<const RadialGradientPatternStorage*>(
1841 &aPattern.mStorage));
1842 return;
1844 case PatternType::CONIC_GRADIENT: {
1845 WriteElement(aStream,
1846 *reinterpret_cast<const ConicGradientPatternStorage*>(
1847 &aPattern.mStorage));
1848 return;
1850 case PatternType::SURFACE: {
1851 WriteElement(aStream, *reinterpret_cast<const SurfacePatternStorage*>(
1852 &aPattern.mStorage));
1853 return;
1855 default:
1856 return;
1860 template <class S>
1861 void RecordedEvent::ReadPatternData(S& aStream,
1862 PatternStorage& aPattern) const {
1863 ReadElementConstrained(aStream, aPattern.mType, PatternType::COLOR,
1864 kHighestPatternType);
1866 switch (aPattern.mType) {
1867 case PatternType::COLOR: {
1868 ReadElement(aStream,
1869 *reinterpret_cast<ColorPatternStorage*>(&aPattern.mStorage));
1870 return;
1872 case PatternType::LINEAR_GRADIENT: {
1873 ReadElement(aStream, *reinterpret_cast<LinearGradientPatternStorage*>(
1874 &aPattern.mStorage));
1875 return;
1877 case PatternType::RADIAL_GRADIENT: {
1878 ReadElement(aStream, *reinterpret_cast<RadialGradientPatternStorage*>(
1879 &aPattern.mStorage));
1880 return;
1882 case PatternType::CONIC_GRADIENT: {
1883 ReadElement(aStream, *reinterpret_cast<ConicGradientPatternStorage*>(
1884 &aPattern.mStorage));
1885 return;
1887 case PatternType::SURFACE: {
1888 SurfacePatternStorage* sps =
1889 reinterpret_cast<SurfacePatternStorage*>(&aPattern.mStorage);
1890 ReadElement(aStream, *sps);
1891 if (sps->mExtend < ExtendMode::CLAMP ||
1892 sps->mExtend > ExtendMode::REFLECT) {
1893 aStream.SetIsBad();
1894 return;
1897 if (sps->mSamplingFilter < SamplingFilter::GOOD ||
1898 sps->mSamplingFilter >= SamplingFilter::SENTINEL) {
1899 aStream.SetIsBad();
1901 return;
1903 default:
1904 return;
1908 inline void RecordedEvent::StorePattern(PatternStorage& aDestination,
1909 const Pattern& aSource) const {
1910 aDestination.mType = aSource.GetType();
1912 switch (aSource.GetType()) {
1913 case PatternType::COLOR: {
1914 reinterpret_cast<ColorPatternStorage*>(&aDestination.mStorage)->mColor =
1915 static_cast<const ColorPattern*>(&aSource)->mColor;
1916 return;
1918 case PatternType::LINEAR_GRADIENT: {
1919 LinearGradientPatternStorage* store =
1920 reinterpret_cast<LinearGradientPatternStorage*>(
1921 &aDestination.mStorage);
1922 const LinearGradientPattern* pat =
1923 static_cast<const LinearGradientPattern*>(&aSource);
1924 store->mBegin = pat->mBegin;
1925 store->mEnd = pat->mEnd;
1926 store->mMatrix = pat->mMatrix;
1927 store->mStops = pat->mStops.get();
1928 return;
1930 case PatternType::RADIAL_GRADIENT: {
1931 RadialGradientPatternStorage* store =
1932 reinterpret_cast<RadialGradientPatternStorage*>(
1933 &aDestination.mStorage);
1934 const RadialGradientPattern* pat =
1935 static_cast<const RadialGradientPattern*>(&aSource);
1936 store->mCenter1 = pat->mCenter1;
1937 store->mCenter2 = pat->mCenter2;
1938 store->mRadius1 = pat->mRadius1;
1939 store->mRadius2 = pat->mRadius2;
1940 store->mMatrix = pat->mMatrix;
1941 store->mStops = pat->mStops.get();
1942 return;
1944 case PatternType::CONIC_GRADIENT: {
1945 ConicGradientPatternStorage* store =
1946 reinterpret_cast<ConicGradientPatternStorage*>(
1947 &aDestination.mStorage);
1948 const ConicGradientPattern* pat =
1949 static_cast<const ConicGradientPattern*>(&aSource);
1950 store->mCenter = pat->mCenter;
1951 store->mAngle = pat->mAngle;
1952 store->mStartOffset = pat->mStartOffset;
1953 store->mEndOffset = pat->mEndOffset;
1954 store->mMatrix = pat->mMatrix;
1955 store->mStops = pat->mStops.get();
1956 return;
1958 case PatternType::SURFACE: {
1959 SurfacePatternStorage* store =
1960 reinterpret_cast<SurfacePatternStorage*>(&aDestination.mStorage);
1961 const SurfacePattern* pat = static_cast<const SurfacePattern*>(&aSource);
1962 store->mExtend = pat->mExtendMode;
1963 store->mSamplingFilter = pat->mSamplingFilter;
1964 store->mMatrix = pat->mMatrix;
1965 store->mSurface = pat->mSurface;
1966 store->mSamplingRect = pat->mSamplingRect;
1967 return;
1972 template <class S>
1973 void RecordedEvent::RecordStrokeOptions(
1974 S& aStream, const StrokeOptions& aStrokeOptions) const {
1975 JoinStyle joinStyle = aStrokeOptions.mLineJoin;
1976 CapStyle capStyle = aStrokeOptions.mLineCap;
1978 WriteElement(aStream, uint64_t(aStrokeOptions.mDashLength));
1979 WriteElement(aStream, aStrokeOptions.mLineWidth);
1980 WriteElement(aStream, aStrokeOptions.mMiterLimit);
1981 WriteElement(aStream, joinStyle);
1982 WriteElement(aStream, capStyle);
1984 if (!aStrokeOptions.mDashPattern) {
1985 return;
1988 WriteElement(aStream, aStrokeOptions.mDashOffset);
1989 aStream.write((char*)aStrokeOptions.mDashPattern,
1990 sizeof(Float) * aStrokeOptions.mDashLength);
1993 template <class S>
1994 void RecordedEvent::ReadStrokeOptions(S& aStream,
1995 StrokeOptions& aStrokeOptions) {
1996 uint64_t dashLength;
1997 JoinStyle joinStyle;
1998 CapStyle capStyle;
2000 ReadElement(aStream, dashLength);
2001 ReadElement(aStream, aStrokeOptions.mLineWidth);
2002 ReadElement(aStream, aStrokeOptions.mMiterLimit);
2003 ReadElementConstrained(aStream, joinStyle, JoinStyle::BEVEL,
2004 JoinStyle::MITER_OR_BEVEL);
2005 ReadElementConstrained(aStream, capStyle, CapStyle::BUTT, CapStyle::SQUARE);
2006 // On 32 bit we truncate the value of dashLength.
2007 // See also bug 811850 for history.
2008 aStrokeOptions.mDashLength = size_t(dashLength);
2009 aStrokeOptions.mLineJoin = joinStyle;
2010 aStrokeOptions.mLineCap = capStyle;
2012 if (!aStrokeOptions.mDashLength || !aStream.good()) {
2013 return;
2016 ReadElement(aStream, aStrokeOptions.mDashOffset);
2018 mDashPatternStorage.resize(aStrokeOptions.mDashLength);
2019 aStrokeOptions.mDashPattern = &mDashPatternStorage.front();
2020 aStream.read((char*)aStrokeOptions.mDashPattern,
2021 sizeof(Float) * aStrokeOptions.mDashLength);
2024 template <class S>
2025 static void ReadDrawOptions(S& aStream, DrawOptions& aDrawOptions) {
2026 ReadElement(aStream, aDrawOptions);
2027 if (aDrawOptions.mAntialiasMode < AntialiasMode::NONE ||
2028 aDrawOptions.mAntialiasMode > AntialiasMode::DEFAULT) {
2029 aStream.SetIsBad();
2030 return;
2033 if (aDrawOptions.mCompositionOp < CompositionOp::OP_CLEAR ||
2034 aDrawOptions.mCompositionOp > CompositionOp::OP_COUNT) {
2035 aStream.SetIsBad();
2039 template <class S>
2040 static void ReadDrawSurfaceOptions(S& aStream,
2041 DrawSurfaceOptions& aDrawSurfaceOptions) {
2042 ReadElement(aStream, aDrawSurfaceOptions);
2043 if (aDrawSurfaceOptions.mSamplingFilter < SamplingFilter::GOOD ||
2044 aDrawSurfaceOptions.mSamplingFilter >= SamplingFilter::SENTINEL) {
2045 aStream.SetIsBad();
2046 return;
2049 if (aDrawSurfaceOptions.mSamplingBounds < SamplingBounds::UNBOUNDED ||
2050 aDrawSurfaceOptions.mSamplingBounds > SamplingBounds::BOUNDED) {
2051 aStream.SetIsBad();
2055 inline void RecordedEvent::OutputSimplePatternInfo(
2056 const PatternStorage& aStorage, std::stringstream& aOutput) const {
2057 switch (aStorage.mType) {
2058 case PatternType::COLOR: {
2059 const DeviceColor color =
2060 reinterpret_cast<const ColorPatternStorage*>(&aStorage.mStorage)
2061 ->mColor;
2062 aOutput << "DeviceColor: (" << color.r << ", " << color.g << ", "
2063 << color.b << ", " << color.a << ")";
2064 return;
2066 case PatternType::LINEAR_GRADIENT: {
2067 const LinearGradientPatternStorage* store =
2068 reinterpret_cast<const LinearGradientPatternStorage*>(
2069 &aStorage.mStorage);
2071 aOutput << "LinearGradient (" << store->mBegin.x << ", "
2072 << store->mBegin.y << ") - (" << store->mEnd.x << ", "
2073 << store->mEnd.y << ") Stops: " << store->mStops;
2074 return;
2076 case PatternType::RADIAL_GRADIENT: {
2077 const RadialGradientPatternStorage* store =
2078 reinterpret_cast<const RadialGradientPatternStorage*>(
2079 &aStorage.mStorage);
2080 aOutput << "RadialGradient (Center 1: (" << store->mCenter1.x << ", "
2081 << store->mCenter2.y << ") Radius 2: " << store->mRadius2;
2082 return;
2084 case PatternType::CONIC_GRADIENT: {
2085 const ConicGradientPatternStorage* store =
2086 reinterpret_cast<const ConicGradientPatternStorage*>(
2087 &aStorage.mStorage);
2088 aOutput << "ConicGradient (Center: (" << store->mCenter.x << ", "
2089 << store->mCenter.y << ") Angle: " << store->mAngle
2090 << " Range:" << store->mStartOffset << " - " << store->mEndOffset;
2091 return;
2093 case PatternType::SURFACE: {
2094 const SurfacePatternStorage* store =
2095 reinterpret_cast<const SurfacePatternStorage*>(&aStorage.mStorage);
2096 aOutput << "Surface (0x" << store->mSurface << ")";
2097 return;
2102 inline bool RecordedDrawTargetCreation::PlayEvent(
2103 Translator* aTranslator) const {
2104 RefPtr<DrawTarget> newDT =
2105 aTranslator->CreateDrawTarget(mRefPtr, mRect.Size(), mFormat);
2107 // If we couldn't create a DrawTarget this will probably cause us to crash
2108 // with nullptr later in the playback, so return false to abort.
2109 if (!newDT) {
2110 return false;
2113 if (mHasExistingData) {
2114 Rect dataRect(0, 0, mExistingData->GetSize().width,
2115 mExistingData->GetSize().height);
2116 newDT->DrawSurface(mExistingData, dataRect, dataRect);
2119 return true;
2122 template <class S>
2123 void RecordedDrawTargetCreation::Record(S& aStream) const {
2124 WriteElement(aStream, mRefPtr);
2125 WriteElement(aStream, mBackendType);
2126 WriteElement(aStream, mRect);
2127 WriteElement(aStream, mFormat);
2128 WriteElement(aStream, mHasExistingData);
2130 if (mHasExistingData) {
2131 MOZ_ASSERT(mExistingData);
2132 MOZ_ASSERT(mExistingData->GetSize() == mRect.Size());
2133 RefPtr<DataSourceSurface> dataSurf = mExistingData->GetDataSurface();
2135 DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ);
2136 for (int y = 0; y < mRect.height; y++) {
2137 aStream.write((const char*)map.GetData() + y * map.GetStride(),
2138 BytesPerPixel(mFormat) * mRect.width);
2143 template <class S>
2144 RecordedDrawTargetCreation::RecordedDrawTargetCreation(S& aStream)
2145 : RecordedEventDerived(DRAWTARGETCREATION), mExistingData(nullptr) {
2146 ReadElement(aStream, mRefPtr);
2147 ReadElementConstrained(aStream, mBackendType, BackendType::NONE,
2148 BackendType::WEBRENDER_TEXT);
2149 ReadElement(aStream, mRect);
2150 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2151 SurfaceFormat::UNKNOWN);
2152 ReadElement(aStream, mHasExistingData);
2154 if (mHasExistingData) {
2155 RefPtr<DataSourceSurface> dataSurf =
2156 Factory::CreateDataSourceSurface(mRect.Size(), mFormat);
2157 if (!dataSurf) {
2158 gfxWarning()
2159 << "RecordedDrawTargetCreation had to reset mHasExistingData";
2160 mHasExistingData = false;
2161 return;
2164 DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ);
2165 for (int y = 0; y < mRect.height; y++) {
2166 aStream.read((char*)map.GetData() + y * map.GetStride(),
2167 BytesPerPixel(mFormat) * mRect.width);
2169 mExistingData = dataSurf;
2173 inline void RecordedDrawTargetCreation::OutputSimpleEventInfo(
2174 std::stringstream& aStringStream) const {
2175 aStringStream << "[" << mRefPtr << "] DrawTarget Creation (Type: "
2176 << NameFromBackend(mBackendType) << ", Size: " << mRect.width
2177 << "x" << mRect.height << ")";
2180 inline bool RecordedDrawTargetDestruction::PlayEvent(
2181 Translator* aTranslator) const {
2182 aTranslator->RemoveDrawTarget(mRefPtr);
2183 return true;
2186 template <class S>
2187 void RecordedDrawTargetDestruction::Record(S& aStream) const {
2188 WriteElement(aStream, mRefPtr);
2191 template <class S>
2192 RecordedDrawTargetDestruction::RecordedDrawTargetDestruction(S& aStream)
2193 : RecordedEventDerived(DRAWTARGETDESTRUCTION) {
2194 ReadElement(aStream, mRefPtr);
2197 inline void RecordedDrawTargetDestruction::OutputSimpleEventInfo(
2198 std::stringstream& aStringStream) const {
2199 aStringStream << "[" << mRefPtr << "] DrawTarget Destruction";
2202 inline bool RecordedSetCurrentDrawTarget::PlayEvent(
2203 Translator* aTranslator) const {
2204 return aTranslator->SetCurrentDrawTarget(mRefPtr);
2207 template <class S>
2208 void RecordedSetCurrentDrawTarget::Record(S& aStream) const {
2209 WriteElement(aStream, mRefPtr);
2212 template <class S>
2213 RecordedSetCurrentDrawTarget::RecordedSetCurrentDrawTarget(S& aStream)
2214 : RecordedEventDerived(SETCURRENTDRAWTARGET) {
2215 ReadElement(aStream, mRefPtr);
2218 inline void RecordedSetCurrentDrawTarget::OutputSimpleEventInfo(
2219 std::stringstream& aStringStream) const {
2220 aStringStream << "[" << mRefPtr << "] SetCurrentDrawTarget";
2223 inline bool RecordedCreateSimilarDrawTarget::PlayEvent(
2224 Translator* aTranslator) const {
2225 DrawTarget* drawTarget = aTranslator->GetCurrentDrawTarget();
2226 if (!drawTarget) {
2227 return false;
2230 RefPtr<DrawTarget> newDT =
2231 drawTarget->CreateSimilarDrawTarget(mSize, mFormat);
2233 // If we couldn't create a DrawTarget this will probably cause us to crash
2234 // with nullptr later in the playback, so return false to abort.
2235 if (!newDT) {
2236 return false;
2239 aTranslator->AddDrawTarget(mRefPtr, newDT);
2240 return true;
2243 template <class S>
2244 void RecordedCreateSimilarDrawTarget::Record(S& aStream) const {
2245 WriteElement(aStream, mRefPtr);
2246 WriteElement(aStream, mSize);
2247 WriteElement(aStream, mFormat);
2250 template <class S>
2251 RecordedCreateSimilarDrawTarget::RecordedCreateSimilarDrawTarget(S& aStream)
2252 : RecordedEventDerived(CREATESIMILARDRAWTARGET) {
2253 ReadElement(aStream, mRefPtr);
2254 ReadElement(aStream, mSize);
2255 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2256 SurfaceFormat::UNKNOWN);
2259 inline void RecordedCreateSimilarDrawTarget::OutputSimpleEventInfo(
2260 std::stringstream& aStringStream) const {
2261 aStringStream << "[" << mRefPtr
2262 << "] CreateSimilarDrawTarget (Size: " << mSize.width << "x"
2263 << mSize.height << ")";
2266 inline bool RecordedCreateDrawTargetForFilter::PlayEvent(
2267 Translator* aTranslator) const {
2268 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2269 if (!dt) {
2270 return false;
2273 IntRect baseRect = dt->GetRect();
2275 auto maxRect = IntRect(IntPoint(0, 0), mMaxSize);
2277 auto clone = dt->GetTransform();
2278 bool invertible = clone.Invert();
2279 // mSourceRect is in filter space. The filter outputs from mSourceRect need
2280 // to be drawn at mDestPoint in user space.
2281 Rect userSpaceSource = Rect(mDestPoint, mSourceRect.Size());
2282 if (invertible) {
2283 // Try to reduce the source rect so that it's not much bigger
2284 // than the draw target. The result is not minimal. Examples
2285 // are left as an exercise for the reader.
2286 auto destRect = IntRectToRect(baseRect);
2287 Rect userSpaceBounds = clone.TransformBounds(destRect);
2288 userSpaceSource = userSpaceSource.Intersect(userSpaceBounds);
2291 // Compute how much we moved the top-left of the source rect by, and use that
2292 // to compute the new dest point, and move our intersected source rect back
2293 // into the (new) filter space.
2294 Point shift = userSpaceSource.TopLeft() - mDestPoint;
2295 Rect filterSpaceSource =
2296 Rect(mSourceRect.TopLeft() + shift, userSpaceSource.Size());
2298 baseRect = RoundedOut(filterSpaceSource);
2299 FilterNode* filter = aTranslator->LookupFilterNode(mFilter);
2300 if (!filter) {
2301 return false;
2304 IntRect transformedRect = filter->MapRectToSource(
2305 baseRect, maxRect, aTranslator->LookupFilterNode(mSource));
2307 // Intersect with maxRect to make sure we didn't end up with something bigger
2308 transformedRect = transformedRect.Intersect(maxRect);
2310 // If we end up with an empty rect make it 1x1 so that things don't break.
2311 if (transformedRect.IsEmpty()) {
2312 transformedRect = IntRect(0, 0, 1, 1);
2315 RefPtr<DrawTarget> newDT =
2316 dt->CreateSimilarDrawTarget(transformedRect.Size(), mFormat);
2317 if (!newDT) {
2318 return false;
2320 newDT =
2321 gfx::Factory::CreateOffsetDrawTarget(newDT, transformedRect.TopLeft());
2323 // If we couldn't create a DrawTarget this will probably cause us to crash
2324 // with nullptr later in the playback, so return false to abort.
2325 if (!newDT) {
2326 return false;
2329 aTranslator->AddDrawTarget(mRefPtr, newDT);
2330 return true;
2333 inline bool RecordedCreateClippedDrawTarget::PlayEvent(
2334 Translator* aTranslator) const {
2335 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2336 if (!dt) {
2337 return false;
2340 RefPtr<DrawTarget> newDT = dt->CreateClippedDrawTarget(mBounds, mFormat);
2342 // If we couldn't create a DrawTarget this will probably cause us to crash
2343 // with nullptr later in the playback, so return false to abort.
2344 if (!newDT) {
2345 return false;
2348 aTranslator->AddDrawTarget(mRefPtr, newDT);
2349 return true;
2352 template <class S>
2353 void RecordedCreateClippedDrawTarget::Record(S& aStream) const {
2354 WriteElement(aStream, mRefPtr);
2355 WriteElement(aStream, mBounds);
2356 WriteElement(aStream, mFormat);
2359 template <class S>
2360 RecordedCreateClippedDrawTarget::RecordedCreateClippedDrawTarget(S& aStream)
2361 : RecordedEventDerived(CREATECLIPPEDDRAWTARGET) {
2362 ReadElement(aStream, mRefPtr);
2363 ReadElement(aStream, mBounds);
2364 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2365 SurfaceFormat::UNKNOWN);
2368 inline void RecordedCreateClippedDrawTarget::OutputSimpleEventInfo(
2369 std::stringstream& aStringStream) const {
2370 aStringStream << "[" << mRefPtr << "] CreateClippedDrawTarget ()";
2373 template <class S>
2374 void RecordedCreateDrawTargetForFilter::Record(S& aStream) const {
2375 WriteElement(aStream, mRefPtr);
2376 WriteElement(aStream, mMaxSize);
2377 WriteElement(aStream, mFormat);
2378 WriteElement(aStream, mFilter);
2379 WriteElement(aStream, mSource);
2380 WriteElement(aStream, mSourceRect);
2381 WriteElement(aStream, mDestPoint);
2384 template <class S>
2385 RecordedCreateDrawTargetForFilter::RecordedCreateDrawTargetForFilter(S& aStream)
2386 : RecordedEventDerived(CREATEDRAWTARGETFORFILTER) {
2387 ReadElement(aStream, mRefPtr);
2388 ReadElement(aStream, mMaxSize);
2389 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2390 SurfaceFormat::UNKNOWN);
2391 ReadElement(aStream, mFilter);
2392 ReadElement(aStream, mSource);
2393 ReadElement(aStream, mSourceRect);
2394 ReadElement(aStream, mDestPoint);
2397 inline void RecordedCreateDrawTargetForFilter::OutputSimpleEventInfo(
2398 std::stringstream& aStringStream) const {
2399 aStringStream << "[" << mRefPtr << "] CreateDrawTargetForFilter ()";
2402 struct GenericPattern {
2403 GenericPattern(const PatternStorage& aStorage, Translator* aTranslator)
2404 : mPattern(nullptr), mTranslator(aTranslator) {
2405 mStorage = const_cast<PatternStorage*>(&aStorage);
2408 ~GenericPattern() {
2409 if (mPattern) {
2410 mPattern->~Pattern();
2414 operator Pattern*() {
2415 switch (mStorage->mType) {
2416 case PatternType::COLOR:
2417 return new (mColPat) ColorPattern(
2418 reinterpret_cast<ColorPatternStorage*>(&mStorage->mStorage)
2419 ->mColor);
2420 case PatternType::SURFACE: {
2421 SurfacePatternStorage* storage =
2422 reinterpret_cast<SurfacePatternStorage*>(&mStorage->mStorage);
2423 mPattern = new (mSurfPat)
2424 SurfacePattern(mTranslator->LookupSourceSurface(storage->mSurface),
2425 storage->mExtend, storage->mMatrix,
2426 storage->mSamplingFilter, storage->mSamplingRect);
2427 return mPattern;
2429 case PatternType::LINEAR_GRADIENT: {
2430 LinearGradientPatternStorage* storage =
2431 reinterpret_cast<LinearGradientPatternStorage*>(
2432 &mStorage->mStorage);
2433 mPattern = new (mLinGradPat) LinearGradientPattern(
2434 storage->mBegin, storage->mEnd,
2435 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2436 : nullptr,
2437 storage->mMatrix);
2438 return mPattern;
2440 case PatternType::RADIAL_GRADIENT: {
2441 RadialGradientPatternStorage* storage =
2442 reinterpret_cast<RadialGradientPatternStorage*>(
2443 &mStorage->mStorage);
2444 mPattern = new (mRadGradPat) RadialGradientPattern(
2445 storage->mCenter1, storage->mCenter2, storage->mRadius1,
2446 storage->mRadius2,
2447 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2448 : nullptr,
2449 storage->mMatrix);
2450 return mPattern;
2452 case PatternType::CONIC_GRADIENT: {
2453 ConicGradientPatternStorage* storage =
2454 reinterpret_cast<ConicGradientPatternStorage*>(&mStorage->mStorage);
2455 mPattern = new (mConGradPat) ConicGradientPattern(
2456 storage->mCenter, storage->mAngle, storage->mStartOffset,
2457 storage->mEndOffset,
2458 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2459 : nullptr,
2460 storage->mMatrix);
2461 return mPattern;
2463 default:
2464 return new (mColPat) ColorPattern(DeviceColor());
2467 return mPattern;
2470 union {
2471 char mColPat[sizeof(ColorPattern)];
2472 char mLinGradPat[sizeof(LinearGradientPattern)];
2473 char mRadGradPat[sizeof(RadialGradientPattern)];
2474 char mConGradPat[sizeof(ConicGradientPattern)];
2475 char mSurfPat[sizeof(SurfacePattern)];
2478 PatternStorage* mStorage;
2479 Pattern* mPattern;
2480 Translator* mTranslator;
2483 inline bool RecordedFillRect::PlayEvent(Translator* aTranslator) const {
2484 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2485 if (!dt) {
2486 return false;
2489 dt->FillRect(mRect, *GenericPattern(mPattern, aTranslator), mOptions);
2490 return true;
2493 template <class S>
2494 void RecordedFillRect::Record(S& aStream) const {
2495 WriteElement(aStream, mRect);
2496 WriteElement(aStream, mOptions);
2497 RecordPatternData(aStream, mPattern);
2500 template <class S>
2501 RecordedFillRect::RecordedFillRect(S& aStream)
2502 : RecordedEventDerived(FILLRECT) {
2503 ReadElement(aStream, mRect);
2504 ReadDrawOptions(aStream, mOptions);
2505 ReadPatternData(aStream, mPattern);
2508 inline void RecordedFillRect::OutputSimpleEventInfo(
2509 std::stringstream& aStringStream) const {
2510 aStringStream << "FillRect (" << mRect.X() << ", " << mRect.Y() << " - "
2511 << mRect.Width() << " x " << mRect.Height() << ") ";
2512 OutputSimplePatternInfo(mPattern, aStringStream);
2515 inline bool RecordedStrokeRect::PlayEvent(Translator* aTranslator) const {
2516 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2517 if (!dt) {
2518 return false;
2521 dt->StrokeRect(mRect, *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2522 mOptions);
2523 return true;
2526 template <class S>
2527 void RecordedStrokeRect::Record(S& aStream) const {
2528 WriteElement(aStream, mRect);
2529 WriteElement(aStream, mOptions);
2530 RecordPatternData(aStream, mPattern);
2531 RecordStrokeOptions(aStream, mStrokeOptions);
2534 template <class S>
2535 RecordedStrokeRect::RecordedStrokeRect(S& aStream)
2536 : RecordedEventDerived(STROKERECT) {
2537 ReadElement(aStream, mRect);
2538 ReadDrawOptions(aStream, mOptions);
2539 ReadPatternData(aStream, mPattern);
2540 ReadStrokeOptions(aStream, mStrokeOptions);
2543 inline void RecordedStrokeRect::OutputSimpleEventInfo(
2544 std::stringstream& aStringStream) const {
2545 aStringStream << "StrokeRect (" << mRect.X() << ", " << mRect.Y() << " - "
2546 << mRect.Width() << " x " << mRect.Height()
2547 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2548 OutputSimplePatternInfo(mPattern, aStringStream);
2551 inline bool RecordedStrokeLine::PlayEvent(Translator* aTranslator) const {
2552 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2553 if (!dt) {
2554 return false;
2557 dt->StrokeLine(mBegin, mEnd, *GenericPattern(mPattern, aTranslator),
2558 mStrokeOptions, mOptions);
2559 return true;
2562 template <class S>
2563 void RecordedStrokeLine::Record(S& aStream) const {
2564 WriteElement(aStream, mBegin);
2565 WriteElement(aStream, mEnd);
2566 WriteElement(aStream, mOptions);
2567 RecordPatternData(aStream, mPattern);
2568 RecordStrokeOptions(aStream, mStrokeOptions);
2571 template <class S>
2572 RecordedStrokeLine::RecordedStrokeLine(S& aStream)
2573 : RecordedEventDerived(STROKELINE) {
2574 ReadElement(aStream, mBegin);
2575 ReadElement(aStream, mEnd);
2576 ReadDrawOptions(aStream, mOptions);
2577 ReadPatternData(aStream, mPattern);
2578 ReadStrokeOptions(aStream, mStrokeOptions);
2581 inline void RecordedStrokeLine::OutputSimpleEventInfo(
2582 std::stringstream& aStringStream) const {
2583 aStringStream << "StrokeLine (" << mBegin.x << ", " << mBegin.y << " - "
2584 << mEnd.x << ", " << mEnd.y
2585 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2586 OutputSimplePatternInfo(mPattern, aStringStream);
2589 inline bool RecordedStrokeCircle::PlayEvent(Translator* aTranslator) const {
2590 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2591 if (!dt) {
2592 return false;
2595 dt->StrokeCircle(mCircle.origin, mCircle.radius,
2596 *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2597 mOptions);
2598 return true;
2601 template <class S>
2602 void RecordedStrokeCircle::Record(S& aStream) const {
2603 WriteElement(aStream, mCircle);
2604 WriteElement(aStream, mOptions);
2605 RecordPatternData(aStream, mPattern);
2606 RecordStrokeOptions(aStream, mStrokeOptions);
2609 template <class S>
2610 RecordedStrokeCircle::RecordedStrokeCircle(S& aStream)
2611 : RecordedEventDerived(STROKECIRCLE) {
2612 ReadElement(aStream, mCircle);
2613 ReadDrawOptions(aStream, mOptions);
2614 ReadPatternData(aStream, mPattern);
2615 ReadStrokeOptions(aStream, mStrokeOptions);
2618 inline void RecordedStrokeCircle::OutputSimpleEventInfo(
2619 std::stringstream& aStringStream) const {
2620 aStringStream << "StrokeCircle (" << mCircle.origin.x << ", "
2621 << mCircle.origin.y << " - " << mCircle.radius
2622 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2623 OutputSimplePatternInfo(mPattern, aStringStream);
2626 inline bool RecordedFill::PlayEvent(Translator* aTranslator) const {
2627 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2628 if (!dt) {
2629 return false;
2632 dt->Fill(aTranslator->LookupPath(mPath),
2633 *GenericPattern(mPattern, aTranslator), mOptions);
2634 return true;
2637 template <class S>
2638 RecordedFill::RecordedFill(S& aStream) : RecordedEventDerived(FILL) {
2639 ReadElement(aStream, mPath);
2640 ReadDrawOptions(aStream, mOptions);
2641 ReadPatternData(aStream, mPattern);
2644 template <class S>
2645 void RecordedFill::Record(S& aStream) const {
2646 WriteElement(aStream, mPath);
2647 WriteElement(aStream, mOptions);
2648 RecordPatternData(aStream, mPattern);
2651 inline void RecordedFill::OutputSimpleEventInfo(
2652 std::stringstream& aStringStream) const {
2653 aStringStream << "Fill (" << mPath << ") ";
2654 OutputSimplePatternInfo(mPattern, aStringStream);
2657 inline bool RecordedFillCircle::PlayEvent(Translator* aTranslator) const {
2658 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2659 if (!dt) {
2660 return false;
2663 dt->FillCircle(mCircle.origin, mCircle.radius,
2664 *GenericPattern(mPattern, aTranslator), mOptions);
2665 return true;
2668 template <class S>
2669 void RecordedFillCircle::Record(S& aStream) const {
2670 WriteElement(aStream, mCircle);
2671 WriteElement(aStream, mOptions);
2672 RecordPatternData(aStream, mPattern);
2675 template <class S>
2676 RecordedFillCircle::RecordedFillCircle(S& aStream)
2677 : RecordedEventDerived(FILLCIRCLE) {
2678 ReadElement(aStream, mCircle);
2679 ReadDrawOptions(aStream, mOptions);
2680 ReadPatternData(aStream, mPattern);
2683 inline void RecordedFillCircle::OutputSimpleEventInfo(
2684 std::stringstream& aStringStream) const {
2685 aStringStream << "FillCircle (" << mCircle.origin.x << ", "
2686 << mCircle.origin.y << " - " << mCircle.radius << ")";
2687 OutputSimplePatternInfo(mPattern, aStringStream);
2690 template <class T>
2691 inline RecordedDrawGlyphs<T>::~RecordedDrawGlyphs() {
2692 delete[] mGlyphs;
2695 template <class T>
2696 inline bool RecordedDrawGlyphs<T>::PlayEvent(Translator* aTranslator) const {
2697 if (mNumGlyphs > 0 && !mGlyphs) {
2698 // Glyph allocation failed
2699 return false;
2702 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2703 if (!dt) {
2704 return false;
2707 ScaledFont* scaledFont = aTranslator->LookupScaledFont(mScaledFont);
2708 if (!scaledFont) {
2709 return false;
2712 GlyphBuffer buffer;
2713 buffer.mGlyphs = mGlyphs;
2714 buffer.mNumGlyphs = mNumGlyphs;
2715 DrawGlyphs(dt, scaledFont, buffer, *GenericPattern(mPattern, aTranslator));
2716 return true;
2719 template <class T>
2720 template <class S>
2721 RecordedDrawGlyphs<T>::RecordedDrawGlyphs(RecordedEvent::EventType aType,
2722 S& aStream)
2723 : RecordedEventDerived<T>(aType) {
2724 ReadElement(aStream, mScaledFont);
2725 ReadDrawOptions(aStream, mOptions);
2726 this->ReadPatternData(aStream, mPattern);
2727 ReadElement(aStream, mNumGlyphs);
2728 if (!aStream.good() || mNumGlyphs <= 0) {
2729 return;
2732 mGlyphs = new (fallible) Glyph[mNumGlyphs];
2733 if (!mGlyphs) {
2734 gfxCriticalNote << "RecordedDrawGlyphs failed to allocate glyphs of size "
2735 << mNumGlyphs;
2736 aStream.SetIsBad();
2737 } else {
2738 aStream.read((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
2742 template <class T>
2743 template <class S>
2744 void RecordedDrawGlyphs<T>::Record(S& aStream) const {
2745 WriteElement(aStream, mScaledFont);
2746 WriteElement(aStream, mOptions);
2747 this->RecordPatternData(aStream, mPattern);
2748 WriteElement(aStream, mNumGlyphs);
2749 aStream.write((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
2752 template <class T>
2753 inline void RecordedDrawGlyphs<T>::OutputSimpleEventInfo(
2754 std::stringstream& aStringStream) const {
2755 aStringStream << this->GetName() << " (" << mScaledFont << ") ";
2756 this->OutputSimplePatternInfo(mPattern, aStringStream);
2759 inline bool RecordedMask::PlayEvent(Translator* aTranslator) const {
2760 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2761 if (!dt) {
2762 return false;
2765 dt->Mask(*GenericPattern(mSource, aTranslator),
2766 *GenericPattern(mMask, aTranslator), mOptions);
2767 return true;
2770 template <class S>
2771 RecordedMask::RecordedMask(S& aStream) : RecordedEventDerived(MASK) {
2772 ReadDrawOptions(aStream, mOptions);
2773 ReadPatternData(aStream, mSource);
2774 ReadPatternData(aStream, mMask);
2777 template <class S>
2778 void RecordedMask::Record(S& aStream) const {
2779 WriteElement(aStream, mOptions);
2780 RecordPatternData(aStream, mSource);
2781 RecordPatternData(aStream, mMask);
2784 inline void RecordedMask::OutputSimpleEventInfo(
2785 std::stringstream& aStringStream) const {
2786 aStringStream << "Mask (Source: ";
2787 OutputSimplePatternInfo(mSource, aStringStream);
2788 aStringStream << " Mask: ";
2789 OutputSimplePatternInfo(mMask, aStringStream);
2792 inline bool RecordedStroke::PlayEvent(Translator* aTranslator) const {
2793 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2794 if (!dt) {
2795 return false;
2798 Path* path = aTranslator->LookupPath(mPath);
2799 if (!path) {
2800 return false;
2803 dt->Stroke(path, *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2804 mOptions);
2805 return true;
2808 template <class S>
2809 void RecordedStroke::Record(S& aStream) const {
2810 WriteElement(aStream, mPath);
2811 WriteElement(aStream, mOptions);
2812 RecordPatternData(aStream, mPattern);
2813 RecordStrokeOptions(aStream, mStrokeOptions);
2816 template <class S>
2817 RecordedStroke::RecordedStroke(S& aStream) : RecordedEventDerived(STROKE) {
2818 ReadElement(aStream, mPath);
2819 ReadDrawOptions(aStream, mOptions);
2820 ReadPatternData(aStream, mPattern);
2821 ReadStrokeOptions(aStream, mStrokeOptions);
2824 inline void RecordedStroke::OutputSimpleEventInfo(
2825 std::stringstream& aStringStream) const {
2826 aStringStream << "Stroke (" << mPath
2827 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2828 OutputSimplePatternInfo(mPattern, aStringStream);
2831 inline bool RecordedClearRect::PlayEvent(Translator* aTranslator) const {
2832 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2833 if (!dt) {
2834 return false;
2837 dt->ClearRect(mRect);
2838 return true;
2841 template <class S>
2842 void RecordedClearRect::Record(S& aStream) const {
2843 WriteElement(aStream, mRect);
2846 template <class S>
2847 RecordedClearRect::RecordedClearRect(S& aStream)
2848 : RecordedEventDerived(CLEARRECT) {
2849 ReadElement(aStream, mRect);
2852 inline void RecordedClearRect::OutputSimpleEventInfo(
2853 std::stringstream& aStringStream) const {
2854 aStringStream << "ClearRect (" << mRect.X() << ", " << mRect.Y() << " - "
2855 << mRect.Width() << " x " << mRect.Height() << ") ";
2858 inline bool RecordedCopySurface::PlayEvent(Translator* aTranslator) const {
2859 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2860 if (!dt) {
2861 return false;
2864 SourceSurface* surface = aTranslator->LookupSourceSurface(mSourceSurface);
2865 if (!surface) {
2866 return false;
2869 dt->CopySurface(surface, mSourceRect, mDest);
2870 return true;
2873 template <class S>
2874 void RecordedCopySurface::Record(S& aStream) const {
2875 WriteElement(aStream, mSourceSurface);
2876 WriteElement(aStream, mSourceRect);
2877 WriteElement(aStream, mDest);
2880 template <class S>
2881 RecordedCopySurface::RecordedCopySurface(S& aStream)
2882 : RecordedEventDerived(COPYSURFACE) {
2883 ReadElement(aStream, mSourceSurface);
2884 ReadElement(aStream, mSourceRect);
2885 ReadElement(aStream, mDest);
2888 inline void RecordedCopySurface::OutputSimpleEventInfo(
2889 std::stringstream& aStringStream) const {
2890 aStringStream << "CopySurface (" << mSourceSurface << ")";
2893 inline bool RecordedPushClip::PlayEvent(Translator* aTranslator) const {
2894 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2895 if (!dt) {
2896 return false;
2899 Path* path = aTranslator->LookupPath(mPath);
2900 if (!path) {
2901 return false;
2904 dt->PushClip(path);
2905 return true;
2908 template <class S>
2909 void RecordedPushClip::Record(S& aStream) const {
2910 WriteElement(aStream, mPath);
2913 template <class S>
2914 RecordedPushClip::RecordedPushClip(S& aStream)
2915 : RecordedEventDerived(PUSHCLIP) {
2916 ReadElement(aStream, mPath);
2919 inline void RecordedPushClip::OutputSimpleEventInfo(
2920 std::stringstream& aStringStream) const {
2921 aStringStream << "PushClip (" << mPath << ") ";
2924 inline bool RecordedPushClipRect::PlayEvent(Translator* aTranslator) const {
2925 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2926 if (!dt) {
2927 return false;
2930 dt->PushClipRect(mRect);
2931 return true;
2934 template <class S>
2935 void RecordedPushClipRect::Record(S& aStream) const {
2936 WriteElement(aStream, mRect);
2939 template <class S>
2940 RecordedPushClipRect::RecordedPushClipRect(S& aStream)
2941 : RecordedEventDerived(PUSHCLIPRECT) {
2942 ReadElement(aStream, mRect);
2945 inline void RecordedPushClipRect::OutputSimpleEventInfo(
2946 std::stringstream& aStringStream) const {
2947 aStringStream << "PushClipRect (" << mRect.X() << ", " << mRect.Y() << " - "
2948 << mRect.Width() << " x " << mRect.Height() << ") ";
2951 inline bool RecordedPopClip::PlayEvent(Translator* aTranslator) const {
2952 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2953 if (!dt) {
2954 return false;
2957 dt->PopClip();
2958 return true;
2961 template <class S>
2962 void RecordedPopClip::Record(S& aStream) const {}
2964 template <class S>
2965 RecordedPopClip::RecordedPopClip(S& aStream) : RecordedEventDerived(POPCLIP) {}
2967 inline void RecordedPopClip::OutputSimpleEventInfo(
2968 std::stringstream& aStringStream) const {
2969 aStringStream << "PopClip";
2972 inline bool RecordedPushLayer::PlayEvent(Translator* aTranslator) const {
2973 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2974 if (!dt) {
2975 return false;
2978 SourceSurface* mask =
2979 mMask ? aTranslator->LookupSourceSurface(mMask) : nullptr;
2980 dt->PushLayer(mOpaque, mOpacity, mask, mMaskTransform, mBounds,
2981 mCopyBackground);
2982 return true;
2985 template <class S>
2986 void RecordedPushLayer::Record(S& aStream) const {
2987 WriteElement(aStream, mOpaque);
2988 WriteElement(aStream, mOpacity);
2989 WriteElement(aStream, mMask);
2990 WriteElement(aStream, mMaskTransform);
2991 WriteElement(aStream, mBounds);
2992 WriteElement(aStream, mCopyBackground);
2995 template <class S>
2996 RecordedPushLayer::RecordedPushLayer(S& aStream)
2997 : RecordedEventDerived(PUSHLAYER) {
2998 ReadElement(aStream, mOpaque);
2999 ReadElement(aStream, mOpacity);
3000 ReadElement(aStream, mMask);
3001 ReadElement(aStream, mMaskTransform);
3002 ReadElement(aStream, mBounds);
3003 ReadElement(aStream, mCopyBackground);
3006 inline void RecordedPushLayer::OutputSimpleEventInfo(
3007 std::stringstream& aStringStream) const {
3008 aStringStream << "PushPLayer (Opaque=" << mOpaque << ", Opacity=" << mOpacity
3009 << ", Mask Ref=" << mMask << ") ";
3012 inline bool RecordedPushLayerWithBlend::PlayEvent(
3013 Translator* aTranslator) const {
3014 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3015 if (!dt) {
3016 return false;
3019 SourceSurface* mask =
3020 mMask ? aTranslator->LookupSourceSurface(mMask) : nullptr;
3021 dt->PushLayerWithBlend(mOpaque, mOpacity, mask, mMaskTransform, mBounds,
3022 mCopyBackground, mCompositionOp);
3023 return true;
3026 template <class S>
3027 void RecordedPushLayerWithBlend::Record(S& aStream) const {
3028 WriteElement(aStream, mOpaque);
3029 WriteElement(aStream, mOpacity);
3030 WriteElement(aStream, mMask);
3031 WriteElement(aStream, mMaskTransform);
3032 WriteElement(aStream, mBounds);
3033 WriteElement(aStream, mCopyBackground);
3034 WriteElement(aStream, mCompositionOp);
3037 template <class S>
3038 RecordedPushLayerWithBlend::RecordedPushLayerWithBlend(S& aStream)
3039 : RecordedEventDerived(PUSHLAYERWITHBLEND) {
3040 ReadElement(aStream, mOpaque);
3041 ReadElement(aStream, mOpacity);
3042 ReadElement(aStream, mMask);
3043 ReadElement(aStream, mMaskTransform);
3044 ReadElement(aStream, mBounds);
3045 ReadElement(aStream, mCopyBackground);
3046 ReadElementConstrained(aStream, mCompositionOp, CompositionOp::OP_OVER,
3047 CompositionOp::OP_COUNT);
3050 inline void RecordedPushLayerWithBlend::OutputSimpleEventInfo(
3051 std::stringstream& aStringStream) const {
3052 aStringStream << "PushLayerWithBlend (Opaque=" << mOpaque
3053 << ", Opacity=" << mOpacity << ", Mask Ref=" << mMask << ") ";
3056 inline bool RecordedPopLayer::PlayEvent(Translator* aTranslator) const {
3057 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3058 if (!dt) {
3059 return false;
3062 dt->PopLayer();
3063 return true;
3066 template <class S>
3067 void RecordedPopLayer::Record(S& aStream) const {}
3069 template <class S>
3070 RecordedPopLayer::RecordedPopLayer(S& aStream)
3071 : RecordedEventDerived(POPLAYER) {}
3073 inline void RecordedPopLayer::OutputSimpleEventInfo(
3074 std::stringstream& aStringStream) const {
3075 aStringStream << "PopLayer";
3078 inline bool RecordedSetPermitSubpixelAA::PlayEvent(
3079 Translator* aTranslator) const {
3080 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3081 if (!dt) {
3082 return false;
3085 dt->SetPermitSubpixelAA(mPermitSubpixelAA);
3086 return true;
3089 template <class S>
3090 void RecordedSetPermitSubpixelAA::Record(S& aStream) const {
3091 WriteElement(aStream, mPermitSubpixelAA);
3094 template <class S>
3095 RecordedSetPermitSubpixelAA::RecordedSetPermitSubpixelAA(S& aStream)
3096 : RecordedEventDerived(SETPERMITSUBPIXELAA) {
3097 ReadElement(aStream, mPermitSubpixelAA);
3100 inline void RecordedSetPermitSubpixelAA::OutputSimpleEventInfo(
3101 std::stringstream& aStringStream) const {
3102 aStringStream << "SetPermitSubpixelAA (" << mPermitSubpixelAA << ")";
3105 inline bool RecordedSetTransform::PlayEvent(Translator* aTranslator) const {
3106 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3107 if (!dt) {
3108 return false;
3111 // If we're drawing to the reference DT, then we need to manually apply
3112 // its initial transform, otherwise we'll just clobber it with only the
3113 // the transform that was visible to the code doing the recording.
3114 if (dt == aTranslator->GetReferenceDrawTarget()) {
3115 dt->SetTransform(mTransform *
3116 aTranslator->GetReferenceDrawTargetTransform());
3117 } else {
3118 dt->SetTransform(mTransform);
3121 return true;
3124 template <class S>
3125 void RecordedSetTransform::Record(S& aStream) const {
3126 WriteElement(aStream, mTransform);
3129 template <class S>
3130 RecordedSetTransform::RecordedSetTransform(S& aStream)
3131 : RecordedEventDerived(SETTRANSFORM) {
3132 ReadElement(aStream, mTransform);
3135 inline void RecordedSetTransform::OutputSimpleEventInfo(
3136 std::stringstream& aStringStream) const {
3137 aStringStream << "SetTransform [ " << mTransform._11 << " " << mTransform._12
3138 << " ; " << mTransform._21 << " " << mTransform._22 << " ; "
3139 << mTransform._31 << " " << mTransform._32 << " ]";
3142 inline bool RecordedDrawSurface::PlayEvent(Translator* aTranslator) const {
3143 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3144 if (!dt) {
3145 return false;
3148 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefSource);
3149 if (!surface) {
3150 return false;
3153 dt->DrawSurface(surface, mDest, mSource, mDSOptions, mOptions);
3154 return true;
3157 template <class S>
3158 void RecordedDrawSurface::Record(S& aStream) const {
3159 WriteElement(aStream, mRefSource);
3160 WriteElement(aStream, mDest);
3161 WriteElement(aStream, mSource);
3162 WriteElement(aStream, mDSOptions);
3163 WriteElement(aStream, mOptions);
3166 template <class S>
3167 RecordedDrawSurface::RecordedDrawSurface(S& aStream)
3168 : RecordedEventDerived(DRAWSURFACE) {
3169 ReadElement(aStream, mRefSource);
3170 ReadElement(aStream, mDest);
3171 ReadElement(aStream, mSource);
3172 ReadDrawSurfaceOptions(aStream, mDSOptions);
3173 ReadDrawOptions(aStream, mOptions);
3176 inline void RecordedDrawSurface::OutputSimpleEventInfo(
3177 std::stringstream& aStringStream) const {
3178 aStringStream << "DrawSurface (" << mRefSource << ")";
3181 inline bool RecordedDrawSurfaceDescriptor::PlayEvent(
3182 Translator* aTranslator) const {
3183 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3184 if (!dt) {
3185 return false;
3188 RefPtr<SourceSurface> surface =
3189 aTranslator->LookupSourceSurfaceFromSurfaceDescriptor(mDesc);
3190 if (!surface) {
3191 return false;
3194 RefPtr<SourceSurface> opt = dt->OptimizeSourceSurface(surface);
3195 if (opt) {
3196 surface = opt;
3199 dt->DrawSurface(surface, mDest, mSource, mDSOptions, mOptions);
3200 return true;
3203 template <class S>
3204 void RecordedDrawSurfaceDescriptor::Record(S& aStream) const {
3205 WriteElement(aStream, mDesc);
3206 WriteElement(aStream, mDest);
3207 WriteElement(aStream, mSource);
3208 WriteElement(aStream, mDSOptions);
3209 WriteElement(aStream, mOptions);
3212 template <class S>
3213 RecordedDrawSurfaceDescriptor::RecordedDrawSurfaceDescriptor(S& aStream)
3214 : RecordedEventDerived(DRAWSURFACEDESCRIPTOR) {
3215 ReadElement(aStream, mDesc);
3216 ReadElement(aStream, mDest);
3217 ReadElement(aStream, mSource);
3218 ReadDrawSurfaceOptions(aStream, mDSOptions);
3219 ReadDrawOptions(aStream, mOptions);
3222 inline void RecordedDrawSurfaceDescriptor::OutputSimpleEventInfo(
3223 std::stringstream& aStringStream) const {
3224 aStringStream << "DrawSurfaceDescriptor (" << mDesc.type() << ")";
3227 inline bool RecordedDrawDependentSurface::PlayEvent(
3228 Translator* aTranslator) const {
3229 aTranslator->DrawDependentSurface(mId, mDest);
3230 return true;
3233 template <class S>
3234 void RecordedDrawDependentSurface::Record(S& aStream) const {
3235 WriteElement(aStream, mId);
3236 WriteElement(aStream, mDest);
3239 template <class S>
3240 RecordedDrawDependentSurface::RecordedDrawDependentSurface(S& aStream)
3241 : RecordedEventDerived(DRAWDEPENDENTSURFACE) {
3242 ReadElement(aStream, mId);
3243 ReadElement(aStream, mDest);
3246 inline void RecordedDrawDependentSurface::OutputSimpleEventInfo(
3247 std::stringstream& aStringStream) const {
3248 aStringStream << "DrawDependentSurface (" << mId << ")";
3251 inline bool RecordedDrawFilter::PlayEvent(Translator* aTranslator) const {
3252 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3253 if (!dt) {
3254 return false;
3257 FilterNode* filter = aTranslator->LookupFilterNode(mNode);
3258 if (!filter) {
3259 return false;
3262 dt->DrawFilter(filter, mSourceRect, mDestPoint, mOptions);
3263 return true;
3266 template <class S>
3267 void RecordedDrawFilter::Record(S& aStream) const {
3268 WriteElement(aStream, mNode);
3269 WriteElement(aStream, mSourceRect);
3270 WriteElement(aStream, mDestPoint);
3271 WriteElement(aStream, mOptions);
3274 template <class S>
3275 RecordedDrawFilter::RecordedDrawFilter(S& aStream)
3276 : RecordedEventDerived(DRAWFILTER) {
3277 ReadElement(aStream, mNode);
3278 ReadElement(aStream, mSourceRect);
3279 ReadElement(aStream, mDestPoint);
3280 ReadDrawOptions(aStream, mOptions);
3283 inline void RecordedDrawFilter::OutputSimpleEventInfo(
3284 std::stringstream& aStringStream) const {
3285 aStringStream << "DrawFilter (" << mNode << ")";
3288 inline bool RecordedDrawSurfaceWithShadow::PlayEvent(
3289 Translator* aTranslator) const {
3290 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3291 if (!dt) {
3292 return false;
3295 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefSource);
3296 if (!surface) {
3297 return false;
3300 dt->DrawSurfaceWithShadow(surface, mDest, mShadow, mOp);
3301 return true;
3304 template <class S>
3305 void RecordedDrawSurfaceWithShadow::Record(S& aStream) const {
3306 WriteElement(aStream, mRefSource);
3307 WriteElement(aStream, mDest);
3308 WriteElement(aStream, mShadow);
3309 WriteElement(aStream, mOp);
3312 template <class S>
3313 RecordedDrawSurfaceWithShadow::RecordedDrawSurfaceWithShadow(S& aStream)
3314 : RecordedEventDerived(DRAWSURFACEWITHSHADOW) {
3315 ReadElement(aStream, mRefSource);
3316 ReadElement(aStream, mDest);
3317 ReadElement(aStream, mShadow);
3318 ReadElementConstrained(aStream, mOp, CompositionOp::OP_OVER,
3319 CompositionOp::OP_COUNT);
3322 inline void RecordedDrawSurfaceWithShadow::OutputSimpleEventInfo(
3323 std::stringstream& aStringStream) const {
3324 aStringStream << "DrawSurfaceWithShadow (" << mRefSource << ") DeviceColor: ("
3325 << mShadow.mColor.r << ", " << mShadow.mColor.g << ", "
3326 << mShadow.mColor.b << ", " << mShadow.mColor.a << ")";
3329 inline bool RecordedDrawShadow::PlayEvent(Translator* aTranslator) const {
3330 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3331 if (!dt) {
3332 return false;
3335 Path* path = aTranslator->LookupPath(mPath);
3336 if (!path) {
3337 return false;
3340 dt->DrawShadow(path, *GenericPattern(mPattern, aTranslator), mShadow,
3341 mOptions, mHasStrokeOptions ? &mStrokeOptions : nullptr);
3342 return true;
3345 template <class S>
3346 void RecordedDrawShadow::Record(S& aStream) const {
3347 WriteElement(aStream, mPath);
3348 RecordPatternData(aStream, mPattern);
3349 WriteElement(aStream, mShadow);
3350 WriteElement(aStream, mOptions);
3351 WriteElement(aStream, mHasStrokeOptions);
3352 if (mHasStrokeOptions) {
3353 RecordStrokeOptions(aStream, mStrokeOptions);
3357 template <class S>
3358 RecordedDrawShadow::RecordedDrawShadow(S& aStream)
3359 : RecordedEventDerived(DRAWSHADOW) {
3360 ReadElement(aStream, mPath);
3361 ReadPatternData(aStream, mPattern);
3362 ReadElement(aStream, mShadow);
3363 ReadDrawOptions(aStream, mOptions);
3364 ReadElement(aStream, mHasStrokeOptions);
3365 if (mHasStrokeOptions) {
3366 ReadStrokeOptions(aStream, mStrokeOptions);
3370 inline void RecordedDrawShadow::OutputSimpleEventInfo(
3371 std::stringstream& aStringStream) const {
3372 aStringStream << "DrawShadow (" << mPath << ") DeviceColor: ("
3373 << mShadow.mColor.r << ", " << mShadow.mColor.g << ", "
3374 << mShadow.mColor.b << ", " << mShadow.mColor.a << ")";
3377 inline RecordedPathCreation::RecordedPathCreation(PathRecording* aPath)
3378 : RecordedEventDerived(PATHCREATION),
3379 mRefPtr(aPath),
3380 mFillRule(aPath->mFillRule),
3381 mPath(aPath) {}
3383 inline bool RecordedPathCreation::PlayEvent(Translator* aTranslator) const {
3384 DrawTarget* drawTarget = aTranslator->GetCurrentDrawTarget();
3385 if (!drawTarget) {
3386 return false;
3389 RefPtr<PathBuilder> builder = drawTarget->CreatePathBuilder(mFillRule);
3390 if (!mPathOps->CheckedStreamToSink(*builder)) {
3391 return false;
3394 RefPtr<Path> path = builder->Finish();
3395 aTranslator->AddPath(mRefPtr, path);
3396 return true;
3399 template <class S>
3400 void RecordedPathCreation::Record(S& aStream) const {
3401 WriteElement(aStream, mRefPtr);
3402 WriteElement(aStream, mFillRule);
3403 mPath->mPathOps.Record(aStream);
3406 template <class S>
3407 RecordedPathCreation::RecordedPathCreation(S& aStream)
3408 : RecordedEventDerived(PATHCREATION) {
3409 ReadElement(aStream, mRefPtr);
3410 ReadElementConstrained(aStream, mFillRule, FillRule::FILL_WINDING,
3411 FillRule::FILL_EVEN_ODD);
3412 mPathOps = MakeUnique<PathOps>(aStream);
3415 inline void RecordedPathCreation::OutputSimpleEventInfo(
3416 std::stringstream& aStringStream) const {
3417 size_t numberOfOps =
3418 mPath ? mPath->mPathOps.NumberOfOps() : mPathOps->NumberOfOps();
3419 aStringStream << "[" << mRefPtr << "] Path created (OpCount: " << numberOfOps
3420 << ")";
3422 inline bool RecordedPathDestruction::PlayEvent(Translator* aTranslator) const {
3423 aTranslator->RemovePath(mRefPtr);
3424 return true;
3427 template <class S>
3428 void RecordedPathDestruction::Record(S& aStream) const {
3429 WriteElement(aStream, mRefPtr);
3432 template <class S>
3433 RecordedPathDestruction::RecordedPathDestruction(S& aStream)
3434 : RecordedEventDerived(PATHDESTRUCTION) {
3435 ReadElement(aStream, mRefPtr);
3438 inline void RecordedPathDestruction::OutputSimpleEventInfo(
3439 std::stringstream& aStringStream) const {
3440 aStringStream << "[" << mRefPtr << "] Path Destroyed";
3443 inline RecordedSourceSurfaceCreation::~RecordedSourceSurfaceCreation() {
3444 if (mDataOwned) {
3445 delete[] mData;
3449 inline bool RecordedSourceSurfaceCreation::PlayEvent(
3450 Translator* aTranslator) const {
3451 if (!mData) {
3452 return false;
3455 RefPtr<SourceSurface> src = Factory::CreateWrappingDataSourceSurface(
3456 mData, mSize.width * BytesPerPixel(mFormat), mSize, mFormat,
3457 [](void* aClosure) { delete[] static_cast<uint8_t*>(aClosure); }, mData);
3458 if (src) {
3459 mDataOwned = false;
3462 aTranslator->AddSourceSurface(mRefPtr, src);
3463 return true;
3466 template <class S>
3467 void RecordedSourceSurfaceCreation::Record(S& aStream) const {
3468 WriteElement(aStream, mRefPtr);
3469 WriteElement(aStream, mSize);
3470 WriteElement(aStream, mFormat);
3471 MOZ_ASSERT(mData);
3472 size_t dataFormatWidth = BytesPerPixel(mFormat) * mSize.width;
3473 const char* endSrc = (const char*)(mData + (mSize.height * mStride));
3474 for (const char* src = (const char*)mData; src < endSrc; src += mStride) {
3475 aStream.write(src, dataFormatWidth);
3479 template <class S>
3480 RecordedSourceSurfaceCreation::RecordedSourceSurfaceCreation(S& aStream)
3481 : RecordedEventDerived(SOURCESURFACECREATION), mDataOwned(true) {
3482 ReadElement(aStream, mRefPtr);
3483 ReadElement(aStream, mSize);
3484 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
3485 SurfaceFormat::UNKNOWN);
3487 if (!Factory::AllowedSurfaceSize(mSize)) {
3488 gfxCriticalNote << "RecordedSourceSurfaceCreation read invalid size "
3489 << mSize;
3490 aStream.SetIsBad();
3493 if (!aStream.good()) {
3494 return;
3497 size_t size = 0;
3498 if (mSize.width >= 0 && mSize.height >= 0) {
3499 size = size_t(mSize.width) * size_t(mSize.height) * BytesPerPixel(mFormat);
3500 mData = new (fallible) uint8_t[size];
3502 if (!mData) {
3503 gfxCriticalNote
3504 << "RecordedSourceSurfaceCreation failed to allocate data of size "
3505 << size;
3506 aStream.SetIsBad();
3507 } else {
3508 aStream.read((char*)mData, size);
3512 inline void RecordedSourceSurfaceCreation::OutputSimpleEventInfo(
3513 std::stringstream& aStringStream) const {
3514 aStringStream << "[" << mRefPtr
3515 << "] SourceSurface created (Size: " << mSize.width << "x"
3516 << mSize.height << ")";
3519 inline bool RecordedSourceSurfaceDestruction::PlayEvent(
3520 Translator* aTranslator) const {
3521 aTranslator->RemoveSourceSurface(mRefPtr);
3522 return true;
3525 template <class S>
3526 void RecordedSourceSurfaceDestruction::Record(S& aStream) const {
3527 WriteElement(aStream, mRefPtr);
3530 template <class S>
3531 RecordedSourceSurfaceDestruction::RecordedSourceSurfaceDestruction(S& aStream)
3532 : RecordedEventDerived(SOURCESURFACEDESTRUCTION) {
3533 ReadElement(aStream, mRefPtr);
3536 inline void RecordedSourceSurfaceDestruction::OutputSimpleEventInfo(
3537 std::stringstream& aStringStream) const {
3538 aStringStream << "[" << mRefPtr << "] SourceSurface Destroyed";
3541 inline bool RecordedOptimizeSourceSurface::PlayEvent(
3542 Translator* aTranslator) const {
3543 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3544 if (!dt) {
3545 return false;
3548 SourceSurface* surface = aTranslator->LookupSourceSurface(mSurface);
3549 if (!surface) {
3550 return false;
3553 RefPtr<SourceSurface> optimizedSurface = dt->OptimizeSourceSurface(surface);
3554 aTranslator->AddSourceSurface(mOptimizedSurface, optimizedSurface);
3555 return true;
3558 template <class S>
3559 void RecordedOptimizeSourceSurface::Record(S& aStream) const {
3560 WriteElement(aStream, mSurface);
3561 WriteElement(aStream, mOptimizedSurface);
3564 template <class S>
3565 RecordedOptimizeSourceSurface::RecordedOptimizeSourceSurface(S& aStream)
3566 : RecordedEventDerived(OPTIMIZESOURCESURFACE) {
3567 ReadElement(aStream, mSurface);
3568 ReadElement(aStream, mOptimizedSurface);
3571 inline void RecordedOptimizeSourceSurface::OutputSimpleEventInfo(
3572 std::stringstream& aStringStream) const {
3573 aStringStream << "[" << mSurface << "] Surface Optimized";
3576 inline bool RecordedExternalSurfaceCreation::PlayEvent(
3577 Translator* aTranslator) const {
3578 RefPtr<SourceSurface> surface = aTranslator->LookupExternalSurface(mKey);
3579 if (!surface) {
3580 return false;
3583 aTranslator->AddSourceSurface(mRefPtr, surface);
3584 return true;
3587 template <class S>
3588 void RecordedExternalSurfaceCreation::Record(S& aStream) const {
3589 WriteElement(aStream, mRefPtr);
3590 WriteElement(aStream, mKey);
3593 template <class S>
3594 RecordedExternalSurfaceCreation::RecordedExternalSurfaceCreation(S& aStream)
3595 : RecordedEventDerived(EXTERNALSURFACECREATION) {
3596 ReadElement(aStream, mRefPtr);
3597 ReadElement(aStream, mKey);
3600 inline void RecordedExternalSurfaceCreation::OutputSimpleEventInfo(
3601 std::stringstream& aStringStream) const {
3602 aStringStream << "[" << mRefPtr
3603 << "] SourceSurfaceSharedData created (Key: " << mKey << ")";
3606 inline RecordedFilterNodeCreation::~RecordedFilterNodeCreation() = default;
3608 inline bool RecordedFilterNodeCreation::PlayEvent(
3609 Translator* aTranslator) const {
3610 DrawTarget* drawTarget = aTranslator->GetCurrentDrawTarget();
3611 if (!drawTarget) {
3612 return false;
3615 RefPtr<FilterNode> node = drawTarget->CreateFilter(mType);
3616 aTranslator->AddFilterNode(mRefPtr, node);
3617 return true;
3620 template <class S>
3621 void RecordedFilterNodeCreation::Record(S& aStream) const {
3622 WriteElement(aStream, mRefPtr);
3623 WriteElement(aStream, mType);
3626 template <class S>
3627 RecordedFilterNodeCreation::RecordedFilterNodeCreation(S& aStream)
3628 : RecordedEventDerived(FILTERNODECREATION) {
3629 ReadElement(aStream, mRefPtr);
3630 ReadElementConstrained(aStream, mType, FilterType::BLEND,
3631 FilterType::OPACITY);
3634 inline void RecordedFilterNodeCreation::OutputSimpleEventInfo(
3635 std::stringstream& aStringStream) const {
3636 aStringStream << "CreateFilter [" << mRefPtr
3637 << "] FilterNode created (Type: " << int(mType) << ")";
3640 inline bool RecordedFilterNodeDestruction::PlayEvent(
3641 Translator* aTranslator) const {
3642 aTranslator->RemoveFilterNode(mRefPtr);
3643 return true;
3646 template <class S>
3647 void RecordedFilterNodeDestruction::Record(S& aStream) const {
3648 WriteElement(aStream, mRefPtr);
3651 template <class S>
3652 RecordedFilterNodeDestruction::RecordedFilterNodeDestruction(S& aStream)
3653 : RecordedEventDerived(FILTERNODEDESTRUCTION) {
3654 ReadElement(aStream, mRefPtr);
3657 inline void RecordedFilterNodeDestruction::OutputSimpleEventInfo(
3658 std::stringstream& aStringStream) const {
3659 aStringStream << "[" << mRefPtr << "] FilterNode Destroyed";
3662 inline RecordedGradientStopsCreation::~RecordedGradientStopsCreation() {
3663 if (mDataOwned) {
3664 delete[] mStops;
3668 inline bool RecordedGradientStopsCreation::PlayEvent(
3669 Translator* aTranslator) const {
3670 if (mNumStops > 0 && !mStops) {
3671 // Stops allocation failed
3672 return false;
3675 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3676 if (!dt) {
3677 return false;
3680 RefPtr<GradientStops> src =
3681 aTranslator->GetOrCreateGradientStops(dt, mStops, mNumStops, mExtendMode);
3682 aTranslator->AddGradientStops(mRefPtr, src);
3683 return true;
3686 template <class S>
3687 void RecordedGradientStopsCreation::Record(S& aStream) const {
3688 WriteElement(aStream, mRefPtr);
3689 WriteElement(aStream, mExtendMode);
3690 WriteElement(aStream, mNumStops);
3691 aStream.write((const char*)mStops, mNumStops * sizeof(GradientStop));
3694 template <class S>
3695 RecordedGradientStopsCreation::RecordedGradientStopsCreation(S& aStream)
3696 : RecordedEventDerived(GRADIENTSTOPSCREATION), mDataOwned(true) {
3697 ReadElement(aStream, mRefPtr);
3698 ReadElementConstrained(aStream, mExtendMode, ExtendMode::CLAMP,
3699 ExtendMode::REFLECT);
3700 ReadElement(aStream, mNumStops);
3701 if (!aStream.good() || mNumStops <= 0) {
3702 return;
3705 mStops = new (fallible) GradientStop[mNumStops];
3706 if (!mStops) {
3707 gfxCriticalNote
3708 << "RecordedGradientStopsCreation failed to allocate stops of size "
3709 << mNumStops;
3710 aStream.SetIsBad();
3711 } else {
3712 aStream.read((char*)mStops, mNumStops * sizeof(GradientStop));
3716 inline void RecordedGradientStopsCreation::OutputSimpleEventInfo(
3717 std::stringstream& aStringStream) const {
3718 aStringStream << "[" << mRefPtr
3719 << "] GradientStops created (Stops: " << mNumStops << ")";
3722 inline bool RecordedGradientStopsDestruction::PlayEvent(
3723 Translator* aTranslator) const {
3724 aTranslator->RemoveGradientStops(mRefPtr);
3725 return true;
3728 template <class S>
3729 void RecordedGradientStopsDestruction::Record(S& aStream) const {
3730 WriteElement(aStream, mRefPtr);
3733 template <class S>
3734 RecordedGradientStopsDestruction::RecordedGradientStopsDestruction(S& aStream)
3735 : RecordedEventDerived(GRADIENTSTOPSDESTRUCTION) {
3736 ReadElement(aStream, mRefPtr);
3739 inline void RecordedGradientStopsDestruction::OutputSimpleEventInfo(
3740 std::stringstream& aStringStream) const {
3741 aStringStream << "[" << mRefPtr << "] GradientStops Destroyed";
3744 inline bool RecordedIntoLuminanceSource::PlayEvent(
3745 Translator* aTranslator) const {
3746 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3747 if (!dt) {
3748 return false;
3751 RefPtr<SourceSurface> src = dt->IntoLuminanceSource(mLuminanceType, mOpacity);
3752 aTranslator->AddSourceSurface(mRefPtr, src);
3753 return true;
3756 template <class S>
3757 void RecordedIntoLuminanceSource::Record(S& aStream) const {
3758 WriteElement(aStream, mRefPtr);
3759 WriteElement(aStream, mLuminanceType);
3760 WriteElement(aStream, mOpacity);
3763 template <class S>
3764 RecordedIntoLuminanceSource::RecordedIntoLuminanceSource(S& aStream)
3765 : RecordedEventDerived(INTOLUMINANCE) {
3766 ReadElement(aStream, mRefPtr);
3767 ReadElementConstrained(aStream, mLuminanceType, LuminanceType::LUMINANCE,
3768 LuminanceType::LINEARRGB);
3769 ReadElement(aStream, mOpacity);
3772 inline void RecordedIntoLuminanceSource::OutputSimpleEventInfo(
3773 std::stringstream& aStringStream) const {
3774 aStringStream << "[" << mRefPtr << "] Into Luminance Source";
3777 inline bool RecordedExtractSubrect::PlayEvent(Translator* aTranslator) const {
3778 SourceSurface* sourceSurf = aTranslator->LookupSourceSurface(mSourceSurface);
3779 if (!sourceSurf) {
3780 return false;
3783 RefPtr<SourceSurface> subSurf = sourceSurf->ExtractSubrect(mSubrect);
3784 if (!subSurf) {
3785 RefPtr<DrawTarget> dt =
3786 aTranslator->GetReferenceDrawTarget()->CreateSimilarDrawTarget(
3787 mSubrect.Size(), sourceSurf->GetFormat());
3788 if (dt) {
3789 dt->CopySurface(sourceSurf, mSubrect, IntPoint());
3790 subSurf = dt->Snapshot();
3793 if (!subSurf) {
3794 return false;
3797 aTranslator->AddSourceSurface(mRefPtr, subSurf);
3798 return true;
3801 template <class S>
3802 void RecordedExtractSubrect::Record(S& aStream) const {
3803 WriteElement(aStream, mRefPtr);
3804 WriteElement(aStream, mSourceSurface);
3805 WriteElement(aStream, mSubrect);
3808 template <class S>
3809 RecordedExtractSubrect::RecordedExtractSubrect(S& aStream)
3810 : RecordedEventDerived(EXTRACTSUBRECT) {
3811 ReadElement(aStream, mRefPtr);
3812 ReadElement(aStream, mSourceSurface);
3813 ReadElement(aStream, mSubrect);
3816 inline void RecordedExtractSubrect::OutputSimpleEventInfo(
3817 std::stringstream& aStringStream) const {
3818 aStringStream << "[" << mRefPtr << "] Exract Subrect";
3821 inline bool RecordedFlush::PlayEvent(Translator* aTranslator) const {
3822 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3823 if (!dt) {
3824 return false;
3827 dt->Flush();
3828 return true;
3831 template <class S>
3832 void RecordedFlush::Record(S& aStream) const {}
3834 template <class S>
3835 RecordedFlush::RecordedFlush(S& aStream) : RecordedEventDerived(FLUSH) {}
3837 inline void RecordedFlush::OutputSimpleEventInfo(
3838 std::stringstream& aStringStream) const {
3839 aStringStream << "Flush";
3842 inline bool RecordedDetachAllSnapshots::PlayEvent(
3843 Translator* aTranslator) const {
3844 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3845 if (!dt) {
3846 return false;
3849 dt->DetachAllSnapshots();
3850 return true;
3853 template <class S>
3854 void RecordedDetachAllSnapshots::Record(S& aStream) const {}
3856 template <class S>
3857 RecordedDetachAllSnapshots::RecordedDetachAllSnapshots(S& aStream)
3858 : RecordedEventDerived(DETACHALLSNAPSHOTS) {}
3860 inline void RecordedDetachAllSnapshots::OutputSimpleEventInfo(
3861 std::stringstream& aStringStream) const {
3862 aStringStream << "DetachAllSnapshots";
3865 inline bool RecordedSnapshot::PlayEvent(Translator* aTranslator) const {
3866 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3867 if (!dt) {
3868 return false;
3871 RefPtr<SourceSurface> src = dt->Snapshot();
3872 aTranslator->AddSourceSurface(mRefPtr, src);
3873 return true;
3876 template <class S>
3877 void RecordedSnapshot::Record(S& aStream) const {
3878 WriteElement(aStream, mRefPtr);
3881 template <class S>
3882 RecordedSnapshot::RecordedSnapshot(S& aStream)
3883 : RecordedEventDerived(SNAPSHOT) {
3884 ReadElement(aStream, mRefPtr);
3887 inline void RecordedSnapshot::OutputSimpleEventInfo(
3888 std::stringstream& aStringStream) const {
3889 aStringStream << "[" << mRefPtr << "] Snapshot Created";
3892 inline RecordedFontData::~RecordedFontData() { delete[] mData; }
3894 inline bool RecordedFontData::PlayEvent(Translator* aTranslator) const {
3895 if (!mData) {
3896 return false;
3899 RefPtr<NativeFontResource> fontResource = Factory::CreateNativeFontResource(
3900 mData, mFontDetails.size, mType, aTranslator->GetFontContext());
3901 if (!fontResource) {
3902 return false;
3905 aTranslator->AddNativeFontResource(mFontDetails.fontDataKey, fontResource);
3906 return true;
3909 template <class S>
3910 void RecordedFontData::Record(S& aStream) const {
3911 MOZ_ASSERT(mGetFontFileDataSucceeded);
3913 WriteElement(aStream, mType);
3914 WriteElement(aStream, mFontDetails.fontDataKey);
3915 if (!mData) {
3916 WriteElement(aStream, 0);
3917 } else {
3918 WriteElement(aStream, mFontDetails.size);
3919 aStream.write((const char*)mData, mFontDetails.size);
3923 inline void RecordedFontData::OutputSimpleEventInfo(
3924 std::stringstream& aStringStream) const {
3925 aStringStream << "Font Data of size " << mFontDetails.size;
3928 inline void RecordedFontData::SetFontData(const uint8_t* aData, uint32_t aSize,
3929 uint32_t aIndex) {
3930 mData = new (fallible) uint8_t[aSize];
3931 if (!mData) {
3932 gfxCriticalNote
3933 << "RecordedFontData failed to allocate data for recording of size "
3934 << aSize;
3935 } else {
3936 memcpy(mData, aData, aSize);
3938 mFontDetails.fontDataKey = SFNTData::GetUniqueKey(aData, aSize, 0, nullptr);
3939 mFontDetails.size = aSize;
3940 mFontDetails.index = aIndex;
3943 inline bool RecordedFontData::GetFontDetails(RecordedFontDetails& fontDetails) {
3944 if (!mGetFontFileDataSucceeded) {
3945 return false;
3948 fontDetails.fontDataKey = mFontDetails.fontDataKey;
3949 fontDetails.size = mFontDetails.size;
3950 fontDetails.index = mFontDetails.index;
3951 return true;
3954 template <class S>
3955 RecordedFontData::RecordedFontData(S& aStream)
3956 : RecordedEventDerived(FONTDATA), mType(FontType::UNKNOWN) {
3957 ReadElementConstrained(aStream, mType, FontType::DWRITE, FontType::UNKNOWN);
3958 ReadElement(aStream, mFontDetails.fontDataKey);
3959 ReadElement(aStream, mFontDetails.size);
3960 if (!mFontDetails.size || !aStream.good()) {
3961 return;
3964 mData = new (fallible) uint8_t[mFontDetails.size];
3965 if (!mData) {
3966 gfxCriticalNote
3967 << "RecordedFontData failed to allocate data for playback of size "
3968 << mFontDetails.size;
3969 aStream.SetIsBad();
3970 } else {
3971 aStream.read((char*)mData, mFontDetails.size);
3975 inline RecordedFontDescriptor::~RecordedFontDescriptor() = default;
3977 inline bool RecordedFontDescriptor::PlayEvent(Translator* aTranslator) const {
3978 RefPtr<UnscaledFont> font = Factory::CreateUnscaledFontFromFontDescriptor(
3979 mType, mData.data(), mData.size(), mIndex);
3980 if (!font) {
3981 gfxDevCrash(LogReason::InvalidFont)
3982 << "Failed creating UnscaledFont of type " << int(mType)
3983 << " from font descriptor";
3984 return false;
3987 aTranslator->AddUnscaledFont(mRefPtr, font);
3988 return true;
3991 template <class S>
3992 void RecordedFontDescriptor::Record(S& aStream) const {
3993 MOZ_ASSERT(mHasDesc);
3994 WriteElement(aStream, mType);
3995 WriteElement(aStream, mRefPtr);
3996 WriteElement(aStream, mIndex);
3997 WriteElement(aStream, (size_t)mData.size());
3998 if (mData.size()) {
3999 aStream.write((char*)mData.data(), mData.size());
4003 inline void RecordedFontDescriptor::OutputSimpleEventInfo(
4004 std::stringstream& aStringStream) const {
4005 aStringStream << "[" << mRefPtr << "] Font Descriptor";
4008 inline void RecordedFontDescriptor::SetFontDescriptor(const uint8_t* aData,
4009 uint32_t aSize,
4010 uint32_t aIndex) {
4011 mData.assign(aData, aData + aSize);
4012 mIndex = aIndex;
4015 template <class S>
4016 RecordedFontDescriptor::RecordedFontDescriptor(S& aStream)
4017 : RecordedEventDerived(FONTDESC) {
4018 ReadElementConstrained(aStream, mType, FontType::DWRITE, FontType::UNKNOWN);
4019 ReadElement(aStream, mRefPtr);
4020 ReadElement(aStream, mIndex);
4022 size_t size;
4023 ReadElement(aStream, size);
4024 if (!aStream.good()) {
4025 return;
4027 if (size) {
4028 mData.resize(size);
4029 aStream.read((char*)mData.data(), size);
4033 inline bool RecordedUnscaledFontCreation::PlayEvent(
4034 Translator* aTranslator) const {
4035 NativeFontResource* fontResource =
4036 aTranslator->LookupNativeFontResource(mFontDataKey);
4037 if (!fontResource) {
4038 gfxDevCrash(LogReason::NativeFontResourceNotFound)
4039 << "NativeFontResource lookup failed for key |" << hexa(mFontDataKey)
4040 << "|.";
4041 return false;
4044 RefPtr<UnscaledFont> unscaledFont = fontResource->CreateUnscaledFont(
4045 mIndex, mInstanceData.data(), mInstanceData.size());
4046 aTranslator->AddUnscaledFont(mRefPtr, unscaledFont);
4047 return true;
4050 template <class S>
4051 void RecordedUnscaledFontCreation::Record(S& aStream) const {
4052 WriteElement(aStream, mRefPtr);
4053 WriteElement(aStream, mFontDataKey);
4054 WriteElement(aStream, mIndex);
4055 WriteElement(aStream, (size_t)mInstanceData.size());
4056 if (mInstanceData.size()) {
4057 aStream.write((char*)mInstanceData.data(), mInstanceData.size());
4061 inline void RecordedUnscaledFontCreation::OutputSimpleEventInfo(
4062 std::stringstream& aStringStream) const {
4063 aStringStream << "[" << mRefPtr << "] UnscaledFont Created";
4066 inline void RecordedUnscaledFontCreation::SetFontInstanceData(
4067 const uint8_t* aData, uint32_t aSize) {
4068 if (aSize) {
4069 mInstanceData.assign(aData, aData + aSize);
4073 template <class S>
4074 RecordedUnscaledFontCreation::RecordedUnscaledFontCreation(S& aStream)
4075 : RecordedEventDerived(UNSCALEDFONTCREATION) {
4076 ReadElement(aStream, mRefPtr);
4077 ReadElement(aStream, mFontDataKey);
4078 ReadElement(aStream, mIndex);
4080 size_t size;
4081 ReadElement(aStream, size);
4082 if (!aStream.good()) {
4083 return;
4085 if (size) {
4086 mInstanceData.resize(size);
4087 aStream.read((char*)mInstanceData.data(), size);
4091 inline bool RecordedUnscaledFontDestruction::PlayEvent(
4092 Translator* aTranslator) const {
4093 aTranslator->RemoveUnscaledFont(mRefPtr);
4094 return true;
4097 template <class S>
4098 void RecordedUnscaledFontDestruction::Record(S& aStream) const {
4099 WriteElement(aStream, mRefPtr);
4102 template <class S>
4103 RecordedUnscaledFontDestruction::RecordedUnscaledFontDestruction(S& aStream)
4104 : RecordedEventDerived(UNSCALEDFONTDESTRUCTION) {
4105 ReadElement(aStream, mRefPtr);
4108 inline void RecordedUnscaledFontDestruction::OutputSimpleEventInfo(
4109 std::stringstream& aStringStream) const {
4110 aStringStream << "[" << mRefPtr << "] UnscaledFont Destroyed";
4113 inline bool RecordedScaledFontCreation::PlayEvent(
4114 Translator* aTranslator) const {
4115 UnscaledFont* unscaledFont = aTranslator->LookupUnscaledFont(mUnscaledFont);
4116 if (!unscaledFont) {
4117 gfxDevCrash(LogReason::UnscaledFontNotFound)
4118 << "UnscaledFont lookup failed for key |" << hexa(mUnscaledFont)
4119 << "|.";
4120 return false;
4123 RefPtr<ScaledFont> scaledFont = unscaledFont->CreateScaledFont(
4124 mGlyphSize, mInstanceData.data(), mInstanceData.size(),
4125 mVariations.data(), mVariations.size());
4127 aTranslator->AddScaledFont(mRefPtr, scaledFont);
4128 return true;
4131 template <class S>
4132 void RecordedScaledFontCreation::Record(S& aStream) const {
4133 WriteElement(aStream, mRefPtr);
4134 WriteElement(aStream, mUnscaledFont);
4135 WriteElement(aStream, mGlyphSize);
4136 WriteElement(aStream, (size_t)mInstanceData.size());
4137 if (mInstanceData.size()) {
4138 aStream.write((char*)mInstanceData.data(), mInstanceData.size());
4140 WriteElement(aStream, (size_t)mVariations.size());
4141 if (mVariations.size()) {
4142 aStream.write((char*)mVariations.data(),
4143 sizeof(FontVariation) * mVariations.size());
4147 inline void RecordedScaledFontCreation::OutputSimpleEventInfo(
4148 std::stringstream& aStringStream) const {
4149 aStringStream << "[" << mRefPtr << "] ScaledFont Created";
4152 inline void RecordedScaledFontCreation::SetFontInstanceData(
4153 const uint8_t* aData, uint32_t aSize, const FontVariation* aVariations,
4154 uint32_t aNumVariations) {
4155 if (aSize) {
4156 mInstanceData.assign(aData, aData + aSize);
4158 if (aNumVariations) {
4159 mVariations.assign(aVariations, aVariations + aNumVariations);
4163 template <class S>
4164 RecordedScaledFontCreation::RecordedScaledFontCreation(S& aStream)
4165 : RecordedEventDerived(SCALEDFONTCREATION) {
4166 ReadElement(aStream, mRefPtr);
4167 ReadElement(aStream, mUnscaledFont);
4168 ReadElement(aStream, mGlyphSize);
4170 size_t size;
4171 ReadElement(aStream, size);
4172 if (!aStream.good()) {
4173 return;
4175 if (size) {
4176 mInstanceData.resize(size);
4177 aStream.read((char*)mInstanceData.data(), size);
4180 size_t numVariations;
4181 ReadElement(aStream, numVariations);
4182 if (!aStream.good()) {
4183 return;
4185 if (numVariations) {
4186 mVariations.resize(numVariations);
4187 aStream.read((char*)mVariations.data(),
4188 sizeof(FontVariation) * numVariations);
4192 inline bool RecordedScaledFontDestruction::PlayEvent(
4193 Translator* aTranslator) const {
4194 aTranslator->RemoveScaledFont(mRefPtr);
4195 return true;
4198 template <class S>
4199 void RecordedScaledFontDestruction::Record(S& aStream) const {
4200 WriteElement(aStream, mRefPtr);
4203 template <class S>
4204 RecordedScaledFontDestruction::RecordedScaledFontDestruction(S& aStream)
4205 : RecordedEventDerived(SCALEDFONTDESTRUCTION) {
4206 ReadElement(aStream, mRefPtr);
4209 inline void RecordedScaledFontDestruction::OutputSimpleEventInfo(
4210 std::stringstream& aStringStream) const {
4211 aStringStream << "[" << mRefPtr << "] ScaledFont Destroyed";
4214 inline bool RecordedMaskSurface::PlayEvent(Translator* aTranslator) const {
4215 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
4216 if (!dt) {
4217 return false;
4220 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefMask);
4221 if (!surface) {
4222 return false;
4225 dt->MaskSurface(*GenericPattern(mPattern, aTranslator), surface, mOffset,
4226 mOptions);
4227 return true;
4230 template <class S>
4231 void RecordedMaskSurface::Record(S& aStream) const {
4232 RecordPatternData(aStream, mPattern);
4233 WriteElement(aStream, mRefMask);
4234 WriteElement(aStream, mOffset);
4235 WriteElement(aStream, mOptions);
4238 template <class S>
4239 RecordedMaskSurface::RecordedMaskSurface(S& aStream)
4240 : RecordedEventDerived(MASKSURFACE) {
4241 ReadPatternData(aStream, mPattern);
4242 ReadElement(aStream, mRefMask);
4243 ReadElement(aStream, mOffset);
4244 ReadDrawOptions(aStream, mOptions);
4247 inline void RecordedMaskSurface::OutputSimpleEventInfo(
4248 std::stringstream& aStringStream) const {
4249 aStringStream << "MaskSurface (" << mRefMask << ") Offset: (" << mOffset.x
4250 << "x" << mOffset.y << ") Pattern: ";
4251 OutputSimplePatternInfo(mPattern, aStringStream);
4254 template <typename T>
4255 void ReplaySetAttribute(FilterNode* aNode, uint32_t aIndex, T aValue) {
4256 aNode->SetAttribute(aIndex, aValue);
4259 inline bool RecordedFilterNodeSetAttribute::PlayEvent(
4260 Translator* aTranslator) const {
4261 FilterNode* node = aTranslator->LookupFilterNode(mNode);
4262 if (!node) {
4263 return false;
4266 #define REPLAY_SET_ATTRIBUTE(type, argtype) \
4267 case ARGTYPE_##argtype: \
4268 ReplaySetAttribute(node, mIndex, *(type*)&mPayload.front()); \
4269 break
4271 switch (mArgType) {
4272 REPLAY_SET_ATTRIBUTE(bool, BOOL);
4273 REPLAY_SET_ATTRIBUTE(uint32_t, UINT32);
4274 REPLAY_SET_ATTRIBUTE(Float, FLOAT);
4275 REPLAY_SET_ATTRIBUTE(Size, SIZE);
4276 REPLAY_SET_ATTRIBUTE(IntSize, INTSIZE);
4277 REPLAY_SET_ATTRIBUTE(IntPoint, INTPOINT);
4278 REPLAY_SET_ATTRIBUTE(Rect, RECT);
4279 REPLAY_SET_ATTRIBUTE(IntRect, INTRECT);
4280 REPLAY_SET_ATTRIBUTE(Point, POINT);
4281 REPLAY_SET_ATTRIBUTE(Matrix, MATRIX);
4282 REPLAY_SET_ATTRIBUTE(Matrix5x4, MATRIX5X4);
4283 REPLAY_SET_ATTRIBUTE(Point3D, POINT3D);
4284 REPLAY_SET_ATTRIBUTE(DeviceColor, COLOR);
4285 case ARGTYPE_FLOAT_ARRAY:
4286 node->SetAttribute(mIndex,
4287 reinterpret_cast<const Float*>(&mPayload.front()),
4288 mPayload.size() / sizeof(Float));
4289 break;
4292 return true;
4295 template <class S>
4296 void RecordedFilterNodeSetAttribute::Record(S& aStream) const {
4297 WriteElement(aStream, mNode);
4298 WriteElement(aStream, mIndex);
4299 WriteElement(aStream, mArgType);
4300 WriteElement(aStream, uint64_t(mPayload.size()));
4301 aStream.write((const char*)&mPayload.front(), mPayload.size());
4304 template <class S>
4305 RecordedFilterNodeSetAttribute::RecordedFilterNodeSetAttribute(S& aStream)
4306 : RecordedEventDerived(FILTERNODESETATTRIBUTE) {
4307 ReadElement(aStream, mNode);
4308 ReadElement(aStream, mIndex);
4309 ReadElementConstrained(aStream, mArgType, ArgType::ARGTYPE_UINT32,
4310 ArgType::ARGTYPE_FLOAT_ARRAY);
4311 uint64_t size;
4312 ReadElement(aStream, size);
4313 if (!aStream.good()) {
4314 return;
4317 mPayload.resize(size_t(size));
4318 aStream.read((char*)&mPayload.front(), size);
4321 inline void RecordedFilterNodeSetAttribute::OutputSimpleEventInfo(
4322 std::stringstream& aStringStream) const {
4323 aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ")";
4326 inline bool RecordedFilterNodeSetInput::PlayEvent(
4327 Translator* aTranslator) const {
4328 FilterNode* node = aTranslator->LookupFilterNode(mNode);
4329 if (!node) {
4330 return false;
4333 if (mInputFilter) {
4334 node->SetInput(mIndex, aTranslator->LookupFilterNode(mInputFilter));
4335 } else {
4336 node->SetInput(mIndex, aTranslator->LookupSourceSurface(mInputSurface));
4339 return true;
4342 template <class S>
4343 void RecordedFilterNodeSetInput::Record(S& aStream) const {
4344 WriteElement(aStream, mNode);
4345 WriteElement(aStream, mIndex);
4346 WriteElement(aStream, mInputFilter);
4347 WriteElement(aStream, mInputSurface);
4350 template <class S>
4351 RecordedFilterNodeSetInput::RecordedFilterNodeSetInput(S& aStream)
4352 : RecordedEventDerived(FILTERNODESETINPUT) {
4353 ReadElement(aStream, mNode);
4354 ReadElement(aStream, mIndex);
4355 ReadElement(aStream, mInputFilter);
4356 ReadElement(aStream, mInputSurface);
4359 inline void RecordedFilterNodeSetInput::OutputSimpleEventInfo(
4360 std::stringstream& aStringStream) const {
4361 aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ", ";
4363 if (mInputFilter) {
4364 aStringStream << "Filter: " << mInputFilter;
4365 } else {
4366 aStringStream << "Surface: " << mInputSurface;
4369 aStringStream << ")";
4372 inline bool RecordedLink::PlayEvent(Translator* aTranslator) const {
4373 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
4374 if (!dt) {
4375 return false;
4377 dt->Link(mDestination.c_str(), mRect);
4378 return true;
4381 template <class S>
4382 void RecordedLink::Record(S& aStream) const {
4383 WriteElement(aStream, mRect);
4384 uint32_t len = mDestination.length();
4385 WriteElement(aStream, len);
4386 if (len) {
4387 aStream.write(mDestination.data(), len);
4391 template <class S>
4392 RecordedLink::RecordedLink(S& aStream) : RecordedEventDerived(LINK) {
4393 ReadElement(aStream, mRect);
4394 uint32_t len;
4395 ReadElement(aStream, len);
4396 mDestination.resize(size_t(len));
4397 if (len && aStream.good()) {
4398 aStream.read(&mDestination.front(), len);
4402 inline void RecordedLink::OutputSimpleEventInfo(
4403 std::stringstream& aStringStream) const {
4404 aStringStream << "Link [" << mDestination << " @ " << mRect << "]";
4407 inline bool RecordedDestination::PlayEvent(Translator* aTranslator) const {
4408 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
4409 if (!dt) {
4410 return false;
4412 dt->Destination(mDestination.c_str(), mPoint);
4413 return true;
4416 template <class S>
4417 void RecordedDestination::Record(S& aStream) const {
4418 WriteElement(aStream, mPoint);
4419 uint32_t len = mDestination.length();
4420 WriteElement(aStream, len);
4421 if (len) {
4422 aStream.write(mDestination.data(), len);
4426 template <class S>
4427 RecordedDestination::RecordedDestination(S& aStream)
4428 : RecordedEventDerived(DESTINATION) {
4429 ReadElement(aStream, mPoint);
4430 uint32_t len;
4431 ReadElement(aStream, len);
4432 mDestination.resize(size_t(len));
4433 if (len && aStream.good()) {
4434 aStream.read(&mDestination.front(), len);
4438 inline void RecordedDestination::OutputSimpleEventInfo(
4439 std::stringstream& aStringStream) const {
4440 aStringStream << "Destination [" << mDestination << " @ " << mPoint << "]";
4443 #define FOR_EACH_EVENT(f) \
4444 f(DRAWTARGETCREATION, RecordedDrawTargetCreation); \
4445 f(DRAWTARGETDESTRUCTION, RecordedDrawTargetDestruction); \
4446 f(SETCURRENTDRAWTARGET, RecordedSetCurrentDrawTarget); \
4447 f(FILLRECT, RecordedFillRect); \
4448 f(STROKERECT, RecordedStrokeRect); \
4449 f(STROKELINE, RecordedStrokeLine); \
4450 f(STROKECIRCLE, RecordedStrokeCircle); \
4451 f(CLEARRECT, RecordedClearRect); \
4452 f(COPYSURFACE, RecordedCopySurface); \
4453 f(SETPERMITSUBPIXELAA, RecordedSetPermitSubpixelAA); \
4454 f(SETTRANSFORM, RecordedSetTransform); \
4455 f(PUSHCLIPRECT, RecordedPushClipRect); \
4456 f(PUSHCLIP, RecordedPushClip); \
4457 f(POPCLIP, RecordedPopClip); \
4458 f(FILL, RecordedFill); \
4459 f(FILLCIRCLE, RecordedFillCircle); \
4460 f(FILLGLYPHS, RecordedFillGlyphs); \
4461 f(STROKEGLYPHS, RecordedStrokeGlyphs); \
4462 f(MASK, RecordedMask); \
4463 f(STROKE, RecordedStroke); \
4464 f(DRAWSURFACE, RecordedDrawSurface); \
4465 f(DRAWSURFACEDESCRIPTOR, RecordedDrawSurfaceDescriptor); \
4466 f(DRAWDEPENDENTSURFACE, RecordedDrawDependentSurface); \
4467 f(DRAWSURFACEWITHSHADOW, RecordedDrawSurfaceWithShadow); \
4468 f(DRAWSHADOW, RecordedDrawShadow); \
4469 f(DRAWFILTER, RecordedDrawFilter); \
4470 f(PATHCREATION, RecordedPathCreation); \
4471 f(PATHDESTRUCTION, RecordedPathDestruction); \
4472 f(SOURCESURFACECREATION, RecordedSourceSurfaceCreation); \
4473 f(SOURCESURFACEDESTRUCTION, RecordedSourceSurfaceDestruction); \
4474 f(FILTERNODECREATION, RecordedFilterNodeCreation); \
4475 f(FILTERNODEDESTRUCTION, RecordedFilterNodeDestruction); \
4476 f(GRADIENTSTOPSCREATION, RecordedGradientStopsCreation); \
4477 f(GRADIENTSTOPSDESTRUCTION, RecordedGradientStopsDestruction); \
4478 f(SNAPSHOT, RecordedSnapshot); \
4479 f(SCALEDFONTCREATION, RecordedScaledFontCreation); \
4480 f(SCALEDFONTDESTRUCTION, RecordedScaledFontDestruction); \
4481 f(MASKSURFACE, RecordedMaskSurface); \
4482 f(FILTERNODESETATTRIBUTE, RecordedFilterNodeSetAttribute); \
4483 f(FILTERNODESETINPUT, RecordedFilterNodeSetInput); \
4484 f(CREATESIMILARDRAWTARGET, RecordedCreateSimilarDrawTarget); \
4485 f(CREATECLIPPEDDRAWTARGET, RecordedCreateClippedDrawTarget); \
4486 f(CREATEDRAWTARGETFORFILTER, RecordedCreateDrawTargetForFilter); \
4487 f(FONTDATA, RecordedFontData); \
4488 f(FONTDESC, RecordedFontDescriptor); \
4489 f(PUSHLAYER, RecordedPushLayer); \
4490 f(PUSHLAYERWITHBLEND, RecordedPushLayerWithBlend); \
4491 f(POPLAYER, RecordedPopLayer); \
4492 f(UNSCALEDFONTCREATION, RecordedUnscaledFontCreation); \
4493 f(UNSCALEDFONTDESTRUCTION, RecordedUnscaledFontDestruction); \
4494 f(INTOLUMINANCE, RecordedIntoLuminanceSource); \
4495 f(EXTRACTSUBRECT, RecordedExtractSubrect); \
4496 f(EXTERNALSURFACECREATION, RecordedExternalSurfaceCreation); \
4497 f(FLUSH, RecordedFlush); \
4498 f(DETACHALLSNAPSHOTS, RecordedDetachAllSnapshots); \
4499 f(OPTIMIZESOURCESURFACE, RecordedOptimizeSourceSurface); \
4500 f(LINK, RecordedLink); \
4501 f(DESTINATION, RecordedDestination);
4503 #define DO_WITH_EVENT_TYPE(_typeenum, _class) \
4504 case _typeenum: { \
4505 auto e = _class(aStream); \
4506 return aAction(&e); \
4509 template <class S>
4510 bool RecordedEvent::DoWithEvent(
4511 S& aStream, EventType aType,
4512 const std::function<bool(RecordedEvent*)>& aAction) {
4513 switch (aType) {
4514 FOR_EACH_EVENT(DO_WITH_EVENT_TYPE)
4515 default:
4516 return false;
4520 } // namespace gfx
4521 } // namespace mozilla
4523 #endif