Bug Summary

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