Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/gfx/2d/RecordedEventImpl.h
Warning:line 3896, 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 MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /var/lib/jenkins/workspace/firefox-scan-build/gfx/2d -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/gfx/2d -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /var/lib/jenkins/workspace/firefox-scan-build/ipc/chromium/src -I /var/lib/jenkins/workspace/firefox-scan-build/gfx/skia -I /var/lib/jenkins/workspace/firefox-scan-build/gfx/skia/skia -I /var/lib/jenkins/workspace/firefox-scan-build/gfx/cairo/cairo/src -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/freetype2 -I /usr/include/libpng16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -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-07-21-021012-413605-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* aLocalDest, const char* aURI, const Rect& aRect)
1767 : RecordedEventDerived(LINK),
1768 mLocalDest(aLocalDest),
1769 mURI(aURI),
1770 mRect(aRect) {}
1771
1772 bool PlayEvent(Translator* aTranslator) const override;
1773 template <class S>
1774 void Record(S& aStream) const;
1775 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1776
1777 std::string GetName() const override { return "Link"; }
1778
1779 private:
1780 friend class RecordedEvent;
1781
1782 std::string mLocalDest;
1783 std::string mURI;
1784 Rect mRect;
1785
1786 template <class S>
1787 MOZ_IMPLICIT RecordedLink(S& aStream);
1788};
1789
1790class RecordedDestination : public RecordedEventDerived<RecordedDestination> {
1791 public:
1792 RecordedDestination(const char* aDestination, const Point& aPoint)
1793 : RecordedEventDerived(DESTINATION),
1794 mDestination(aDestination),
1795 mPoint(aPoint) {}
1796
1797 bool PlayEvent(Translator* aTranslator) const override;
1798 template <class S>
1799 void Record(S& aStream) const;
1800 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
1801
1802 std::string GetName() const override { return "Destination"; }
1803
1804 private:
1805 friend class RecordedEvent;
1806
1807 std::string mDestination;
1808 Point mPoint;
1809
1810 template <class S>
1811 MOZ_IMPLICIT RecordedDestination(S& aStream);
1812};
1813
1814static std::string NameFromBackend(BackendType aType) {
1815 switch (aType) {
1816 case BackendType::NONE:
1817 return "None";
1818 case BackendType::DIRECT2D:
1819 return "Direct2D";
1820 default:
1821 return "Unknown";
1822 }
1823}
1824
1825template <class S>
1826void RecordedEvent::RecordPatternData(S& aStream,
1827 const PatternStorage& aPattern) const {
1828 WriteElement(aStream, aPattern.mType);
1829
1830 switch (aPattern.mType) {
1831 case PatternType::COLOR: {
1832 WriteElement(aStream, *reinterpret_cast<const ColorPatternStorage*>(
1833 &aPattern.mStorage));
1834 return;
1835 }
1836 case PatternType::LINEAR_GRADIENT: {
1837 WriteElement(aStream,
1838 *reinterpret_cast<const LinearGradientPatternStorage*>(
1839 &aPattern.mStorage));
1840 return;
1841 }
1842 case PatternType::RADIAL_GRADIENT: {
1843 WriteElement(aStream,
1844 *reinterpret_cast<const RadialGradientPatternStorage*>(
1845 &aPattern.mStorage));
1846 return;
1847 }
1848 case PatternType::CONIC_GRADIENT: {
1849 WriteElement(aStream,
1850 *reinterpret_cast<const ConicGradientPatternStorage*>(
1851 &aPattern.mStorage));
1852 return;
1853 }
1854 case PatternType::SURFACE: {
1855 WriteElement(aStream, *reinterpret_cast<const SurfacePatternStorage*>(
1856 &aPattern.mStorage));
1857 return;
1858 }
1859 default:
1860 return;
1861 }
1862}
1863
1864template <class S>
1865void RecordedEvent::ReadPatternData(S& aStream,
1866 PatternStorage& aPattern) const {
1867 ReadElementConstrained(aStream, aPattern.mType, PatternType::COLOR,
1868 kHighestPatternType);
1869
1870 switch (aPattern.mType) {
1871 case PatternType::COLOR: {
1872 ReadElement(aStream,
1873 *reinterpret_cast<ColorPatternStorage*>(&aPattern.mStorage));
1874 return;
1875 }
1876 case PatternType::LINEAR_GRADIENT: {
1877 ReadElement(aStream, *reinterpret_cast<LinearGradientPatternStorage*>(
1878 &aPattern.mStorage));
1879 return;
1880 }
1881 case PatternType::RADIAL_GRADIENT: {
1882 ReadElement(aStream, *reinterpret_cast<RadialGradientPatternStorage*>(
1883 &aPattern.mStorage));
1884 return;
1885 }
1886 case PatternType::CONIC_GRADIENT: {
1887 ReadElement(aStream, *reinterpret_cast<ConicGradientPatternStorage*>(
1888 &aPattern.mStorage));
1889 return;
1890 }
1891 case PatternType::SURFACE: {
1892 SurfacePatternStorage* sps =
1893 reinterpret_cast<SurfacePatternStorage*>(&aPattern.mStorage);
1894 ReadElement(aStream, *sps);
1895 if (sps->mExtend < ExtendMode::CLAMP ||
1896 sps->mExtend > ExtendMode::REFLECT) {
1897 aStream.SetIsBad();
1898 return;
1899 }
1900
1901 if (sps->mSamplingFilter < SamplingFilter::GOOD ||
1902 sps->mSamplingFilter >= SamplingFilter::SENTINEL) {
1903 aStream.SetIsBad();
1904 }
1905 return;
1906 }
1907 default:
1908 return;
1909 }
1910}
1911
1912inline void RecordedEvent::StorePattern(PatternStorage& aDestination,
1913 const Pattern& aSource) const {
1914 aDestination.mType = aSource.GetType();
1915
1916 switch (aSource.GetType()) {
1917 case PatternType::COLOR: {
1918 reinterpret_cast<ColorPatternStorage*>(&aDestination.mStorage)->mColor =
1919 static_cast<const ColorPattern*>(&aSource)->mColor;
1920 return;
1921 }
1922 case PatternType::LINEAR_GRADIENT: {
1923 LinearGradientPatternStorage* store =
1924 reinterpret_cast<LinearGradientPatternStorage*>(
1925 &aDestination.mStorage);
1926 const LinearGradientPattern* pat =
1927 static_cast<const LinearGradientPattern*>(&aSource);
1928 store->mBegin = pat->mBegin;
1929 store->mEnd = pat->mEnd;
1930 store->mMatrix = pat->mMatrix;
1931 store->mStops = pat->mStops.get();
1932 return;
1933 }
1934 case PatternType::RADIAL_GRADIENT: {
1935 RadialGradientPatternStorage* store =
1936 reinterpret_cast<RadialGradientPatternStorage*>(
1937 &aDestination.mStorage);
1938 const RadialGradientPattern* pat =
1939 static_cast<const RadialGradientPattern*>(&aSource);
1940 store->mCenter1 = pat->mCenter1;
1941 store->mCenter2 = pat->mCenter2;
1942 store->mRadius1 = pat->mRadius1;
1943 store->mRadius2 = pat->mRadius2;
1944 store->mMatrix = pat->mMatrix;
1945 store->mStops = pat->mStops.get();
1946 return;
1947 }
1948 case PatternType::CONIC_GRADIENT: {
1949 ConicGradientPatternStorage* store =
1950 reinterpret_cast<ConicGradientPatternStorage*>(
1951 &aDestination.mStorage);
1952 const ConicGradientPattern* pat =
1953 static_cast<const ConicGradientPattern*>(&aSource);
1954 store->mCenter = pat->mCenter;
1955 store->mAngle = pat->mAngle;
1956 store->mStartOffset = pat->mStartOffset;
1957 store->mEndOffset = pat->mEndOffset;
1958 store->mMatrix = pat->mMatrix;
1959 store->mStops = pat->mStops.get();
1960 return;
1961 }
1962 case PatternType::SURFACE: {
1963 SurfacePatternStorage* store =
1964 reinterpret_cast<SurfacePatternStorage*>(&aDestination.mStorage);
1965 const SurfacePattern* pat = static_cast<const SurfacePattern*>(&aSource);
1966 store->mExtend = pat->mExtendMode;
1967 store->mSamplingFilter = pat->mSamplingFilter;
1968 store->mMatrix = pat->mMatrix;
1969 store->mSurface = pat->mSurface;
1970 store->mSamplingRect = pat->mSamplingRect;
1971 return;
1972 }
1973 }
1974}
1975
1976template <class S>
1977void RecordedEvent::RecordStrokeOptions(
1978 S& aStream, const StrokeOptions& aStrokeOptions) const {
1979 JoinStyle joinStyle = aStrokeOptions.mLineJoin;
1980 CapStyle capStyle = aStrokeOptions.mLineCap;
1981
1982 WriteElement(aStream, uint64_t(aStrokeOptions.mDashLength));
1983 WriteElement(aStream, aStrokeOptions.mLineWidth);
1984 WriteElement(aStream, aStrokeOptions.mMiterLimit);
1985 WriteElement(aStream, joinStyle);
1986 WriteElement(aStream, capStyle);
1987
1988 if (!aStrokeOptions.mDashPattern) {
1989 return;
1990 }
1991
1992 WriteElement(aStream, aStrokeOptions.mDashOffset);
1993 aStream.write((char*)aStrokeOptions.mDashPattern,
1994 sizeof(Float) * aStrokeOptions.mDashLength);
1995}
1996
1997template <class S>
1998void RecordedEvent::ReadStrokeOptions(S& aStream,
1999 StrokeOptions& aStrokeOptions) {
2000 uint64_t dashLength;
2001 JoinStyle joinStyle;
2002 CapStyle capStyle;
2003
2004 ReadElement(aStream, dashLength);
2005 ReadElement(aStream, aStrokeOptions.mLineWidth);
2006 ReadElement(aStream, aStrokeOptions.mMiterLimit);
2007 ReadElementConstrained(aStream, joinStyle, JoinStyle::BEVEL,
2008 JoinStyle::MITER_OR_BEVEL);
2009 ReadElementConstrained(aStream, capStyle, CapStyle::BUTT, CapStyle::SQUARE);
2010 // On 32 bit we truncate the value of dashLength.
2011 // See also bug 811850 for history.
2012 aStrokeOptions.mDashLength = size_t(dashLength);
2013 aStrokeOptions.mLineJoin = joinStyle;
2014 aStrokeOptions.mLineCap = capStyle;
2015
2016 if (!aStrokeOptions.mDashLength || !aStream.good()) {
2017 return;
2018 }
2019
2020 ReadElement(aStream, aStrokeOptions.mDashOffset);
2021
2022 mDashPatternStorage.resize(aStrokeOptions.mDashLength);
2023 aStrokeOptions.mDashPattern = &mDashPatternStorage.front();
2024 aStream.read((char*)aStrokeOptions.mDashPattern,
2025 sizeof(Float) * aStrokeOptions.mDashLength);
2026}
2027
2028template <class S>
2029static void ReadDrawOptions(S& aStream, DrawOptions& aDrawOptions) {
2030 ReadElement(aStream, aDrawOptions);
2031 if (aDrawOptions.mAntialiasMode < AntialiasMode::NONE ||
2032 aDrawOptions.mAntialiasMode > AntialiasMode::DEFAULT) {
2033 aStream.SetIsBad();
2034 return;
2035 }
2036
2037 if (aDrawOptions.mCompositionOp < CompositionOp::OP_CLEAR ||
2038 aDrawOptions.mCompositionOp > CompositionOp::OP_COUNT) {
2039 aStream.SetIsBad();
2040 }
2041}
2042
2043template <class S>
2044static void ReadDrawSurfaceOptions(S& aStream,
2045 DrawSurfaceOptions& aDrawSurfaceOptions) {
2046 ReadElement(aStream, aDrawSurfaceOptions);
2047 if (aDrawSurfaceOptions.mSamplingFilter < SamplingFilter::GOOD ||
2048 aDrawSurfaceOptions.mSamplingFilter >= SamplingFilter::SENTINEL) {
2049 aStream.SetIsBad();
2050 return;
2051 }
2052
2053 if (aDrawSurfaceOptions.mSamplingBounds < SamplingBounds::UNBOUNDED ||
2054 aDrawSurfaceOptions.mSamplingBounds > SamplingBounds::BOUNDED) {
2055 aStream.SetIsBad();
2056 }
2057}
2058
2059inline void RecordedEvent::OutputSimplePatternInfo(
2060 const PatternStorage& aStorage, std::stringstream& aOutput) const {
2061 switch (aStorage.mType) {
2062 case PatternType::COLOR: {
2063 const DeviceColor color =
2064 reinterpret_cast<const ColorPatternStorage*>(&aStorage.mStorage)
2065 ->mColor;
2066 aOutput << "DeviceColor: (" << color.r << ", " << color.g << ", "
2067 << color.b << ", " << color.a << ")";
2068 return;
2069 }
2070 case PatternType::LINEAR_GRADIENT: {
2071 const LinearGradientPatternStorage* store =
2072 reinterpret_cast<const LinearGradientPatternStorage*>(
2073 &aStorage.mStorage);
2074
2075 aOutput << "LinearGradient (" << store->mBegin.x << ", "
2076 << store->mBegin.y << ") - (" << store->mEnd.x << ", "
2077 << store->mEnd.y << ") Stops: " << store->mStops;
2078 return;
2079 }
2080 case PatternType::RADIAL_GRADIENT: {
2081 const RadialGradientPatternStorage* store =
2082 reinterpret_cast<const RadialGradientPatternStorage*>(
2083 &aStorage.mStorage);
2084 aOutput << "RadialGradient (Center 1: (" << store->mCenter1.x << ", "
2085 << store->mCenter2.y << ") Radius 2: " << store->mRadius2;
2086 return;
2087 }
2088 case PatternType::CONIC_GRADIENT: {
2089 const ConicGradientPatternStorage* store =
2090 reinterpret_cast<const ConicGradientPatternStorage*>(
2091 &aStorage.mStorage);
2092 aOutput << "ConicGradient (Center: (" << store->mCenter.x << ", "
2093 << store->mCenter.y << ") Angle: " << store->mAngle
2094 << " Range:" << store->mStartOffset << " - " << store->mEndOffset;
2095 return;
2096 }
2097 case PatternType::SURFACE: {
2098 const SurfacePatternStorage* store =
2099 reinterpret_cast<const SurfacePatternStorage*>(&aStorage.mStorage);
2100 aOutput << "Surface (0x" << store->mSurface << ")";
2101 return;
2102 }
2103 }
2104}
2105
2106inline bool RecordedDrawTargetCreation::PlayEvent(
2107 Translator* aTranslator) const {
2108 RefPtr<DrawTarget> newDT =
2109 aTranslator->CreateDrawTarget(mRefPtr, mRect.Size(), mFormat);
2110
2111 // If we couldn't create a DrawTarget this will probably cause us to crash
2112 // with nullptr later in the playback, so return false to abort.
2113 if (!newDT) {
2114 return false;
2115 }
2116
2117 if (mHasExistingData) {
2118 Rect dataRect(0, 0, mExistingData->GetSize().width,
2119 mExistingData->GetSize().height);
2120 newDT->DrawSurface(mExistingData, dataRect, dataRect);
2121 }
2122
2123 return true;
2124}
2125
2126template <class S>
2127void RecordedDrawTargetCreation::Record(S& aStream) const {
2128 WriteElement(aStream, mRefPtr);
2129 WriteElement(aStream, mBackendType);
2130 WriteElement(aStream, mRect);
2131 WriteElement(aStream, mFormat);
2132 WriteElement(aStream, mHasExistingData);
2133
2134 if (mHasExistingData) {
2135 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"
, 2135); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mExistingData"
")"); do { *((volatile int*)__null) = 2135; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2136 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"
, 2136); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mExistingData->GetSize() == mRect.Size()"
")"); do { *((volatile int*)__null) = 2136; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2137 RefPtr<DataSourceSurface> dataSurf = mExistingData->GetDataSurface();
2138
2139 DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ);
2140 for (int y = 0; y < mRect.height; y++) {
2141 aStream.write((const char*)map.GetData() + y * map.GetStride(),
2142 BytesPerPixel(mFormat) * mRect.width);
2143 }
2144 }
2145}
2146
2147template <class S>
2148RecordedDrawTargetCreation::RecordedDrawTargetCreation(S& aStream)
2149 : RecordedEventDerived(DRAWTARGETCREATION), mExistingData(nullptr) {
2150 ReadElement(aStream, mRefPtr);
2151 ReadElementConstrained(aStream, mBackendType, BackendType::NONE,
2152 BackendType::WEBRENDER_TEXT);
2153 ReadElement(aStream, mRect);
2154 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2155 SurfaceFormat::UNKNOWN);
2156 ReadElement(aStream, mHasExistingData);
2157
2158 if (mHasExistingData) {
2159 RefPtr<DataSourceSurface> dataSurf =
2160 Factory::CreateDataSourceSurface(mRect.Size(), mFormat);
2161 if (!dataSurf) {
2162 gfxWarningmozilla::gfx::WarningLog()
2163 << "RecordedDrawTargetCreation had to reset mHasExistingData";
2164 mHasExistingData = false;
2165 return;
2166 }
2167
2168 DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ);
2169 for (int y = 0; y < mRect.height; y++) {
2170 aStream.read((char*)map.GetData() + y * map.GetStride(),
2171 BytesPerPixel(mFormat) * mRect.width);
2172 }
2173 mExistingData = dataSurf;
2174 }
2175}
2176
2177inline void RecordedDrawTargetCreation::OutputSimpleEventInfo(
2178 std::stringstream& aStringStream) const {
2179 aStringStream << "[" << mRefPtr << "] DrawTarget Creation (Type: "
2180 << NameFromBackend(mBackendType) << ", Size: " << mRect.width
2181 << "x" << mRect.height << ")";
2182}
2183
2184inline bool RecordedDrawTargetDestruction::PlayEvent(
2185 Translator* aTranslator) const {
2186 aTranslator->RemoveDrawTarget(mRefPtr);
2187 return true;
2188}
2189
2190template <class S>
2191void RecordedDrawTargetDestruction::Record(S& aStream) const {
2192 WriteElement(aStream, mRefPtr);
2193}
2194
2195template <class S>
2196RecordedDrawTargetDestruction::RecordedDrawTargetDestruction(S& aStream)
2197 : RecordedEventDerived(DRAWTARGETDESTRUCTION) {
2198 ReadElement(aStream, mRefPtr);
2199}
2200
2201inline void RecordedDrawTargetDestruction::OutputSimpleEventInfo(
2202 std::stringstream& aStringStream) const {
2203 aStringStream << "[" << mRefPtr << "] DrawTarget Destruction";
2204}
2205
2206inline bool RecordedSetCurrentDrawTarget::PlayEvent(
2207 Translator* aTranslator) const {
2208 return aTranslator->SetCurrentDrawTarget(mRefPtr);
2209}
2210
2211template <class S>
2212void RecordedSetCurrentDrawTarget::Record(S& aStream) const {
2213 WriteElement(aStream, mRefPtr);
2214}
2215
2216template <class S>
2217RecordedSetCurrentDrawTarget::RecordedSetCurrentDrawTarget(S& aStream)
2218 : RecordedEventDerived(SETCURRENTDRAWTARGET) {
2219 ReadElement(aStream, mRefPtr);
2220}
2221
2222inline void RecordedSetCurrentDrawTarget::OutputSimpleEventInfo(
2223 std::stringstream& aStringStream) const {
2224 aStringStream << "[" << mRefPtr << "] SetCurrentDrawTarget";
2225}
2226
2227inline bool RecordedCreateSimilarDrawTarget::PlayEvent(
2228 Translator* aTranslator) const {
2229 DrawTarget* drawTarget = aTranslator->GetCurrentDrawTarget();
2230 if (!drawTarget) {
2231 return false;
2232 }
2233
2234 RefPtr<DrawTarget> newDT =
2235 drawTarget->CreateSimilarDrawTarget(mSize, mFormat);
2236
2237 // If we couldn't create a DrawTarget this will probably cause us to crash
2238 // with nullptr later in the playback, so return false to abort.
2239 if (!newDT) {
2240 return false;
2241 }
2242
2243 aTranslator->AddDrawTarget(mRefPtr, newDT);
2244 return true;
2245}
2246
2247template <class S>
2248void RecordedCreateSimilarDrawTarget::Record(S& aStream) const {
2249 WriteElement(aStream, mRefPtr);
2250 WriteElement(aStream, mSize);
2251 WriteElement(aStream, mFormat);
2252}
2253
2254template <class S>
2255RecordedCreateSimilarDrawTarget::RecordedCreateSimilarDrawTarget(S& aStream)
2256 : RecordedEventDerived(CREATESIMILARDRAWTARGET) {
2257 ReadElement(aStream, mRefPtr);
2258 ReadElement(aStream, mSize);
2259 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2260 SurfaceFormat::UNKNOWN);
2261}
2262
2263inline void RecordedCreateSimilarDrawTarget::OutputSimpleEventInfo(
2264 std::stringstream& aStringStream) const {
2265 aStringStream << "[" << mRefPtr
2266 << "] CreateSimilarDrawTarget (Size: " << mSize.width << "x"
2267 << mSize.height << ")";
2268}
2269
2270inline bool RecordedCreateDrawTargetForFilter::PlayEvent(
2271 Translator* aTranslator) const {
2272 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2273 if (!dt) {
2274 return false;
2275 }
2276
2277 IntRect baseRect = dt->GetRect();
2278
2279 auto maxRect = IntRect(IntPoint(0, 0), mMaxSize);
2280
2281 auto clone = dt->GetTransform();
2282 bool invertible = clone.Invert();
2283 // mSourceRect is in filter space. The filter outputs from mSourceRect need
2284 // to be drawn at mDestPoint in user space.
2285 Rect userSpaceSource = Rect(mDestPoint, mSourceRect.Size());
2286 if (invertible) {
2287 // Try to reduce the source rect so that it's not much bigger
2288 // than the draw target. The result is not minimal. Examples
2289 // are left as an exercise for the reader.
2290 auto destRect = IntRectToRect(baseRect);
2291 Rect userSpaceBounds = clone.TransformBounds(destRect);
2292 userSpaceSource = userSpaceSource.Intersect(userSpaceBounds);
2293 }
2294
2295 // Compute how much we moved the top-left of the source rect by, and use that
2296 // to compute the new dest point, and move our intersected source rect back
2297 // into the (new) filter space.
2298 Point shift = userSpaceSource.TopLeft() - mDestPoint;
2299 Rect filterSpaceSource =
2300 Rect(mSourceRect.TopLeft() + shift, userSpaceSource.Size());
2301
2302 baseRect = RoundedOut(filterSpaceSource);
2303 FilterNode* filter = aTranslator->LookupFilterNode(mFilter);
2304 if (!filter) {
2305 return false;
2306 }
2307
2308 IntRect transformedRect = filter->MapRectToSource(
2309 baseRect, maxRect, aTranslator->LookupFilterNode(mSource));
2310
2311 // Intersect with maxRect to make sure we didn't end up with something bigger
2312 transformedRect = transformedRect.Intersect(maxRect);
2313
2314 // If we end up with an empty rect make it 1x1 so that things don't break.
2315 if (transformedRect.IsEmpty()) {
2316 transformedRect = IntRect(0, 0, 1, 1);
2317 }
2318
2319 RefPtr<DrawTarget> newDT =
2320 dt->CreateSimilarDrawTarget(transformedRect.Size(), mFormat);
2321 if (!newDT) {
2322 return false;
2323 }
2324 newDT =
2325 gfx::Factory::CreateOffsetDrawTarget(newDT, transformedRect.TopLeft());
2326
2327 // If we couldn't create a DrawTarget this will probably cause us to crash
2328 // with nullptr later in the playback, so return false to abort.
2329 if (!newDT) {
2330 return false;
2331 }
2332
2333 aTranslator->AddDrawTarget(mRefPtr, newDT);
2334 return true;
2335}
2336
2337inline bool RecordedCreateClippedDrawTarget::PlayEvent(
2338 Translator* aTranslator) const {
2339 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2340 if (!dt) {
2341 return false;
2342 }
2343
2344 RefPtr<DrawTarget> newDT = dt->CreateClippedDrawTarget(mBounds, mFormat);
2345
2346 // If we couldn't create a DrawTarget this will probably cause us to crash
2347 // with nullptr later in the playback, so return false to abort.
2348 if (!newDT) {
2349 return false;
2350 }
2351
2352 aTranslator->AddDrawTarget(mRefPtr, newDT);
2353 return true;
2354}
2355
2356template <class S>
2357void RecordedCreateClippedDrawTarget::Record(S& aStream) const {
2358 WriteElement(aStream, mRefPtr);
2359 WriteElement(aStream, mBounds);
2360 WriteElement(aStream, mFormat);
2361}
2362
2363template <class S>
2364RecordedCreateClippedDrawTarget::RecordedCreateClippedDrawTarget(S& aStream)
2365 : RecordedEventDerived(CREATECLIPPEDDRAWTARGET) {
2366 ReadElement(aStream, mRefPtr);
2367 ReadElement(aStream, mBounds);
2368 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2369 SurfaceFormat::UNKNOWN);
2370}
2371
2372inline void RecordedCreateClippedDrawTarget::OutputSimpleEventInfo(
2373 std::stringstream& aStringStream) const {
2374 aStringStream << "[" << mRefPtr << "] CreateClippedDrawTarget ()";
2375}
2376
2377template <class S>
2378void RecordedCreateDrawTargetForFilter::Record(S& aStream) const {
2379 WriteElement(aStream, mRefPtr);
2380 WriteElement(aStream, mMaxSize);
2381 WriteElement(aStream, mFormat);
2382 WriteElement(aStream, mFilter);
2383 WriteElement(aStream, mSource);
2384 WriteElement(aStream, mSourceRect);
2385 WriteElement(aStream, mDestPoint);
2386}
2387
2388template <class S>
2389RecordedCreateDrawTargetForFilter::RecordedCreateDrawTargetForFilter(S& aStream)
2390 : RecordedEventDerived(CREATEDRAWTARGETFORFILTER) {
2391 ReadElement(aStream, mRefPtr);
2392 ReadElement(aStream, mMaxSize);
2393 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
2394 SurfaceFormat::UNKNOWN);
2395 ReadElement(aStream, mFilter);
2396 ReadElement(aStream, mSource);
2397 ReadElement(aStream, mSourceRect);
2398 ReadElement(aStream, mDestPoint);
2399}
2400
2401inline void RecordedCreateDrawTargetForFilter::OutputSimpleEventInfo(
2402 std::stringstream& aStringStream) const {
2403 aStringStream << "[" << mRefPtr << "] CreateDrawTargetForFilter ()";
2404}
2405
2406struct GenericPattern {
2407 GenericPattern(const PatternStorage& aStorage, Translator* aTranslator)
2408 : mPattern(nullptr), mTranslator(aTranslator) {
2409 mStorage = const_cast<PatternStorage*>(&aStorage);
2410 }
2411
2412 ~GenericPattern() {
2413 if (mPattern) {
2414 mPattern->~Pattern();
2415 }
2416 }
2417
2418 operator Pattern*() {
2419 switch (mStorage->mType) {
2420 case PatternType::COLOR:
2421 return new (mColPat) ColorPattern(
2422 reinterpret_cast<ColorPatternStorage*>(&mStorage->mStorage)
2423 ->mColor);
2424 case PatternType::SURFACE: {
2425 SurfacePatternStorage* storage =
2426 reinterpret_cast<SurfacePatternStorage*>(&mStorage->mStorage);
2427 mPattern = new (mSurfPat)
2428 SurfacePattern(mTranslator->LookupSourceSurface(storage->mSurface),
2429 storage->mExtend, storage->mMatrix,
2430 storage->mSamplingFilter, storage->mSamplingRect);
2431 return mPattern;
2432 }
2433 case PatternType::LINEAR_GRADIENT: {
2434 LinearGradientPatternStorage* storage =
2435 reinterpret_cast<LinearGradientPatternStorage*>(
2436 &mStorage->mStorage);
2437 mPattern = new (mLinGradPat) LinearGradientPattern(
2438 storage->mBegin, storage->mEnd,
2439 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2440 : nullptr,
2441 storage->mMatrix);
2442 return mPattern;
2443 }
2444 case PatternType::RADIAL_GRADIENT: {
2445 RadialGradientPatternStorage* storage =
2446 reinterpret_cast<RadialGradientPatternStorage*>(
2447 &mStorage->mStorage);
2448 mPattern = new (mRadGradPat) RadialGradientPattern(
2449 storage->mCenter1, storage->mCenter2, storage->mRadius1,
2450 storage->mRadius2,
2451 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2452 : nullptr,
2453 storage->mMatrix);
2454 return mPattern;
2455 }
2456 case PatternType::CONIC_GRADIENT: {
2457 ConicGradientPatternStorage* storage =
2458 reinterpret_cast<ConicGradientPatternStorage*>(&mStorage->mStorage);
2459 mPattern = new (mConGradPat) ConicGradientPattern(
2460 storage->mCenter, storage->mAngle, storage->mStartOffset,
2461 storage->mEndOffset,
2462 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops)
2463 : nullptr,
2464 storage->mMatrix);
2465 return mPattern;
2466 }
2467 default:
2468 return new (mColPat) ColorPattern(DeviceColor());
2469 }
2470
2471 return mPattern;
2472 }
2473
2474 union {
2475 char mColPat[sizeof(ColorPattern)];
2476 char mLinGradPat[sizeof(LinearGradientPattern)];
2477 char mRadGradPat[sizeof(RadialGradientPattern)];
2478 char mConGradPat[sizeof(ConicGradientPattern)];
2479 char mSurfPat[sizeof(SurfacePattern)];
2480 };
2481
2482 PatternStorage* mStorage;
2483 Pattern* mPattern;
2484 Translator* mTranslator;
2485};
2486
2487inline bool RecordedFillRect::PlayEvent(Translator* aTranslator) const {
2488 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2489 if (!dt) {
2490 return false;
2491 }
2492
2493 dt->FillRect(mRect, *GenericPattern(mPattern, aTranslator), mOptions);
2494 return true;
2495}
2496
2497template <class S>
2498void RecordedFillRect::Record(S& aStream) const {
2499 WriteElement(aStream, mRect);
2500 WriteElement(aStream, mOptions);
2501 RecordPatternData(aStream, mPattern);
2502}
2503
2504template <class S>
2505RecordedFillRect::RecordedFillRect(S& aStream)
2506 : RecordedEventDerived(FILLRECT) {
2507 ReadElement(aStream, mRect);
2508 ReadDrawOptions(aStream, mOptions);
2509 ReadPatternData(aStream, mPattern);
2510}
2511
2512inline void RecordedFillRect::OutputSimpleEventInfo(
2513 std::stringstream& aStringStream) const {
2514 aStringStream << "FillRect (" << mRect.X() << ", " << mRect.Y() << " - "
2515 << mRect.Width() << " x " << mRect.Height() << ") ";
2516 OutputSimplePatternInfo(mPattern, aStringStream);
2517}
2518
2519inline bool RecordedStrokeRect::PlayEvent(Translator* aTranslator) const {
2520 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2521 if (!dt) {
2522 return false;
2523 }
2524
2525 dt->StrokeRect(mRect, *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2526 mOptions);
2527 return true;
2528}
2529
2530template <class S>
2531void RecordedStrokeRect::Record(S& aStream) const {
2532 WriteElement(aStream, mRect);
2533 WriteElement(aStream, mOptions);
2534 RecordPatternData(aStream, mPattern);
2535 RecordStrokeOptions(aStream, mStrokeOptions);
2536}
2537
2538template <class S>
2539RecordedStrokeRect::RecordedStrokeRect(S& aStream)
2540 : RecordedEventDerived(STROKERECT) {
2541 ReadElement(aStream, mRect);
2542 ReadDrawOptions(aStream, mOptions);
2543 ReadPatternData(aStream, mPattern);
2544 ReadStrokeOptions(aStream, mStrokeOptions);
2545}
2546
2547inline void RecordedStrokeRect::OutputSimpleEventInfo(
2548 std::stringstream& aStringStream) const {
2549 aStringStream << "StrokeRect (" << mRect.X() << ", " << mRect.Y() << " - "
2550 << mRect.Width() << " x " << mRect.Height()
2551 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2552 OutputSimplePatternInfo(mPattern, aStringStream);
2553}
2554
2555inline bool RecordedStrokeLine::PlayEvent(Translator* aTranslator) const {
2556 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2557 if (!dt) {
2558 return false;
2559 }
2560
2561 dt->StrokeLine(mBegin, mEnd, *GenericPattern(mPattern, aTranslator),
2562 mStrokeOptions, mOptions);
2563 return true;
2564}
2565
2566template <class S>
2567void RecordedStrokeLine::Record(S& aStream) const {
2568 WriteElement(aStream, mBegin);
2569 WriteElement(aStream, mEnd);
2570 WriteElement(aStream, mOptions);
2571 RecordPatternData(aStream, mPattern);
2572 RecordStrokeOptions(aStream, mStrokeOptions);
2573}
2574
2575template <class S>
2576RecordedStrokeLine::RecordedStrokeLine(S& aStream)
2577 : RecordedEventDerived(STROKELINE) {
2578 ReadElement(aStream, mBegin);
2579 ReadElement(aStream, mEnd);
2580 ReadDrawOptions(aStream, mOptions);
2581 ReadPatternData(aStream, mPattern);
2582 ReadStrokeOptions(aStream, mStrokeOptions);
2583}
2584
2585inline void RecordedStrokeLine::OutputSimpleEventInfo(
2586 std::stringstream& aStringStream) const {
2587 aStringStream << "StrokeLine (" << mBegin.x << ", " << mBegin.y << " - "
2588 << mEnd.x << ", " << mEnd.y
2589 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2590 OutputSimplePatternInfo(mPattern, aStringStream);
2591}
2592
2593inline bool RecordedStrokeCircle::PlayEvent(Translator* aTranslator) const {
2594 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2595 if (!dt) {
2596 return false;
2597 }
2598
2599 dt->StrokeCircle(mCircle.origin, mCircle.radius,
2600 *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2601 mOptions);
2602 return true;
2603}
2604
2605template <class S>
2606void RecordedStrokeCircle::Record(S& aStream) const {
2607 WriteElement(aStream, mCircle);
2608 WriteElement(aStream, mOptions);
2609 RecordPatternData(aStream, mPattern);
2610 RecordStrokeOptions(aStream, mStrokeOptions);
2611}
2612
2613template <class S>
2614RecordedStrokeCircle::RecordedStrokeCircle(S& aStream)
2615 : RecordedEventDerived(STROKECIRCLE) {
2616 ReadElement(aStream, mCircle);
2617 ReadDrawOptions(aStream, mOptions);
2618 ReadPatternData(aStream, mPattern);
2619 ReadStrokeOptions(aStream, mStrokeOptions);
2620}
2621
2622inline void RecordedStrokeCircle::OutputSimpleEventInfo(
2623 std::stringstream& aStringStream) const {
2624 aStringStream << "StrokeCircle (" << mCircle.origin.x << ", "
2625 << mCircle.origin.y << " - " << mCircle.radius
2626 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2627 OutputSimplePatternInfo(mPattern, aStringStream);
2628}
2629
2630inline bool RecordedFill::PlayEvent(Translator* aTranslator) const {
2631 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2632 if (!dt) {
2633 return false;
2634 }
2635
2636 dt->Fill(aTranslator->LookupPath(mPath),
2637 *GenericPattern(mPattern, aTranslator), mOptions);
2638 return true;
2639}
2640
2641template <class S>
2642RecordedFill::RecordedFill(S& aStream) : RecordedEventDerived(FILL) {
2643 ReadElement(aStream, mPath);
2644 ReadDrawOptions(aStream, mOptions);
2645 ReadPatternData(aStream, mPattern);
2646}
2647
2648template <class S>
2649void RecordedFill::Record(S& aStream) const {
2650 WriteElement(aStream, mPath);
2651 WriteElement(aStream, mOptions);
2652 RecordPatternData(aStream, mPattern);
2653}
2654
2655inline void RecordedFill::OutputSimpleEventInfo(
2656 std::stringstream& aStringStream) const {
2657 aStringStream << "Fill (" << mPath << ") ";
2658 OutputSimplePatternInfo(mPattern, aStringStream);
2659}
2660
2661inline bool RecordedFillCircle::PlayEvent(Translator* aTranslator) const {
2662 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2663 if (!dt) {
2664 return false;
2665 }
2666
2667 dt->FillCircle(mCircle.origin, mCircle.radius,
2668 *GenericPattern(mPattern, aTranslator), mOptions);
2669 return true;
2670}
2671
2672template <class S>
2673void RecordedFillCircle::Record(S& aStream) const {
2674 WriteElement(aStream, mCircle);
2675 WriteElement(aStream, mOptions);
2676 RecordPatternData(aStream, mPattern);
2677}
2678
2679template <class S>
2680RecordedFillCircle::RecordedFillCircle(S& aStream)
2681 : RecordedEventDerived(FILLCIRCLE) {
2682 ReadElement(aStream, mCircle);
2683 ReadDrawOptions(aStream, mOptions);
2684 ReadPatternData(aStream, mPattern);
2685}
2686
2687inline void RecordedFillCircle::OutputSimpleEventInfo(
2688 std::stringstream& aStringStream) const {
2689 aStringStream << "FillCircle (" << mCircle.origin.x << ", "
2690 << mCircle.origin.y << " - " << mCircle.radius << ")";
2691 OutputSimplePatternInfo(mPattern, aStringStream);
2692}
2693
2694template <class T>
2695inline RecordedDrawGlyphs<T>::~RecordedDrawGlyphs() {
2696 delete[] mGlyphs;
2697}
2698
2699template <class T>
2700inline bool RecordedDrawGlyphs<T>::PlayEvent(Translator* aTranslator) const {
2701 if (mNumGlyphs > 0 && !mGlyphs) {
2702 // Glyph allocation failed
2703 return false;
2704 }
2705
2706 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2707 if (!dt) {
2708 return false;
2709 }
2710
2711 ScaledFont* scaledFont = aTranslator->LookupScaledFont(mScaledFont);
2712 if (!scaledFont) {
2713 return false;
2714 }
2715
2716 GlyphBuffer buffer;
2717 buffer.mGlyphs = mGlyphs;
2718 buffer.mNumGlyphs = mNumGlyphs;
2719 DrawGlyphs(dt, scaledFont, buffer, *GenericPattern(mPattern, aTranslator));
2720 return true;
2721}
2722
2723template <class T>
2724template <class S>
2725RecordedDrawGlyphs<T>::RecordedDrawGlyphs(RecordedEvent::EventType aType,
2726 S& aStream)
2727 : RecordedEventDerived<T>(aType) {
2728 ReadElement(aStream, mScaledFont);
2729 ReadDrawOptions(aStream, mOptions);
2730 this->ReadPatternData(aStream, mPattern);
2731 ReadElement(aStream, mNumGlyphs);
2732 if (!aStream.good() || mNumGlyphs <= 0) {
2733 return;
2734 }
2735
2736 mGlyphs = new (fallible) Glyph[mNumGlyphs];
2737 if (!mGlyphs) {
2738 gfxCriticalNotemozilla::gfx::CriticalLog(mozilla::gfx::CriticalLog::DefaultOptions
(false))
<< "RecordedDrawGlyphs failed to allocate glyphs of size "
2739 << mNumGlyphs;
2740 aStream.SetIsBad();
2741 } else {
2742 aStream.read((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
2743 }
2744}
2745
2746template <class T>
2747template <class S>
2748void RecordedDrawGlyphs<T>::Record(S& aStream) const {
2749 WriteElement(aStream, mScaledFont);
2750 WriteElement(aStream, mOptions);
2751 this->RecordPatternData(aStream, mPattern);
2752 WriteElement(aStream, mNumGlyphs);
2753 aStream.write((char*)mGlyphs, sizeof(Glyph) * mNumGlyphs);
2754}
2755
2756template <class T>
2757inline void RecordedDrawGlyphs<T>::OutputSimpleEventInfo(
2758 std::stringstream& aStringStream) const {
2759 aStringStream << this->GetName() << " (" << mScaledFont << ") ";
2760 this->OutputSimplePatternInfo(mPattern, aStringStream);
2761}
2762
2763inline bool RecordedMask::PlayEvent(Translator* aTranslator) const {
2764 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2765 if (!dt) {
2766 return false;
2767 }
2768
2769 dt->Mask(*GenericPattern(mSource, aTranslator),
2770 *GenericPattern(mMask, aTranslator), mOptions);
2771 return true;
2772}
2773
2774template <class S>
2775RecordedMask::RecordedMask(S& aStream) : RecordedEventDerived(MASK) {
2776 ReadDrawOptions(aStream, mOptions);
2777 ReadPatternData(aStream, mSource);
2778 ReadPatternData(aStream, mMask);
2779}
2780
2781template <class S>
2782void RecordedMask::Record(S& aStream) const {
2783 WriteElement(aStream, mOptions);
2784 RecordPatternData(aStream, mSource);
2785 RecordPatternData(aStream, mMask);
2786}
2787
2788inline void RecordedMask::OutputSimpleEventInfo(
2789 std::stringstream& aStringStream) const {
2790 aStringStream << "Mask (Source: ";
2791 OutputSimplePatternInfo(mSource, aStringStream);
2792 aStringStream << " Mask: ";
2793 OutputSimplePatternInfo(mMask, aStringStream);
2794}
2795
2796inline bool RecordedStroke::PlayEvent(Translator* aTranslator) const {
2797 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2798 if (!dt) {
2799 return false;
2800 }
2801
2802 Path* path = aTranslator->LookupPath(mPath);
2803 if (!path) {
2804 return false;
2805 }
2806
2807 dt->Stroke(path, *GenericPattern(mPattern, aTranslator), mStrokeOptions,
2808 mOptions);
2809 return true;
2810}
2811
2812template <class S>
2813void RecordedStroke::Record(S& aStream) const {
2814 WriteElement(aStream, mPath);
2815 WriteElement(aStream, mOptions);
2816 RecordPatternData(aStream, mPattern);
2817 RecordStrokeOptions(aStream, mStrokeOptions);
2818}
2819
2820template <class S>
2821RecordedStroke::RecordedStroke(S& aStream) : RecordedEventDerived(STROKE) {
2822 ReadElement(aStream, mPath);
2823 ReadDrawOptions(aStream, mOptions);
2824 ReadPatternData(aStream, mPattern);
2825 ReadStrokeOptions(aStream, mStrokeOptions);
2826}
2827
2828inline void RecordedStroke::OutputSimpleEventInfo(
2829 std::stringstream& aStringStream) const {
2830 aStringStream << "Stroke (" << mPath
2831 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px ";
2832 OutputSimplePatternInfo(mPattern, aStringStream);
2833}
2834
2835inline bool RecordedClearRect::PlayEvent(Translator* aTranslator) const {
2836 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2837 if (!dt) {
2838 return false;
2839 }
2840
2841 dt->ClearRect(mRect);
2842 return true;
2843}
2844
2845template <class S>
2846void RecordedClearRect::Record(S& aStream) const {
2847 WriteElement(aStream, mRect);
2848}
2849
2850template <class S>
2851RecordedClearRect::RecordedClearRect(S& aStream)
2852 : RecordedEventDerived(CLEARRECT) {
2853 ReadElement(aStream, mRect);
2854}
2855
2856inline void RecordedClearRect::OutputSimpleEventInfo(
2857 std::stringstream& aStringStream) const {
2858 aStringStream << "ClearRect (" << mRect.X() << ", " << mRect.Y() << " - "
2859 << mRect.Width() << " x " << mRect.Height() << ") ";
2860}
2861
2862inline bool RecordedCopySurface::PlayEvent(Translator* aTranslator) const {
2863 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2864 if (!dt) {
2865 return false;
2866 }
2867
2868 SourceSurface* surface = aTranslator->LookupSourceSurface(mSourceSurface);
2869 if (!surface) {
2870 return false;
2871 }
2872
2873 dt->CopySurface(surface, mSourceRect, mDest);
2874 return true;
2875}
2876
2877template <class S>
2878void RecordedCopySurface::Record(S& aStream) const {
2879 WriteElement(aStream, mSourceSurface);
2880 WriteElement(aStream, mSourceRect);
2881 WriteElement(aStream, mDest);
2882}
2883
2884template <class S>
2885RecordedCopySurface::RecordedCopySurface(S& aStream)
2886 : RecordedEventDerived(COPYSURFACE) {
2887 ReadElement(aStream, mSourceSurface);
2888 ReadElement(aStream, mSourceRect);
2889 ReadElement(aStream, mDest);
2890}
2891
2892inline void RecordedCopySurface::OutputSimpleEventInfo(
2893 std::stringstream& aStringStream) const {
2894 aStringStream << "CopySurface (" << mSourceSurface << ")";
2895}
2896
2897inline bool RecordedPushClip::PlayEvent(Translator* aTranslator) const {
2898 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2899 if (!dt) {
2900 return false;
2901 }
2902
2903 Path* path = aTranslator->LookupPath(mPath);
2904 if (!path) {
2905 return false;
2906 }
2907
2908 dt->PushClip(path);
2909 return true;
2910}
2911
2912template <class S>
2913void RecordedPushClip::Record(S& aStream) const {
2914 WriteElement(aStream, mPath);
2915}
2916
2917template <class S>
2918RecordedPushClip::RecordedPushClip(S& aStream)
2919 : RecordedEventDerived(PUSHCLIP) {
2920 ReadElement(aStream, mPath);
2921}
2922
2923inline void RecordedPushClip::OutputSimpleEventInfo(
2924 std::stringstream& aStringStream) const {
2925 aStringStream << "PushClip (" << mPath << ") ";
2926}
2927
2928inline bool RecordedPushClipRect::PlayEvent(Translator* aTranslator) const {
2929 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2930 if (!dt) {
2931 return false;
2932 }
2933
2934 dt->PushClipRect(mRect);
2935 return true;
2936}
2937
2938template <class S>
2939void RecordedPushClipRect::Record(S& aStream) const {
2940 WriteElement(aStream, mRect);
2941}
2942
2943template <class S>
2944RecordedPushClipRect::RecordedPushClipRect(S& aStream)
2945 : RecordedEventDerived(PUSHCLIPRECT) {
2946 ReadElement(aStream, mRect);
2947}
2948
2949inline void RecordedPushClipRect::OutputSimpleEventInfo(
2950 std::stringstream& aStringStream) const {
2951 aStringStream << "PushClipRect (" << mRect.X() << ", " << mRect.Y() << " - "
2952 << mRect.Width() << " x " << mRect.Height() << ") ";
2953}
2954
2955inline bool RecordedPopClip::PlayEvent(Translator* aTranslator) const {
2956 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2957 if (!dt) {
2958 return false;
2959 }
2960
2961 dt->PopClip();
2962 return true;
2963}
2964
2965template <class S>
2966void RecordedPopClip::Record(S& aStream) const {}
2967
2968template <class S>
2969RecordedPopClip::RecordedPopClip(S& aStream) : RecordedEventDerived(POPCLIP) {}
2970
2971inline void RecordedPopClip::OutputSimpleEventInfo(
2972 std::stringstream& aStringStream) const {
2973 aStringStream << "PopClip";
2974}
2975
2976inline bool RecordedPushLayer::PlayEvent(Translator* aTranslator) const {
2977 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
2978 if (!dt) {
2979 return false;
2980 }
2981
2982 SourceSurface* mask =
2983 mMask ? aTranslator->LookupSourceSurface(mMask) : nullptr;
2984 dt->PushLayer(mOpaque, mOpacity, mask, mMaskTransform, mBounds,
2985 mCopyBackground);
2986 return true;
2987}
2988
2989template <class S>
2990void RecordedPushLayer::Record(S& aStream) const {
2991 WriteElement(aStream, mOpaque);
2992 WriteElement(aStream, mOpacity);
2993 WriteElement(aStream, mMask);
2994 WriteElement(aStream, mMaskTransform);
2995 WriteElement(aStream, mBounds);
2996 WriteElement(aStream, mCopyBackground);
2997}
2998
2999template <class S>
3000RecordedPushLayer::RecordedPushLayer(S& aStream)
3001 : RecordedEventDerived(PUSHLAYER) {
3002 ReadElement(aStream, mOpaque);
3003 ReadElement(aStream, mOpacity);
3004 ReadElement(aStream, mMask);
3005 ReadElement(aStream, mMaskTransform);
3006 ReadElement(aStream, mBounds);
3007 ReadElement(aStream, mCopyBackground);
3008}
3009
3010inline void RecordedPushLayer::OutputSimpleEventInfo(
3011 std::stringstream& aStringStream) const {
3012 aStringStream << "PushPLayer (Opaque=" << mOpaque << ", Opacity=" << mOpacity
3013 << ", Mask Ref=" << mMask << ") ";
3014}
3015
3016inline bool RecordedPushLayerWithBlend::PlayEvent(
3017 Translator* aTranslator) const {
3018 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3019 if (!dt) {
3020 return false;
3021 }
3022
3023 SourceSurface* mask =
3024 mMask ? aTranslator->LookupSourceSurface(mMask) : nullptr;
3025 dt->PushLayerWithBlend(mOpaque, mOpacity, mask, mMaskTransform, mBounds,
3026 mCopyBackground, mCompositionOp);
3027 return true;
3028}
3029
3030template <class S>
3031void RecordedPushLayerWithBlend::Record(S& aStream) const {
3032 WriteElement(aStream, mOpaque);
3033 WriteElement(aStream, mOpacity);
3034 WriteElement(aStream, mMask);
3035 WriteElement(aStream, mMaskTransform);
3036 WriteElement(aStream, mBounds);
3037 WriteElement(aStream, mCopyBackground);
3038 WriteElement(aStream, mCompositionOp);
3039}
3040
3041template <class S>
3042RecordedPushLayerWithBlend::RecordedPushLayerWithBlend(S& aStream)
3043 : RecordedEventDerived(PUSHLAYERWITHBLEND) {
3044 ReadElement(aStream, mOpaque);
3045 ReadElement(aStream, mOpacity);
3046 ReadElement(aStream, mMask);
3047 ReadElement(aStream, mMaskTransform);
3048 ReadElement(aStream, mBounds);
3049 ReadElement(aStream, mCopyBackground);
3050 ReadElementConstrained(aStream, mCompositionOp, CompositionOp::OP_OVER,
3051 CompositionOp::OP_COUNT);
3052}
3053
3054inline void RecordedPushLayerWithBlend::OutputSimpleEventInfo(
3055 std::stringstream& aStringStream) const {
3056 aStringStream << "PushLayerWithBlend (Opaque=" << mOpaque
3057 << ", Opacity=" << mOpacity << ", Mask Ref=" << mMask << ") ";
3058}
3059
3060inline bool RecordedPopLayer::PlayEvent(Translator* aTranslator) const {
3061 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3062 if (!dt) {
3063 return false;
3064 }
3065
3066 dt->PopLayer();
3067 return true;
3068}
3069
3070template <class S>
3071void RecordedPopLayer::Record(S& aStream) const {}
3072
3073template <class S>
3074RecordedPopLayer::RecordedPopLayer(S& aStream)
3075 : RecordedEventDerived(POPLAYER) {}
3076
3077inline void RecordedPopLayer::OutputSimpleEventInfo(
3078 std::stringstream& aStringStream) const {
3079 aStringStream << "PopLayer";
3080}
3081
3082inline bool RecordedSetPermitSubpixelAA::PlayEvent(
3083 Translator* aTranslator) const {
3084 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3085 if (!dt) {
3086 return false;
3087 }
3088
3089 dt->SetPermitSubpixelAA(mPermitSubpixelAA);
3090 return true;
3091}
3092
3093template <class S>
3094void RecordedSetPermitSubpixelAA::Record(S& aStream) const {
3095 WriteElement(aStream, mPermitSubpixelAA);
3096}
3097
3098template <class S>
3099RecordedSetPermitSubpixelAA::RecordedSetPermitSubpixelAA(S& aStream)
3100 : RecordedEventDerived(SETPERMITSUBPIXELAA) {
3101 ReadElement(aStream, mPermitSubpixelAA);
3102}
3103
3104inline void RecordedSetPermitSubpixelAA::OutputSimpleEventInfo(
3105 std::stringstream& aStringStream) const {
3106 aStringStream << "SetPermitSubpixelAA (" << mPermitSubpixelAA << ")";
3107}
3108
3109inline bool RecordedSetTransform::PlayEvent(Translator* aTranslator) const {
3110 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3111 if (!dt) {
3112 return false;
3113 }
3114
3115 // If we're drawing to the reference DT, then we need to manually apply
3116 // its initial transform, otherwise we'll just clobber it with only the
3117 // the transform that was visible to the code doing the recording.
3118 if (dt == aTranslator->GetReferenceDrawTarget()) {
3119 dt->SetTransform(mTransform *
3120 aTranslator->GetReferenceDrawTargetTransform());
3121 } else {
3122 dt->SetTransform(mTransform);
3123 }
3124
3125 return true;
3126}
3127
3128template <class S>
3129void RecordedSetTransform::Record(S& aStream) const {
3130 WriteElement(aStream, mTransform);
3131}
3132
3133template <class S>
3134RecordedSetTransform::RecordedSetTransform(S& aStream)
3135 : RecordedEventDerived(SETTRANSFORM) {
3136 ReadElement(aStream, mTransform);
3137}
3138
3139inline void RecordedSetTransform::OutputSimpleEventInfo(
3140 std::stringstream& aStringStream) const {
3141 aStringStream << "SetTransform [ " << mTransform._11 << " " << mTransform._12
3142 << " ; " << mTransform._21 << " " << mTransform._22 << " ; "
3143 << mTransform._31 << " " << mTransform._32 << " ]";
3144}
3145
3146inline bool RecordedDrawSurface::PlayEvent(Translator* aTranslator) const {
3147 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3148 if (!dt) {
3149 return false;
3150 }
3151
3152 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefSource);
3153 if (!surface) {
3154 return false;
3155 }
3156
3157 dt->DrawSurface(surface, mDest, mSource, mDSOptions, mOptions);
3158 return true;
3159}
3160
3161template <class S>
3162void RecordedDrawSurface::Record(S& aStream) const {
3163 WriteElement(aStream, mRefSource);
3164 WriteElement(aStream, mDest);
3165 WriteElement(aStream, mSource);
3166 WriteElement(aStream, mDSOptions);
3167 WriteElement(aStream, mOptions);
3168}
3169
3170template <class S>
3171RecordedDrawSurface::RecordedDrawSurface(S& aStream)
3172 : RecordedEventDerived(DRAWSURFACE) {
3173 ReadElement(aStream, mRefSource);
3174 ReadElement(aStream, mDest);
3175 ReadElement(aStream, mSource);
3176 ReadDrawSurfaceOptions(aStream, mDSOptions);
3177 ReadDrawOptions(aStream, mOptions);
3178}
3179
3180inline void RecordedDrawSurface::OutputSimpleEventInfo(
3181 std::stringstream& aStringStream) const {
3182 aStringStream << "DrawSurface (" << mRefSource << ")";
3183}
3184
3185inline bool RecordedDrawSurfaceDescriptor::PlayEvent(
3186 Translator* aTranslator) const {
3187 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3188 if (!dt) {
3189 return false;
3190 }
3191
3192 RefPtr<SourceSurface> surface =
3193 aTranslator->LookupSourceSurfaceFromSurfaceDescriptor(mDesc);
3194 if (!surface) {
3195 return false;
3196 }
3197
3198 RefPtr<SourceSurface> opt = dt->OptimizeSourceSurface(surface);
3199 if (opt) {
3200 surface = opt;
3201 }
3202
3203 dt->DrawSurface(surface, mDest, mSource, mDSOptions, mOptions);
3204 return true;
3205}
3206
3207template <class S>
3208void RecordedDrawSurfaceDescriptor::Record(S& aStream) const {
3209 WriteElement(aStream, mDesc);
3210 WriteElement(aStream, mDest);
3211 WriteElement(aStream, mSource);
3212 WriteElement(aStream, mDSOptions);
3213 WriteElement(aStream, mOptions);
3214}
3215
3216template <class S>
3217RecordedDrawSurfaceDescriptor::RecordedDrawSurfaceDescriptor(S& aStream)
3218 : RecordedEventDerived(DRAWSURFACEDESCRIPTOR) {
3219 ReadElement(aStream, mDesc);
3220 ReadElement(aStream, mDest);
3221 ReadElement(aStream, mSource);
3222 ReadDrawSurfaceOptions(aStream, mDSOptions);
3223 ReadDrawOptions(aStream, mOptions);
3224}
3225
3226inline void RecordedDrawSurfaceDescriptor::OutputSimpleEventInfo(
3227 std::stringstream& aStringStream) const {
3228 aStringStream << "DrawSurfaceDescriptor (" << mDesc.type() << ")";
3229}
3230
3231inline bool RecordedDrawDependentSurface::PlayEvent(
3232 Translator* aTranslator) const {
3233 aTranslator->DrawDependentSurface(mId, mDest);
3234 return true;
3235}
3236
3237template <class S>
3238void RecordedDrawDependentSurface::Record(S& aStream) const {
3239 WriteElement(aStream, mId);
3240 WriteElement(aStream, mDest);
3241}
3242
3243template <class S>
3244RecordedDrawDependentSurface::RecordedDrawDependentSurface(S& aStream)
3245 : RecordedEventDerived(DRAWDEPENDENTSURFACE) {
3246 ReadElement(aStream, mId);
3247 ReadElement(aStream, mDest);
3248}
3249
3250inline void RecordedDrawDependentSurface::OutputSimpleEventInfo(
3251 std::stringstream& aStringStream) const {
3252 aStringStream << "DrawDependentSurface (" << mId << ")";
3253}
3254
3255inline bool RecordedDrawFilter::PlayEvent(Translator* aTranslator) const {
3256 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3257 if (!dt) {
3258 return false;
3259 }
3260
3261 FilterNode* filter = aTranslator->LookupFilterNode(mNode);
3262 if (!filter) {
3263 return false;
3264 }
3265
3266 dt->DrawFilter(filter, mSourceRect, mDestPoint, mOptions);
3267 return true;
3268}
3269
3270template <class S>
3271void RecordedDrawFilter::Record(S& aStream) const {
3272 WriteElement(aStream, mNode);
3273 WriteElement(aStream, mSourceRect);
3274 WriteElement(aStream, mDestPoint);
3275 WriteElement(aStream, mOptions);
3276}
3277
3278template <class S>
3279RecordedDrawFilter::RecordedDrawFilter(S& aStream)
3280 : RecordedEventDerived(DRAWFILTER) {
3281 ReadElement(aStream, mNode);
3282 ReadElement(aStream, mSourceRect);
3283 ReadElement(aStream, mDestPoint);
3284 ReadDrawOptions(aStream, mOptions);
3285}
3286
3287inline void RecordedDrawFilter::OutputSimpleEventInfo(
3288 std::stringstream& aStringStream) const {
3289 aStringStream << "DrawFilter (" << mNode << ")";
3290}
3291
3292inline bool RecordedDrawSurfaceWithShadow::PlayEvent(
3293 Translator* aTranslator) const {
3294 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3295 if (!dt) {
3296 return false;
3297 }
3298
3299 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefSource);
3300 if (!surface) {
3301 return false;
3302 }
3303
3304 dt->DrawSurfaceWithShadow(surface, mDest, mShadow, mOp);
3305 return true;
3306}
3307
3308template <class S>
3309void RecordedDrawSurfaceWithShadow::Record(S& aStream) const {
3310 WriteElement(aStream, mRefSource);
3311 WriteElement(aStream, mDest);
3312 WriteElement(aStream, mShadow);
3313 WriteElement(aStream, mOp);
3314}
3315
3316template <class S>
3317RecordedDrawSurfaceWithShadow::RecordedDrawSurfaceWithShadow(S& aStream)
3318 : RecordedEventDerived(DRAWSURFACEWITHSHADOW) {
3319 ReadElement(aStream, mRefSource);
3320 ReadElement(aStream, mDest);
3321 ReadElement(aStream, mShadow);
3322 ReadElementConstrained(aStream, mOp, CompositionOp::OP_OVER,
3323 CompositionOp::OP_COUNT);
3324}
3325
3326inline void RecordedDrawSurfaceWithShadow::OutputSimpleEventInfo(
3327 std::stringstream& aStringStream) const {
3328 aStringStream << "DrawSurfaceWithShadow (" << mRefSource << ") DeviceColor: ("
3329 << mShadow.mColor.r << ", " << mShadow.mColor.g << ", "
3330 << mShadow.mColor.b << ", " << mShadow.mColor.a << ")";
3331}
3332
3333inline bool RecordedDrawShadow::PlayEvent(Translator* aTranslator) const {
3334 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3335 if (!dt) {
3336 return false;
3337 }
3338
3339 Path* path = aTranslator->LookupPath(mPath);
3340 if (!path) {
3341 return false;
3342 }
3343
3344 dt->DrawShadow(path, *GenericPattern(mPattern, aTranslator), mShadow,
3345 mOptions, mHasStrokeOptions ? &mStrokeOptions : nullptr);
3346 return true;
3347}
3348
3349template <class S>
3350void RecordedDrawShadow::Record(S& aStream) const {
3351 WriteElement(aStream, mPath);
3352 RecordPatternData(aStream, mPattern);
3353 WriteElement(aStream, mShadow);
3354 WriteElement(aStream, mOptions);
3355 WriteElement(aStream, mHasStrokeOptions);
3356 if (mHasStrokeOptions) {
3357 RecordStrokeOptions(aStream, mStrokeOptions);
3358 }
3359}
3360
3361template <class S>
3362RecordedDrawShadow::RecordedDrawShadow(S& aStream)
3363 : RecordedEventDerived(DRAWSHADOW) {
3364 ReadElement(aStream, mPath);
3365 ReadPatternData(aStream, mPattern);
3366 ReadElement(aStream, mShadow);
3367 ReadDrawOptions(aStream, mOptions);
3368 ReadElement(aStream, mHasStrokeOptions);
3369 if (mHasStrokeOptions) {
3370 ReadStrokeOptions(aStream, mStrokeOptions);
3371 }
3372}
3373
3374inline void RecordedDrawShadow::OutputSimpleEventInfo(
3375 std::stringstream& aStringStream) const {
3376 aStringStream << "DrawShadow (" << mPath << ") DeviceColor: ("
3377 << mShadow.mColor.r << ", " << mShadow.mColor.g << ", "
3378 << mShadow.mColor.b << ", " << mShadow.mColor.a << ")";
3379}
3380
3381inline RecordedPathCreation::RecordedPathCreation(PathRecording* aPath)
3382 : RecordedEventDerived(PATHCREATION),
3383 mRefPtr(aPath),
3384 mFillRule(aPath->mFillRule),
3385 mPath(aPath) {}
3386
3387inline bool RecordedPathCreation::PlayEvent(Translator* aTranslator) const {
3388 DrawTarget* drawTarget = aTranslator->GetCurrentDrawTarget();
3389 if (!drawTarget) {
3390 return false;
3391 }
3392
3393 RefPtr<PathBuilder> builder = drawTarget->CreatePathBuilder(mFillRule);
3394 if (!mPathOps->CheckedStreamToSink(*builder)) {
3395 return false;
3396 }
3397
3398 RefPtr<Path> path = builder->Finish();
3399 aTranslator->AddPath(mRefPtr, path);
3400 return true;
3401}
3402
3403template <class S>
3404void RecordedPathCreation::Record(S& aStream) const {
3405 WriteElement(aStream, mRefPtr);
3406 WriteElement(aStream, mFillRule);
3407 mPath->mPathOps.Record(aStream);
3408}
3409
3410template <class S>
3411RecordedPathCreation::RecordedPathCreation(S& aStream)
3412 : RecordedEventDerived(PATHCREATION) {
3413 ReadElement(aStream, mRefPtr);
3414 ReadElementConstrained(aStream, mFillRule, FillRule::FILL_WINDING,
3415 FillRule::FILL_EVEN_ODD);
3416 mPathOps = MakeUnique<PathOps>(aStream);
3417}
3418
3419inline void RecordedPathCreation::OutputSimpleEventInfo(
3420 std::stringstream& aStringStream) const {
3421 size_t numberOfOps =
3422 mPath ? mPath->mPathOps.NumberOfOps() : mPathOps->NumberOfOps();
3423 aStringStream << "[" << mRefPtr << "] Path created (OpCount: " << numberOfOps
3424 << ")";
3425}
3426inline bool RecordedPathDestruction::PlayEvent(Translator* aTranslator) const {
3427 aTranslator->RemovePath(mRefPtr);
3428 return true;
3429}
3430
3431template <class S>
3432void RecordedPathDestruction::Record(S& aStream) const {
3433 WriteElement(aStream, mRefPtr);
3434}
3435
3436template <class S>
3437RecordedPathDestruction::RecordedPathDestruction(S& aStream)
3438 : RecordedEventDerived(PATHDESTRUCTION) {
3439 ReadElement(aStream, mRefPtr);
3440}
3441
3442inline void RecordedPathDestruction::OutputSimpleEventInfo(
3443 std::stringstream& aStringStream) const {
3444 aStringStream << "[" << mRefPtr << "] Path Destroyed";
3445}
3446
3447inline RecordedSourceSurfaceCreation::~RecordedSourceSurfaceCreation() {
3448 if (mDataOwned) {
3449 delete[] mData;
3450 }
3451}
3452
3453inline bool RecordedSourceSurfaceCreation::PlayEvent(
3454 Translator* aTranslator) const {
3455 if (!mData) {
3456 return false;
3457 }
3458
3459 RefPtr<SourceSurface> src = Factory::CreateWrappingDataSourceSurface(
3460 mData, mSize.width * BytesPerPixel(mFormat), mSize, mFormat,
3461 [](void* aClosure) { delete[] static_cast<uint8_t*>(aClosure); }, mData);
3462 if (src) {
3463 mDataOwned = false;
3464 }
3465
3466 aTranslator->AddSourceSurface(mRefPtr, src);
3467 return true;
3468}
3469
3470template <class S>
3471void RecordedSourceSurfaceCreation::Record(S& aStream) const {
3472 WriteElement(aStream, mRefPtr);
3473 WriteElement(aStream, mSize);
3474 WriteElement(aStream, mFormat);
3475 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"
, 3475); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mData" ")")
; do { *((volatile int*)__null) = 3475; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3476 size_t dataFormatWidth = BytesPerPixel(mFormat) * mSize.width;
3477 const char* endSrc = (const char*)(mData + (mSize.height * mStride));
3478 for (const char* src = (const char*)mData; src < endSrc; src += mStride) {
3479 aStream.write(src, dataFormatWidth);
3480 }
3481}
3482
3483template <class S>
3484RecordedSourceSurfaceCreation::RecordedSourceSurfaceCreation(S& aStream)
3485 : RecordedEventDerived(SOURCESURFACECREATION), mDataOwned(true) {
3486 ReadElement(aStream, mRefPtr);
3487 ReadElement(aStream, mSize);
3488 ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
3489 SurfaceFormat::UNKNOWN);
3490
3491 if (!Factory::AllowedSurfaceSize(mSize)) {
3492 gfxCriticalNotemozilla::gfx::CriticalLog(mozilla::gfx::CriticalLog::DefaultOptions
(false))
<< "RecordedSourceSurfaceCreation read invalid size "
3493 << mSize;
3494 aStream.SetIsBad();
3495 }
3496
3497 if (!aStream.good()) {
3498 return;
3499 }
3500
3501 size_t size = 0;
3502 if (mSize.width >= 0 && mSize.height >= 0) {
3503 size = size_t(mSize.width) * size_t(mSize.height) * BytesPerPixel(mFormat);
3504 mData = new (fallible) uint8_t[size];
3505 }
3506 if (!mData) {
3507 gfxCriticalNotemozilla::gfx::CriticalLog(mozilla::gfx::CriticalLog::DefaultOptions
(false))
3508 << "RecordedSourceSurfaceCreation failed to allocate data of size "
3509 << size;
3510 aStream.SetIsBad();
3511 } else {
3512 aStream.read((char*)mData, size);
3513 }
3514}
3515
3516inline void RecordedSourceSurfaceCreation::OutputSimpleEventInfo(
3517 std::stringstream& aStringStream) const {
3518 aStringStream << "[" << mRefPtr
3519 << "] SourceSurface created (Size: " << mSize.width << "x"
3520 << mSize.height << ")";
3521}
3522
3523inline bool RecordedSourceSurfaceDestruction::PlayEvent(
3524 Translator* aTranslator) const {
3525 aTranslator->RemoveSourceSurface(mRefPtr);
3526 return true;
3527}
3528
3529template <class S>
3530void RecordedSourceSurfaceDestruction::Record(S& aStream) const {
3531 WriteElement(aStream, mRefPtr);
3532}
3533
3534template <class S>
3535RecordedSourceSurfaceDestruction::RecordedSourceSurfaceDestruction(S& aStream)
3536 : RecordedEventDerived(SOURCESURFACEDESTRUCTION) {
3537 ReadElement(aStream, mRefPtr);
3538}
3539
3540inline void RecordedSourceSurfaceDestruction::OutputSimpleEventInfo(
3541 std::stringstream& aStringStream) const {
3542 aStringStream << "[" << mRefPtr << "] SourceSurface Destroyed";
3543}
3544
3545inline bool RecordedOptimizeSourceSurface::PlayEvent(
3546 Translator* aTranslator) const {
3547 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3548 if (!dt) {
3549 return false;
3550 }
3551
3552 SourceSurface* surface = aTranslator->LookupSourceSurface(mSurface);
3553 if (!surface) {
3554 return false;
3555 }
3556
3557 RefPtr<SourceSurface> optimizedSurface = dt->OptimizeSourceSurface(surface);
3558 aTranslator->AddSourceSurface(mOptimizedSurface, optimizedSurface);
3559 return true;
3560}
3561
3562template <class S>
3563void RecordedOptimizeSourceSurface::Record(S& aStream) const {
3564 WriteElement(aStream, mSurface);
3565 WriteElement(aStream, mOptimizedSurface);
3566}
3567
3568template <class S>
3569RecordedOptimizeSourceSurface::RecordedOptimizeSourceSurface(S& aStream)
3570 : RecordedEventDerived(OPTIMIZESOURCESURFACE) {
3571 ReadElement(aStream, mSurface);
3572 ReadElement(aStream, mOptimizedSurface);
3573}
3574
3575inline void RecordedOptimizeSourceSurface::OutputSimpleEventInfo(
3576 std::stringstream& aStringStream) const {
3577 aStringStream << "[" << mSurface << "] Surface Optimized";
3578}
3579
3580inline bool RecordedExternalSurfaceCreation::PlayEvent(
3581 Translator* aTranslator) const {
3582 RefPtr<SourceSurface> surface = aTranslator->LookupExternalSurface(mKey);
3583 if (!surface) {
3584 return false;
3585 }
3586
3587 aTranslator->AddSourceSurface(mRefPtr, surface);
3588 return true;
3589}
3590
3591template <class S>
3592void RecordedExternalSurfaceCreation::Record(S& aStream) const {
3593 WriteElement(aStream, mRefPtr);
3594 WriteElement(aStream, mKey);
3595}
3596
3597template <class S>
3598RecordedExternalSurfaceCreation::RecordedExternalSurfaceCreation(S& aStream)
3599 : RecordedEventDerived(EXTERNALSURFACECREATION) {
3600 ReadElement(aStream, mRefPtr);
3601 ReadElement(aStream, mKey);
3602}
3603
3604inline void RecordedExternalSurfaceCreation::OutputSimpleEventInfo(
3605 std::stringstream& aStringStream) const {
3606 aStringStream << "[" << mRefPtr
3607 << "] SourceSurfaceSharedData created (Key: " << mKey << ")";
3608}
3609
3610inline RecordedFilterNodeCreation::~RecordedFilterNodeCreation() = default;
3611
3612inline bool RecordedFilterNodeCreation::PlayEvent(
3613 Translator* aTranslator) const {
3614 DrawTarget* drawTarget = aTranslator->GetCurrentDrawTarget();
3615 if (!drawTarget) {
3616 return false;
3617 }
3618
3619 RefPtr<FilterNode> node = drawTarget->CreateFilter(mType);
3620 aTranslator->AddFilterNode(mRefPtr, node);
3621 return true;
3622}
3623
3624template <class S>
3625void RecordedFilterNodeCreation::Record(S& aStream) const {
3626 WriteElement(aStream, mRefPtr);
3627 WriteElement(aStream, mType);
3628}
3629
3630template <class S>
3631RecordedFilterNodeCreation::RecordedFilterNodeCreation(S& aStream)
3632 : RecordedEventDerived(FILTERNODECREATION) {
3633 ReadElement(aStream, mRefPtr);
3634 ReadElementConstrained(aStream, mType, FilterType::BLEND,
3635 FilterType::OPACITY);
3636}
3637
3638inline void RecordedFilterNodeCreation::OutputSimpleEventInfo(
3639 std::stringstream& aStringStream) const {
3640 aStringStream << "CreateFilter [" << mRefPtr
3641 << "] FilterNode created (Type: " << int(mType) << ")";
3642}
3643
3644inline bool RecordedFilterNodeDestruction::PlayEvent(
3645 Translator* aTranslator) const {
3646 aTranslator->RemoveFilterNode(mRefPtr);
3647 return true;
3648}
3649
3650template <class S>
3651void RecordedFilterNodeDestruction::Record(S& aStream) const {
3652 WriteElement(aStream, mRefPtr);
3653}
3654
3655template <class S>
3656RecordedFilterNodeDestruction::RecordedFilterNodeDestruction(S& aStream)
3657 : RecordedEventDerived(FILTERNODEDESTRUCTION) {
3658 ReadElement(aStream, mRefPtr);
3659}
3660
3661inline void RecordedFilterNodeDestruction::OutputSimpleEventInfo(
3662 std::stringstream& aStringStream) const {
3663 aStringStream << "[" << mRefPtr << "] FilterNode Destroyed";
3664}
3665
3666inline RecordedGradientStopsCreation::~RecordedGradientStopsCreation() {
3667 if (mDataOwned) {
3668 delete[] mStops;
3669 }
3670}
3671
3672inline bool RecordedGradientStopsCreation::PlayEvent(
3673 Translator* aTranslator) const {
3674 if (mNumStops > 0 && !mStops) {
3675 // Stops allocation failed
3676 return false;
3677 }
3678
3679 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3680 if (!dt) {
3681 return false;
3682 }
3683
3684 RefPtr<GradientStops> src =
3685 aTranslator->GetOrCreateGradientStops(dt, mStops, mNumStops, mExtendMode);
3686 aTranslator->AddGradientStops(mRefPtr, src);
3687 return true;
3688}
3689
3690template <class S>
3691void RecordedGradientStopsCreation::Record(S& aStream) const {
3692 WriteElement(aStream, mRefPtr);
3693 WriteElement(aStream, mExtendMode);
3694 WriteElement(aStream, mNumStops);
3695 aStream.write((const char*)mStops, mNumStops * sizeof(GradientStop));
3696}
3697
3698template <class S>
3699RecordedGradientStopsCreation::RecordedGradientStopsCreation(S& aStream)
3700 : RecordedEventDerived(GRADIENTSTOPSCREATION), mDataOwned(true) {
3701 ReadElement(aStream, mRefPtr);
3702 ReadElementConstrained(aStream, mExtendMode, ExtendMode::CLAMP,
3703 ExtendMode::REFLECT);
3704 ReadElement(aStream, mNumStops);
3705 if (!aStream.good() || mNumStops <= 0) {
3706 return;
3707 }
3708
3709 mStops = new (fallible) GradientStop[mNumStops];
3710 if (!mStops) {
3711 gfxCriticalNotemozilla::gfx::CriticalLog(mozilla::gfx::CriticalLog::DefaultOptions
(false))
3712 << "RecordedGradientStopsCreation failed to allocate stops of size "
3713 << mNumStops;
3714 aStream.SetIsBad();
3715 } else {
3716 aStream.read((char*)mStops, mNumStops * sizeof(GradientStop));
3717 }
3718}
3719
3720inline void RecordedGradientStopsCreation::OutputSimpleEventInfo(
3721 std::stringstream& aStringStream) const {
3722 aStringStream << "[" << mRefPtr
3723 << "] GradientStops created (Stops: " << mNumStops << ")";
3724}
3725
3726inline bool RecordedGradientStopsDestruction::PlayEvent(
3727 Translator* aTranslator) const {
3728 aTranslator->RemoveGradientStops(mRefPtr);
3729 return true;
3730}
3731
3732template <class S>
3733void RecordedGradientStopsDestruction::Record(S& aStream) const {
3734 WriteElement(aStream, mRefPtr);
3735}
3736
3737template <class S>
3738RecordedGradientStopsDestruction::RecordedGradientStopsDestruction(S& aStream)
3739 : RecordedEventDerived(GRADIENTSTOPSDESTRUCTION) {
3740 ReadElement(aStream, mRefPtr);
3741}
3742
3743inline void RecordedGradientStopsDestruction::OutputSimpleEventInfo(
3744 std::stringstream& aStringStream) const {
3745 aStringStream << "[" << mRefPtr << "] GradientStops Destroyed";
3746}
3747
3748inline bool RecordedIntoLuminanceSource::PlayEvent(
3749 Translator* aTranslator) const {
3750 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3751 if (!dt) {
3752 return false;
3753 }
3754
3755 RefPtr<SourceSurface> src = dt->IntoLuminanceSource(mLuminanceType, mOpacity);
3756 aTranslator->AddSourceSurface(mRefPtr, src);
3757 return true;
3758}
3759
3760template <class S>
3761void RecordedIntoLuminanceSource::Record(S& aStream) const {
3762 WriteElement(aStream, mRefPtr);
3763 WriteElement(aStream, mLuminanceType);
3764 WriteElement(aStream, mOpacity);
3765}
3766
3767template <class S>
3768RecordedIntoLuminanceSource::RecordedIntoLuminanceSource(S& aStream)
3769 : RecordedEventDerived(INTOLUMINANCE) {
3770 ReadElement(aStream, mRefPtr);
3771 ReadElementConstrained(aStream, mLuminanceType, LuminanceType::LUMINANCE,
3772 LuminanceType::LINEARRGB);
3773 ReadElement(aStream, mOpacity);
3774}
3775
3776inline void RecordedIntoLuminanceSource::OutputSimpleEventInfo(
3777 std::stringstream& aStringStream) const {
3778 aStringStream << "[" << mRefPtr << "] Into Luminance Source";
3779}
3780
3781inline bool RecordedExtractSubrect::PlayEvent(Translator* aTranslator) const {
3782 SourceSurface* sourceSurf = aTranslator->LookupSourceSurface(mSourceSurface);
3783 if (!sourceSurf) {
3784 return false;
3785 }
3786
3787 RefPtr<SourceSurface> subSurf = sourceSurf->ExtractSubrect(mSubrect);
3788 if (!subSurf) {
3789 RefPtr<DrawTarget> dt =
3790 aTranslator->GetReferenceDrawTarget()->CreateSimilarDrawTarget(
3791 mSubrect.Size(), sourceSurf->GetFormat());
3792 if (dt) {
3793 dt->CopySurface(sourceSurf, mSubrect, IntPoint());
3794 subSurf = dt->Snapshot();
3795 }
3796 }
3797 if (!subSurf) {
3798 return false;
3799 }
3800
3801 aTranslator->AddSourceSurface(mRefPtr, subSurf);
3802 return true;
3803}
3804
3805template <class S>
3806void RecordedExtractSubrect::Record(S& aStream) const {
3807 WriteElement(aStream, mRefPtr);
3808 WriteElement(aStream, mSourceSurface);
3809 WriteElement(aStream, mSubrect);
3810}
3811
3812template <class S>
3813RecordedExtractSubrect::RecordedExtractSubrect(S& aStream)
3814 : RecordedEventDerived(EXTRACTSUBRECT) {
3815 ReadElement(aStream, mRefPtr);
3816 ReadElement(aStream, mSourceSurface);
3817 ReadElement(aStream, mSubrect);
3818}
3819
3820inline void RecordedExtractSubrect::OutputSimpleEventInfo(
3821 std::stringstream& aStringStream) const {
3822 aStringStream << "[" << mRefPtr << "] Exract Subrect";
3823}
3824
3825inline bool RecordedFlush::PlayEvent(Translator* aTranslator) const {
3826 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3827 if (!dt) {
3828 return false;
3829 }
3830
3831 dt->Flush();
3832 return true;
3833}
3834
3835template <class S>
3836void RecordedFlush::Record(S& aStream) const {}
3837
3838template <class S>
3839RecordedFlush::RecordedFlush(S& aStream) : RecordedEventDerived(FLUSH) {}
3840
3841inline void RecordedFlush::OutputSimpleEventInfo(
3842 std::stringstream& aStringStream) const {
3843 aStringStream << "Flush";
3844}
3845
3846inline bool RecordedDetachAllSnapshots::PlayEvent(
3847 Translator* aTranslator) const {
3848 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3849 if (!dt) {
3850 return false;
3851 }
3852
3853 dt->DetachAllSnapshots();
3854 return true;
3855}
3856
3857template <class S>
3858void RecordedDetachAllSnapshots::Record(S& aStream) const {}
3859
3860template <class S>
3861RecordedDetachAllSnapshots::RecordedDetachAllSnapshots(S& aStream)
3862 : RecordedEventDerived(DETACHALLSNAPSHOTS) {}
3863
3864inline void RecordedDetachAllSnapshots::OutputSimpleEventInfo(
3865 std::stringstream& aStringStream) const {
3866 aStringStream << "DetachAllSnapshots";
3867}
3868
3869inline bool RecordedSnapshot::PlayEvent(Translator* aTranslator) const {
3870 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
3871 if (!dt) {
3872 return false;
3873 }
3874
3875 RefPtr<SourceSurface> src = dt->Snapshot();
3876 aTranslator->AddSourceSurface(mRefPtr, src);
3877 return true;
3878}
3879
3880template <class S>
3881void RecordedSnapshot::Record(S& aStream) const {
3882 WriteElement(aStream, mRefPtr);
3883}
3884
3885template <class S>
3886RecordedSnapshot::RecordedSnapshot(S& aStream)
3887 : RecordedEventDerived(SNAPSHOT) {
3888 ReadElement(aStream, mRefPtr);
3889}
3890
3891inline void RecordedSnapshot::OutputSimpleEventInfo(
3892 std::stringstream& aStringStream) const {
3893 aStringStream << "[" << mRefPtr << "] Snapshot Created";
3894}
3895
3896inline RecordedFontData::~RecordedFontData() { delete[] mData; }
20
Memory allocated by malloc() should be deallocated by free(), not 'delete[]'
3897
3898inline bool RecordedFontData::PlayEvent(Translator* aTranslator) const {
3899 if (!mData) {
3900 return false;
3901 }
3902
3903 RefPtr<NativeFontResource> fontResource = Factory::CreateNativeFontResource(
3904 mData, mFontDetails.size, mType, aTranslator->GetFontContext());
3905 if (!fontResource) {
3906 return false;
3907 }
3908
3909 aTranslator->AddNativeFontResource(mFontDetails.fontDataKey, fontResource);
3910 return true;
3911}
3912
3913template <class S>
3914void RecordedFontData::Record(S& aStream) const {
3915 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"
, 3915); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mGetFontFileDataSucceeded"
")"); do { *((volatile int*)__null) = 3915; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3916
3917 WriteElement(aStream, mType);
3918 WriteElement(aStream, mFontDetails.fontDataKey);
3919 if (!mData) {
3920 WriteElement(aStream, 0);
3921 } else {
3922 WriteElement(aStream, mFontDetails.size);
3923 aStream.write((const char*)mData, mFontDetails.size);
3924 }
3925}
3926
3927inline void RecordedFontData::OutputSimpleEventInfo(
3928 std::stringstream& aStringStream) const {
3929 aStringStream << "Font Data of size " << mFontDetails.size;
3930}
3931
3932inline void RecordedFontData::SetFontData(const uint8_t* aData, uint32_t aSize,
3933 uint32_t aIndex) {
3934 mData = new (fallible) uint8_t[aSize];
3935 if (!mData) {
3936 gfxCriticalNotemozilla::gfx::CriticalLog(mozilla::gfx::CriticalLog::DefaultOptions
(false))
3937 << "RecordedFontData failed to allocate data for recording of size "
3938 << aSize;
3939 } else {
3940 memcpy(mData, aData, aSize);
3941 }
3942 mFontDetails.fontDataKey = SFNTData::GetUniqueKey(aData, aSize, 0, nullptr);
3943 mFontDetails.size = aSize;
3944 mFontDetails.index = aIndex;
3945}
3946
3947inline bool RecordedFontData::GetFontDetails(RecordedFontDetails& fontDetails) {
3948 if (!mGetFontFileDataSucceeded) {
3949 return false;
3950 }
3951
3952 fontDetails.fontDataKey = mFontDetails.fontDataKey;
3953 fontDetails.size = mFontDetails.size;
3954 fontDetails.index = mFontDetails.index;
3955 return true;
3956}
3957
3958template <class S>
3959RecordedFontData::RecordedFontData(S& aStream)
3960 : RecordedEventDerived(FONTDATA), mType(FontType::UNKNOWN) {
3961 ReadElementConstrained(aStream, mType, FontType::DWRITE, FontType::UNKNOWN);
3962 ReadElement(aStream, mFontDetails.fontDataKey);
3963 ReadElement(aStream, mFontDetails.size);
3964 if (!mFontDetails.size || !aStream.good()) {
11
Assuming field 'size' is not equal to 0
12
Taking false branch
3965 return;
3966 }
3967
3968 mData = new (fallible) uint8_t[mFontDetails.size];
13
Calling 'operator new[]'
15
Returning from 'operator new[]'
3969 if (!mData) {
16
Assuming field 'mData' is non-null
17
Taking false branch
3970 gfxCriticalNotemozilla::gfx::CriticalLog(mozilla::gfx::CriticalLog::DefaultOptions
(false))
3971 << "RecordedFontData failed to allocate data for playback of size "
3972 << mFontDetails.size;
3973 aStream.SetIsBad();
3974 } else {
3975 aStream.read((char*)mData, mFontDetails.size);
3976 }
3977}
3978
3979inline RecordedFontDescriptor::~RecordedFontDescriptor() = default;
3980
3981inline bool RecordedFontDescriptor::PlayEvent(Translator* aTranslator) const {
3982 RefPtr<UnscaledFont> font = Factory::CreateUnscaledFontFromFontDescriptor(
3983 mType, mData.data(), mData.size(), mIndex);
3984 if (!font) {
3985 gfxDevCrash(LogReason::InvalidFont)mozilla::gfx::CriticalLog(int(gfx::LogOptions::AutoPrefix) | int
(gfx::LogOptions::AssertOnCall) | int(gfx::LogOptions::CrashAction
), (LogReason::InvalidFont))
3986 << "Failed creating UnscaledFont of type " << int(mType)
3987 << " from font descriptor";
3988 return false;
3989 }
3990
3991 aTranslator->AddUnscaledFont(mRefPtr, font);
3992 return true;
3993}
3994
3995template <class S>
3996void RecordedFontDescriptor::Record(S& aStream) const {
3997 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"
, 3997); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mHasDesc" ")"
); do { *((volatile int*)__null) = 3997; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3998 WriteElement(aStream, mType);
3999 WriteElement(aStream, mRefPtr);
4000 WriteElement(aStream, mIndex);
4001 WriteElement(aStream, (size_t)mData.size());
4002 if (mData.size()) {
4003 aStream.write((char*)mData.data(), mData.size());
4004 }
4005}
4006
4007inline void RecordedFontDescriptor::OutputSimpleEventInfo(
4008 std::stringstream& aStringStream) const {
4009 aStringStream << "[" << mRefPtr << "] Font Descriptor";
4010}
4011
4012inline void RecordedFontDescriptor::SetFontDescriptor(const uint8_t* aData,
4013 uint32_t aSize,
4014 uint32_t aIndex) {
4015 mData.assign(aData, aData + aSize);
4016 mIndex = aIndex;
4017}
4018
4019template <class S>
4020RecordedFontDescriptor::RecordedFontDescriptor(S& aStream)
4021 : RecordedEventDerived(FONTDESC) {
4022 ReadElementConstrained(aStream, mType, FontType::DWRITE, FontType::UNKNOWN);
4023 ReadElement(aStream, mRefPtr);
4024 ReadElement(aStream, mIndex);
4025
4026 size_t size;
4027 ReadElement(aStream, size);
4028 if (!aStream.good()) {
4029 return;
4030 }
4031 if (size) {
4032 mData.resize(size);
4033 aStream.read((char*)mData.data(), size);
4034 }
4035}
4036
4037inline bool RecordedUnscaledFontCreation::PlayEvent(
4038 Translator* aTranslator) const {
4039 NativeFontResource* fontResource =
4040 aTranslator->LookupNativeFontResource(mFontDataKey);
4041 if (!fontResource) {
4042 gfxDevCrash(LogReason::NativeFontResourceNotFound)mozilla::gfx::CriticalLog(int(gfx::LogOptions::AutoPrefix) | int
(gfx::LogOptions::AssertOnCall) | int(gfx::LogOptions::CrashAction
), (LogReason::NativeFontResourceNotFound))
4043 << "NativeFontResource lookup failed for key |" << hexa(mFontDataKey)
4044 << "|.";
4045 return false;
4046 }
4047
4048 RefPtr<UnscaledFont> unscaledFont = fontResource->CreateUnscaledFont(
4049 mIndex, mInstanceData.data(), mInstanceData.size());
4050 aTranslator->AddUnscaledFont(mRefPtr, unscaledFont);
4051 return true;
4052}
4053
4054template <class S>
4055void RecordedUnscaledFontCreation::Record(S& aStream) const {
4056 WriteElement(aStream, mRefPtr);
4057 WriteElement(aStream, mFontDataKey);
4058 WriteElement(aStream, mIndex);
4059 WriteElement(aStream, (size_t)mInstanceData.size());
4060 if (mInstanceData.size()) {
4061 aStream.write((char*)mInstanceData.data(), mInstanceData.size());
4062 }
4063}
4064
4065inline void RecordedUnscaledFontCreation::OutputSimpleEventInfo(
4066 std::stringstream& aStringStream) const {
4067 aStringStream << "[" << mRefPtr << "] UnscaledFont Created";
4068}
4069
4070inline void RecordedUnscaledFontCreation::SetFontInstanceData(
4071 const uint8_t* aData, uint32_t aSize) {
4072 if (aSize) {
4073 mInstanceData.assign(aData, aData + aSize);
4074 }
4075}
4076
4077template <class S>
4078RecordedUnscaledFontCreation::RecordedUnscaledFontCreation(S& aStream)
4079 : RecordedEventDerived(UNSCALEDFONTCREATION) {
4080 ReadElement(aStream, mRefPtr);
4081 ReadElement(aStream, mFontDataKey);
4082 ReadElement(aStream, mIndex);
4083
4084 size_t size;
4085 ReadElement(aStream, size);
4086 if (!aStream.good()) {
4087 return;
4088 }
4089 if (size) {
4090 mInstanceData.resize(size);
4091 aStream.read((char*)mInstanceData.data(), size);
4092 }
4093}
4094
4095inline bool RecordedUnscaledFontDestruction::PlayEvent(
4096 Translator* aTranslator) const {
4097 aTranslator->RemoveUnscaledFont(mRefPtr);
4098 return true;
4099}
4100
4101template <class S>
4102void RecordedUnscaledFontDestruction::Record(S& aStream) const {
4103 WriteElement(aStream, mRefPtr);
4104}
4105
4106template <class S>
4107RecordedUnscaledFontDestruction::RecordedUnscaledFontDestruction(S& aStream)
4108 : RecordedEventDerived(UNSCALEDFONTDESTRUCTION) {
4109 ReadElement(aStream, mRefPtr);
4110}
4111
4112inline void RecordedUnscaledFontDestruction::OutputSimpleEventInfo(
4113 std::stringstream& aStringStream) const {
4114 aStringStream << "[" << mRefPtr << "] UnscaledFont Destroyed";
4115}
4116
4117inline bool RecordedScaledFontCreation::PlayEvent(
4118 Translator* aTranslator) const {
4119 UnscaledFont* unscaledFont = aTranslator->LookupUnscaledFont(mUnscaledFont);
4120 if (!unscaledFont) {
4121 gfxDevCrash(LogReason::UnscaledFontNotFound)mozilla::gfx::CriticalLog(int(gfx::LogOptions::AutoPrefix) | int
(gfx::LogOptions::AssertOnCall) | int(gfx::LogOptions::CrashAction
), (LogReason::UnscaledFontNotFound))
4122 << "UnscaledFont lookup failed for key |" << hexa(mUnscaledFont)
4123 << "|.";
4124 return false;
4125 }
4126
4127 RefPtr<ScaledFont> scaledFont = unscaledFont->CreateScaledFont(
4128 mGlyphSize, mInstanceData.data(), mInstanceData.size(),
4129 mVariations.data(), mVariations.size());
4130
4131 aTranslator->AddScaledFont(mRefPtr, scaledFont);
4132 return true;
4133}
4134
4135template <class S>
4136void RecordedScaledFontCreation::Record(S& aStream) const {
4137 WriteElement(aStream, mRefPtr);
4138 WriteElement(aStream, mUnscaledFont);
4139 WriteElement(aStream, mGlyphSize);
4140 WriteElement(aStream, (size_t)mInstanceData.size());
4141 if (mInstanceData.size()) {
4142 aStream.write((char*)mInstanceData.data(), mInstanceData.size());
4143 }
4144 WriteElement(aStream, (size_t)mVariations.size());
4145 if (mVariations.size()) {
4146 aStream.write((char*)mVariations.data(),
4147 sizeof(FontVariation) * mVariations.size());
4148 }
4149}
4150
4151inline void RecordedScaledFontCreation::OutputSimpleEventInfo(
4152 std::stringstream& aStringStream) const {
4153 aStringStream << "[" << mRefPtr << "] ScaledFont Created";
4154}
4155
4156inline void RecordedScaledFontCreation::SetFontInstanceData(
4157 const uint8_t* aData, uint32_t aSize, const FontVariation* aVariations,
4158 uint32_t aNumVariations) {
4159 if (aSize) {
4160 mInstanceData.assign(aData, aData + aSize);
4161 }
4162 if (aNumVariations) {
4163 mVariations.assign(aVariations, aVariations + aNumVariations);
4164 }
4165}
4166
4167template <class S>
4168RecordedScaledFontCreation::RecordedScaledFontCreation(S& aStream)
4169 : RecordedEventDerived(SCALEDFONTCREATION) {
4170 ReadElement(aStream, mRefPtr);
4171 ReadElement(aStream, mUnscaledFont);
4172 ReadElement(aStream, mGlyphSize);
4173
4174 size_t size;
4175 ReadElement(aStream, size);
4176 if (!aStream.good()) {
4177 return;
4178 }
4179 if (size) {
4180 mInstanceData.resize(size);
4181 aStream.read((char*)mInstanceData.data(), size);
4182 }
4183
4184 size_t numVariations;
4185 ReadElement(aStream, numVariations);
4186 if (!aStream.good()) {
4187 return;
4188 }
4189 if (numVariations) {
4190 mVariations.resize(numVariations);
4191 aStream.read((char*)mVariations.data(),
4192 sizeof(FontVariation) * numVariations);
4193 }
4194}
4195
4196inline bool RecordedScaledFontDestruction::PlayEvent(
4197 Translator* aTranslator) const {
4198 aTranslator->RemoveScaledFont(mRefPtr);
4199 return true;
4200}
4201
4202template <class S>
4203void RecordedScaledFontDestruction::Record(S& aStream) const {
4204 WriteElement(aStream, mRefPtr);
4205}
4206
4207template <class S>
4208RecordedScaledFontDestruction::RecordedScaledFontDestruction(S& aStream)
4209 : RecordedEventDerived(SCALEDFONTDESTRUCTION) {
4210 ReadElement(aStream, mRefPtr);
4211}
4212
4213inline void RecordedScaledFontDestruction::OutputSimpleEventInfo(
4214 std::stringstream& aStringStream) const {
4215 aStringStream << "[" << mRefPtr << "] ScaledFont Destroyed";
4216}
4217
4218inline bool RecordedMaskSurface::PlayEvent(Translator* aTranslator) const {
4219 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
4220 if (!dt) {
4221 return false;
4222 }
4223
4224 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefMask);
4225 if (!surface) {
4226 return false;
4227 }
4228
4229 dt->MaskSurface(*GenericPattern(mPattern, aTranslator), surface, mOffset,
4230 mOptions);
4231 return true;
4232}
4233
4234template <class S>
4235void RecordedMaskSurface::Record(S& aStream) const {
4236 RecordPatternData(aStream, mPattern);
4237 WriteElement(aStream, mRefMask);
4238 WriteElement(aStream, mOffset);
4239 WriteElement(aStream, mOptions);
4240}
4241
4242template <class S>
4243RecordedMaskSurface::RecordedMaskSurface(S& aStream)
4244 : RecordedEventDerived(MASKSURFACE) {
4245 ReadPatternData(aStream, mPattern);
4246 ReadElement(aStream, mRefMask);
4247 ReadElement(aStream, mOffset);
4248 ReadDrawOptions(aStream, mOptions);
4249}
4250
4251inline void RecordedMaskSurface::OutputSimpleEventInfo(
4252 std::stringstream& aStringStream) const {
4253 aStringStream << "MaskSurface (" << mRefMask << ") Offset: (" << mOffset.x
4254 << "x" << mOffset.y << ") Pattern: ";
4255 OutputSimplePatternInfo(mPattern, aStringStream);
4256}
4257
4258template <typename T>
4259void ReplaySetAttribute(FilterNode* aNode, uint32_t aIndex, T aValue) {
4260 aNode->SetAttribute(aIndex, aValue);
4261}
4262
4263inline bool RecordedFilterNodeSetAttribute::PlayEvent(
4264 Translator* aTranslator) const {
4265 FilterNode* node = aTranslator->LookupFilterNode(mNode);
4266 if (!node) {
4267 return false;
4268 }
4269
4270#define REPLAY_SET_ATTRIBUTE(type, argtype)case ARGTYPE_argtype: ReplaySetAttribute(node, mIndex, *(type
*)&mPayload.front()); break
\
4271 case ARGTYPE_##argtype: \
4272 ReplaySetAttribute(node, mIndex, *(type*)&mPayload.front()); \
4273 break
4274
4275 switch (mArgType) {
4276 REPLAY_SET_ATTRIBUTE(bool, BOOL)case ARGTYPE_BOOL: ReplaySetAttribute(node, mIndex, *(bool*)&
mPayload.front()); break
;
4277 REPLAY_SET_ATTRIBUTE(uint32_t, UINT32)case ARGTYPE_UINT32: ReplaySetAttribute(node, mIndex, *(uint32_t
*)&mPayload.front()); break
;
4278 REPLAY_SET_ATTRIBUTE(Float, FLOAT)case ARGTYPE_FLOAT: ReplaySetAttribute(node, mIndex, *(Float*
)&mPayload.front()); break
;
4279 REPLAY_SET_ATTRIBUTE(Size, SIZE)case ARGTYPE_SIZE: ReplaySetAttribute(node, mIndex, *(Size*)&
mPayload.front()); break
;
4280 REPLAY_SET_ATTRIBUTE(IntSize, INTSIZE)case ARGTYPE_INTSIZE: ReplaySetAttribute(node, mIndex, *(IntSize
*)&mPayload.front()); break
;
4281 REPLAY_SET_ATTRIBUTE(IntPoint, INTPOINT)case ARGTYPE_INTPOINT: ReplaySetAttribute(node, mIndex, *(IntPoint
*)&mPayload.front()); break
;
4282 REPLAY_SET_ATTRIBUTE(Rect, RECT)case ARGTYPE_RECT: ReplaySetAttribute(node, mIndex, *(Rect*)&
mPayload.front()); break
;
4283 REPLAY_SET_ATTRIBUTE(IntRect, INTRECT)case ARGTYPE_INTRECT: ReplaySetAttribute(node, mIndex, *(IntRect
*)&mPayload.front()); break
;
4284 REPLAY_SET_ATTRIBUTE(Point, POINT)case ARGTYPE_POINT: ReplaySetAttribute(node, mIndex, *(Point*
)&mPayload.front()); break
;
4285 REPLAY_SET_ATTRIBUTE(Matrix, MATRIX)case ARGTYPE_MATRIX: ReplaySetAttribute(node, mIndex, *(Matrix
*)&mPayload.front()); break
;
4286 REPLAY_SET_ATTRIBUTE(Matrix5x4, MATRIX5X4)case ARGTYPE_MATRIX5X4: ReplaySetAttribute(node, mIndex, *(Matrix5x4
*)&mPayload.front()); break
;
4287 REPLAY_SET_ATTRIBUTE(Point3D, POINT3D)case ARGTYPE_POINT3D: ReplaySetAttribute(node, mIndex, *(Point3D
*)&mPayload.front()); break
;
4288 REPLAY_SET_ATTRIBUTE(DeviceColor, COLOR)case ARGTYPE_COLOR: ReplaySetAttribute(node, mIndex, *(DeviceColor
*)&mPayload.front()); break
;
4289 case ARGTYPE_FLOAT_ARRAY:
4290 node->SetAttribute(mIndex,
4291 reinterpret_cast<const Float*>(&mPayload.front()),
4292 mPayload.size() / sizeof(Float));
4293 break;
4294 }
4295
4296 return true;
4297}
4298
4299template <class S>
4300void RecordedFilterNodeSetAttribute::Record(S& aStream) const {
4301 WriteElement(aStream, mNode);
4302 WriteElement(aStream, mIndex);
4303 WriteElement(aStream, mArgType);
4304 WriteElement(aStream, uint64_t(mPayload.size()));
4305 aStream.write((const char*)&mPayload.front(), mPayload.size());
4306}
4307
4308template <class S>
4309RecordedFilterNodeSetAttribute::RecordedFilterNodeSetAttribute(S& aStream)
4310 : RecordedEventDerived(FILTERNODESETATTRIBUTE) {
4311 ReadElement(aStream, mNode);
4312 ReadElement(aStream, mIndex);
4313 ReadElementConstrained(aStream, mArgType, ArgType::ARGTYPE_UINT32,
4314 ArgType::ARGTYPE_FLOAT_ARRAY);
4315 uint64_t size;
4316 ReadElement(aStream, size);
4317 if (!aStream.good()) {
4318 return;
4319 }
4320
4321 mPayload.resize(size_t(size));
4322 aStream.read((char*)&mPayload.front(), size);
4323}
4324
4325inline void RecordedFilterNodeSetAttribute::OutputSimpleEventInfo(
4326 std::stringstream& aStringStream) const {
4327 aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ")";
4328}
4329
4330inline bool RecordedFilterNodeSetInput::PlayEvent(
4331 Translator* aTranslator) const {
4332 FilterNode* node = aTranslator->LookupFilterNode(mNode);
4333 if (!node) {
4334 return false;
4335 }
4336
4337 if (mInputFilter) {
4338 node->SetInput(mIndex, aTranslator->LookupFilterNode(mInputFilter));
4339 } else {
4340 node->SetInput(mIndex, aTranslator->LookupSourceSurface(mInputSurface));
4341 }
4342
4343 return true;
4344}
4345
4346template <class S>
4347void RecordedFilterNodeSetInput::Record(S& aStream) const {
4348 WriteElement(aStream, mNode);
4349 WriteElement(aStream, mIndex);
4350 WriteElement(aStream, mInputFilter);
4351 WriteElement(aStream, mInputSurface);
4352}
4353
4354template <class S>
4355RecordedFilterNodeSetInput::RecordedFilterNodeSetInput(S& aStream)
4356 : RecordedEventDerived(FILTERNODESETINPUT) {
4357 ReadElement(aStream, mNode);
4358 ReadElement(aStream, mIndex);
4359 ReadElement(aStream, mInputFilter);
4360 ReadElement(aStream, mInputSurface);
4361}
4362
4363inline void RecordedFilterNodeSetInput::OutputSimpleEventInfo(
4364 std::stringstream& aStringStream) const {
4365 aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ", ";
4366
4367 if (mInputFilter) {
4368 aStringStream << "Filter: " << mInputFilter;
4369 } else {
4370 aStringStream << "Surface: " << mInputSurface;
4371 }
4372
4373 aStringStream << ")";
4374}
4375
4376inline bool RecordedLink::PlayEvent(Translator* aTranslator) const {
4377 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
4378 if (!dt) {
4379 return false;
4380 }
4381 dt->Link(mLocalDest.c_str(), mURI.c_str(), mRect);
4382 return true;
4383}
4384
4385template <class S>
4386void RecordedLink::Record(S& aStream) const {
4387 WriteElement(aStream, mRect);
4388 uint32_t len = mLocalDest.length();
4389 WriteElement(aStream, len);
4390 if (len) {
4391 aStream.write(mLocalDest.data(), len);
4392 }
4393 len = mURI.length();
4394 WriteElement(aStream, len);
4395 if (len) {
4396 aStream.write(mURI.data(), len);
4397 }
4398}
4399
4400template <class S>
4401RecordedLink::RecordedLink(S& aStream) : RecordedEventDerived(LINK) {
4402 ReadElement(aStream, mRect);
4403 uint32_t len;
4404 ReadElement(aStream, len);
4405 mLocalDest.resize(size_t(len));
4406 if (len && aStream.good()) {
4407 aStream.read(&mLocalDest.front(), len);
4408 }
4409 ReadElement(aStream, len);
4410 mURI.resize(size_t(len));
4411 if (len && aStream.good()) {
4412 aStream.read(&mURI.front(), len);
4413 }
4414}
4415
4416inline void RecordedLink::OutputSimpleEventInfo(
4417 std::stringstream& aStringStream) const {
4418 if (mLocalDest.empty()) {
4419 aStringStream << "Link [" << mURI << " @ " << mRect << "]";
4420 } else {
4421 aStringStream << "Link [" << mLocalDest << " / " << mURI << " @ " << mRect
4422 << "]";
4423 }
4424}
4425
4426inline bool RecordedDestination::PlayEvent(Translator* aTranslator) const {
4427 DrawTarget* dt = aTranslator->GetCurrentDrawTarget();
4428 if (!dt) {
4429 return false;
4430 }
4431 dt->Destination(mDestination.c_str(), mPoint);
4432 return true;
4433}
4434
4435template <class S>
4436void RecordedDestination::Record(S& aStream) const {
4437 WriteElement(aStream, mPoint);
4438 uint32_t len = mDestination.length();
4439 WriteElement(aStream, len);
4440 if (len) {
4441 aStream.write(mDestination.data(), len);
4442 }
4443}
4444
4445template <class S>
4446RecordedDestination::RecordedDestination(S& aStream)
4447 : RecordedEventDerived(DESTINATION) {
4448 ReadElement(aStream, mPoint);
4449 uint32_t len;
4450 ReadElement(aStream, len);
4451 mDestination.resize(size_t(len));
4452 if (len && aStream.good()) {
4453 aStream.read(&mDestination.front(), len);
4454 }
4455}
4456
4457inline void RecordedDestination::OutputSimpleEventInfo(
4458 std::stringstream& aStringStream) const {
4459 aStringStream << "Destination [" << mDestination << " @ " << mPoint << "]";
4460}
4461
4462#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);
\
4463 f(DRAWTARGETCREATION, RecordedDrawTargetCreation); \
4464 f(DRAWTARGETDESTRUCTION, RecordedDrawTargetDestruction); \
4465 f(SETCURRENTDRAWTARGET, RecordedSetCurrentDrawTarget); \
4466 f(FILLRECT, RecordedFillRect); \
4467 f(STROKERECT, RecordedStrokeRect); \
4468 f(STROKELINE, RecordedStrokeLine); \
4469 f(STROKECIRCLE, RecordedStrokeCircle); \
4470 f(CLEARRECT, RecordedClearRect); \
4471 f(COPYSURFACE, RecordedCopySurface); \
4472 f(SETPERMITSUBPIXELAA, RecordedSetPermitSubpixelAA); \
4473 f(SETTRANSFORM, RecordedSetTransform); \
4474 f(PUSHCLIPRECT, RecordedPushClipRect); \
4475 f(PUSHCLIP, RecordedPushClip); \
4476 f(POPCLIP, RecordedPopClip); \
4477 f(FILL, RecordedFill); \
4478 f(FILLCIRCLE, RecordedFillCircle); \
4479 f(FILLGLYPHS, RecordedFillGlyphs); \
4480 f(STROKEGLYPHS, RecordedStrokeGlyphs); \
4481 f(MASK, RecordedMask); \
4482 f(STROKE, RecordedStroke); \
4483 f(DRAWSURFACE, RecordedDrawSurface); \
4484 f(DRAWSURFACEDESCRIPTOR, RecordedDrawSurfaceDescriptor); \
4485 f(DRAWDEPENDENTSURFACE, RecordedDrawDependentSurface); \
4486 f(DRAWSURFACEWITHSHADOW, RecordedDrawSurfaceWithShadow); \
4487 f(DRAWSHADOW, RecordedDrawShadow); \
4488 f(DRAWFILTER, RecordedDrawFilter); \
4489 f(PATHCREATION, RecordedPathCreation); \
4490 f(PATHDESTRUCTION, RecordedPathDestruction); \
4491 f(SOURCESURFACECREATION, RecordedSourceSurfaceCreation); \
4492 f(SOURCESURFACEDESTRUCTION, RecordedSourceSurfaceDestruction); \
4493 f(FILTERNODECREATION, RecordedFilterNodeCreation); \
4494 f(FILTERNODEDESTRUCTION, RecordedFilterNodeDestruction); \
4495 f(GRADIENTSTOPSCREATION, RecordedGradientStopsCreation); \
4496 f(GRADIENTSTOPSDESTRUCTION, RecordedGradientStopsDestruction); \
4497 f(SNAPSHOT, RecordedSnapshot); \
4498 f(SCALEDFONTCREATION, RecordedScaledFontCreation); \
4499 f(SCALEDFONTDESTRUCTION, RecordedScaledFontDestruction); \
4500 f(MASKSURFACE, RecordedMaskSurface); \
4501 f(FILTERNODESETATTRIBUTE, RecordedFilterNodeSetAttribute); \
4502 f(FILTERNODESETINPUT, RecordedFilterNodeSetInput); \
4503 f(CREATESIMILARDRAWTARGET, RecordedCreateSimilarDrawTarget); \
4504 f(CREATECLIPPEDDRAWTARGET, RecordedCreateClippedDrawTarget); \
4505 f(CREATEDRAWTARGETFORFILTER, RecordedCreateDrawTargetForFilter); \
4506 f(FONTDATA, RecordedFontData); \
4507 f(FONTDESC, RecordedFontDescriptor); \
4508 f(PUSHLAYER, RecordedPushLayer); \
4509 f(PUSHLAYERWITHBLEND, RecordedPushLayerWithBlend); \
4510 f(POPLAYER, RecordedPopLayer); \
4511 f(UNSCALEDFONTCREATION, RecordedUnscaledFontCreation); \
4512 f(UNSCALEDFONTDESTRUCTION, RecordedUnscaledFontDestruction); \
4513 f(INTOLUMINANCE, RecordedIntoLuminanceSource); \
4514 f(EXTRACTSUBRECT, RecordedExtractSubrect); \
4515 f(EXTERNALSURFACECREATION, RecordedExternalSurfaceCreation); \
4516 f(FLUSH, RecordedFlush); \
4517 f(DETACHALLSNAPSHOTS, RecordedDetachAllSnapshots); \
4518 f(OPTIMIZESOURCESURFACE, RecordedOptimizeSourceSurface); \
4519 f(LINK, RecordedLink); \
4520 f(DESTINATION, RecordedDestination);
4521
4522#define DO_WITH_EVENT_TYPE(_typeenum, _class)case _typeenum: { auto e = _class(aStream); return aAction(&
e); }
\
4523 case _typeenum: { \
4524 auto e = _class(aStream); \
4525 return aAction(&e); \
4526 }
4527
4528template <class S>
4529bool RecordedEvent::DoWithEvent(
4530 S& aStream, EventType aType,
4531 const std::function<bool(RecordedEvent*)>& aAction) {
4532 switch (aType) {
9
Control jumps to 'case FONTDATA:' at line 4533
4533 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'
4534 default:
4535 return false;
4536 }
4537}
4538
4539} // namespace gfx
4540} // namespace mozilla
4541
4542#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 */