Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/gfx/2d/RecordedEventImpl.h
Warning:line 3939, column 48
Memory allocated by malloc() should be deallocated by free(), not 'delete[]'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name InlineTranslator.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/gfx/2d -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/gfx/2d -resource-dir /usr/lib/llvm-19/lib/clang/19 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D USE_SSE2 -D USE_CAIRO -D MOZ2D_HAS_MOZ_CAIRO -D MOZ_ENABLE_FREETYPE -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /var/lib/jenkins/workspace/firefox-scan-build/gfx/2d -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/gfx/2d -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /var/lib/jenkins/workspace/firefox-scan-build/ipc/chromium/src -I /var/lib/jenkins/workspace/firefox-scan-build/gfx/skia -I /var/lib/jenkins/workspace/firefox-scan-build/gfx/skia/skia -I /var/lib/jenkins/workspace/firefox-scan-build/gfx/cairo/cairo/src -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/freetype2 -I /usr/include/libpng16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-09-22-115206-3586786-1 -x c++ /var/lib/jenkins/workspace/firefox-scan-build/gfx/2d/InlineTranslator.cpp

/var/lib/jenkins/workspace/firefox-scan-build/gfx/2d/InlineTranslator.cpp

1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3/* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7#include "InlineTranslator.h"
8#include "RecordedEventImpl.h"
9
10#include "mozilla/gfx/RecordingTypes.h"
11
12using namespace mozilla::gfx;
13
14namespace mozilla::gfx {
15
16InlineTranslator::InlineTranslator() : mFontContext(nullptr) {}
17
18InlineTranslator::InlineTranslator(DrawTarget* aDT, void* aFontContext)
19 : mBaseDT(aDT), mFontContext(aFontContext) {}
20
21bool InlineTranslator::TranslateRecording(char* aData, size_t aLen) {
22 MemReader reader(aData, aLen);
23
24 uint32_t magicInt;
25 ReadElement(reader, magicInt);
26 if (magicInt != mozilla::gfx::kMagicInt) {
1
Assuming 'magicInt' is equal to 'kMagicInt'
2
Taking false branch
27 mError = "Magic";
28 return false;
29 }
30
31 uint16_t majorRevision;
32 ReadElement(reader, majorRevision);
33 if (majorRevision != kMajorRevision) {
3
Assuming 'majorRevision' is equal to 'kMajorRevision'
4
Taking false branch
34 mError = "Major";
35 return false;
36 }
37
38 uint16_t minorRevision;
39 ReadElement(reader, minorRevision);
40 if (minorRevision > kMinorRevision) {
5
Assuming 'minorRevision' is <= 'kMinorRevision'
6
Taking false branch
41 mError = "Minor";
42 return false;
43 }
44
45 uint8_t eventType = RecordedEvent::EventType::INVALID;
46 ReadElement(reader, eventType);
47 while (reader.good()) {
7
Loop condition is true. Entering loop body
48 bool success = RecordedEvent::DoWithEvent(
8
Calling 'RecordedEvent::DoWithEvent'
49 reader, static_cast<RecordedEvent::EventType>(eventType),
50 [&](RecordedEvent* recordedEvent) -> bool {
51 // Make sure that the whole event was read from the stream
52 // successfully.
53 if (!reader.good()) {
54 mError = " READ";
55 return false;
56 }
57
58 if (!recordedEvent->PlayEvent(this)) {
59 mError = " PLAY";
60 return false;
61 }
62
63 return true;
64 });
65 if (!success) {
66 mError = RecordedEvent::GetEventName(
67 static_cast<RecordedEvent::EventType>(eventType)) +
68 mError;
69 return false;
70 }
71
72 ReadElement(reader, eventType);
73 }
74
75 return true;
76}
77
78already_AddRefed<DrawTarget> InlineTranslator::CreateDrawTarget(
79 ReferencePtr aRefPtr, const gfx::IntSize& aSize,
80 gfx::SurfaceFormat aFormat) {
81 MOZ_ASSERT(mBaseDT, "mBaseDT has not been initialized.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mBaseDT)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mBaseDT))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mBaseDT" " (" "mBaseDT has not been initialized."
")", "/var/lib/jenkins/workspace/firefox-scan-build/gfx/2d/InlineTranslator.cpp"
, 81); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mBaseDT" ") ("
"mBaseDT has not been initialized." ")"); do { *((volatile int
*)__null) = 81; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
82
83 RefPtr<DrawTarget> drawTarget = mBaseDT;
84 AddDrawTarget(aRefPtr, drawTarget);
85 return drawTarget.forget();
86}
87
88already_AddRefed<SourceSurface> InlineTranslator::LookupExternalSurface(
89 uint64_t aKey) {
90 if (!mExternalSurfaces) {
91 return nullptr;
92 }
93 RefPtr<SourceSurface> surface = mExternalSurfaces->Get(aKey);
94 return surface.forget();
95}
96
97} // namespace mozilla::gfx

/var/lib/jenkins/workspace/firefox-scan-build/gfx/2d/RecordedEventImpl.h

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

/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/cxxalloc.h

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#ifndef mozilla_cxxalloc_h
6#define mozilla_cxxalloc_h
7
8/*
9 * We implement the default operators new/delete as part of
10 * libmozalloc, replacing their definitions in libstdc++. The
11 * operator new* definitions in libmozalloc will never return a NULL
12 * pointer.
13 *
14 * Each operator new immediately below returns a pointer to memory
15 * that can be delete'd by any of
16 *
17 * (1) the matching infallible operator delete immediately below
18 * (2) the matching system |operator delete(void*, std::nothrow)|
19 * (3) the matching system |operator delete(void*) noexcept(false)|
20 *
21 * NB: these are declared |noexcept(false)|, though they will never
22 * throw that exception. This declaration is consistent with the rule
23 * that |::operator new() noexcept(false)| will never return NULL.
24 *
25 * NB: mozilla::fallible can be used instead of std::nothrow.
26 */
27
28#ifndef MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline
29# define MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline MFBT_API__attribute__((weak)) __attribute__((visibility("default")))
30#endif
31
32MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void* operator new(size_t size) noexcept(false) {
33 return moz_xmalloc(size);
34}
35
36MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void* operator new(size_t size,
37 const std::nothrow_t&) noexcept(true) {
38 return malloc_implmalloc(size);
39}
40
41MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void* operator new[](size_t size) noexcept(false) {
42 return moz_xmalloc(size);
43}
44
45MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void* operator new[](size_t size,
46 const std::nothrow_t&) noexcept(true) {
47 return malloc_implmalloc(size);
14
Memory is allocated
48}
49
50MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void operator delete(void* ptr) noexcept(true) {
51 return free_implfree(ptr);
52}
53
54MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void operator delete(void* ptr,
55 const std::nothrow_t&) noexcept(true) {
56 return free_implfree(ptr);
57}
58
59MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void operator delete[](void* ptr) noexcept(true) {
60 return free_implfree(ptr);
61}
62
63MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void operator delete[](
64 void* ptr, const std::nothrow_t&) noexcept(true) {
65 return free_implfree(ptr);
66}
67
68#if defined(XP_WIN)
69// We provide the global sized delete overloads unconditionally because the
70// MSVC runtime headers do, despite compiling with /Zc:sizedDealloc-
71MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void operator delete(void* ptr,
72 size_t /*size*/) noexcept(true) {
73 return free_implfree(ptr);
74}
75
76MOZALLOC_EXPORT_NEW__attribute__((always_inline)) inline void operator delete[](void* ptr,
77 size_t /*size*/) noexcept(true) {
78 return free_implfree(ptr);
79}
80#endif
81
82#endif /* mozilla_cxxalloc_h */