Backed out 2 changesets (bug 1855992) for causing talos failures @ mozilla::net:...
[gecko.git] / gfx / 2d / RecordedEventImpl.h
blobee0e42f1c699b8e5f187b339324833e6ec8cca0a
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef MOZILLA_GFX_RECORDEDEVENTIMPL_H_
8 #define MOZILLA_GFX_RECORDEDEVENTIMPL_H_
10 #include "RecordedEvent.h"
12 #include "PathRecording.h"
13 #include "RecordingTypes.h"
14 #include "Tools.h"
15 #include "Filters.h"
16 #include "Logging.h"
17 #include "ScaledFontBase.h"
18 #include "SFNTData.h"
20 namespace mozilla {
21 namespace gfx {
23 template <class Derived>
24 class RecordedDrawingEvent : public RecordedEventDerived<Derived> {
25 public:
26 ReferencePtr GetDestinedDT() override { return mDT; }
28 protected:
29 RecordedDrawingEvent(RecordedEvent::EventType aType, DrawTarget* aTarget)
30 : RecordedEventDerived<Derived>(aType), mDT(aTarget) {}
32 template <class S>
33 RecordedDrawingEvent(RecordedEvent::EventType aType, S& aStream);
34 template <class S>
35 void Record(S& aStream) const;
37 ReferencePtr mDT;
40 class RecordedDrawTargetCreation
41 : public RecordedEventDerived<RecordedDrawTargetCreation> {
42 public:
43 RecordedDrawTargetCreation(ReferencePtr aRefPtr, BackendType aType,
44 const IntRect& aRect, SurfaceFormat aFormat,
45 bool aHasExistingData = false,
46 SourceSurface* aExistingData = nullptr)
47 : RecordedEventDerived(DRAWTARGETCREATION),
48 mRefPtr(aRefPtr),
49 mBackendType(aType),
50 mRect(aRect),
51 mFormat(aFormat),
52 mHasExistingData(aHasExistingData),
53 mExistingData(aExistingData) {}
55 bool PlayEvent(Translator* aTranslator) const override;
57 template <class S>
58 void Record(S& aStream) const;
59 virtual void OutputSimpleEventInfo(
60 std::stringstream& aStringStream) const override;
62 std::string GetName() const override { return "DrawTarget Creation"; }
64 ReferencePtr mRefPtr;
65 BackendType mBackendType;
66 IntRect mRect;
67 SurfaceFormat mFormat;
68 bool mHasExistingData = false;
69 RefPtr<SourceSurface> mExistingData;
71 private:
72 friend class RecordedEvent;
74 template <class S>
75 MOZ_IMPLICIT RecordedDrawTargetCreation(S& aStream);
78 class RecordedDrawTargetDestruction
79 : public RecordedEventDerived<RecordedDrawTargetDestruction> {
80 public:
81 MOZ_IMPLICIT RecordedDrawTargetDestruction(ReferencePtr aRefPtr)
82 : RecordedEventDerived(DRAWTARGETDESTRUCTION),
83 mRefPtr(aRefPtr),
84 mBackendType(BackendType::NONE) {}
86 bool PlayEvent(Translator* aTranslator) const override;
88 template <class S>
89 void Record(S& aStream) const;
90 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
92 std::string GetName() const override { return "DrawTarget Destruction"; }
94 ReferencePtr mRefPtr;
96 BackendType mBackendType;
98 private:
99 friend class RecordedEvent;
101 template <class S>
102 MOZ_IMPLICIT RecordedDrawTargetDestruction(S& aStream);
105 class RecordedCreateSimilarDrawTarget
106 : public RecordedEventDerived<RecordedCreateSimilarDrawTarget> {
107 public:
108 RecordedCreateSimilarDrawTarget(ReferencePtr aRefPtr, const IntSize& aSize,
109 SurfaceFormat aFormat)
110 : RecordedEventDerived(CREATESIMILARDRAWTARGET),
111 mRefPtr(aRefPtr),
112 mSize(aSize),
113 mFormat(aFormat) {}
115 bool PlayEvent(Translator* aTranslator) const override;
117 template <class S>
118 void Record(S& aStream) const;
119 virtual void OutputSimpleEventInfo(
120 std::stringstream& aStringStream) const override;
122 std::string GetName() const override { return "CreateSimilarDrawTarget"; }
124 ReferencePtr mRefPtr;
125 IntSize mSize;
126 SurfaceFormat mFormat;
128 private:
129 friend class RecordedEvent;
131 template <class S>
132 MOZ_IMPLICIT RecordedCreateSimilarDrawTarget(S& aStream);
135 class RecordedCreateClippedDrawTarget
136 : public RecordedDrawingEvent<RecordedCreateClippedDrawTarget> {
137 public:
138 RecordedCreateClippedDrawTarget(DrawTarget* aDT, ReferencePtr aRefPtr,
139 const Rect& aBounds, SurfaceFormat aFormat)
140 : RecordedDrawingEvent(CREATECLIPPEDDRAWTARGET, aDT),
141 mRefPtr(aRefPtr),
142 mBounds(aBounds),
143 mFormat(aFormat) {}
145 bool PlayEvent(Translator* aTranslator) const override;
147 template <class S>
148 void Record(S& aStream) const;
149 virtual void OutputSimpleEventInfo(
150 std::stringstream& aStringStream) const override;
152 std::string GetName() const override { return "CreateClippedDrawTarget"; }
154 ReferencePtr mRefPtr;
155 Rect mBounds;
156 SurfaceFormat mFormat;
158 private:
159 friend class RecordedEvent;
161 template <class S>
162 MOZ_IMPLICIT RecordedCreateClippedDrawTarget(S& aStream);
165 class RecordedCreateDrawTargetForFilter
166 : public RecordedDrawingEvent<RecordedCreateDrawTargetForFilter> {
167 public:
168 RecordedCreateDrawTargetForFilter(DrawTarget* aDT, ReferencePtr aRefPtr,
169 const IntSize& aMaxSize,
170 SurfaceFormat aFormat, FilterNode* aFilter,
171 FilterNode* aSource,
172 const Rect& aSourceRect,
173 const Point& aDestPoint)
174 : RecordedDrawingEvent(CREATEDRAWTARGETFORFILTER, aDT),
175 mRefPtr(aRefPtr),
176 mMaxSize(aMaxSize),
177 mFormat(aFormat),
178 mFilter(aFilter),
179 mSource(aSource),
180 mSourceRect(aSourceRect),
181 mDestPoint(aDestPoint) {}
183 bool PlayEvent(Translator* aTranslator) const override;
185 template <class S>
186 void Record(S& aStream) const;
187 virtual void OutputSimpleEventInfo(
188 std::stringstream& aStringStream) const override;
190 std::string GetName() const override {
191 return "CreateSimilarDrawTargetForFilter";
194 ReferencePtr mRefPtr;
195 IntSize mMaxSize;
196 SurfaceFormat mFormat;
197 ReferencePtr mFilter;
198 ReferencePtr mSource;
199 Rect mSourceRect;
200 Point mDestPoint;
202 private:
203 friend class RecordedEvent;
205 template <class S>
206 MOZ_IMPLICIT RecordedCreateDrawTargetForFilter(S& aStream);
209 class RecordedFillRect : public RecordedDrawingEvent<RecordedFillRect> {
210 public:
211 RecordedFillRect(DrawTarget* aDT, const Rect& aRect, const Pattern& aPattern,
212 const DrawOptions& aOptions)
213 : RecordedDrawingEvent(FILLRECT, aDT),
214 mRect(aRect),
215 mPattern(),
216 mOptions(aOptions) {
217 StorePattern(mPattern, aPattern);
220 bool PlayEvent(Translator* aTranslator) const override;
222 template <class S>
223 void Record(S& aStream) const;
224 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
226 std::string GetName() const override { return "FillRect"; }
228 private:
229 friend class RecordedEvent;
231 template <class S>
232 MOZ_IMPLICIT RecordedFillRect(S& aStream);
234 Rect mRect;
235 PatternStorage mPattern;
236 DrawOptions mOptions;
239 class RecordedStrokeRect : public RecordedDrawingEvent<RecordedStrokeRect> {
240 public:
241 RecordedStrokeRect(DrawTarget* aDT, const Rect& aRect,
242 const Pattern& aPattern,
243 const StrokeOptions& aStrokeOptions,
244 const DrawOptions& aOptions)
245 : RecordedDrawingEvent(STROKERECT, aDT),
246 mRect(aRect),
247 mPattern(),
248 mStrokeOptions(aStrokeOptions),
249 mOptions(aOptions) {
250 StorePattern(mPattern, aPattern);
253 bool PlayEvent(Translator* aTranslator) const override;
255 template <class S>
256 void Record(S& aStream) const;
257 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
259 std::string GetName() const override { return "StrokeRect"; }
261 private:
262 friend class RecordedEvent;
264 template <class S>
265 MOZ_IMPLICIT RecordedStrokeRect(S& aStream);
267 Rect mRect;
268 PatternStorage mPattern;
269 StrokeOptions mStrokeOptions;
270 DrawOptions mOptions;
273 class RecordedStrokeLine : public RecordedDrawingEvent<RecordedStrokeLine> {
274 public:
275 RecordedStrokeLine(DrawTarget* aDT, const Point& aBegin, const Point& aEnd,
276 const Pattern& aPattern,
277 const StrokeOptions& aStrokeOptions,
278 const DrawOptions& aOptions)
279 : RecordedDrawingEvent(STROKELINE, aDT),
280 mBegin(aBegin),
281 mEnd(aEnd),
282 mPattern(),
283 mStrokeOptions(aStrokeOptions),
284 mOptions(aOptions) {
285 StorePattern(mPattern, aPattern);
288 bool PlayEvent(Translator* aTranslator) const override;
290 template <class S>
291 void Record(S& aStream) const;
292 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
294 std::string GetName() const override { return "StrokeLine"; }
296 private:
297 friend class RecordedEvent;
299 template <class S>
300 MOZ_IMPLICIT RecordedStrokeLine(S& aStream);
302 Point mBegin;
303 Point mEnd;
304 PatternStorage mPattern;
305 StrokeOptions mStrokeOptions;
306 DrawOptions mOptions;
309 class RecordedStrokeCircle : public RecordedDrawingEvent<RecordedStrokeCircle> {
310 public:
311 RecordedStrokeCircle(DrawTarget* aDT, Circle aCircle, const Pattern& aPattern,
312 const StrokeOptions& aStrokeOptions,
313 const DrawOptions& aOptions)
314 : RecordedDrawingEvent(STROKECIRCLE, aDT),
315 mCircle(aCircle),
316 mPattern(),
317 mStrokeOptions(aStrokeOptions),
318 mOptions(aOptions) {
319 StorePattern(mPattern, aPattern);
322 bool PlayEvent(Translator* aTranslator) const override;
324 template <class S>
325 void Record(S& aStream) const;
326 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
328 std::string GetName() const override { return "StrokeCircle"; }
330 private:
331 friend class RecordedEvent;
333 template <class S>
334 MOZ_IMPLICIT RecordedStrokeCircle(S& aStream);
336 Circle mCircle;
337 PatternStorage mPattern;
338 StrokeOptions mStrokeOptions;
339 DrawOptions mOptions;
342 class RecordedFill : public RecordedDrawingEvent<RecordedFill> {
343 public:
344 RecordedFill(DrawTarget* aDT, ReferencePtr aPath, const Pattern& aPattern,
345 const DrawOptions& aOptions)
346 : RecordedDrawingEvent(FILL, aDT),
347 mPath(aPath),
348 mPattern(),
349 mOptions(aOptions) {
350 StorePattern(mPattern, aPattern);
353 bool PlayEvent(Translator* aTranslator) const override;
355 template <class S>
356 void Record(S& aStream) const;
357 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
359 std::string GetName() const override { return "Fill"; }
361 private:
362 friend class RecordedEvent;
364 template <class S>
365 MOZ_IMPLICIT RecordedFill(S& aStream);
367 ReferencePtr mPath;
368 PatternStorage mPattern;
369 DrawOptions mOptions;
372 class RecordedFillCircle : public RecordedDrawingEvent<RecordedFillCircle> {
373 public:
374 RecordedFillCircle(DrawTarget* aDT, Circle aCircle, const Pattern& aPattern,
375 const DrawOptions& aOptions)
376 : RecordedDrawingEvent(FILLCIRCLE, aDT),
377 mCircle(aCircle),
378 mPattern(),
379 mOptions(aOptions) {
380 StorePattern(mPattern, aPattern);
383 bool PlayEvent(Translator* aTranslator) const override;
385 template <class S>
386 void Record(S& aStream) const;
387 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
389 std::string GetName() const override { return "FillCircle"; }
391 private:
392 friend class RecordedEvent;
394 template <class S>
395 MOZ_IMPLICIT RecordedFillCircle(S& aStream);
397 Circle mCircle;
398 PatternStorage mPattern;
399 DrawOptions mOptions;
402 class RecordedFillGlyphs : public RecordedDrawingEvent<RecordedFillGlyphs> {
403 public:
404 RecordedFillGlyphs(DrawTarget* aDT, ReferencePtr aScaledFont,
405 const Pattern& aPattern, const DrawOptions& aOptions,
406 const Glyph* aGlyphs, uint32_t aNumGlyphs)
407 : RecordedDrawingEvent(FILLGLYPHS, aDT),
408 mScaledFont(aScaledFont),
409 mPattern(),
410 mOptions(aOptions) {
411 StorePattern(mPattern, aPattern);
412 mNumGlyphs = aNumGlyphs;
413 mGlyphs = new Glyph[aNumGlyphs];
414 memcpy(mGlyphs, aGlyphs, sizeof(Glyph) * aNumGlyphs);
416 virtual ~RecordedFillGlyphs();
418 bool PlayEvent(Translator* aTranslator) const override;
420 template <class S>
421 void Record(S& aStream) const;
422 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
424 std::string GetName() const override { return "FillGlyphs"; }
426 private:
427 friend class RecordedEvent;
429 template <class S>
430 MOZ_IMPLICIT RecordedFillGlyphs(S& aStream);
432 ReferencePtr mScaledFont;
433 PatternStorage mPattern;
434 DrawOptions mOptions;
435 Glyph* mGlyphs = nullptr;
436 uint32_t mNumGlyphs = 0;
439 class RecordedMask : public RecordedDrawingEvent<RecordedMask> {
440 public:
441 RecordedMask(DrawTarget* aDT, const Pattern& aSource, const Pattern& aMask,
442 const DrawOptions& aOptions)
443 : RecordedDrawingEvent(MASK, aDT),
444 mSource(),
445 mMask(),
446 mOptions(aOptions) {
447 StorePattern(mSource, aSource);
448 StorePattern(mMask, aMask);
451 bool PlayEvent(Translator* aTranslator) const override;
453 template <class S>
454 void Record(S& aStream) const;
455 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
457 std::string GetName() const override { return "Mask"; }
459 private:
460 friend class RecordedEvent;
462 template <class S>
463 MOZ_IMPLICIT RecordedMask(S& aStream);
465 PatternStorage mSource;
466 PatternStorage mMask;
467 DrawOptions mOptions;
470 class RecordedStroke : public RecordedDrawingEvent<RecordedStroke> {
471 public:
472 RecordedStroke(DrawTarget* aDT, ReferencePtr aPath, const Pattern& aPattern,
473 const StrokeOptions& aStrokeOptions,
474 const DrawOptions& aOptions)
475 : RecordedDrawingEvent(STROKE, aDT),
476 mPath(aPath),
477 mPattern(),
478 mStrokeOptions(aStrokeOptions),
479 mOptions(aOptions) {
480 StorePattern(mPattern, aPattern);
483 bool PlayEvent(Translator* aTranslator) const override;
485 template <class S>
486 void Record(S& aStream) const;
487 virtual void OutputSimpleEventInfo(
488 std::stringstream& aStringStream) const override;
490 std::string GetName() const override { return "Stroke"; }
492 private:
493 friend class RecordedEvent;
495 template <class S>
496 MOZ_IMPLICIT RecordedStroke(S& aStream);
498 ReferencePtr mPath;
499 PatternStorage mPattern;
500 StrokeOptions mStrokeOptions;
501 DrawOptions mOptions;
504 class RecordedClearRect : public RecordedDrawingEvent<RecordedClearRect> {
505 public:
506 RecordedClearRect(DrawTarget* aDT, const Rect& aRect)
507 : RecordedDrawingEvent(CLEARRECT, aDT), mRect(aRect) {}
509 bool PlayEvent(Translator* aTranslator) const override;
511 template <class S>
512 void Record(S& aStream) const;
513 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
515 std::string GetName() const override { return "ClearRect"; }
517 private:
518 friend class RecordedEvent;
520 template <class S>
521 MOZ_IMPLICIT RecordedClearRect(S& aStream);
523 Rect mRect;
526 class RecordedCopySurface : public RecordedDrawingEvent<RecordedCopySurface> {
527 public:
528 RecordedCopySurface(DrawTarget* aDT, ReferencePtr aSourceSurface,
529 const IntRect& aSourceRect, const IntPoint& aDest)
530 : RecordedDrawingEvent(COPYSURFACE, aDT),
531 mSourceSurface(aSourceSurface),
532 mSourceRect(aSourceRect),
533 mDest(aDest) {}
535 bool PlayEvent(Translator* aTranslator) const override;
537 template <class S>
538 void Record(S& aStream) const;
539 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
541 std::string GetName() const override { return "CopySurface"; }
543 private:
544 friend class RecordedEvent;
546 template <class S>
547 MOZ_IMPLICIT RecordedCopySurface(S& aStream);
549 ReferencePtr mSourceSurface;
550 IntRect mSourceRect;
551 IntPoint mDest;
554 class RecordedPushClip : public RecordedDrawingEvent<RecordedPushClip> {
555 public:
556 RecordedPushClip(DrawTarget* aDT, ReferencePtr aPath)
557 : RecordedDrawingEvent(PUSHCLIP, aDT), mPath(aPath) {}
559 bool PlayEvent(Translator* aTranslator) const override;
561 template <class S>
562 void Record(S& aStream) const;
563 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
565 std::string GetName() const override { return "PushClip"; }
567 private:
568 friend class RecordedEvent;
570 template <class S>
571 MOZ_IMPLICIT RecordedPushClip(S& aStream);
573 ReferencePtr mPath;
576 class RecordedPushClipRect : public RecordedDrawingEvent<RecordedPushClipRect> {
577 public:
578 RecordedPushClipRect(DrawTarget* aDT, const Rect& aRect)
579 : RecordedDrawingEvent(PUSHCLIPRECT, aDT), mRect(aRect) {}
581 bool PlayEvent(Translator* aTranslator) const override;
583 template <class S>
584 void Record(S& aStream) const;
585 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
587 std::string GetName() const override { return "PushClipRect"; }
589 private:
590 friend class RecordedEvent;
592 template <class S>
593 MOZ_IMPLICIT RecordedPushClipRect(S& aStream);
595 Rect mRect;
598 class RecordedPopClip : public RecordedDrawingEvent<RecordedPopClip> {
599 public:
600 MOZ_IMPLICIT RecordedPopClip(DrawTarget* aDT)
601 : RecordedDrawingEvent(POPCLIP, aDT) {}
603 bool PlayEvent(Translator* aTranslator) const override;
605 template <class S>
606 void Record(S& aStream) const;
607 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
609 std::string GetName() const override { return "PopClip"; }
611 private:
612 friend class RecordedEvent;
614 template <class S>
615 MOZ_IMPLICIT RecordedPopClip(S& aStream);
618 class RecordedPushLayer : public RecordedDrawingEvent<RecordedPushLayer> {
619 public:
620 RecordedPushLayer(DrawTarget* aDT, bool aOpaque, Float aOpacity,
621 SourceSurface* aMask, const Matrix& aMaskTransform,
622 const IntRect& aBounds, bool aCopyBackground)
623 : RecordedDrawingEvent(PUSHLAYER, aDT),
624 mOpaque(aOpaque),
625 mOpacity(aOpacity),
626 mMask(aMask),
627 mMaskTransform(aMaskTransform),
628 mBounds(aBounds),
629 mCopyBackground(aCopyBackground) {}
631 bool PlayEvent(Translator* aTranslator) const override;
633 template <class S>
634 void Record(S& aStream) const;
635 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
637 std::string GetName() const override { return "PushLayer"; }
639 private:
640 friend class RecordedEvent;
642 template <class S>
643 MOZ_IMPLICIT RecordedPushLayer(S& aStream);
645 bool mOpaque;
646 Float mOpacity;
647 ReferencePtr mMask;
648 Matrix mMaskTransform;
649 IntRect mBounds;
650 bool mCopyBackground;
653 class RecordedPushLayerWithBlend
654 : public RecordedDrawingEvent<RecordedPushLayerWithBlend> {
655 public:
656 RecordedPushLayerWithBlend(DrawTarget* aDT, bool aOpaque, Float aOpacity,
657 SourceSurface* aMask, const Matrix& aMaskTransform,
658 const IntRect& aBounds, bool aCopyBackground,
659 CompositionOp aCompositionOp)
660 : RecordedDrawingEvent(PUSHLAYERWITHBLEND, aDT),
661 mOpaque(aOpaque),
662 mOpacity(aOpacity),
663 mMask(aMask),
664 mMaskTransform(aMaskTransform),
665 mBounds(aBounds),
666 mCopyBackground(aCopyBackground),
667 mCompositionOp(aCompositionOp) {}
669 bool PlayEvent(Translator* aTranslator) const override;
671 template <class S>
672 void Record(S& aStream) const;
673 virtual void OutputSimpleEventInfo(
674 std::stringstream& aStringStream) const override;
676 std::string GetName() const override { return "PushLayerWithBlend"; }
678 private:
679 friend class RecordedEvent;
681 template <class S>
682 MOZ_IMPLICIT RecordedPushLayerWithBlend(S& aStream);
684 bool mOpaque;
685 Float mOpacity;
686 ReferencePtr mMask;
687 Matrix mMaskTransform;
688 IntRect mBounds;
689 bool mCopyBackground;
690 CompositionOp mCompositionOp;
693 class RecordedPopLayer : public RecordedDrawingEvent<RecordedPopLayer> {
694 public:
695 MOZ_IMPLICIT RecordedPopLayer(DrawTarget* aDT)
696 : RecordedDrawingEvent(POPLAYER, aDT) {}
698 bool PlayEvent(Translator* aTranslator) const override;
700 template <class S>
701 void Record(S& aStream) const;
702 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
704 std::string GetName() const override { return "PopLayer"; }
706 private:
707 friend class RecordedEvent;
709 template <class S>
710 MOZ_IMPLICIT RecordedPopLayer(S& aStream);
713 class RecordedSetTransform : public RecordedDrawingEvent<RecordedSetTransform> {
714 public:
715 RecordedSetTransform(DrawTarget* aDT, const Matrix& aTransform)
716 : RecordedDrawingEvent(SETTRANSFORM, aDT), mTransform(aTransform) {}
718 bool PlayEvent(Translator* aTranslator) const override;
720 template <class S>
721 void Record(S& aStream) const;
722 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
724 std::string GetName() const override { return "SetTransform"; }
726 Matrix mTransform;
728 private:
729 friend class RecordedEvent;
731 template <class S>
732 MOZ_IMPLICIT RecordedSetTransform(S& aStream);
735 class RecordedDrawSurface : public RecordedDrawingEvent<RecordedDrawSurface> {
736 public:
737 RecordedDrawSurface(DrawTarget* aDT, ReferencePtr aRefSource,
738 const Rect& aDest, const Rect& aSource,
739 const DrawSurfaceOptions& aDSOptions,
740 const DrawOptions& aOptions)
741 : RecordedDrawingEvent(DRAWSURFACE, aDT),
742 mRefSource(aRefSource),
743 mDest(aDest),
744 mSource(aSource),
745 mDSOptions(aDSOptions),
746 mOptions(aOptions) {}
748 bool PlayEvent(Translator* aTranslator) const override;
750 template <class S>
751 void Record(S& aStream) const;
752 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
754 std::string GetName() const override { return "DrawSurface"; }
756 private:
757 friend class RecordedEvent;
759 template <class S>
760 MOZ_IMPLICIT RecordedDrawSurface(S& aStream);
762 ReferencePtr mRefSource;
763 Rect mDest;
764 Rect mSource;
765 DrawSurfaceOptions mDSOptions;
766 DrawOptions mOptions;
769 class RecordedDrawDependentSurface
770 : public RecordedDrawingEvent<RecordedDrawDependentSurface> {
771 public:
772 RecordedDrawDependentSurface(DrawTarget* aDT, uint64_t aId, const Rect& aDest)
773 : RecordedDrawingEvent(DRAWDEPENDENTSURFACE, aDT),
774 mId(aId),
775 mDest(aDest) {}
777 bool PlayEvent(Translator* aTranslator) const override;
779 template <class S>
780 void Record(S& aStream) const;
781 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
783 std::string GetName() const override { return "DrawDependentSurface"; }
785 private:
786 friend class RecordedEvent;
788 template <class S>
789 MOZ_IMPLICIT RecordedDrawDependentSurface(S& aStream);
791 uint64_t mId;
792 Rect mDest;
795 class RecordedDrawSurfaceWithShadow
796 : public RecordedDrawingEvent<RecordedDrawSurfaceWithShadow> {
797 public:
798 RecordedDrawSurfaceWithShadow(DrawTarget* aDT, ReferencePtr aRefSource,
799 const Point& aDest,
800 const ShadowOptions& aShadow, CompositionOp aOp)
801 : RecordedDrawingEvent(DRAWSURFACEWITHSHADOW, aDT),
802 mRefSource(aRefSource),
803 mDest(aDest),
804 mShadow(aShadow),
805 mOp(aOp) {}
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 "DrawSurfaceWithShadow"; }
815 private:
816 friend class RecordedEvent;
818 template <class S>
819 MOZ_IMPLICIT RecordedDrawSurfaceWithShadow(S& aStream);
821 ReferencePtr mRefSource;
822 Point mDest;
823 ShadowOptions mShadow;
824 CompositionOp mOp;
827 class RecordedDrawFilter : public RecordedDrawingEvent<RecordedDrawFilter> {
828 public:
829 RecordedDrawFilter(DrawTarget* aDT, ReferencePtr aNode,
830 const Rect& aSourceRect, const Point& aDestPoint,
831 const DrawOptions& aOptions)
832 : RecordedDrawingEvent(DRAWFILTER, aDT),
833 mNode(aNode),
834 mSourceRect(aSourceRect),
835 mDestPoint(aDestPoint),
836 mOptions(aOptions) {}
838 bool PlayEvent(Translator* aTranslator) const override;
840 template <class S>
841 void Record(S& aStream) const;
842 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
844 std::string GetName() const override { return "DrawFilter"; }
846 private:
847 friend class RecordedEvent;
849 template <class S>
850 MOZ_IMPLICIT RecordedDrawFilter(S& aStream);
852 ReferencePtr mNode;
853 Rect mSourceRect;
854 Point mDestPoint;
855 DrawOptions mOptions;
858 class RecordedPathCreation : public RecordedEventDerived<RecordedPathCreation> {
859 public:
860 MOZ_IMPLICIT RecordedPathCreation(PathRecording* aPath);
862 bool PlayEvent(Translator* aTranslator) const override;
864 template <class S>
865 void Record(S& aStream) const;
866 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
868 std::string GetName() const override { return "Path Creation"; }
870 private:
871 friend class RecordedEvent;
873 ReferencePtr mRefPtr;
874 FillRule mFillRule;
875 RefPtr<PathRecording> mPath;
876 UniquePtr<PathOps> mPathOps;
878 template <class S>
879 MOZ_IMPLICIT RecordedPathCreation(S& aStream);
882 class RecordedPathDestruction
883 : public RecordedEventDerived<RecordedPathDestruction> {
884 public:
885 MOZ_IMPLICIT RecordedPathDestruction(PathRecording* aPath)
886 : RecordedEventDerived(PATHDESTRUCTION), mRefPtr(aPath) {}
888 bool PlayEvent(Translator* aTranslator) const override;
890 template <class S>
891 void Record(S& aStream) const;
892 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
894 std::string GetName() const override { return "Path Destruction"; }
896 private:
897 friend class RecordedEvent;
899 ReferencePtr mRefPtr;
901 template <class S>
902 MOZ_IMPLICIT RecordedPathDestruction(S& aStream);
905 class RecordedSourceSurfaceCreation
906 : public RecordedEventDerived<RecordedSourceSurfaceCreation> {
907 public:
908 RecordedSourceSurfaceCreation(ReferencePtr aRefPtr, uint8_t* aData,
909 int32_t aStride, const IntSize& aSize,
910 SurfaceFormat aFormat)
911 : RecordedEventDerived(SOURCESURFACECREATION),
912 mRefPtr(aRefPtr),
913 mData(aData),
914 mStride(aStride),
915 mSize(aSize),
916 mFormat(aFormat),
917 mDataOwned(false) {}
919 ~RecordedSourceSurfaceCreation();
921 bool PlayEvent(Translator* aTranslator) const override;
923 template <class S>
924 void Record(S& aStream) const;
925 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
927 std::string GetName() const override { return "SourceSurface Creation"; }
929 private:
930 friend class RecordedEvent;
932 ReferencePtr mRefPtr;
933 uint8_t* mData = nullptr;
934 int32_t mStride;
935 IntSize mSize;
936 SurfaceFormat mFormat;
937 mutable bool mDataOwned;
939 template <class S>
940 MOZ_IMPLICIT RecordedSourceSurfaceCreation(S& aStream);
943 class RecordedSourceSurfaceDestruction
944 : public RecordedEventDerived<RecordedSourceSurfaceDestruction> {
945 public:
946 MOZ_IMPLICIT RecordedSourceSurfaceDestruction(ReferencePtr aRefPtr)
947 : RecordedEventDerived(SOURCESURFACEDESTRUCTION), mRefPtr(aRefPtr) {}
949 bool PlayEvent(Translator* aTranslator) const override;
951 template <class S>
952 void Record(S& aStream) const;
953 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
955 std::string GetName() const override { return "SourceSurface Destruction"; }
957 private:
958 friend class RecordedEvent;
960 ReferencePtr mRefPtr;
962 template <class S>
963 MOZ_IMPLICIT RecordedSourceSurfaceDestruction(S& aStream);
966 class RecordedOptimizeSourceSurface
967 : public RecordedEventDerived<RecordedOptimizeSourceSurface> {
968 public:
969 RecordedOptimizeSourceSurface(ReferencePtr aSurface, ReferencePtr aDT,
970 ReferencePtr aOptimizedSurface)
971 : RecordedEventDerived(OPTIMIZESOURCESURFACE),
972 mSurface(aSurface),
973 mDT(aDT),
974 mOptimizedSurface(aOptimizedSurface) {}
976 bool PlayEvent(Translator* aTranslator) const override;
978 template <class S>
979 void Record(S& aStream) const;
980 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
982 std::string GetName() const override { return "OptimizeSourceSurface"; }
984 private:
985 friend class RecordedEvent;
987 ReferencePtr mSurface;
988 ReferencePtr mDT;
989 ReferencePtr mOptimizedSurface;
991 template <class S>
992 MOZ_IMPLICIT RecordedOptimizeSourceSurface(S& aStream);
995 class RecordedExternalSurfaceCreation
996 : public RecordedEventDerived<RecordedExternalSurfaceCreation> {
997 public:
998 RecordedExternalSurfaceCreation(ReferencePtr aRefPtr, const uint64_t aKey)
999 : RecordedEventDerived(EXTERNALSURFACECREATION),
1000 mRefPtr(aRefPtr),
1001 mKey(aKey) {}
1003 ~RecordedExternalSurfaceCreation() = default;
1005 virtual bool PlayEvent(Translator* aTranslator) const;
1007 template <class S>
1008 void Record(S& aStream) const;
1009 virtual void OutputSimpleEventInfo(std::stringstream& aStringStream) const;
1011 virtual std::string GetName() const {
1012 return "SourceSurfaceSharedData Creation";
1015 private:
1016 friend class RecordedEvent;
1018 ReferencePtr mRefPtr;
1019 uint64_t mKey;
1021 template <class S>
1022 MOZ_IMPLICIT RecordedExternalSurfaceCreation(S& aStream);
1025 class RecordedFilterNodeCreation
1026 : public RecordedEventDerived<RecordedFilterNodeCreation> {
1027 public:
1028 RecordedFilterNodeCreation(ReferencePtr aRefPtr, FilterType aType)
1029 : RecordedEventDerived(FILTERNODECREATION),
1030 mRefPtr(aRefPtr),
1031 mType(aType) {}
1033 ~RecordedFilterNodeCreation();
1035 bool PlayEvent(Translator* aTranslator) const override;
1037 template <class S>
1038 void Record(S& aStream) const;
1039 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1041 std::string GetName() const override { return "FilterNode Creation"; }
1043 private:
1044 friend class RecordedEvent;
1046 ReferencePtr mRefPtr;
1047 FilterType mType;
1049 template <class S>
1050 MOZ_IMPLICIT RecordedFilterNodeCreation(S& aStream);
1053 class RecordedFilterNodeDestruction
1054 : public RecordedEventDerived<RecordedFilterNodeDestruction> {
1055 public:
1056 MOZ_IMPLICIT RecordedFilterNodeDestruction(ReferencePtr aRefPtr)
1057 : RecordedEventDerived(FILTERNODEDESTRUCTION), mRefPtr(aRefPtr) {}
1059 bool PlayEvent(Translator* aTranslator) const override;
1061 template <class S>
1062 void Record(S& aStream) const;
1063 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1065 std::string GetName() const override { return "FilterNode Destruction"; }
1067 private:
1068 friend class RecordedEvent;
1070 ReferencePtr mRefPtr;
1072 template <class S>
1073 MOZ_IMPLICIT RecordedFilterNodeDestruction(S& aStream);
1076 class RecordedGradientStopsCreation
1077 : public RecordedEventDerived<RecordedGradientStopsCreation> {
1078 public:
1079 RecordedGradientStopsCreation(ReferencePtr aRefPtr, GradientStop* aStops,
1080 uint32_t aNumStops, ExtendMode aExtendMode)
1081 : RecordedEventDerived(GRADIENTSTOPSCREATION),
1082 mRefPtr(aRefPtr),
1083 mStops(aStops),
1084 mNumStops(aNumStops),
1085 mExtendMode(aExtendMode),
1086 mDataOwned(false) {}
1088 ~RecordedGradientStopsCreation();
1090 bool PlayEvent(Translator* aTranslator) const override;
1092 template <class S>
1093 void Record(S& aStream) const;
1094 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1096 std::string GetName() const override { return "GradientStops Creation"; }
1098 private:
1099 friend class RecordedEvent;
1101 ReferencePtr mRefPtr;
1102 GradientStop* mStops = nullptr;
1103 uint32_t mNumStops = 0;
1104 ExtendMode mExtendMode;
1105 bool mDataOwned;
1107 template <class S>
1108 MOZ_IMPLICIT RecordedGradientStopsCreation(S& aStream);
1111 class RecordedGradientStopsDestruction
1112 : public RecordedEventDerived<RecordedGradientStopsDestruction> {
1113 public:
1114 MOZ_IMPLICIT RecordedGradientStopsDestruction(ReferencePtr aRefPtr)
1115 : RecordedEventDerived(GRADIENTSTOPSDESTRUCTION), mRefPtr(aRefPtr) {}
1117 bool PlayEvent(Translator* aTranslator) const override;
1119 template <class S>
1120 void Record(S& aStream) const;
1121 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1123 std::string GetName() const override { return "GradientStops Destruction"; }
1125 private:
1126 friend class RecordedEvent;
1128 ReferencePtr mRefPtr;
1130 template <class S>
1131 MOZ_IMPLICIT RecordedGradientStopsDestruction(S& aStream);
1134 class RecordedFlush : public RecordedDrawingEvent<RecordedFlush> {
1135 public:
1136 explicit RecordedFlush(DrawTarget* aDT) : RecordedDrawingEvent(FLUSH, aDT) {}
1138 bool PlayEvent(Translator* aTranslator) const final;
1140 template <class S>
1141 void Record(S& aStream) const;
1142 virtual void OutputSimpleEventInfo(
1143 std::stringstream& aStringStream) const override;
1145 virtual std::string GetName() const override { return "Flush"; }
1147 private:
1148 friend class RecordedEvent;
1150 template <class S>
1151 MOZ_IMPLICIT RecordedFlush(S& aStream);
1154 class RecordedDetachAllSnapshots
1155 : public RecordedDrawingEvent<RecordedDetachAllSnapshots> {
1156 public:
1157 explicit RecordedDetachAllSnapshots(DrawTarget* aDT)
1158 : RecordedDrawingEvent(DETACHALLSNAPSHOTS, aDT) {}
1160 bool PlayEvent(Translator* aTranslator) const final;
1162 template <class S>
1163 void Record(S& aStream) const;
1164 virtual void OutputSimpleEventInfo(
1165 std::stringstream& aStringStream) const override;
1167 virtual std::string GetName() const override { return "DetachAllSnapshots"; }
1169 private:
1170 friend class RecordedEvent;
1172 template <class S>
1173 MOZ_IMPLICIT RecordedDetachAllSnapshots(S& aStream);
1176 class RecordedSnapshot : public RecordedEventDerived<RecordedSnapshot> {
1177 public:
1178 RecordedSnapshot(ReferencePtr aRefPtr, DrawTarget* aDT)
1179 : RecordedEventDerived(SNAPSHOT), mRefPtr(aRefPtr), mDT(aDT) {}
1181 bool PlayEvent(Translator* aTranslator) const override;
1183 template <class S>
1184 void Record(S& aStream) const;
1185 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1187 std::string GetName() const override { return "Snapshot"; }
1189 private:
1190 friend class RecordedEvent;
1192 ReferencePtr mRefPtr;
1193 ReferencePtr mDT;
1195 template <class S>
1196 MOZ_IMPLICIT RecordedSnapshot(S& aStream);
1199 class RecordedIntoLuminanceSource
1200 : public RecordedEventDerived<RecordedIntoLuminanceSource> {
1201 public:
1202 RecordedIntoLuminanceSource(ReferencePtr aRefPtr, DrawTarget* aDT,
1203 LuminanceType aLuminanceType, float aOpacity)
1204 : RecordedEventDerived(INTOLUMINANCE),
1205 mRefPtr(aRefPtr),
1206 mDT(aDT),
1207 mLuminanceType(aLuminanceType),
1208 mOpacity(aOpacity) {}
1210 bool PlayEvent(Translator* aTranslator) const override;
1212 template <class S>
1213 void Record(S& aStream) const;
1214 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1216 std::string GetName() const override { return "IntoLuminanceSource"; }
1218 private:
1219 friend class RecordedEvent;
1221 ReferencePtr mRefPtr;
1222 ReferencePtr mDT;
1223 LuminanceType mLuminanceType;
1224 float mOpacity;
1226 template <class S>
1227 MOZ_IMPLICIT RecordedIntoLuminanceSource(S& aStream);
1230 class RecordedFontData : public RecordedEventDerived<RecordedFontData> {
1231 public:
1232 static void FontDataProc(const uint8_t* aData, uint32_t aSize,
1233 uint32_t aIndex, void* aBaton) {
1234 auto recordedFontData = static_cast<RecordedFontData*>(aBaton);
1235 recordedFontData->SetFontData(aData, aSize, aIndex);
1238 explicit RecordedFontData(UnscaledFont* aUnscaledFont)
1239 : RecordedEventDerived(FONTDATA),
1240 mType(aUnscaledFont->GetType()),
1241 mFontDetails() {
1242 mGetFontFileDataSucceeded =
1243 aUnscaledFont->GetFontFileData(&FontDataProc, this) && mData;
1246 virtual ~RecordedFontData();
1248 bool IsValid() const { return mGetFontFileDataSucceeded; }
1250 bool PlayEvent(Translator* aTranslator) const override;
1252 template <class S>
1253 void Record(S& aStream) const;
1254 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1256 std::string GetName() const override { return "Font Data"; }
1258 void SetFontData(const uint8_t* aData, uint32_t aSize, uint32_t aIndex);
1260 bool GetFontDetails(RecordedFontDetails& fontDetails);
1262 private:
1263 friend class RecordedEvent;
1265 FontType mType;
1266 uint8_t* mData = nullptr;
1267 RecordedFontDetails mFontDetails;
1269 bool mGetFontFileDataSucceeded;
1271 template <class S>
1272 MOZ_IMPLICIT RecordedFontData(S& aStream);
1275 class RecordedFontDescriptor
1276 : public RecordedEventDerived<RecordedFontDescriptor> {
1277 public:
1278 static void FontDescCb(const uint8_t* aData, uint32_t aSize, uint32_t aIndex,
1279 void* aBaton) {
1280 auto recordedFontDesc = static_cast<RecordedFontDescriptor*>(aBaton);
1281 recordedFontDesc->SetFontDescriptor(aData, aSize, aIndex);
1284 explicit RecordedFontDescriptor(UnscaledFont* aUnscaledFont)
1285 : RecordedEventDerived(FONTDESC),
1286 mType(aUnscaledFont->GetType()),
1287 mIndex(0),
1288 mRefPtr(aUnscaledFont) {
1289 mHasDesc = aUnscaledFont->GetFontDescriptor(FontDescCb, this);
1292 virtual ~RecordedFontDescriptor();
1294 bool IsValid() const { return mHasDesc; }
1296 bool PlayEvent(Translator* aTranslator) const override;
1298 template <class S>
1299 void Record(S& aStream) const;
1300 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1302 std::string GetName() const override { return "Font Desc"; }
1304 private:
1305 friend class RecordedEvent;
1307 void SetFontDescriptor(const uint8_t* aData, uint32_t aSize, uint32_t aIndex);
1309 bool mHasDesc;
1311 FontType mType;
1312 std::vector<uint8_t> mData;
1313 uint32_t mIndex;
1314 ReferencePtr mRefPtr;
1316 template <class S>
1317 MOZ_IMPLICIT RecordedFontDescriptor(S& aStream);
1320 class RecordedUnscaledFontCreation
1321 : public RecordedEventDerived<RecordedUnscaledFontCreation> {
1322 public:
1323 static void FontInstanceDataProc(const uint8_t* aData, uint32_t aSize,
1324 void* aBaton) {
1325 auto recordedUnscaledFontCreation =
1326 static_cast<RecordedUnscaledFontCreation*>(aBaton);
1327 recordedUnscaledFontCreation->SetFontInstanceData(aData, aSize);
1330 RecordedUnscaledFontCreation(UnscaledFont* aUnscaledFont,
1331 RecordedFontDetails aFontDetails)
1332 : RecordedEventDerived(UNSCALEDFONTCREATION),
1333 mRefPtr(aUnscaledFont),
1334 mFontDataKey(aFontDetails.fontDataKey),
1335 mIndex(aFontDetails.index) {
1336 aUnscaledFont->GetFontInstanceData(FontInstanceDataProc, this);
1339 bool PlayEvent(Translator* aTranslator) const override;
1341 template <class S>
1342 void Record(S& aStream) const;
1343 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1345 std::string GetName() const override { return "UnscaledFont Creation"; }
1347 void SetFontInstanceData(const uint8_t* aData, uint32_t aSize);
1349 private:
1350 friend class RecordedEvent;
1352 ReferencePtr mRefPtr;
1353 uint64_t mFontDataKey;
1354 uint32_t mIndex;
1355 std::vector<uint8_t> mInstanceData;
1357 template <class S>
1358 MOZ_IMPLICIT RecordedUnscaledFontCreation(S& aStream);
1361 class RecordedUnscaledFontDestruction
1362 : public RecordedEventDerived<RecordedUnscaledFontDestruction> {
1363 public:
1364 MOZ_IMPLICIT RecordedUnscaledFontDestruction(ReferencePtr aRefPtr)
1365 : RecordedEventDerived(UNSCALEDFONTDESTRUCTION), mRefPtr(aRefPtr) {}
1367 bool PlayEvent(Translator* aTranslator) const override;
1368 template <class S>
1369 void Record(S& aStream) const;
1370 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1372 std::string GetName() const override { return "UnscaledFont Destruction"; }
1374 private:
1375 friend class RecordedEvent;
1377 ReferencePtr mRefPtr;
1379 template <class S>
1380 MOZ_IMPLICIT RecordedUnscaledFontDestruction(S& aStream);
1383 class RecordedScaledFontCreation
1384 : public RecordedEventDerived<RecordedScaledFontCreation> {
1385 public:
1386 static void FontInstanceDataProc(const uint8_t* aData, uint32_t aSize,
1387 const FontVariation* aVariations,
1388 uint32_t aNumVariations, void* aBaton) {
1389 auto recordedScaledFontCreation =
1390 static_cast<RecordedScaledFontCreation*>(aBaton);
1391 recordedScaledFontCreation->SetFontInstanceData(aData, aSize, aVariations,
1392 aNumVariations);
1395 RecordedScaledFontCreation(ScaledFont* aScaledFont,
1396 UnscaledFont* aUnscaledFont)
1397 : RecordedEventDerived(SCALEDFONTCREATION),
1398 mRefPtr(aScaledFont),
1399 mUnscaledFont(aUnscaledFont),
1400 mGlyphSize(aScaledFont->GetSize()) {
1401 aScaledFont->GetFontInstanceData(FontInstanceDataProc, this);
1404 bool PlayEvent(Translator* aTranslator) const override;
1406 template <class S>
1407 void Record(S& aStream) const;
1408 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1410 std::string GetName() const override { return "ScaledFont Creation"; }
1412 void SetFontInstanceData(const uint8_t* aData, uint32_t aSize,
1413 const FontVariation* aVariations,
1414 uint32_t aNumVariations);
1416 private:
1417 friend class RecordedEvent;
1419 ReferencePtr mRefPtr;
1420 ReferencePtr mUnscaledFont;
1421 Float mGlyphSize;
1422 std::vector<uint8_t> mInstanceData;
1423 std::vector<FontVariation> mVariations;
1425 template <class S>
1426 MOZ_IMPLICIT RecordedScaledFontCreation(S& aStream);
1429 class RecordedScaledFontDestruction
1430 : public RecordedEventDerived<RecordedScaledFontDestruction> {
1431 public:
1432 MOZ_IMPLICIT RecordedScaledFontDestruction(ReferencePtr aRefPtr)
1433 : RecordedEventDerived(SCALEDFONTDESTRUCTION), mRefPtr(aRefPtr) {}
1435 bool PlayEvent(Translator* aTranslator) const override;
1437 template <class S>
1438 void Record(S& aStream) const;
1439 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1441 std::string GetName() const override { return "ScaledFont Destruction"; }
1443 private:
1444 friend class RecordedEvent;
1446 ReferencePtr mRefPtr;
1448 template <class S>
1449 MOZ_IMPLICIT RecordedScaledFontDestruction(S& aStream);
1452 class RecordedMaskSurface : public RecordedDrawingEvent<RecordedMaskSurface> {
1453 public:
1454 RecordedMaskSurface(DrawTarget* aDT, const Pattern& aPattern,
1455 ReferencePtr aRefMask, const Point& aOffset,
1456 const DrawOptions& aOptions)
1457 : RecordedDrawingEvent(MASKSURFACE, aDT),
1458 mPattern(),
1459 mRefMask(aRefMask),
1460 mOffset(aOffset),
1461 mOptions(aOptions) {
1462 StorePattern(mPattern, aPattern);
1465 bool PlayEvent(Translator* aTranslator) const override;
1467 template <class S>
1468 void Record(S& aStream) const;
1469 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1471 std::string GetName() const override { return "MaskSurface"; }
1473 private:
1474 friend class RecordedEvent;
1476 template <class S>
1477 MOZ_IMPLICIT RecordedMaskSurface(S& aStream);
1479 PatternStorage mPattern;
1480 ReferencePtr mRefMask;
1481 Point mOffset;
1482 DrawOptions mOptions;
1485 class RecordedFilterNodeSetAttribute
1486 : public RecordedEventDerived<RecordedFilterNodeSetAttribute> {
1487 public:
1488 enum ArgType {
1489 ARGTYPE_UINT32,
1490 ARGTYPE_BOOL,
1491 ARGTYPE_FLOAT,
1492 ARGTYPE_SIZE,
1493 ARGTYPE_INTSIZE,
1494 ARGTYPE_INTPOINT,
1495 ARGTYPE_RECT,
1496 ARGTYPE_INTRECT,
1497 ARGTYPE_POINT,
1498 ARGTYPE_MATRIX,
1499 ARGTYPE_MATRIX5X4,
1500 ARGTYPE_POINT3D,
1501 ARGTYPE_COLOR,
1502 ARGTYPE_FLOAT_ARRAY
1505 template <typename T>
1506 RecordedFilterNodeSetAttribute(FilterNode* aNode, uint32_t aIndex,
1507 T aArgument, ArgType aArgType)
1508 : RecordedEventDerived(FILTERNODESETATTRIBUTE),
1509 mNode(aNode),
1510 mIndex(aIndex),
1511 mArgType(aArgType) {
1512 mPayload.resize(sizeof(T));
1513 memcpy(&mPayload.front(), &aArgument, sizeof(T));
1516 RecordedFilterNodeSetAttribute(FilterNode* aNode, uint32_t aIndex,
1517 const Float* aFloat, uint32_t aSize)
1518 : RecordedEventDerived(FILTERNODESETATTRIBUTE),
1519 mNode(aNode),
1520 mIndex(aIndex),
1521 mArgType(ARGTYPE_FLOAT_ARRAY) {
1522 mPayload.resize(sizeof(Float) * aSize);
1523 memcpy(&mPayload.front(), aFloat, sizeof(Float) * aSize);
1526 bool PlayEvent(Translator* aTranslator) const override;
1527 template <class S>
1528 void Record(S& aStream) const;
1529 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1531 std::string GetName() const override { return "SetAttribute"; }
1533 private:
1534 friend class RecordedEvent;
1536 ReferencePtr mNode;
1538 uint32_t mIndex;
1539 ArgType mArgType;
1540 std::vector<uint8_t> mPayload;
1542 template <class S>
1543 MOZ_IMPLICIT RecordedFilterNodeSetAttribute(S& aStream);
1546 class RecordedFilterNodeSetInput
1547 : public RecordedEventDerived<RecordedFilterNodeSetInput> {
1548 public:
1549 RecordedFilterNodeSetInput(FilterNode* aNode, uint32_t aIndex,
1550 FilterNode* aInputNode)
1551 : RecordedEventDerived(FILTERNODESETINPUT),
1552 mNode(aNode),
1553 mIndex(aIndex),
1554 mInputFilter(aInputNode),
1555 mInputSurface(nullptr) {}
1557 RecordedFilterNodeSetInput(FilterNode* aNode, uint32_t aIndex,
1558 SourceSurface* aInputSurface)
1559 : RecordedEventDerived(FILTERNODESETINPUT),
1560 mNode(aNode),
1561 mIndex(aIndex),
1562 mInputFilter(nullptr),
1563 mInputSurface(aInputSurface) {}
1565 bool PlayEvent(Translator* aTranslator) const override;
1566 template <class S>
1567 void Record(S& aStream) const;
1568 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1570 std::string GetName() const override { return "SetInput"; }
1572 private:
1573 friend class RecordedEvent;
1575 ReferencePtr mNode;
1576 uint32_t mIndex;
1577 ReferencePtr mInputFilter;
1578 ReferencePtr mInputSurface;
1580 template <class S>
1581 MOZ_IMPLICIT RecordedFilterNodeSetInput(S& aStream);
1584 class RecordedLink : public RecordedDrawingEvent<RecordedLink> {
1585 public:
1586 RecordedLink(DrawTarget* aDT, const char* aDestination, const Rect& aRect)
1587 : RecordedDrawingEvent(LINK, aDT),
1588 mDestination(aDestination),
1589 mRect(aRect) {}
1591 bool PlayEvent(Translator* aTranslator) const override;
1592 template <class S>
1593 void Record(S& aStream) const;
1594 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1596 std::string GetName() const override { return "Link"; }
1598 private:
1599 friend class RecordedEvent;
1601 std::string mDestination;
1602 Rect mRect;
1604 template <class S>
1605 MOZ_IMPLICIT RecordedLink(S& aStream);
1608 class RecordedDestination : public RecordedDrawingEvent<RecordedDestination> {
1609 public:
1610 RecordedDestination(DrawTarget* aDT, const char* aDestination,
1611 const Point& aPoint)
1612 : RecordedDrawingEvent(DESTINATION, aDT),
1613 mDestination(aDestination),
1614 mPoint(aPoint) {}
1616 bool PlayEvent(Translator* aTranslator) const override;
1617 template <class S>
1618 void Record(S& aStream) const;
1619 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1621 std::string GetName() const override { return "Destination"; }
1623 private:
1624 friend class RecordedEvent;
1626 std::string mDestination;
1627 Point mPoint;
1629 template <class S>
1630 MOZ_IMPLICIT RecordedDestination(S& aStream);
1633 static std::string NameFromBackend(BackendType aType) {
1634 switch (aType) {
1635 case BackendType::NONE:
1636 return "None";
1637 case BackendType::DIRECT2D:
1638 return "Direct2D";
1639 default:
1640 return "Unknown";
1644 template <class S>
1645 void RecordedEvent::RecordPatternData(S& aStream,
1646 const PatternStorage& aPattern) const {
1647 WriteElement(aStream, aPattern.mType);
1649 switch (aPattern.mType) {
1650 case PatternType::COLOR: {
1651 WriteElement(aStream, *reinterpret_cast<const ColorPatternStorage*>(
1652 &aPattern.mStorage));
1653 return;
1655 case PatternType::LINEAR_GRADIENT: {
1656 WriteElement(aStream,
1657 *reinterpret_cast<const LinearGradientPatternStorage*>(
1658 &aPattern.mStorage));
1659 return;
1661 case PatternType::RADIAL_GRADIENT: {
1662 WriteElement(aStream,
1663 *reinterpret_cast<const RadialGradientPatternStorage*>(
1664 &aPattern.mStorage));
1665 return;
1667 case PatternType::CONIC_GRADIENT: {
1668 WriteElement(aStream,
1669 *reinterpret_cast<const ConicGradientPatternStorage*>(
1670 &aPattern.mStorage));
1671 return;
1673 case PatternType::SURFACE: {
1674 WriteElement(aStream, *reinterpret_cast<const SurfacePatternStorage*>(
1675 &aPattern.mStorage));
1676 return;
1678 default:
1679 return;
1683 template <class S>
1684 void RecordedEvent::ReadPatternData(S& aStream,
1685 PatternStorage& aPattern) const {
1686 ReadElementConstrained(aStream, aPattern.mType, PatternType::COLOR,
1687 kHighestPatternType);
1689 switch (aPattern.mType) {
1690 case PatternType::COLOR: {
1691 ReadElement(aStream,
1692 *reinterpret_cast<ColorPatternStorage*>(&aPattern.mStorage));
1693 return;
1695 case PatternType::LINEAR_GRADIENT: {
1696 ReadElement(aStream, *reinterpret_cast<LinearGradientPatternStorage*>(
1697 &aPattern.mStorage));
1698 return;
1700 case PatternType::RADIAL_GRADIENT: {
1701 ReadElement(aStream, *reinterpret_cast<RadialGradientPatternStorage*>(
1702 &aPattern.mStorage));
1703 return;
1705 case PatternType::CONIC_GRADIENT: {
1706 ReadElement(aStream, *reinterpret_cast<ConicGradientPatternStorage*>(
1707 &aPattern.mStorage));
1708 return;
1710 case PatternType::SURFACE: {
1711 SurfacePatternStorage* sps =
1712 reinterpret_cast<SurfacePatternStorage*>(&aPattern.mStorage);
1713 ReadElement(aStream, *sps);
1714 if (sps->mExtend < ExtendMode::CLAMP ||
1715 sps->mExtend > ExtendMode::REFLECT) {
1716 aStream.SetIsBad();
1717 return;
1720 if (sps->mSamplingFilter < SamplingFilter::GOOD ||
1721 sps->mSamplingFilter >= SamplingFilter::SENTINEL) {
1722 aStream.SetIsBad();
1724 return;
1726 default:
1727 return;
1731 inline void RecordedEvent::StorePattern(PatternStorage& aDestination,
1732 const Pattern& aSource) const {
1733 aDestination.mType = aSource.GetType();
1735 switch (aSource.GetType()) {
1736 case PatternType::COLOR: {
1737 reinterpret_cast<ColorPatternStorage*>(&aDestination.mStorage)->mColor =
1738 static_cast<const ColorPattern*>(&aSource)->mColor;
1739 return;
1741 case PatternType::LINEAR_GRADIENT: {
1742 LinearGradientPatternStorage* store =
1743 reinterpret_cast<LinearGradientPatternStorage*>(
1744 &aDestination.mStorage);
1745 const LinearGradientPattern* pat =
1746 static_cast<const LinearGradientPattern*>(&aSource);
1747 store->mBegin = pat->mBegin;
1748 store->mEnd = pat->mEnd;
1749 store->mMatrix = pat->mMatrix;
1750 store->mStops = pat->mStops.get();
1751 return;
1753 case PatternType::RADIAL_GRADIENT: {
1754 RadialGradientPatternStorage* store =
1755 reinterpret_cast<RadialGradientPatternStorage*>(
1756 &aDestination.mStorage);
1757 const RadialGradientPattern* pat =
1758 static_cast<const RadialGradientPattern*>(&aSource);
1759 store->mCenter1 = pat->mCenter1;
1760 store->mCenter2 = pat->mCenter2;
1761 store->mRadius1 = pat->mRadius1;
1762 store->mRadius2 = pat->mRadius2;
1763 store->mMatrix = pat->mMatrix;
1764 store->mStops = pat->mStops.get();
1765 return;
1767 case PatternType::CONIC_GRADIENT: {
1768 ConicGradientPatternStorage* store =
1769 reinterpret_cast<ConicGradientPatternStorage*>(
1770 &aDestination.mStorage);
1771 const ConicGradientPattern* pat =
1772 static_cast<const ConicGradientPattern*>(&aSource);
1773 store->mCenter = pat->mCenter;
1774 store->mAngle = pat->mAngle;
1775 store->mStartOffset = pat->mStartOffset;
1776 store->mEndOffset = pat->mEndOffset;
1777 store->mMatrix = pat->mMatrix;
1778 store->mStops = pat->mStops.get();
1779 return;
1781 case PatternType::SURFACE: {
1782 SurfacePatternStorage* store =
1783 reinterpret_cast<SurfacePatternStorage*>(&aDestination.mStorage);
1784 const SurfacePattern* pat = static_cast<const SurfacePattern*>(&aSource);
1785 store->mExtend = pat->mExtendMode;
1786 store->mSamplingFilter = pat->mSamplingFilter;
1787 store->mMatrix = pat->mMatrix;
1788 store->mSurface = pat->mSurface;
1789 store->mSamplingRect = pat->mSamplingRect;
1790 return;
1795 template <class S>
1796 void RecordedEvent::RecordStrokeOptions(
1797 S& aStream, const StrokeOptions& aStrokeOptions) const {
1798 JoinStyle joinStyle = aStrokeOptions.mLineJoin;
1799 CapStyle capStyle = aStrokeOptions.mLineCap;
1801 WriteElement(aStream, uint64_t(aStrokeOptions.mDashLength));
1802 WriteElement(aStream, aStrokeOptions.mLineWidth);
1803 WriteElement(aStream, aStrokeOptions.mMiterLimit);
1804 WriteElement(aStream, joinStyle);
1805 WriteElement(aStream, capStyle);
1807 if (!aStrokeOptions.mDashPattern) {
1808 return;
1811 WriteElement(aStream, aStrokeOptions.mDashOffset);
1812 aStream.write((char*)aStrokeOptions.mDashPattern,
1813 sizeof(Float) * aStrokeOptions.mDashLength);
1816 template <class S>
1817 void RecordedEvent::ReadStrokeOptions(S& aStream,
1818 StrokeOptions& aStrokeOptions) {
1819 uint64_t dashLength;
1820 JoinStyle joinStyle;
1821 CapStyle capStyle;
1823 ReadElement(aStream, dashLength);
1824 ReadElement(aStream, aStrokeOptions.mLineWidth);
1825 ReadElement(aStream, aStrokeOptions.mMiterLimit);
1826 ReadElementConstrained(aStream, joinStyle, JoinStyle::BEVEL,
1827 JoinStyle::MITER_OR_BEVEL);
1828 ReadElementConstrained(aStream, capStyle, CapStyle::BUTT, CapStyle::SQUARE);
1829 // On 32 bit we truncate the value of dashLength.
1830 // See also bug 811850 for history.
1831 aStrokeOptions.mDashLength = size_t(dashLength);
1832 aStrokeOptions.mLineJoin = joinStyle;
1833 aStrokeOptions.mLineCap = capStyle;
1835 if (!aStrokeOptions.mDashLength || !aStream.good()) {
1836 return;
1839 ReadElement(aStream, aStrokeOptions.mDashOffset);
1841 mDashPatternStorage.resize(aStrokeOptions.mDashLength);
1842 aStrokeOptions.mDashPattern = &mDashPatternStorage.front();
1843 aStream.read((char*)aStrokeOptions.mDashPattern,
1844 sizeof(Float) * aStrokeOptions.mDashLength);
1847 template <class S>
1848 static void ReadDrawOptions(S& aStream, DrawOptions& aDrawOptions) {
1849 ReadElement(aStream, aDrawOptions);
1850 if (aDrawOptions.mAntialiasMode < AntialiasMode::NONE ||
1851 aDrawOptions.mAntialiasMode > AntialiasMode::DEFAULT) {
1852 aStream.SetIsBad();
1853 return;
1856 if (aDrawOptions.mCompositionOp < CompositionOp::OP_CLEAR ||
1857 aDrawOptions.mCompositionOp > CompositionOp::OP_COUNT) {
1858 aStream.SetIsBad();
1862 template <class S>
1863 static void ReadDrawSurfaceOptions(S& aStream,
1864 DrawSurfaceOptions& aDrawSurfaceOptions) {
1865 ReadElement(aStream, aDrawSurfaceOptions);
1866 if (aDrawSurfaceOptions.mSamplingFilter < SamplingFilter::GOOD ||
1867 aDrawSurfaceOptions.mSamplingFilter >= SamplingFilter::SENTINEL) {
1868 aStream.SetIsBad();
1869 return;
1872 if (aDrawSurfaceOptions.mSamplingBounds < SamplingBounds::UNBOUNDED ||
1873 aDrawSurfaceOptions.mSamplingBounds > SamplingBounds::BOUNDED) {
1874 aStream.SetIsBad();
1878 inline void RecordedEvent::OutputSimplePatternInfo(
1879 const PatternStorage& aStorage, std::stringstream& aOutput) const {
1880 switch (aStorage.mType) {
1881 case PatternType::COLOR: {
1882 const DeviceColor color =
1883 reinterpret_cast<const ColorPatternStorage*>(&aStorage.mStorage)
1884 ->mColor;
1885 aOutput << "DeviceColor: (" << color.r << ", " << color.g << ", "
1886 << color.b << ", " << color.a << ")";
1887 return;
1889 case PatternType::LINEAR_GRADIENT: {
1890 const LinearGradientPatternStorage* store =
1891 reinterpret_cast<const LinearGradientPatternStorage*>(
1892 &aStorage.mStorage);
1894 aOutput << "LinearGradient (" << store->mBegin.x << ", "
1895 << store->mBegin.y << ") - (" << store->mEnd.x << ", "
1896 << store->mEnd.y << ") Stops: " << store->mStops;
1897 return;
1899 case PatternType::RADIAL_GRADIENT: {
1900 const RadialGradientPatternStorage* store =
1901 reinterpret_cast<const RadialGradientPatternStorage*>(
1902 &aStorage.mStorage);
1903 aOutput << "RadialGradient (Center 1: (" << store->mCenter1.x << ", "
1904 << store->mCenter2.y << ") Radius 2: " << store->mRadius2;
1905 return;
1907 case PatternType::CONIC_GRADIENT: {
1908 const ConicGradientPatternStorage* store =
1909 reinterpret_cast<const ConicGradientPatternStorage*>(
1910 &aStorage.mStorage);
1911 aOutput << "ConicGradient (Center: (" << store->mCenter.x << ", "
1912 << store->mCenter.y << ") Angle: " << store->mAngle
1913 << " Range:" << store->mStartOffset << " - " << store->mEndOffset;
1914 return;
1916 case PatternType::SURFACE: {
1917 const SurfacePatternStorage* store =
1918 reinterpret_cast<const SurfacePatternStorage*>(&aStorage.mStorage);
1919 aOutput << "Surface (0x" << store->mSurface << ")";
1920 return;
1925 template <class T>
1926 template <class S>
1927 RecordedDrawingEvent<T>::RecordedDrawingEvent(RecordedEvent::EventType aType,
1928 S& aStream)
1929 : RecordedEventDerived<T>(aType) {
1930 ReadElement(aStream, mDT);
1933 template <class T>
1934 template <class S>
1935 void RecordedDrawingEvent<T>::Record(S& aStream) const {
1936 WriteElement(aStream, mDT);
1939 inline bool RecordedDrawTargetCreation::PlayEvent(
1940 Translator* aTranslator) const {
1941 RefPtr<DrawTarget> newDT =
1942 aTranslator->CreateDrawTarget(mRefPtr, mRect.Size(), mFormat);
1944 // If we couldn't create a DrawTarget this will probably cause us to crash
1945 // with nullptr later in the playback, so return false to abort.
1946 if (!newDT) {
1947 return false;
1950 if (mHasExistingData) {
1951 Rect dataRect(0, 0, mExistingData->GetSize().width,
1952 mExistingData->GetSize().height);
1953 newDT->DrawSurface(mExistingData, dataRect, dataRect);
1956 return true;
1959 template <class S>
1960 void RecordedDrawTargetCreation::Record(S& aStream) const {
1961 WriteElement(aStream, mRefPtr);
1962 WriteElement(aStream, mBackendType);
1963 WriteElement(aStream, mRect);
1964 WriteElement(aStream, mFormat);
1965 WriteElement(aStream, mHasExistingData);
1967 if (mHasExistingData) {
1968 MOZ_ASSERT(mExistingData);
1969 MOZ_ASSERT(mExistingData->GetSize() == mRect.Size());
1970 RefPtr<DataSourceSurface> dataSurf = mExistingData->GetDataSurface();
1972 DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ);
1973 for (int y = 0; y < mRect.height; y++) {
1974 aStream.write((const char*)map.GetData() + y * map.GetStride(),
1975 BytesPerPixel(mFormat) * mRect.width);
1980 template <class S>
1981 RecordedDrawTargetCreation::RecordedDrawTargetCreation(S& aStream)
1982 : RecordedEventDerived(DRAWTARGETCREATION), mExistingData(nullptr) {
1983 ReadElement(aStream, mRefPtr);
1984 ReadElementConstrained(aStream, mBackendType, BackendType::NONE,
1985 BackendType::WEBRENDER_TEXT);
1986 ReadElement(aStream, mRect);
1987 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
1988 SurfaceFormat::UNKNOWN);
1989 ReadElement(aStream, mHasExistingData);
1991 if (mHasExistingData) {
1992 RefPtr<DataSourceSurface> dataSurf =
1993 Factory::CreateDataSourceSurface(mRect.Size(), mFormat);
1994 if (!dataSurf) {
1995 gfxWarning()
1996 << "RecordedDrawTargetCreation had to reset mHasExistingData";
1997 mHasExistingData = false;
1998 return;
2001 DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ);
2002 for (int y = 0; y < mRect.height; y++) {
2003 aStream.read((char*)map.GetData() + y * map.GetStride(),
2004 BytesPerPixel(mFormat) * mRect.width);
2006 mExistingData = dataSurf;
2010 inline void RecordedDrawTargetCreation::OutputSimpleEventInfo(
2011 std::stringstream& aStringStream) const {
2012 aStringStream << "[" << mRefPtr << "] DrawTarget Creation (Type: "
2013 << NameFromBackend(mBackendType) << ", Size: " << mRect.width
2014 << "x" << mRect.height << ")";
2017 inline bool RecordedDrawTargetDestruction::PlayEvent(
2018 Translator* aTranslator) const {
2019 aTranslator->RemoveDrawTarget(mRefPtr);
2020 return true;
2023 template <class S>
2024 void RecordedDrawTargetDestruction::Record(S& aStream) const {
2025 WriteElement(aStream, mRefPtr);
2028 template <class S>
2029 RecordedDrawTargetDestruction::RecordedDrawTargetDestruction(S& aStream)
2030 : RecordedEventDerived(DRAWTARGETDESTRUCTION) {
2031 ReadElement(aStream, mRefPtr);
2034 inline void RecordedDrawTargetDestruction::OutputSimpleEventInfo(
2035 std::stringstream& aStringStream) const {
2036 aStringStream << "[" << mRefPtr << "] DrawTarget Destruction";
2039 inline bool RecordedCreateSimilarDrawTarget::PlayEvent(
2040 Translator* aTranslator) const {
2041 RefPtr<DrawTarget> drawTarget = aTranslator->GetReferenceDrawTarget();
2042 if (!drawTarget) {
2043 // We might end up with a null reference draw target due to a device
2044 // failure, just return false so that we can recover.
2045 return false;
2048 RefPtr<DrawTarget> newDT =
2049 drawTarget->CreateSimilarDrawTarget(mSize, mFormat);
2051 // If we couldn't create a DrawTarget this will probably cause us to crash
2052 // with nullptr later in the playback, so return false to abort.
2053 if (!newDT) {
2054 return false;
2057 aTranslator->AddDrawTarget(mRefPtr, newDT);
2058 return true;
2061 template <class S>
2062 void RecordedCreateSimilarDrawTarget::Record(S& aStream) const {
2063 WriteElement(aStream, mRefPtr);
2064 WriteElement(aStream, mSize);
2065 WriteElement(aStream, mFormat);
2068 template <class S>
2069 RecordedCreateSimilarDrawTarget::RecordedCreateSimilarDrawTarget(S& aStream)
2070 : RecordedEventDerived(CREATESIMILARDRAWTARGET) {
2071 ReadElement(aStream, mRefPtr);
2072 ReadElement(aStream, mSize);
2073 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2074 SurfaceFormat::UNKNOWN);
2077 inline void RecordedCreateSimilarDrawTarget::OutputSimpleEventInfo(
2078 std::stringstream& aStringStream) const {
2079 aStringStream << "[" << mRefPtr
2080 << "] CreateSimilarDrawTarget (Size: " << mSize.width << "x"
2081 << mSize.height << ")";
2084 inline bool RecordedCreateDrawTargetForFilter::PlayEvent(
2085 Translator* aTranslator) const {
2086 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2087 if (!dt) {
2088 return false;
2091 IntRect baseRect = dt->GetRect();
2093 auto maxRect = IntRect(IntPoint(0, 0), mMaxSize);
2095 auto clone = dt->GetTransform();
2096 bool invertible = clone.Invert();
2097 // mSourceRect is in filter space. The filter outputs from mSourceRect need
2098 // to be drawn at mDestPoint in user space.
2099 Rect userSpaceSource = Rect(mDestPoint, mSourceRect.Size());
2100 if (invertible) {
2101 // Try to reduce the source rect so that it's not much bigger
2102 // than the draw target. The result is not minimal. Examples
2103 // are left as an exercise for the reader.
2104 auto destRect = IntRectToRect(baseRect);
2105 Rect userSpaceBounds = clone.TransformBounds(destRect);
2106 userSpaceSource = userSpaceSource.Intersect(userSpaceBounds);
2109 // Compute how much we moved the top-left of the source rect by, and use that
2110 // to compute the new dest point, and move our intersected source rect back
2111 // into the (new) filter space.
2112 Point shift = userSpaceSource.TopLeft() - mDestPoint;
2113 Rect filterSpaceSource =
2114 Rect(mSourceRect.TopLeft() + shift, userSpaceSource.Size());
2116 baseRect = RoundedOut(filterSpaceSource);
2117 FilterNode* filter = aTranslator->LookupFilterNode(mFilter);
2118 if (!filter) {
2119 return false;
2122 IntRect transformedRect = filter->MapRectToSource(
2123 baseRect, maxRect, aTranslator->LookupFilterNode(mSource));
2125 // Intersect with maxRect to make sure we didn't end up with something bigger
2126 transformedRect = transformedRect.Intersect(maxRect);
2128 // If we end up with an empty rect make it 1x1 so that things don't break.
2129 if (transformedRect.IsEmpty()) {
2130 transformedRect = IntRect(0, 0, 1, 1);
2133 RefPtr<DrawTarget> newDT =
2134 dt->CreateSimilarDrawTarget(transformedRect.Size(), mFormat);
2135 if (!newDT) {
2136 return false;
2138 newDT =
2139 gfx::Factory::CreateOffsetDrawTarget(newDT, transformedRect.TopLeft());
2141 // If we couldn't create a DrawTarget this will probably cause us to crash
2142 // with nullptr later in the playback, so return false to abort.
2143 if (!newDT) {
2144 return false;
2147 aTranslator->AddDrawTarget(mRefPtr, newDT);
2148 return true;
2151 inline bool RecordedCreateClippedDrawTarget::PlayEvent(
2152 Translator* aTranslator) const {
2153 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2154 if (!dt) {
2155 return false;
2158 RefPtr<DrawTarget> newDT = dt->CreateClippedDrawTarget(mBounds, mFormat);
2160 // If we couldn't create a DrawTarget this will probably cause us to crash
2161 // with nullptr later in the playback, so return false to abort.
2162 if (!newDT) {
2163 return false;
2166 aTranslator->AddDrawTarget(mRefPtr, newDT);
2167 return true;
2170 template <class S>
2171 void RecordedCreateClippedDrawTarget::Record(S& aStream) const {
2172 RecordedDrawingEvent::Record(aStream);
2173 WriteElement(aStream, mRefPtr);
2174 WriteElement(aStream, mBounds);
2175 WriteElement(aStream, mFormat);
2178 template <class S>
2179 RecordedCreateClippedDrawTarget::RecordedCreateClippedDrawTarget(S& aStream)
2180 : RecordedDrawingEvent(CREATECLIPPEDDRAWTARGET, aStream) {
2181 ReadElement(aStream, mRefPtr);
2182 ReadElement(aStream, mBounds);
2183 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2184 SurfaceFormat::UNKNOWN);
2187 inline void RecordedCreateClippedDrawTarget::OutputSimpleEventInfo(
2188 std::stringstream& aStringStream) const {
2189 aStringStream << "[" << mRefPtr << "] CreateClippedDrawTarget ()";
2192 template <class S>
2193 void RecordedCreateDrawTargetForFilter::Record(S& aStream) const {
2194 RecordedDrawingEvent::Record(aStream);
2195 WriteElement(aStream, mRefPtr);
2196 WriteElement(aStream, mMaxSize);
2197 WriteElement(aStream, mFormat);
2198 WriteElement(aStream, mFilter);
2199 WriteElement(aStream, mSource);
2200 WriteElement(aStream, mSourceRect);
2201 WriteElement(aStream, mDestPoint);
2204 template <class S>
2205 RecordedCreateDrawTargetForFilter::RecordedCreateDrawTargetForFilter(S& aStream)
2206 : RecordedDrawingEvent(CREATEDRAWTARGETFORFILTER, aStream) {
2207 ReadElement(aStream, mRefPtr);
2208 ReadElement(aStream, mMaxSize);
2209 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2210 SurfaceFormat::UNKNOWN);
2211 ReadElement(aStream, mFilter);
2212 ReadElement(aStream, mSource);
2213 ReadElement(aStream, mSourceRect);
2214 ReadElement(aStream, mDestPoint);
2217 inline void RecordedCreateDrawTargetForFilter::OutputSimpleEventInfo(
2218 std::stringstream& aStringStream) const {
2219 aStringStream << "[" << mRefPtr << "] CreateDrawTargetForFilter ()";
2222 struct GenericPattern {
2223 GenericPattern(const PatternStorage& aStorage, Translator* aTranslator)
2224 : mPattern(nullptr), mTranslator(aTranslator) {
2225 mStorage = const_cast<PatternStorage*>(&aStorage);
2228 ~GenericPattern() {
2229 if (mPattern) {
2230 mPattern->~Pattern();
2234 operator Pattern*() {
2235 switch (mStorage->mType) {
2236 case PatternType::COLOR:
2237 return new (mColPat) ColorPattern(
2238 reinterpret_cast<ColorPatternStorage*>(&mStorage->mStorage)
2239 ->mColor);
2240 case PatternType::SURFACE: {
2241 SurfacePatternStorage* storage =
2242 reinterpret_cast<SurfacePatternStorage*>(&mStorage->mStorage);
2243 mPattern = new (mSurfPat)
2244 SurfacePattern(mTranslator->LookupSourceSurface(storage->mSurface),
2245 storage->mExtend, storage->mMatrix,
2246 storage->mSamplingFilter, storage->mSamplingRect);
2247 return mPattern;
2249 case PatternType::LINEAR_GRADIENT: {
2250 LinearGradientPatternStorage* storage =
2251 reinterpret_cast<LinearGradientPatternStorage*>(
2252 &mStorage->mStorage);
2253 mPattern = new (mLinGradPat) LinearGradientPattern(
2254 storage->mBegin, storage->mEnd,
2255 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2256 : nullptr,
2257 storage->mMatrix);
2258 return mPattern;
2260 case PatternType::RADIAL_GRADIENT: {
2261 RadialGradientPatternStorage* storage =
2262 reinterpret_cast<RadialGradientPatternStorage*>(
2263 &mStorage->mStorage);
2264 mPattern = new (mRadGradPat) RadialGradientPattern(
2265 storage->mCenter1, storage->mCenter2, storage->mRadius1,
2266 storage->mRadius2,
2267 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2268 : nullptr,
2269 storage->mMatrix);
2270 return mPattern;
2272 case PatternType::CONIC_GRADIENT: {
2273 ConicGradientPatternStorage* storage =
2274 reinterpret_cast<ConicGradientPatternStorage*>(&mStorage->mStorage);
2275 mPattern = new (mConGradPat) ConicGradientPattern(
2276 storage->mCenter, storage->mAngle, storage->mStartOffset,
2277 storage->mEndOffset,
2278 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2279 : nullptr,
2280 storage->mMatrix);
2281 return mPattern;
2283 default:
2284 return new (mColPat) ColorPattern(DeviceColor());
2287 return mPattern;
2290 union {
2291 char mColPat[sizeof(ColorPattern)];
2292 char mLinGradPat[sizeof(LinearGradientPattern)];
2293 char mRadGradPat[sizeof(RadialGradientPattern)];
2294 char mConGradPat[sizeof(ConicGradientPattern)];
2295 char mSurfPat[sizeof(SurfacePattern)];
2298 PatternStorage* mStorage;
2299 Pattern* mPattern;
2300 Translator* mTranslator;
2303 inline bool RecordedFillRect::PlayEvent(Translator* aTranslator) const {
2304 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2305 if (!dt) {
2306 return false;
2309 dt->FillRect(mRect, *GenericPattern(mPattern, aTranslator), mOptions);
2310 return true;
2313 template <class S>
2314 void RecordedFillRect::Record(S& aStream) const {
2315 RecordedDrawingEvent::Record(aStream);
2316 WriteElement(aStream, mRect);
2317 WriteElement(aStream, mOptions);
2318 RecordPatternData(aStream, mPattern);
2321 template <class S>
2322 RecordedFillRect::RecordedFillRect(S& aStream)
2323 : RecordedDrawingEvent(FILLRECT, aStream) {
2324 ReadElement(aStream, mRect);
2325 ReadDrawOptions(aStream, mOptions);
2326 ReadPatternData(aStream, mPattern);
2329 inline void RecordedFillRect::OutputSimpleEventInfo(
2330 std::stringstream& aStringStream) const {
2331 aStringStream << "[" << mDT << "] FillRect (" << mRect.X() << ", "
2332 << mRect.Y() << " - " << mRect.Width() << " x "
2333 << mRect.Height() << ") ";
2334 OutputSimplePatternInfo(mPattern, aStringStream);
2337 inline bool RecordedStrokeRect::PlayEvent(Translator* aTranslator) const {
2338 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2339 if (!dt) {
2340 return false;
2343 dt->StrokeRect(mRect, *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2344 mOptions);
2345 return true;
2348 template <class S>
2349 void RecordedStrokeRect::Record(S& aStream) const {
2350 RecordedDrawingEvent::Record(aStream);
2351 WriteElement(aStream, mRect);
2352 WriteElement(aStream, mOptions);
2353 RecordPatternData(aStream, mPattern);
2354 RecordStrokeOptions(aStream, mStrokeOptions);
2357 template <class S>
2358 RecordedStrokeRect::RecordedStrokeRect(S& aStream)
2359 : RecordedDrawingEvent(STROKERECT, aStream) {
2360 ReadElement(aStream, mRect);
2361 ReadDrawOptions(aStream, mOptions);
2362 ReadPatternData(aStream, mPattern);
2363 ReadStrokeOptions(aStream, mStrokeOptions);
2366 inline void RecordedStrokeRect::OutputSimpleEventInfo(
2367 std::stringstream& aStringStream) const {
2368 aStringStream << "[" << mDT << "] StrokeRect (" << mRect.X() << ", "
2369 << mRect.Y() << " - " << mRect.Width() << " x "
2370 << mRect.Height()
2371 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2372 OutputSimplePatternInfo(mPattern, aStringStream);
2375 inline bool RecordedStrokeLine::PlayEvent(Translator* aTranslator) const {
2376 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2377 if (!dt) {
2378 return false;
2381 dt->StrokeLine(mBegin, mEnd, *GenericPattern(mPattern, aTranslator),
2382 mStrokeOptions, mOptions);
2383 return true;
2386 template <class S>
2387 void RecordedStrokeLine::Record(S& aStream) const {
2388 RecordedDrawingEvent::Record(aStream);
2389 WriteElement(aStream, mBegin);
2390 WriteElement(aStream, mEnd);
2391 WriteElement(aStream, mOptions);
2392 RecordPatternData(aStream, mPattern);
2393 RecordStrokeOptions(aStream, mStrokeOptions);
2396 template <class S>
2397 RecordedStrokeLine::RecordedStrokeLine(S& aStream)
2398 : RecordedDrawingEvent(STROKELINE, aStream) {
2399 ReadElement(aStream, mBegin);
2400 ReadElement(aStream, mEnd);
2401 ReadDrawOptions(aStream, mOptions);
2402 ReadPatternData(aStream, mPattern);
2403 ReadStrokeOptions(aStream, mStrokeOptions);
2406 inline void RecordedStrokeLine::OutputSimpleEventInfo(
2407 std::stringstream& aStringStream) const {
2408 aStringStream << "[" << mDT << "] StrokeLine (" << mBegin.x << ", "
2409 << mBegin.y << " - " << mEnd.x << ", " << mEnd.y
2410 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2411 OutputSimplePatternInfo(mPattern, aStringStream);
2414 inline bool RecordedStrokeCircle::PlayEvent(Translator* aTranslator) const {
2415 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2416 if (!dt) {
2417 return false;
2420 dt->StrokeCircle(mCircle.origin, mCircle.radius,
2421 *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2422 mOptions);
2423 return true;
2426 template <class S>
2427 void RecordedStrokeCircle::Record(S& aStream) const {
2428 RecordedDrawingEvent::Record(aStream);
2429 WriteElement(aStream, mCircle);
2430 WriteElement(aStream, mOptions);
2431 RecordPatternData(aStream, mPattern);
2432 RecordStrokeOptions(aStream, mStrokeOptions);
2435 template <class S>
2436 RecordedStrokeCircle::RecordedStrokeCircle(S& aStream)
2437 : RecordedDrawingEvent(STROKECIRCLE, aStream) {
2438 ReadElement(aStream, mCircle);
2439 ReadDrawOptions(aStream, mOptions);
2440 ReadPatternData(aStream, mPattern);
2441 ReadStrokeOptions(aStream, mStrokeOptions);
2444 inline void RecordedStrokeCircle::OutputSimpleEventInfo(
2445 std::stringstream& aStringStream) const {
2446 aStringStream << "[" << mDT << "] StrokeCircle (" << mCircle.origin.x << ", "
2447 << mCircle.origin.y << " - " << mCircle.radius
2448 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2449 OutputSimplePatternInfo(mPattern, aStringStream);
2452 inline bool RecordedFill::PlayEvent(Translator* aTranslator) const {
2453 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2454 if (!dt) {
2455 return false;
2458 dt->Fill(aTranslator->LookupPath(mPath),
2459 *GenericPattern(mPattern, aTranslator), mOptions);
2460 return true;
2463 template <class S>
2464 RecordedFill::RecordedFill(S& aStream) : RecordedDrawingEvent(FILL, aStream) {
2465 ReadElement(aStream, mPath);
2466 ReadDrawOptions(aStream, mOptions);
2467 ReadPatternData(aStream, mPattern);
2470 template <class S>
2471 void RecordedFill::Record(S& aStream) const {
2472 RecordedDrawingEvent::Record(aStream);
2473 WriteElement(aStream, mPath);
2474 WriteElement(aStream, mOptions);
2475 RecordPatternData(aStream, mPattern);
2478 inline void RecordedFill::OutputSimpleEventInfo(
2479 std::stringstream& aStringStream) const {
2480 aStringStream << "[" << mDT << "] Fill (" << mPath << ") ";
2481 OutputSimplePatternInfo(mPattern, aStringStream);
2484 inline bool RecordedFillCircle::PlayEvent(Translator* aTranslator) const {
2485 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2486 if (!dt) {
2487 return false;
2490 dt->FillCircle(mCircle.origin, mCircle.radius,
2491 *GenericPattern(mPattern, aTranslator), mOptions);
2492 return true;
2495 template <class S>
2496 void RecordedFillCircle::Record(S& aStream) const {
2497 RecordedDrawingEvent::Record(aStream);
2498 WriteElement(aStream, mCircle);
2499 WriteElement(aStream, mOptions);
2500 RecordPatternData(aStream, mPattern);
2503 template <class S>
2504 RecordedFillCircle::RecordedFillCircle(S& aStream)
2505 : RecordedDrawingEvent(FILLCIRCLE, aStream) {
2506 ReadElement(aStream, mCircle);
2507 ReadDrawOptions(aStream, mOptions);
2508 ReadPatternData(aStream, mPattern);
2511 inline void RecordedFillCircle::OutputSimpleEventInfo(
2512 std::stringstream& aStringStream) const {
2513 aStringStream << "[" << mDT << "] StrokeCircle (" << mCircle.origin.x << ", "
2514 << mCircle.origin.y << " - " << mCircle.radius << ")";
2515 OutputSimplePatternInfo(mPattern, aStringStream);
2518 inline RecordedFillGlyphs::~RecordedFillGlyphs() { delete[] mGlyphs; }
2520 inline bool RecordedFillGlyphs::PlayEvent(Translator* aTranslator) const {
2521 if (mNumGlyphs > 0 && !mGlyphs) {
2522 // Glyph allocation failed
2523 return false;
2526 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2527 if (!dt) {
2528 return false;
2531 ScaledFont* scaledFont = aTranslator->LookupScaledFont(mScaledFont);
2532 if (!scaledFont) {
2533 return false;
2536 GlyphBuffer buffer;
2537 buffer.mGlyphs = mGlyphs;
2538 buffer.mNumGlyphs = mNumGlyphs;
2539 dt->FillGlyphs(scaledFont, buffer, *GenericPattern(mPattern, aTranslator),
2540 mOptions);
2541 return true;
2544 template <class S>
2545 RecordedFillGlyphs::RecordedFillGlyphs(S& aStream)
2546 : RecordedDrawingEvent(FILLGLYPHS, aStream) {
2547 ReadElement(aStream, mScaledFont);
2548 ReadDrawOptions(aStream, mOptions);
2549 ReadPatternData(aStream, mPattern);
2550 ReadElement(aStream, mNumGlyphs);
2551 if (!aStream.good() || mNumGlyphs <= 0) {
2552 return;
2555 mGlyphs = new (fallible) Glyph[mNumGlyphs];
2556 if (!mGlyphs) {
2557 gfxCriticalNote << "RecordedFillGlyphs failed to allocate glyphs of size "
2558 << mNumGlyphs;
2559 aStream.SetIsBad();
2560 } else {
2561 aStream.read((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
2565 template <class S>
2566 void RecordedFillGlyphs::Record(S& aStream) const {
2567 RecordedDrawingEvent::Record(aStream);
2568 WriteElement(aStream, mScaledFont);
2569 WriteElement(aStream, mOptions);
2570 RecordPatternData(aStream, mPattern);
2571 WriteElement(aStream, mNumGlyphs);
2572 aStream.write((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
2575 inline void RecordedFillGlyphs::OutputSimpleEventInfo(
2576 std::stringstream& aStringStream) const {
2577 aStringStream << "[" << mDT << "] FillGlyphs (" << mScaledFont << ") ";
2578 OutputSimplePatternInfo(mPattern, aStringStream);
2581 inline bool RecordedMask::PlayEvent(Translator* aTranslator) const {
2582 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2583 if (!dt) {
2584 return false;
2587 dt->Mask(*GenericPattern(mSource, aTranslator),
2588 *GenericPattern(mMask, aTranslator), mOptions);
2589 return true;
2592 template <class S>
2593 RecordedMask::RecordedMask(S& aStream) : RecordedDrawingEvent(MASK, aStream) {
2594 ReadDrawOptions(aStream, mOptions);
2595 ReadPatternData(aStream, mSource);
2596 ReadPatternData(aStream, mMask);
2599 template <class S>
2600 void RecordedMask::Record(S& aStream) const {
2601 RecordedDrawingEvent::Record(aStream);
2602 WriteElement(aStream, mOptions);
2603 RecordPatternData(aStream, mSource);
2604 RecordPatternData(aStream, mMask);
2607 inline void RecordedMask::OutputSimpleEventInfo(
2608 std::stringstream& aStringStream) const {
2609 aStringStream << "[" << mDT << "] Mask (Source: ";
2610 OutputSimplePatternInfo(mSource, aStringStream);
2611 aStringStream << " Mask: ";
2612 OutputSimplePatternInfo(mMask, aStringStream);
2615 inline bool RecordedStroke::PlayEvent(Translator* aTranslator) const {
2616 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2617 if (!dt) {
2618 return false;
2621 Path* path = aTranslator->LookupPath(mPath);
2622 if (!path) {
2623 return false;
2626 dt->Stroke(path, *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2627 mOptions);
2628 return true;
2631 template <class S>
2632 void RecordedStroke::Record(S& aStream) const {
2633 RecordedDrawingEvent::Record(aStream);
2634 WriteElement(aStream, mPath);
2635 WriteElement(aStream, mOptions);
2636 RecordPatternData(aStream, mPattern);
2637 RecordStrokeOptions(aStream, mStrokeOptions);
2640 template <class S>
2641 RecordedStroke::RecordedStroke(S& aStream)
2642 : RecordedDrawingEvent(STROKE, aStream) {
2643 ReadElement(aStream, mPath);
2644 ReadDrawOptions(aStream, mOptions);
2645 ReadPatternData(aStream, mPattern);
2646 ReadStrokeOptions(aStream, mStrokeOptions);
2649 inline void RecordedStroke::OutputSimpleEventInfo(
2650 std::stringstream& aStringStream) const {
2651 aStringStream << "[" << mDT << "] Stroke (" << mPath
2652 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2653 OutputSimplePatternInfo(mPattern, aStringStream);
2656 inline bool RecordedClearRect::PlayEvent(Translator* aTranslator) const {
2657 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2658 if (!dt) {
2659 return false;
2662 dt->ClearRect(mRect);
2663 return true;
2666 template <class S>
2667 void RecordedClearRect::Record(S& aStream) const {
2668 RecordedDrawingEvent::Record(aStream);
2669 WriteElement(aStream, mRect);
2672 template <class S>
2673 RecordedClearRect::RecordedClearRect(S& aStream)
2674 : RecordedDrawingEvent(CLEARRECT, aStream) {
2675 ReadElement(aStream, mRect);
2678 inline void RecordedClearRect::OutputSimpleEventInfo(
2679 std::stringstream& aStringStream) const {
2680 aStringStream << "[" << mDT << "] ClearRect (" << mRect.X() << ", "
2681 << mRect.Y() << " - " << mRect.Width() << " x "
2682 << mRect.Height() << ") ";
2685 inline bool RecordedCopySurface::PlayEvent(Translator* aTranslator) const {
2686 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2687 if (!dt) {
2688 return false;
2691 SourceSurface* surface = aTranslator->LookupSourceSurface(mSourceSurface);
2692 if (!surface) {
2693 return false;
2696 dt->CopySurface(surface, mSourceRect, mDest);
2697 return true;
2700 template <class S>
2701 void RecordedCopySurface::Record(S& aStream) const {
2702 RecordedDrawingEvent::Record(aStream);
2703 WriteElement(aStream, mSourceSurface);
2704 WriteElement(aStream, mSourceRect);
2705 WriteElement(aStream, mDest);
2708 template <class S>
2709 RecordedCopySurface::RecordedCopySurface(S& aStream)
2710 : RecordedDrawingEvent(COPYSURFACE, aStream) {
2711 ReadElement(aStream, mSourceSurface);
2712 ReadElement(aStream, mSourceRect);
2713 ReadElement(aStream, mDest);
2716 inline void RecordedCopySurface::OutputSimpleEventInfo(
2717 std::stringstream& aStringStream) const {
2718 aStringStream << "[" << mDT << "] CopySurface (" << mSourceSurface << ")";
2721 inline bool RecordedPushClip::PlayEvent(Translator* aTranslator) const {
2722 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2723 if (!dt) {
2724 return false;
2727 Path* path = aTranslator->LookupPath(mPath);
2728 if (!path) {
2729 return false;
2732 dt->PushClip(path);
2733 return true;
2736 template <class S>
2737 void RecordedPushClip::Record(S& aStream) const {
2738 RecordedDrawingEvent::Record(aStream);
2739 WriteElement(aStream, mPath);
2742 template <class S>
2743 RecordedPushClip::RecordedPushClip(S& aStream)
2744 : RecordedDrawingEvent(PUSHCLIP, aStream) {
2745 ReadElement(aStream, mPath);
2748 inline void RecordedPushClip::OutputSimpleEventInfo(
2749 std::stringstream& aStringStream) const {
2750 aStringStream << "[" << mDT << "] PushClip (" << mPath << ") ";
2753 inline bool RecordedPushClipRect::PlayEvent(Translator* aTranslator) const {
2754 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2755 if (!dt) {
2756 return false;
2759 dt->PushClipRect(mRect);
2760 return true;
2763 template <class S>
2764 void RecordedPushClipRect::Record(S& aStream) const {
2765 RecordedDrawingEvent::Record(aStream);
2766 WriteElement(aStream, mRect);
2769 template <class S>
2770 RecordedPushClipRect::RecordedPushClipRect(S& aStream)
2771 : RecordedDrawingEvent(PUSHCLIPRECT, aStream) {
2772 ReadElement(aStream, mRect);
2775 inline void RecordedPushClipRect::OutputSimpleEventInfo(
2776 std::stringstream& aStringStream) const {
2777 aStringStream << "[" << mDT << "] PushClipRect (" << mRect.X() << ", "
2778 << mRect.Y() << " - " << mRect.Width() << " x "
2779 << mRect.Height() << ") ";
2782 inline bool RecordedPopClip::PlayEvent(Translator* aTranslator) const {
2783 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2784 if (!dt) {
2785 return false;
2788 dt->PopClip();
2789 return true;
2792 template <class S>
2793 void RecordedPopClip::Record(S& aStream) const {
2794 RecordedDrawingEvent::Record(aStream);
2797 template <class S>
2798 RecordedPopClip::RecordedPopClip(S& aStream)
2799 : RecordedDrawingEvent(POPCLIP, aStream) {}
2801 inline void RecordedPopClip::OutputSimpleEventInfo(
2802 std::stringstream& aStringStream) const {
2803 aStringStream << "[" << mDT << "] PopClip";
2806 inline bool RecordedPushLayer::PlayEvent(Translator* aTranslator) const {
2807 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2808 if (!dt) {
2809 return false;
2812 SourceSurface* mask =
2813 mMask ? aTranslator->LookupSourceSurface(mMask) : nullptr;
2814 dt->PushLayer(mOpaque, mOpacity, mask, mMaskTransform, mBounds,
2815 mCopyBackground);
2816 return true;
2819 template <class S>
2820 void RecordedPushLayer::Record(S& aStream) const {
2821 RecordedDrawingEvent::Record(aStream);
2822 WriteElement(aStream, mOpaque);
2823 WriteElement(aStream, mOpacity);
2824 WriteElement(aStream, mMask);
2825 WriteElement(aStream, mMaskTransform);
2826 WriteElement(aStream, mBounds);
2827 WriteElement(aStream, mCopyBackground);
2830 template <class S>
2831 RecordedPushLayer::RecordedPushLayer(S& aStream)
2832 : RecordedDrawingEvent(PUSHLAYER, aStream) {
2833 ReadElement(aStream, mOpaque);
2834 ReadElement(aStream, mOpacity);
2835 ReadElement(aStream, mMask);
2836 ReadElement(aStream, mMaskTransform);
2837 ReadElement(aStream, mBounds);
2838 ReadElement(aStream, mCopyBackground);
2841 inline void RecordedPushLayer::OutputSimpleEventInfo(
2842 std::stringstream& aStringStream) const {
2843 aStringStream << "[" << mDT << "] PushPLayer (Opaque=" << mOpaque
2844 << ", Opacity=" << mOpacity << ", Mask Ref=" << mMask << ") ";
2847 inline bool RecordedPushLayerWithBlend::PlayEvent(
2848 Translator* aTranslator) const {
2849 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2850 if (!dt) {
2851 return false;
2854 SourceSurface* mask =
2855 mMask ? aTranslator->LookupSourceSurface(mMask) : nullptr;
2856 dt->PushLayerWithBlend(mOpaque, mOpacity, mask, mMaskTransform, mBounds,
2857 mCopyBackground, mCompositionOp);
2858 return true;
2861 template <class S>
2862 void RecordedPushLayerWithBlend::Record(S& aStream) const {
2863 RecordedDrawingEvent::Record(aStream);
2864 WriteElement(aStream, mOpaque);
2865 WriteElement(aStream, mOpacity);
2866 WriteElement(aStream, mMask);
2867 WriteElement(aStream, mMaskTransform);
2868 WriteElement(aStream, mBounds);
2869 WriteElement(aStream, mCopyBackground);
2870 WriteElement(aStream, mCompositionOp);
2873 template <class S>
2874 RecordedPushLayerWithBlend::RecordedPushLayerWithBlend(S& aStream)
2875 : RecordedDrawingEvent(PUSHLAYERWITHBLEND, aStream) {
2876 ReadElement(aStream, mOpaque);
2877 ReadElement(aStream, mOpacity);
2878 ReadElement(aStream, mMask);
2879 ReadElement(aStream, mMaskTransform);
2880 ReadElement(aStream, mBounds);
2881 ReadElement(aStream, mCopyBackground);
2882 ReadElementConstrained(aStream, mCompositionOp, CompositionOp::OP_OVER,
2883 CompositionOp::OP_COUNT);
2886 inline void RecordedPushLayerWithBlend::OutputSimpleEventInfo(
2887 std::stringstream& aStringStream) const {
2888 aStringStream << "[" << mDT << "] PushLayerWithBlend (Opaque=" << mOpaque
2889 << ", Opacity=" << mOpacity << ", Mask Ref=" << mMask << ") ";
2892 inline bool RecordedPopLayer::PlayEvent(Translator* aTranslator) const {
2893 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2894 if (!dt) {
2895 return false;
2898 dt->PopLayer();
2899 return true;
2902 template <class S>
2903 void RecordedPopLayer::Record(S& aStream) const {
2904 RecordedDrawingEvent::Record(aStream);
2907 template <class S>
2908 RecordedPopLayer::RecordedPopLayer(S& aStream)
2909 : RecordedDrawingEvent(POPLAYER, aStream) {}
2911 inline void RecordedPopLayer::OutputSimpleEventInfo(
2912 std::stringstream& aStringStream) const {
2913 aStringStream << "[" << mDT << "] PopLayer";
2916 inline bool RecordedSetTransform::PlayEvent(Translator* aTranslator) const {
2917 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2918 if (!dt) {
2919 return false;
2922 // If we're drawing to the reference DT, then we need to manually apply
2923 // its initial transform, otherwise we'll just clobber it with only the
2924 // the transform that was visible to the code doing the recording.
2925 if (dt == aTranslator->GetReferenceDrawTarget()) {
2926 dt->SetTransform(mTransform *
2927 aTranslator->GetReferenceDrawTargetTransform());
2928 } else {
2929 dt->SetTransform(mTransform);
2932 return true;
2935 template <class S>
2936 void RecordedSetTransform::Record(S& aStream) const {
2937 RecordedDrawingEvent::Record(aStream);
2938 WriteElement(aStream, mTransform);
2941 template <class S>
2942 RecordedSetTransform::RecordedSetTransform(S& aStream)
2943 : RecordedDrawingEvent(SETTRANSFORM, aStream) {
2944 ReadElement(aStream, mTransform);
2947 inline void RecordedSetTransform::OutputSimpleEventInfo(
2948 std::stringstream& aStringStream) const {
2949 aStringStream << "[" << mDT << "] SetTransform [ " << mTransform._11 << " "
2950 << mTransform._12 << " ; " << mTransform._21 << " "
2951 << mTransform._22 << " ; " << mTransform._31 << " "
2952 << mTransform._32 << " ]";
2955 inline bool RecordedDrawSurface::PlayEvent(Translator* aTranslator) const {
2956 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
2957 if (!dt) {
2958 return false;
2961 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefSource);
2962 if (!surface) {
2963 return false;
2966 dt->DrawSurface(surface, mDest, mSource, mDSOptions, mOptions);
2967 return true;
2970 template <class S>
2971 void RecordedDrawSurface::Record(S& aStream) const {
2972 RecordedDrawingEvent::Record(aStream);
2973 WriteElement(aStream, mRefSource);
2974 WriteElement(aStream, mDest);
2975 WriteElement(aStream, mSource);
2976 WriteElement(aStream, mDSOptions);
2977 WriteElement(aStream, mOptions);
2980 template <class S>
2981 RecordedDrawSurface::RecordedDrawSurface(S& aStream)
2982 : RecordedDrawingEvent(DRAWSURFACE, aStream) {
2983 ReadElement(aStream, mRefSource);
2984 ReadElement(aStream, mDest);
2985 ReadElement(aStream, mSource);
2986 ReadDrawSurfaceOptions(aStream, mDSOptions);
2987 ReadDrawOptions(aStream, mOptions);
2990 inline void RecordedDrawSurface::OutputSimpleEventInfo(
2991 std::stringstream& aStringStream) const {
2992 aStringStream << "[" << mDT << "] DrawSurface (" << mRefSource << ")";
2995 inline bool RecordedDrawDependentSurface::PlayEvent(
2996 Translator* aTranslator) const {
2997 aTranslator->DrawDependentSurface(mDT, mId, mDest);
2998 return true;
3001 template <class S>
3002 void RecordedDrawDependentSurface::Record(S& aStream) const {
3003 RecordedDrawingEvent::Record(aStream);
3004 WriteElement(aStream, mId);
3005 WriteElement(aStream, mDest);
3008 template <class S>
3009 RecordedDrawDependentSurface::RecordedDrawDependentSurface(S& aStream)
3010 : RecordedDrawingEvent(DRAWDEPENDENTSURFACE, aStream) {
3011 ReadElement(aStream, mId);
3012 ReadElement(aStream, mDest);
3015 inline void RecordedDrawDependentSurface::OutputSimpleEventInfo(
3016 std::stringstream& aStringStream) const {
3017 aStringStream << "[" << mDT << "] DrawDependentSurface (" << mId << ")";
3020 inline bool RecordedDrawFilter::PlayEvent(Translator* aTranslator) const {
3021 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
3022 if (!dt) {
3023 return false;
3026 FilterNode* filter = aTranslator->LookupFilterNode(mNode);
3027 if (!filter) {
3028 return false;
3031 dt->DrawFilter(filter, mSourceRect, mDestPoint, mOptions);
3032 return true;
3035 template <class S>
3036 void RecordedDrawFilter::Record(S& aStream) const {
3037 RecordedDrawingEvent::Record(aStream);
3038 WriteElement(aStream, mNode);
3039 WriteElement(aStream, mSourceRect);
3040 WriteElement(aStream, mDestPoint);
3041 WriteElement(aStream, mOptions);
3044 template <class S>
3045 RecordedDrawFilter::RecordedDrawFilter(S& aStream)
3046 : RecordedDrawingEvent(DRAWFILTER, aStream) {
3047 ReadElement(aStream, mNode);
3048 ReadElement(aStream, mSourceRect);
3049 ReadElement(aStream, mDestPoint);
3050 ReadDrawOptions(aStream, mOptions);
3053 inline void RecordedDrawFilter::OutputSimpleEventInfo(
3054 std::stringstream& aStringStream) const {
3055 aStringStream << "[" << mDT << "] DrawFilter (" << mNode << ")";
3058 inline bool RecordedDrawSurfaceWithShadow::PlayEvent(
3059 Translator* aTranslator) const {
3060 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
3061 if (!dt) {
3062 return false;
3065 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefSource);
3066 if (!surface) {
3067 return false;
3070 dt->DrawSurfaceWithShadow(surface, mDest, mShadow, mOp);
3071 return true;
3074 template <class S>
3075 void RecordedDrawSurfaceWithShadow::Record(S& aStream) const {
3076 RecordedDrawingEvent::Record(aStream);
3077 WriteElement(aStream, mRefSource);
3078 WriteElement(aStream, mDest);
3079 WriteElement(aStream, mShadow);
3080 WriteElement(aStream, mOp);
3083 template <class S>
3084 RecordedDrawSurfaceWithShadow::RecordedDrawSurfaceWithShadow(S& aStream)
3085 : RecordedDrawingEvent(DRAWSURFACEWITHSHADOW, aStream) {
3086 ReadElement(aStream, mRefSource);
3087 ReadElement(aStream, mDest);
3088 ReadElement(aStream, mShadow);
3089 ReadElementConstrained(aStream, mOp, CompositionOp::OP_OVER,
3090 CompositionOp::OP_COUNT);
3093 inline void RecordedDrawSurfaceWithShadow::OutputSimpleEventInfo(
3094 std::stringstream& aStringStream) const {
3095 aStringStream << "[" << mDT << "] DrawSurfaceWithShadow (" << mRefSource
3096 << ") DeviceColor: (" << mShadow.mColor.r << ", "
3097 << mShadow.mColor.g << ", " << mShadow.mColor.b << ", "
3098 << mShadow.mColor.a << ")";
3101 inline RecordedPathCreation::RecordedPathCreation(PathRecording* aPath)
3102 : RecordedEventDerived(PATHCREATION),
3103 mRefPtr(aPath),
3104 mFillRule(aPath->mFillRule),
3105 mPath(aPath) {}
3107 inline bool RecordedPathCreation::PlayEvent(Translator* aTranslator) const {
3108 RefPtr<DrawTarget> drawTarget = aTranslator->GetReferenceDrawTarget();
3109 if (!drawTarget) {
3110 // We might end up with a null reference draw target due to a device
3111 // failure, just return false so that we can recover.
3112 return false;
3115 RefPtr<PathBuilder> builder = drawTarget->CreatePathBuilder(mFillRule);
3116 if (!mPathOps->CheckedStreamToSink(*builder)) {
3117 return false;
3120 RefPtr<Path> path = builder->Finish();
3121 aTranslator->AddPath(mRefPtr, path);
3122 return true;
3125 template <class S>
3126 void RecordedPathCreation::Record(S& aStream) const {
3127 WriteElement(aStream, mRefPtr);
3128 WriteElement(aStream, mFillRule);
3129 mPath->mPathOps.Record(aStream);
3132 template <class S>
3133 RecordedPathCreation::RecordedPathCreation(S& aStream)
3134 : RecordedEventDerived(PATHCREATION) {
3135 ReadElement(aStream, mRefPtr);
3136 ReadElementConstrained(aStream, mFillRule, FillRule::FILL_WINDING,
3137 FillRule::FILL_EVEN_ODD);
3138 mPathOps = MakeUnique<PathOps>(aStream);
3141 inline void RecordedPathCreation::OutputSimpleEventInfo(
3142 std::stringstream& aStringStream) const {
3143 size_t numberOfOps =
3144 mPath ? mPath->mPathOps.NumberOfOps() : mPathOps->NumberOfOps();
3145 aStringStream << "[" << mRefPtr << "] Path created (OpCount: " << numberOfOps
3146 << ")";
3148 inline bool RecordedPathDestruction::PlayEvent(Translator* aTranslator) const {
3149 aTranslator->RemovePath(mRefPtr);
3150 return true;
3153 template <class S>
3154 void RecordedPathDestruction::Record(S& aStream) const {
3155 WriteElement(aStream, mRefPtr);
3158 template <class S>
3159 RecordedPathDestruction::RecordedPathDestruction(S& aStream)
3160 : RecordedEventDerived(PATHDESTRUCTION) {
3161 ReadElement(aStream, mRefPtr);
3164 inline void RecordedPathDestruction::OutputSimpleEventInfo(
3165 std::stringstream& aStringStream) const {
3166 aStringStream << "[" << mRefPtr << "] Path Destroyed";
3169 inline RecordedSourceSurfaceCreation::~RecordedSourceSurfaceCreation() {
3170 if (mDataOwned) {
3171 delete[] mData;
3175 inline bool RecordedSourceSurfaceCreation::PlayEvent(
3176 Translator* aTranslator) const {
3177 if (!mData) {
3178 return false;
3181 RefPtr<SourceSurface> src = Factory::CreateWrappingDataSourceSurface(
3182 mData, mSize.width * BytesPerPixel(mFormat), mSize, mFormat,
3183 [](void* aClosure) { delete[] static_cast<uint8_t*>(aClosure); }, mData);
3184 if (src) {
3185 mDataOwned = false;
3188 aTranslator->AddSourceSurface(mRefPtr, src);
3189 return true;
3192 template <class S>
3193 void RecordedSourceSurfaceCreation::Record(S& aStream) const {
3194 WriteElement(aStream, mRefPtr);
3195 WriteElement(aStream, mSize);
3196 WriteElement(aStream, mFormat);
3197 MOZ_ASSERT(mData);
3198 size_t dataFormatWidth = BytesPerPixel(mFormat) * mSize.width;
3199 const char* endSrc = (const char*)(mData + (mSize.height * mStride));
3200 for (const char* src = (const char*)mData; src < endSrc; src += mStride) {
3201 aStream.write(src, dataFormatWidth);
3205 template <class S>
3206 RecordedSourceSurfaceCreation::RecordedSourceSurfaceCreation(S& aStream)
3207 : RecordedEventDerived(SOURCESURFACECREATION), mDataOwned(true) {
3208 ReadElement(aStream, mRefPtr);
3209 ReadElement(aStream, mSize);
3210 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
3211 SurfaceFormat::UNKNOWN);
3213 if (!Factory::AllowedSurfaceSize(mSize)) {
3214 gfxCriticalNote << "RecordedSourceSurfaceCreation read invalid size "
3215 << mSize;
3216 aStream.SetIsBad();
3219 if (!aStream.good()) {
3220 return;
3223 size_t size = 0;
3224 if (mSize.width >= 0 && mSize.height >= 0) {
3225 size = size_t(mSize.width) * size_t(mSize.height) * BytesPerPixel(mFormat);
3226 mData = new (fallible) uint8_t[size];
3228 if (!mData) {
3229 gfxCriticalNote
3230 << "RecordedSourceSurfaceCreation failed to allocate data of size "
3231 << size;
3232 aStream.SetIsBad();
3233 } else {
3234 aStream.read((char*)mData, size);
3238 inline void RecordedSourceSurfaceCreation::OutputSimpleEventInfo(
3239 std::stringstream& aStringStream) const {
3240 aStringStream << "[" << mRefPtr
3241 << "] SourceSurface created (Size: " << mSize.width << "x"
3242 << mSize.height << ")";
3245 inline bool RecordedSourceSurfaceDestruction::PlayEvent(
3246 Translator* aTranslator) const {
3247 aTranslator->RemoveSourceSurface(mRefPtr);
3248 return true;
3251 template <class S>
3252 void RecordedSourceSurfaceDestruction::Record(S& aStream) const {
3253 WriteElement(aStream, mRefPtr);
3256 template <class S>
3257 RecordedSourceSurfaceDestruction::RecordedSourceSurfaceDestruction(S& aStream)
3258 : RecordedEventDerived(SOURCESURFACEDESTRUCTION) {
3259 ReadElement(aStream, mRefPtr);
3262 inline void RecordedSourceSurfaceDestruction::OutputSimpleEventInfo(
3263 std::stringstream& aStringStream) const {
3264 aStringStream << "[" << mRefPtr << "] SourceSurface Destroyed";
3267 inline bool RecordedOptimizeSourceSurface::PlayEvent(
3268 Translator* aTranslator) const {
3269 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
3270 if (!dt) {
3271 return false;
3274 SourceSurface* surface = aTranslator->LookupSourceSurface(mSurface);
3275 if (!surface) {
3276 return false;
3279 RefPtr<SourceSurface> optimizedSurface = dt->OptimizeSourceSurface(surface);
3280 aTranslator->AddSourceSurface(mOptimizedSurface, optimizedSurface);
3281 return true;
3284 template <class S>
3285 void RecordedOptimizeSourceSurface::Record(S& aStream) const {
3286 WriteElement(aStream, mSurface);
3287 WriteElement(aStream, mDT);
3288 WriteElement(aStream, mOptimizedSurface);
3291 template <class S>
3292 RecordedOptimizeSourceSurface::RecordedOptimizeSourceSurface(S& aStream)
3293 : RecordedEventDerived(OPTIMIZESOURCESURFACE) {
3294 ReadElement(aStream, mSurface);
3295 ReadElement(aStream, mDT);
3296 ReadElement(aStream, mOptimizedSurface);
3299 inline void RecordedOptimizeSourceSurface::OutputSimpleEventInfo(
3300 std::stringstream& aStringStream) const {
3301 aStringStream << "[" << mSurface << "] Surface Optimized (DT: " << mDT << ")";
3304 inline bool RecordedExternalSurfaceCreation::PlayEvent(
3305 Translator* aTranslator) const {
3306 RefPtr<SourceSurface> surface = aTranslator->LookupExternalSurface(mKey);
3307 if (!surface) {
3308 return false;
3311 aTranslator->AddSourceSurface(mRefPtr, surface);
3312 return true;
3315 template <class S>
3316 void RecordedExternalSurfaceCreation::Record(S& aStream) const {
3317 WriteElement(aStream, mRefPtr);
3318 WriteElement(aStream, mKey);
3321 template <class S>
3322 RecordedExternalSurfaceCreation::RecordedExternalSurfaceCreation(S& aStream)
3323 : RecordedEventDerived(EXTERNALSURFACECREATION) {
3324 ReadElement(aStream, mRefPtr);
3325 ReadElement(aStream, mKey);
3328 inline void RecordedExternalSurfaceCreation::OutputSimpleEventInfo(
3329 std::stringstream& aStringStream) const {
3330 aStringStream << "[" << mRefPtr
3331 << "] SourceSurfaceSharedData created (Key: " << mKey << ")";
3334 inline RecordedFilterNodeCreation::~RecordedFilterNodeCreation() = default;
3336 inline bool RecordedFilterNodeCreation::PlayEvent(
3337 Translator* aTranslator) const {
3338 RefPtr<DrawTarget> drawTarget = aTranslator->GetReferenceDrawTarget();
3339 if (!drawTarget) {
3340 // We might end up with a null reference draw target due to a device
3341 // failure, just return false so that we can recover.
3342 return false;
3345 RefPtr<FilterNode> node = drawTarget->CreateFilter(mType);
3346 aTranslator->AddFilterNode(mRefPtr, node);
3347 return true;
3350 template <class S>
3351 void RecordedFilterNodeCreation::Record(S& aStream) const {
3352 WriteElement(aStream, mRefPtr);
3353 WriteElement(aStream, mType);
3356 template <class S>
3357 RecordedFilterNodeCreation::RecordedFilterNodeCreation(S& aStream)
3358 : RecordedEventDerived(FILTERNODECREATION) {
3359 ReadElement(aStream, mRefPtr);
3360 ReadElementConstrained(aStream, mType, FilterType::BLEND,
3361 FilterType::OPACITY);
3364 inline void RecordedFilterNodeCreation::OutputSimpleEventInfo(
3365 std::stringstream& aStringStream) const {
3366 aStringStream << "[" << mRefPtr
3367 << "] FilterNode created (Type: " << int(mType) << ")";
3370 inline bool RecordedFilterNodeDestruction::PlayEvent(
3371 Translator* aTranslator) const {
3372 aTranslator->RemoveFilterNode(mRefPtr);
3373 return true;
3376 template <class S>
3377 void RecordedFilterNodeDestruction::Record(S& aStream) const {
3378 WriteElement(aStream, mRefPtr);
3381 template <class S>
3382 RecordedFilterNodeDestruction::RecordedFilterNodeDestruction(S& aStream)
3383 : RecordedEventDerived(FILTERNODEDESTRUCTION) {
3384 ReadElement(aStream, mRefPtr);
3387 inline void RecordedFilterNodeDestruction::OutputSimpleEventInfo(
3388 std::stringstream& aStringStream) const {
3389 aStringStream << "[" << mRefPtr << "] FilterNode Destroyed";
3392 inline RecordedGradientStopsCreation::~RecordedGradientStopsCreation() {
3393 if (mDataOwned) {
3394 delete[] mStops;
3398 inline bool RecordedGradientStopsCreation::PlayEvent(
3399 Translator* aTranslator) const {
3400 if (mNumStops > 0 && !mStops) {
3401 // Stops allocation failed
3402 return false;
3404 RefPtr<GradientStops> src =
3405 aTranslator->GetOrCreateGradientStops(mStops, mNumStops, mExtendMode);
3406 aTranslator->AddGradientStops(mRefPtr, src);
3407 return true;
3410 template <class S>
3411 void RecordedGradientStopsCreation::Record(S& aStream) const {
3412 WriteElement(aStream, mRefPtr);
3413 WriteElement(aStream, mExtendMode);
3414 WriteElement(aStream, mNumStops);
3415 aStream.write((const char*)mStops, mNumStops * sizeof(GradientStop));
3418 template <class S>
3419 RecordedGradientStopsCreation::RecordedGradientStopsCreation(S& aStream)
3420 : RecordedEventDerived(GRADIENTSTOPSCREATION), mDataOwned(true) {
3421 ReadElement(aStream, mRefPtr);
3422 ReadElementConstrained(aStream, mExtendMode, ExtendMode::CLAMP,
3423 ExtendMode::REFLECT);
3424 ReadElement(aStream, mNumStops);
3425 if (!aStream.good() || mNumStops <= 0) {
3426 return;
3429 mStops = new (fallible) GradientStop[mNumStops];
3430 if (!mStops) {
3431 gfxCriticalNote
3432 << "RecordedGradientStopsCreation failed to allocate stops of size "
3433 << mNumStops;
3434 aStream.SetIsBad();
3435 } else {
3436 aStream.read((char*)mStops, mNumStops * sizeof(GradientStop));
3440 inline void RecordedGradientStopsCreation::OutputSimpleEventInfo(
3441 std::stringstream& aStringStream) const {
3442 aStringStream << "[" << mRefPtr
3443 << "] GradientStops created (Stops: " << mNumStops << ")";
3446 inline bool RecordedGradientStopsDestruction::PlayEvent(
3447 Translator* aTranslator) const {
3448 aTranslator->RemoveGradientStops(mRefPtr);
3449 return true;
3452 template <class S>
3453 void RecordedGradientStopsDestruction::Record(S& aStream) const {
3454 WriteElement(aStream, mRefPtr);
3457 template <class S>
3458 RecordedGradientStopsDestruction::RecordedGradientStopsDestruction(S& aStream)
3459 : RecordedEventDerived(GRADIENTSTOPSDESTRUCTION) {
3460 ReadElement(aStream, mRefPtr);
3463 inline void RecordedGradientStopsDestruction::OutputSimpleEventInfo(
3464 std::stringstream& aStringStream) const {
3465 aStringStream << "[" << mRefPtr << "] GradientStops Destroyed";
3468 inline bool RecordedIntoLuminanceSource::PlayEvent(
3469 Translator* aTranslator) const {
3470 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
3471 if (!dt) {
3472 return false;
3475 RefPtr<SourceSurface> src = dt->IntoLuminanceSource(mLuminanceType, mOpacity);
3476 aTranslator->AddSourceSurface(mRefPtr, src);
3477 return true;
3480 template <class S>
3481 void RecordedIntoLuminanceSource::Record(S& aStream) const {
3482 WriteElement(aStream, mRefPtr);
3483 WriteElement(aStream, mDT);
3484 WriteElement(aStream, mLuminanceType);
3485 WriteElement(aStream, mOpacity);
3488 template <class S>
3489 RecordedIntoLuminanceSource::RecordedIntoLuminanceSource(S& aStream)
3490 : RecordedEventDerived(INTOLUMINANCE) {
3491 ReadElement(aStream, mRefPtr);
3492 ReadElement(aStream, mDT);
3493 ReadElementConstrained(aStream, mLuminanceType, LuminanceType::LUMINANCE,
3494 LuminanceType::LINEARRGB);
3495 ReadElement(aStream, mOpacity);
3498 inline void RecordedIntoLuminanceSource::OutputSimpleEventInfo(
3499 std::stringstream& aStringStream) const {
3500 aStringStream << "[" << mRefPtr << "] Into Luminance Source (DT: " << mDT
3501 << ")";
3504 inline bool RecordedFlush::PlayEvent(Translator* aTranslator) const {
3505 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
3506 if (!dt) {
3507 return false;
3510 dt->Flush();
3511 return true;
3514 template <class S>
3515 void RecordedFlush::Record(S& aStream) const {
3516 RecordedDrawingEvent::Record(aStream);
3519 template <class S>
3520 RecordedFlush::RecordedFlush(S& aStream)
3521 : RecordedDrawingEvent(FLUSH, aStream) {}
3523 inline void RecordedFlush::OutputSimpleEventInfo(
3524 std::stringstream& aStringStream) const {
3525 aStringStream << "[" << mDT << "] Flush";
3528 inline bool RecordedDetachAllSnapshots::PlayEvent(
3529 Translator* aTranslator) const {
3530 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
3531 if (!dt) {
3532 return false;
3535 dt->DetachAllSnapshots();
3536 return true;
3539 template <class S>
3540 void RecordedDetachAllSnapshots::Record(S& aStream) const {
3541 RecordedDrawingEvent::Record(aStream);
3544 template <class S>
3545 RecordedDetachAllSnapshots::RecordedDetachAllSnapshots(S& aStream)
3546 : RecordedDrawingEvent(DETACHALLSNAPSHOTS, aStream) {}
3548 inline void RecordedDetachAllSnapshots::OutputSimpleEventInfo(
3549 std::stringstream& aStringStream) const {
3550 aStringStream << "[" << mDT << "] DetachAllSnapshots";
3553 inline bool RecordedSnapshot::PlayEvent(Translator* aTranslator) const {
3554 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
3555 if (!dt) {
3556 return false;
3559 RefPtr<SourceSurface> src = aTranslator->LookupDrawTarget(mDT)->Snapshot();
3560 aTranslator->AddSourceSurface(mRefPtr, src);
3561 return true;
3564 template <class S>
3565 void RecordedSnapshot::Record(S& aStream) const {
3566 WriteElement(aStream, mRefPtr);
3567 WriteElement(aStream, mDT);
3570 template <class S>
3571 RecordedSnapshot::RecordedSnapshot(S& aStream)
3572 : RecordedEventDerived(SNAPSHOT) {
3573 ReadElement(aStream, mRefPtr);
3574 ReadElement(aStream, mDT);
3577 inline void RecordedSnapshot::OutputSimpleEventInfo(
3578 std::stringstream& aStringStream) const {
3579 aStringStream << "[" << mRefPtr << "] Snapshot Created (DT: " << mDT << ")";
3582 inline RecordedFontData::~RecordedFontData() { delete[] mData; }
3584 inline bool RecordedFontData::PlayEvent(Translator* aTranslator) const {
3585 if (!mData) {
3586 return false;
3589 RefPtr<NativeFontResource> fontResource = Factory::CreateNativeFontResource(
3590 mData, mFontDetails.size, mType, aTranslator->GetFontContext());
3591 if (!fontResource) {
3592 return false;
3595 aTranslator->AddNativeFontResource(mFontDetails.fontDataKey, fontResource);
3596 return true;
3599 template <class S>
3600 void RecordedFontData::Record(S& aStream) const {
3601 MOZ_ASSERT(mGetFontFileDataSucceeded);
3603 WriteElement(aStream, mType);
3604 WriteElement(aStream, mFontDetails.fontDataKey);
3605 if (!mData) {
3606 WriteElement(aStream, 0);
3607 } else {
3608 WriteElement(aStream, mFontDetails.size);
3609 aStream.write((const char*)mData, mFontDetails.size);
3613 inline void RecordedFontData::OutputSimpleEventInfo(
3614 std::stringstream& aStringStream) const {
3615 aStringStream << "Font Data of size " << mFontDetails.size;
3618 inline void RecordedFontData::SetFontData(const uint8_t* aData, uint32_t aSize,
3619 uint32_t aIndex) {
3620 mData = new (fallible) uint8_t[aSize];
3621 if (!mData) {
3622 gfxCriticalNote
3623 << "RecordedFontData failed to allocate data for recording of size "
3624 << aSize;
3625 } else {
3626 memcpy(mData, aData, aSize);
3628 mFontDetails.fontDataKey = SFNTData::GetUniqueKey(aData, aSize, 0, nullptr);
3629 mFontDetails.size = aSize;
3630 mFontDetails.index = aIndex;
3633 inline bool RecordedFontData::GetFontDetails(RecordedFontDetails& fontDetails) {
3634 if (!mGetFontFileDataSucceeded) {
3635 return false;
3638 fontDetails.fontDataKey = mFontDetails.fontDataKey;
3639 fontDetails.size = mFontDetails.size;
3640 fontDetails.index = mFontDetails.index;
3641 return true;
3644 template <class S>
3645 RecordedFontData::RecordedFontData(S& aStream)
3646 : RecordedEventDerived(FONTDATA), mType(FontType::UNKNOWN) {
3647 ReadElementConstrained(aStream, mType, FontType::DWRITE, FontType::UNKNOWN);
3648 ReadElement(aStream, mFontDetails.fontDataKey);
3649 ReadElement(aStream, mFontDetails.size);
3650 if (!mFontDetails.size || !aStream.good()) {
3651 return;
3654 mData = new (fallible) uint8_t[mFontDetails.size];
3655 if (!mData) {
3656 gfxCriticalNote
3657 << "RecordedFontData failed to allocate data for playback of size "
3658 << mFontDetails.size;
3659 aStream.SetIsBad();
3660 } else {
3661 aStream.read((char*)mData, mFontDetails.size);
3665 inline RecordedFontDescriptor::~RecordedFontDescriptor() = default;
3667 inline bool RecordedFontDescriptor::PlayEvent(Translator* aTranslator) const {
3668 RefPtr<UnscaledFont> font = Factory::CreateUnscaledFontFromFontDescriptor(
3669 mType, mData.data(), mData.size(), mIndex);
3670 if (!font) {
3671 gfxDevCrash(LogReason::InvalidFont)
3672 << "Failed creating UnscaledFont of type " << int(mType)
3673 << " from font descriptor";
3674 return false;
3677 aTranslator->AddUnscaledFont(mRefPtr, font);
3678 return true;
3681 template <class S>
3682 void RecordedFontDescriptor::Record(S& aStream) const {
3683 MOZ_ASSERT(mHasDesc);
3684 WriteElement(aStream, mType);
3685 WriteElement(aStream, mRefPtr);
3686 WriteElement(aStream, mIndex);
3687 WriteElement(aStream, (size_t)mData.size());
3688 if (mData.size()) {
3689 aStream.write((char*)mData.data(), mData.size());
3693 inline void RecordedFontDescriptor::OutputSimpleEventInfo(
3694 std::stringstream& aStringStream) const {
3695 aStringStream << "[" << mRefPtr << "] Font Descriptor";
3698 inline void RecordedFontDescriptor::SetFontDescriptor(const uint8_t* aData,
3699 uint32_t aSize,
3700 uint32_t aIndex) {
3701 mData.assign(aData, aData + aSize);
3702 mIndex = aIndex;
3705 template <class S>
3706 RecordedFontDescriptor::RecordedFontDescriptor(S& aStream)
3707 : RecordedEventDerived(FONTDESC) {
3708 ReadElementConstrained(aStream, mType, FontType::DWRITE, FontType::UNKNOWN);
3709 ReadElement(aStream, mRefPtr);
3710 ReadElement(aStream, mIndex);
3712 size_t size;
3713 ReadElement(aStream, size);
3714 if (!aStream.good()) {
3715 return;
3717 if (size) {
3718 mData.resize(size);
3719 aStream.read((char*)mData.data(), size);
3723 inline bool RecordedUnscaledFontCreation::PlayEvent(
3724 Translator* aTranslator) const {
3725 NativeFontResource* fontResource =
3726 aTranslator->LookupNativeFontResource(mFontDataKey);
3727 if (!fontResource) {
3728 gfxDevCrash(LogReason::NativeFontResourceNotFound)
3729 << "NativeFontResource lookup failed for key |" << hexa(mFontDataKey)
3730 << "|.";
3731 return false;
3734 RefPtr<UnscaledFont> unscaledFont = fontResource->CreateUnscaledFont(
3735 mIndex, mInstanceData.data(), mInstanceData.size());
3736 aTranslator->AddUnscaledFont(mRefPtr, unscaledFont);
3737 return true;
3740 template <class S>
3741 void RecordedUnscaledFontCreation::Record(S& aStream) const {
3742 WriteElement(aStream, mRefPtr);
3743 WriteElement(aStream, mFontDataKey);
3744 WriteElement(aStream, mIndex);
3745 WriteElement(aStream, (size_t)mInstanceData.size());
3746 if (mInstanceData.size()) {
3747 aStream.write((char*)mInstanceData.data(), mInstanceData.size());
3751 inline void RecordedUnscaledFontCreation::OutputSimpleEventInfo(
3752 std::stringstream& aStringStream) const {
3753 aStringStream << "[" << mRefPtr << "] UnscaledFont Created";
3756 inline void RecordedUnscaledFontCreation::SetFontInstanceData(
3757 const uint8_t* aData, uint32_t aSize) {
3758 if (aSize) {
3759 mInstanceData.assign(aData, aData + aSize);
3763 template <class S>
3764 RecordedUnscaledFontCreation::RecordedUnscaledFontCreation(S& aStream)
3765 : RecordedEventDerived(UNSCALEDFONTCREATION) {
3766 ReadElement(aStream, mRefPtr);
3767 ReadElement(aStream, mFontDataKey);
3768 ReadElement(aStream, mIndex);
3770 size_t size;
3771 ReadElement(aStream, size);
3772 if (!aStream.good()) {
3773 return;
3775 if (size) {
3776 mInstanceData.resize(size);
3777 aStream.read((char*)mInstanceData.data(), size);
3781 inline bool RecordedUnscaledFontDestruction::PlayEvent(
3782 Translator* aTranslator) const {
3783 aTranslator->RemoveUnscaledFont(mRefPtr);
3784 return true;
3787 template <class S>
3788 void RecordedUnscaledFontDestruction::Record(S& aStream) const {
3789 WriteElement(aStream, mRefPtr);
3792 template <class S>
3793 RecordedUnscaledFontDestruction::RecordedUnscaledFontDestruction(S& aStream)
3794 : RecordedEventDerived(UNSCALEDFONTDESTRUCTION) {
3795 ReadElement(aStream, mRefPtr);
3798 inline void RecordedUnscaledFontDestruction::OutputSimpleEventInfo(
3799 std::stringstream& aStringStream) const {
3800 aStringStream << "[" << mRefPtr << "] UnscaledFont Destroyed";
3803 inline bool RecordedScaledFontCreation::PlayEvent(
3804 Translator* aTranslator) const {
3805 UnscaledFont* unscaledFont = aTranslator->LookupUnscaledFont(mUnscaledFont);
3806 if (!unscaledFont) {
3807 gfxDevCrash(LogReason::UnscaledFontNotFound)
3808 << "UnscaledFont lookup failed for key |" << hexa(mUnscaledFont)
3809 << "|.";
3810 return false;
3813 RefPtr<ScaledFont> scaledFont = unscaledFont->CreateScaledFont(
3814 mGlyphSize, mInstanceData.data(), mInstanceData.size(),
3815 mVariations.data(), mVariations.size());
3817 aTranslator->AddScaledFont(mRefPtr, scaledFont);
3818 return true;
3821 template <class S>
3822 void RecordedScaledFontCreation::Record(S& aStream) const {
3823 WriteElement(aStream, mRefPtr);
3824 WriteElement(aStream, mUnscaledFont);
3825 WriteElement(aStream, mGlyphSize);
3826 WriteElement(aStream, (size_t)mInstanceData.size());
3827 if (mInstanceData.size()) {
3828 aStream.write((char*)mInstanceData.data(), mInstanceData.size());
3830 WriteElement(aStream, (size_t)mVariations.size());
3831 if (mVariations.size()) {
3832 aStream.write((char*)mVariations.data(),
3833 sizeof(FontVariation) * mVariations.size());
3837 inline void RecordedScaledFontCreation::OutputSimpleEventInfo(
3838 std::stringstream& aStringStream) const {
3839 aStringStream << "[" << mRefPtr << "] ScaledFont Created";
3842 inline void RecordedScaledFontCreation::SetFontInstanceData(
3843 const uint8_t* aData, uint32_t aSize, const FontVariation* aVariations,
3844 uint32_t aNumVariations) {
3845 if (aSize) {
3846 mInstanceData.assign(aData, aData + aSize);
3848 if (aNumVariations) {
3849 mVariations.assign(aVariations, aVariations + aNumVariations);
3853 template <class S>
3854 RecordedScaledFontCreation::RecordedScaledFontCreation(S& aStream)
3855 : RecordedEventDerived(SCALEDFONTCREATION) {
3856 ReadElement(aStream, mRefPtr);
3857 ReadElement(aStream, mUnscaledFont);
3858 ReadElement(aStream, mGlyphSize);
3860 size_t size;
3861 ReadElement(aStream, size);
3862 if (!aStream.good()) {
3863 return;
3865 if (size) {
3866 mInstanceData.resize(size);
3867 aStream.read((char*)mInstanceData.data(), size);
3870 size_t numVariations;
3871 ReadElement(aStream, numVariations);
3872 if (!aStream.good()) {
3873 return;
3875 if (numVariations) {
3876 mVariations.resize(numVariations);
3877 aStream.read((char*)mVariations.data(),
3878 sizeof(FontVariation) * numVariations);
3882 inline bool RecordedScaledFontDestruction::PlayEvent(
3883 Translator* aTranslator) const {
3884 aTranslator->RemoveScaledFont(mRefPtr);
3885 return true;
3888 template <class S>
3889 void RecordedScaledFontDestruction::Record(S& aStream) const {
3890 WriteElement(aStream, mRefPtr);
3893 template <class S>
3894 RecordedScaledFontDestruction::RecordedScaledFontDestruction(S& aStream)
3895 : RecordedEventDerived(SCALEDFONTDESTRUCTION) {
3896 ReadElement(aStream, mRefPtr);
3899 inline void RecordedScaledFontDestruction::OutputSimpleEventInfo(
3900 std::stringstream& aStringStream) const {
3901 aStringStream << "[" << mRefPtr << "] ScaledFont Destroyed";
3904 inline bool RecordedMaskSurface::PlayEvent(Translator* aTranslator) const {
3905 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
3906 if (!dt) {
3907 return false;
3910 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefMask);
3911 if (!surface) {
3912 return false;
3915 dt->MaskSurface(*GenericPattern(mPattern, aTranslator), surface, mOffset,
3916 mOptions);
3917 return true;
3920 template <class S>
3921 void RecordedMaskSurface::Record(S& aStream) const {
3922 RecordedDrawingEvent::Record(aStream);
3923 RecordPatternData(aStream, mPattern);
3924 WriteElement(aStream, mRefMask);
3925 WriteElement(aStream, mOffset);
3926 WriteElement(aStream, mOptions);
3929 template <class S>
3930 RecordedMaskSurface::RecordedMaskSurface(S& aStream)
3931 : RecordedDrawingEvent(MASKSURFACE, aStream) {
3932 ReadPatternData(aStream, mPattern);
3933 ReadElement(aStream, mRefMask);
3934 ReadElement(aStream, mOffset);
3935 ReadDrawOptions(aStream, mOptions);
3938 inline void RecordedMaskSurface::OutputSimpleEventInfo(
3939 std::stringstream& aStringStream) const {
3940 aStringStream << "[" << mDT << "] MaskSurface (" << mRefMask << ") Offset: ("
3941 << mOffset.x << "x" << mOffset.y << ") Pattern: ";
3942 OutputSimplePatternInfo(mPattern, aStringStream);
3945 template <typename T>
3946 void ReplaySetAttribute(FilterNode* aNode, uint32_t aIndex, T aValue) {
3947 aNode->SetAttribute(aIndex, aValue);
3950 inline bool RecordedFilterNodeSetAttribute::PlayEvent(
3951 Translator* aTranslator) const {
3952 FilterNode* node = aTranslator->LookupFilterNode(mNode);
3953 if (!node) {
3954 return false;
3957 #define REPLAY_SET_ATTRIBUTE(type, argtype) \
3958 case ARGTYPE_##argtype: \
3959 ReplaySetAttribute(node, mIndex, *(type*)&mPayload.front()); \
3960 break
3962 switch (mArgType) {
3963 REPLAY_SET_ATTRIBUTE(bool, BOOL);
3964 REPLAY_SET_ATTRIBUTE(uint32_t, UINT32);
3965 REPLAY_SET_ATTRIBUTE(Float, FLOAT);
3966 REPLAY_SET_ATTRIBUTE(Size, SIZE);
3967 REPLAY_SET_ATTRIBUTE(IntSize, INTSIZE);
3968 REPLAY_SET_ATTRIBUTE(IntPoint, INTPOINT);
3969 REPLAY_SET_ATTRIBUTE(Rect, RECT);
3970 REPLAY_SET_ATTRIBUTE(IntRect, INTRECT);
3971 REPLAY_SET_ATTRIBUTE(Point, POINT);
3972 REPLAY_SET_ATTRIBUTE(Matrix, MATRIX);
3973 REPLAY_SET_ATTRIBUTE(Matrix5x4, MATRIX5X4);
3974 REPLAY_SET_ATTRIBUTE(Point3D, POINT3D);
3975 REPLAY_SET_ATTRIBUTE(DeviceColor, COLOR);
3976 case ARGTYPE_FLOAT_ARRAY:
3977 node->SetAttribute(mIndex,
3978 reinterpret_cast<const Float*>(&mPayload.front()),
3979 mPayload.size() / sizeof(Float));
3980 break;
3983 return true;
3986 template <class S>
3987 void RecordedFilterNodeSetAttribute::Record(S& aStream) const {
3988 WriteElement(aStream, mNode);
3989 WriteElement(aStream, mIndex);
3990 WriteElement(aStream, mArgType);
3991 WriteElement(aStream, uint64_t(mPayload.size()));
3992 aStream.write((const char*)&mPayload.front(), mPayload.size());
3995 template <class S>
3996 RecordedFilterNodeSetAttribute::RecordedFilterNodeSetAttribute(S& aStream)
3997 : RecordedEventDerived(FILTERNODESETATTRIBUTE) {
3998 ReadElement(aStream, mNode);
3999 ReadElement(aStream, mIndex);
4000 ReadElementConstrained(aStream, mArgType, ArgType::ARGTYPE_UINT32,
4001 ArgType::ARGTYPE_FLOAT_ARRAY);
4002 uint64_t size;
4003 ReadElement(aStream, size);
4004 if (!aStream.good()) {
4005 return;
4008 mPayload.resize(size_t(size));
4009 aStream.read((char*)&mPayload.front(), size);
4012 inline void RecordedFilterNodeSetAttribute::OutputSimpleEventInfo(
4013 std::stringstream& aStringStream) const {
4014 aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ")";
4017 inline bool RecordedFilterNodeSetInput::PlayEvent(
4018 Translator* aTranslator) const {
4019 FilterNode* node = aTranslator->LookupFilterNode(mNode);
4020 if (!node) {
4021 return false;
4024 if (mInputFilter) {
4025 node->SetInput(mIndex, aTranslator->LookupFilterNode(mInputFilter));
4026 } else {
4027 node->SetInput(mIndex, aTranslator->LookupSourceSurface(mInputSurface));
4030 return true;
4033 template <class S>
4034 void RecordedFilterNodeSetInput::Record(S& aStream) const {
4035 WriteElement(aStream, mNode);
4036 WriteElement(aStream, mIndex);
4037 WriteElement(aStream, mInputFilter);
4038 WriteElement(aStream, mInputSurface);
4041 template <class S>
4042 RecordedFilterNodeSetInput::RecordedFilterNodeSetInput(S& aStream)
4043 : RecordedEventDerived(FILTERNODESETINPUT) {
4044 ReadElement(aStream, mNode);
4045 ReadElement(aStream, mIndex);
4046 ReadElement(aStream, mInputFilter);
4047 ReadElement(aStream, mInputSurface);
4050 inline void RecordedFilterNodeSetInput::OutputSimpleEventInfo(
4051 std::stringstream& aStringStream) const {
4052 aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ", ";
4054 if (mInputFilter) {
4055 aStringStream << "Filter: " << mInputFilter;
4056 } else {
4057 aStringStream << "Surface: " << mInputSurface;
4060 aStringStream << ")";
4063 inline bool RecordedLink::PlayEvent(Translator* aTranslator) const {
4064 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
4065 if (!dt) {
4066 return false;
4068 dt->Link(mDestination.c_str(), mRect);
4069 return true;
4072 template <class S>
4073 void RecordedLink::Record(S& aStream) const {
4074 RecordedDrawingEvent::Record(aStream);
4075 WriteElement(aStream, mRect);
4076 uint32_t len = mDestination.length();
4077 WriteElement(aStream, len);
4078 if (len) {
4079 aStream.write(mDestination.data(), len);
4083 template <class S>
4084 RecordedLink::RecordedLink(S& aStream) : RecordedDrawingEvent(LINK, aStream) {
4085 ReadElement(aStream, mRect);
4086 uint32_t len;
4087 ReadElement(aStream, len);
4088 mDestination.resize(size_t(len));
4089 if (len && aStream.good()) {
4090 aStream.read(&mDestination.front(), len);
4094 inline void RecordedLink::OutputSimpleEventInfo(
4095 std::stringstream& aStringStream) const {
4096 aStringStream << "Link [" << mDestination << " @ " << mRect << "]";
4099 inline bool RecordedDestination::PlayEvent(Translator* aTranslator) const {
4100 DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
4101 if (!dt) {
4102 return false;
4104 dt->Destination(mDestination.c_str(), mPoint);
4105 return true;
4108 template <class S>
4109 void RecordedDestination::Record(S& aStream) const {
4110 RecordedDrawingEvent::Record(aStream);
4111 WriteElement(aStream, mPoint);
4112 uint32_t len = mDestination.length();
4113 WriteElement(aStream, len);
4114 if (len) {
4115 aStream.write(mDestination.data(), len);
4119 template <class S>
4120 RecordedDestination::RecordedDestination(S& aStream)
4121 : RecordedDrawingEvent(DESTINATION, aStream) {
4122 ReadElement(aStream, mPoint);
4123 uint32_t len;
4124 ReadElement(aStream, len);
4125 mDestination.resize(size_t(len));
4126 if (len && aStream.good()) {
4127 aStream.read(&mDestination.front(), len);
4131 inline void RecordedDestination::OutputSimpleEventInfo(
4132 std::stringstream& aStringStream) const {
4133 aStringStream << "Destination [" << mDestination << " @ " << mPoint << "]";
4136 #define FOR_EACH_EVENT(f) \
4137 f(DRAWTARGETCREATION, RecordedDrawTargetCreation); \
4138 f(DRAWTARGETDESTRUCTION, RecordedDrawTargetDestruction); \
4139 f(FILLRECT, RecordedFillRect); \
4140 f(STROKERECT, RecordedStrokeRect); \
4141 f(STROKELINE, RecordedStrokeLine); \
4142 f(STROKECIRCLE, RecordedStrokeCircle); \
4143 f(CLEARRECT, RecordedClearRect); \
4144 f(COPYSURFACE, RecordedCopySurface); \
4145 f(SETTRANSFORM, RecordedSetTransform); \
4146 f(PUSHCLIPRECT, RecordedPushClipRect); \
4147 f(PUSHCLIP, RecordedPushClip); \
4148 f(POPCLIP, RecordedPopClip); \
4149 f(FILL, RecordedFill); \
4150 f(FILLCIRCLE, RecordedFillCircle); \
4151 f(FILLGLYPHS, RecordedFillGlyphs); \
4152 f(MASK, RecordedMask); \
4153 f(STROKE, RecordedStroke); \
4154 f(DRAWSURFACE, RecordedDrawSurface); \
4155 f(DRAWDEPENDENTSURFACE, RecordedDrawDependentSurface); \
4156 f(DRAWSURFACEWITHSHADOW, RecordedDrawSurfaceWithShadow); \
4157 f(DRAWFILTER, RecordedDrawFilter); \
4158 f(PATHCREATION, RecordedPathCreation); \
4159 f(PATHDESTRUCTION, RecordedPathDestruction); \
4160 f(SOURCESURFACECREATION, RecordedSourceSurfaceCreation); \
4161 f(SOURCESURFACEDESTRUCTION, RecordedSourceSurfaceDestruction); \
4162 f(FILTERNODECREATION, RecordedFilterNodeCreation); \
4163 f(FILTERNODEDESTRUCTION, RecordedFilterNodeDestruction); \
4164 f(GRADIENTSTOPSCREATION, RecordedGradientStopsCreation); \
4165 f(GRADIENTSTOPSDESTRUCTION, RecordedGradientStopsDestruction); \
4166 f(SNAPSHOT, RecordedSnapshot); \
4167 f(SCALEDFONTCREATION, RecordedScaledFontCreation); \
4168 f(SCALEDFONTDESTRUCTION, RecordedScaledFontDestruction); \
4169 f(MASKSURFACE, RecordedMaskSurface); \
4170 f(FILTERNODESETATTRIBUTE, RecordedFilterNodeSetAttribute); \
4171 f(FILTERNODESETINPUT, RecordedFilterNodeSetInput); \
4172 f(CREATESIMILARDRAWTARGET, RecordedCreateSimilarDrawTarget); \
4173 f(CREATECLIPPEDDRAWTARGET, RecordedCreateClippedDrawTarget); \
4174 f(CREATEDRAWTARGETFORFILTER, RecordedCreateDrawTargetForFilter); \
4175 f(FONTDATA, RecordedFontData); \
4176 f(FONTDESC, RecordedFontDescriptor); \
4177 f(PUSHLAYER, RecordedPushLayer); \
4178 f(PUSHLAYERWITHBLEND, RecordedPushLayerWithBlend); \
4179 f(POPLAYER, RecordedPopLayer); \
4180 f(UNSCALEDFONTCREATION, RecordedUnscaledFontCreation); \
4181 f(UNSCALEDFONTDESTRUCTION, RecordedUnscaledFontDestruction); \
4182 f(INTOLUMINANCE, RecordedIntoLuminanceSource); \
4183 f(EXTERNALSURFACECREATION, RecordedExternalSurfaceCreation); \
4184 f(FLUSH, RecordedFlush); \
4185 f(DETACHALLSNAPSHOTS, RecordedDetachAllSnapshots); \
4186 f(OPTIMIZESOURCESURFACE, RecordedOptimizeSourceSurface); \
4187 f(LINK, RecordedLink); \
4188 f(DESTINATION, RecordedDestination);
4190 #define DO_WITH_EVENT_TYPE(_typeenum, _class) \
4191 case _typeenum: { \
4192 auto e = _class(aStream); \
4193 return aAction(&e); \
4196 template <class S>
4197 bool RecordedEvent::DoWithEvent(
4198 S& aStream, EventType aType,
4199 const std::function<bool(RecordedEvent*)>& aAction) {
4200 switch (aType) {
4201 FOR_EACH_EVENT(DO_WITH_EVENT_TYPE)
4202 default:
4203 return false;
4207 } // namespace gfx
4208 } // namespace mozilla
4210 #endif