Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; 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 "DrawTargetRecording.h"
8 : #include "PathRecording.h"
9 : #include <stdio.h>
10 :
11 : #include "Logging.h"
12 : #include "Tools.h"
13 : #include "Filters.h"
14 : #include "mozilla/UniquePtr.h"
15 : #include "RecordingTypes.h"
16 : #include "RecordedEventImpl.h"
17 :
18 : namespace mozilla {
19 : namespace gfx {
20 :
21 0 : struct RecordingSourceSurfaceUserData
22 : {
23 : void *refPtr;
24 : RefPtr<DrawEventRecorderPrivate> recorder;
25 : };
26 :
27 0 : void RecordingSourceSurfaceUserDataFunc(void *aUserData)
28 : {
29 : RecordingSourceSurfaceUserData *userData =
30 0 : static_cast<RecordingSourceSurfaceUserData*>(aUserData);
31 :
32 0 : userData->recorder->RemoveSourceSurface((SourceSurface*)userData->refPtr);
33 0 : userData->recorder->RemoveStoredObject(userData->refPtr);
34 0 : userData->recorder->RecordEvent(
35 0 : RecordedSourceSurfaceDestruction(ReferencePtr(userData->refPtr)));
36 :
37 0 : delete userData;
38 0 : }
39 :
40 : static void
41 0 : StoreSourceSurfaceRecording(DrawEventRecorderPrivate *aRecorder, SourceSurface *aSurface,
42 : DataSourceSurface *aDataSurf, const char *reason)
43 : {
44 0 : if (!aDataSurf) {
45 0 : gfxWarning() << "Recording failed to record SourceSurface for " << reason;
46 : // Insert a bogus source surface.
47 0 : int32_t stride = aSurface->GetSize().width * BytesPerPixel(aSurface->GetFormat());
48 0 : UniquePtr<uint8_t[]> sourceData(new uint8_t[stride * aSurface->GetSize().height]());
49 : aRecorder->RecordEvent(
50 0 : RecordedSourceSurfaceCreation(aSurface, sourceData.get(), stride,
51 0 : aSurface->GetSize(), aSurface->GetFormat()));
52 : } else {
53 0 : DataSourceSurface::ScopedMap map(aDataSurf, DataSourceSurface::READ);
54 : aRecorder->RecordEvent(
55 0 : RecordedSourceSurfaceCreation(aSurface, map.GetData(), map.GetStride(),
56 0 : aDataSurf->GetSize(), aDataSurf->GetFormat()));
57 : }
58 0 : }
59 :
60 : static void
61 0 : EnsureSurfaceStoredRecording(DrawEventRecorderPrivate *aRecorder, SourceSurface *aSurface,
62 : const char *reason)
63 : {
64 0 : if (aRecorder->HasStoredObject(aSurface)) {
65 0 : return;
66 : }
67 :
68 0 : RefPtr<DataSourceSurface> dataSurf = aSurface->GetDataSurface();
69 0 : StoreSourceSurfaceRecording(aRecorder, aSurface, dataSurf, reason);
70 0 : aRecorder->AddStoredObject(aSurface);
71 0 : aRecorder->AddSourceSurface(aSurface);
72 :
73 0 : RecordingSourceSurfaceUserData *userData = new RecordingSourceSurfaceUserData;
74 0 : userData->refPtr = aSurface;
75 0 : userData->recorder = aRecorder;
76 : aSurface->AddUserData(reinterpret_cast<UserDataKey*>(aRecorder),
77 0 : userData, &RecordingSourceSurfaceUserDataFunc);
78 0 : return;
79 : }
80 :
81 : class SourceSurfaceRecording : public SourceSurface
82 : {
83 : public:
84 0 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceRecording)
85 0 : SourceSurfaceRecording(IntSize aSize, SurfaceFormat aFormat, DrawEventRecorderPrivate *aRecorder)
86 0 : : mSize(aSize), mFormat(aFormat), mRecorder(aRecorder)
87 : {
88 0 : mRecorder->AddStoredObject(this);
89 0 : }
90 :
91 0 : ~SourceSurfaceRecording()
92 0 : {
93 0 : mRecorder->RemoveStoredObject(this);
94 0 : mRecorder->RecordEvent(RecordedSourceSurfaceDestruction(ReferencePtr(this)));
95 0 : }
96 :
97 0 : virtual SurfaceType GetType() const { return SurfaceType::RECORDING; }
98 0 : virtual IntSize GetSize() const { return mSize; }
99 0 : virtual SurfaceFormat GetFormat() const { return mFormat; }
100 0 : virtual already_AddRefed<DataSourceSurface> GetDataSurface() { return nullptr; }
101 :
102 : IntSize mSize;
103 : SurfaceFormat mFormat;
104 : RefPtr<DrawEventRecorderPrivate> mRecorder;
105 : };
106 :
107 : class DataSourceSurfaceRecording : public DataSourceSurface
108 : {
109 : public:
110 0 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceRecording, override)
111 0 : DataSourceSurfaceRecording(UniquePtr<uint8_t[]> aData, IntSize aSize,
112 : int32_t aStride, SurfaceFormat aFormat)
113 0 : : mData(Move(aData))
114 : , mSize(aSize)
115 : , mStride(aStride)
116 0 : , mFormat(aFormat)
117 : {
118 0 : }
119 :
120 0 : ~DataSourceSurfaceRecording()
121 0 : {
122 0 : }
123 :
124 : static already_AddRefed<DataSourceSurface>
125 0 : Init(uint8_t *aData, IntSize aSize, int32_t aStride, SurfaceFormat aFormat)
126 : {
127 : //XXX: do we need to ensure any alignment here?
128 0 : auto data = MakeUnique<uint8_t[]>(aStride * aSize.height * BytesPerPixel(aFormat));
129 0 : if (data) {
130 0 : memcpy(data.get(), aData, aStride * aSize.height * BytesPerPixel(aFormat));
131 0 : RefPtr<DataSourceSurfaceRecording> surf = new DataSourceSurfaceRecording(Move(data), aSize, aStride, aFormat);
132 0 : return surf.forget();
133 : }
134 0 : return nullptr;
135 : }
136 :
137 0 : virtual SurfaceType GetType() const override { return SurfaceType::RECORDING; }
138 0 : virtual IntSize GetSize() const override { return mSize; }
139 0 : virtual int32_t Stride() override { return mStride; }
140 0 : virtual SurfaceFormat GetFormat() const override { return mFormat; }
141 0 : virtual uint8_t* GetData() override { return mData.get(); }
142 :
143 : UniquePtr<uint8_t[]> mData;
144 : IntSize mSize;
145 : int32_t mStride;
146 : SurfaceFormat mFormat;
147 : };
148 :
149 :
150 : class GradientStopsRecording : public GradientStops
151 : {
152 : public:
153 0 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStopsRecording)
154 0 : explicit GradientStopsRecording(DrawEventRecorderPrivate *aRecorder)
155 0 : : mRecorder(aRecorder)
156 : {
157 0 : mRecorder->AddStoredObject(this);
158 0 : }
159 :
160 0 : ~GradientStopsRecording()
161 0 : {
162 0 : mRecorder->RemoveStoredObject(this);
163 0 : mRecorder->RecordEvent(RecordedGradientStopsDestruction(ReferencePtr(this)));
164 0 : }
165 :
166 0 : virtual BackendType GetBackendType() const { return BackendType::RECORDING; }
167 :
168 : RefPtr<DrawEventRecorderPrivate> mRecorder;
169 : };
170 :
171 : class FilterNodeRecording : public FilterNode
172 : {
173 : public:
174 0 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeRecording, override)
175 : using FilterNode::SetAttribute;
176 :
177 0 : explicit FilterNodeRecording(DrawEventRecorderPrivate *aRecorder)
178 0 : : mRecorder(aRecorder)
179 : {
180 0 : mRecorder->AddStoredObject(this);
181 0 : }
182 :
183 0 : ~FilterNodeRecording()
184 0 : {
185 0 : mRecorder->RemoveStoredObject(this);
186 0 : mRecorder->RecordEvent(RecordedFilterNodeDestruction(ReferencePtr(this)));
187 0 : }
188 :
189 0 : virtual void SetInput(uint32_t aIndex, SourceSurface *aSurface) override
190 : {
191 0 : EnsureSurfaceStoredRecording(mRecorder, aSurface, "SetInput");
192 :
193 0 : mRecorder->RecordEvent(RecordedFilterNodeSetInput(this, aIndex, aSurface));
194 0 : }
195 0 : virtual void SetInput(uint32_t aIndex, FilterNode *aFilter) override
196 : {
197 0 : MOZ_ASSERT(mRecorder->HasStoredObject(aFilter));
198 :
199 0 : mRecorder->RecordEvent(RecordedFilterNodeSetInput(this, aIndex, aFilter));
200 0 : }
201 :
202 : #define FORWARD_SET_ATTRIBUTE(type, argtype) \
203 : virtual void SetAttribute(uint32_t aIndex, type aValue) override { \
204 : mRecorder->RecordEvent(RecordedFilterNodeSetAttribute(this, aIndex, aValue, RecordedFilterNodeSetAttribute::ARGTYPE_##argtype)); \
205 : }
206 :
207 0 : FORWARD_SET_ATTRIBUTE(bool, BOOL);
208 0 : FORWARD_SET_ATTRIBUTE(uint32_t, UINT32);
209 0 : FORWARD_SET_ATTRIBUTE(Float, FLOAT);
210 0 : FORWARD_SET_ATTRIBUTE(const Size&, SIZE);
211 0 : FORWARD_SET_ATTRIBUTE(const IntSize&, INTSIZE);
212 0 : FORWARD_SET_ATTRIBUTE(const IntPoint&, INTPOINT);
213 0 : FORWARD_SET_ATTRIBUTE(const Rect&, RECT);
214 0 : FORWARD_SET_ATTRIBUTE(const IntRect&, INTRECT);
215 0 : FORWARD_SET_ATTRIBUTE(const Point&, POINT);
216 0 : FORWARD_SET_ATTRIBUTE(const Matrix&, MATRIX);
217 0 : FORWARD_SET_ATTRIBUTE(const Matrix5x4&, MATRIX5X4);
218 0 : FORWARD_SET_ATTRIBUTE(const Point3D&, POINT3D);
219 0 : FORWARD_SET_ATTRIBUTE(const Color&, COLOR);
220 :
221 : #undef FORWARD_SET_ATTRIBUTE
222 :
223 0 : virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) override {
224 0 : mRecorder->RecordEvent(RecordedFilterNodeSetAttribute(this, aIndex, aFloat, aSize));
225 0 : }
226 :
227 0 : virtual FilterBackend GetBackendType() override { return FILTER_BACKEND_RECORDING; }
228 :
229 : RefPtr<DrawEventRecorderPrivate> mRecorder;
230 : };
231 :
232 0 : DrawTargetRecording::DrawTargetRecording(DrawEventRecorder *aRecorder, DrawTarget *aDT, IntSize aSize, bool aHasData)
233 : : mRecorder(static_cast<DrawEventRecorderPrivate*>(aRecorder))
234 : , mFinalDT(aDT)
235 0 : , mSize(aSize)
236 : {
237 0 : RefPtr<SourceSurface> snapshot = aHasData ? mFinalDT->Snapshot() : nullptr;
238 0 : mRecorder->RecordEvent(RecordedDrawTargetCreation(this,
239 0 : mFinalDT->GetBackendType(),
240 : mSize,
241 : mFinalDT->GetFormat(),
242 0 : aHasData, snapshot));
243 0 : mFormat = mFinalDT->GetFormat();
244 0 : }
245 :
246 0 : DrawTargetRecording::DrawTargetRecording(const DrawTargetRecording *aDT,
247 : IntSize aSize,
248 0 : SurfaceFormat aFormat)
249 : : mRecorder(aDT->mRecorder)
250 : , mFinalDT(aDT->mFinalDT)
251 0 : , mSize(aSize)
252 : {
253 0 : mRecorder->RecordEvent(RecordedCreateSimilarDrawTarget(this,
254 : aSize,
255 0 : aFormat));
256 0 : mFormat = aFormat;
257 0 : }
258 :
259 0 : DrawTargetRecording::~DrawTargetRecording()
260 : {
261 0 : mRecorder->RecordEvent(RecordedDrawTargetDestruction(ReferencePtr(this)));
262 0 : }
263 :
264 : void
265 0 : DrawTargetRecording::FillRect(const Rect &aRect,
266 : const Pattern &aPattern,
267 : const DrawOptions &aOptions)
268 : {
269 0 : EnsurePatternDependenciesStored(aPattern);
270 :
271 0 : mRecorder->RecordEvent(RecordedFillRect(this, aRect, aPattern, aOptions));
272 0 : }
273 :
274 : void
275 0 : DrawTargetRecording::StrokeRect(const Rect &aRect,
276 : const Pattern &aPattern,
277 : const StrokeOptions &aStrokeOptions,
278 : const DrawOptions &aOptions)
279 : {
280 0 : EnsurePatternDependenciesStored(aPattern);
281 :
282 0 : mRecorder->RecordEvent(RecordedStrokeRect(this, aRect, aPattern, aStrokeOptions, aOptions));
283 0 : }
284 :
285 : void
286 0 : DrawTargetRecording::StrokeLine(const Point &aBegin,
287 : const Point &aEnd,
288 : const Pattern &aPattern,
289 : const StrokeOptions &aStrokeOptions,
290 : const DrawOptions &aOptions)
291 : {
292 0 : EnsurePatternDependenciesStored(aPattern);
293 :
294 0 : mRecorder->RecordEvent(RecordedStrokeLine(this, aBegin, aEnd, aPattern, aStrokeOptions, aOptions));
295 0 : }
296 :
297 : void
298 0 : DrawTargetRecording::Fill(const Path *aPath,
299 : const Pattern &aPattern,
300 : const DrawOptions &aOptions)
301 : {
302 0 : RefPtr<PathRecording> pathRecording = EnsurePathStored(aPath);
303 0 : EnsurePatternDependenciesStored(aPattern);
304 :
305 0 : mRecorder->RecordEvent(RecordedFill(this, pathRecording, aPattern, aOptions));
306 0 : }
307 :
308 0 : struct RecordingFontUserData
309 : {
310 : void *refPtr;
311 : RefPtr<DrawEventRecorderPrivate> recorder;
312 : };
313 :
314 0 : void RecordingFontUserDataDestroyFunc(void *aUserData)
315 : {
316 : RecordingFontUserData *userData =
317 0 : static_cast<RecordingFontUserData*>(aUserData);
318 :
319 0 : userData->recorder->RecordEvent(RecordedScaledFontDestruction(ReferencePtr(userData->refPtr)));
320 0 : userData->recorder->RemoveScaledFont((ScaledFont*)userData->refPtr);
321 0 : delete userData;
322 0 : }
323 :
324 : void
325 0 : DrawTargetRecording::FillGlyphs(ScaledFont *aFont,
326 : const GlyphBuffer &aBuffer,
327 : const Pattern &aPattern,
328 : const DrawOptions &aOptions,
329 : const GlyphRenderingOptions *aRenderingOptions)
330 : {
331 0 : EnsurePatternDependenciesStored(aPattern);
332 :
333 0 : UserDataKey* userDataKey = reinterpret_cast<UserDataKey*>(mRecorder.get());
334 0 : if (!aFont->GetUserData(userDataKey)) {
335 0 : UnscaledFont* unscaledFont = aFont->GetUnscaledFont();
336 0 : if (!mRecorder->HasStoredObject(unscaledFont)) {
337 0 : RecordedFontData fontData(unscaledFont);
338 : RecordedFontDetails fontDetails;
339 0 : if (fontData.GetFontDetails(fontDetails)) {
340 : // Try to serialise the whole font, just in case this is a web font that
341 : // is not present on the system.
342 0 : if (!mRecorder->HasStoredFontData(fontDetails.fontDataKey)) {
343 0 : mRecorder->RecordEvent(fontData);
344 0 : mRecorder->AddStoredFontData(fontDetails.fontDataKey);
345 : }
346 0 : mRecorder->RecordEvent(RecordedUnscaledFontCreation(unscaledFont, fontDetails));
347 : } else {
348 : // If that fails, record just the font description and try to load it from
349 : // the system on the other side.
350 0 : RecordedFontDescriptor fontDesc(unscaledFont);
351 0 : if (fontDesc.IsValid()) {
352 0 : mRecorder->RecordEvent(fontDesc);
353 : } else {
354 0 : gfxWarning() << "DrawTargetRecording::FillGlyphs failed to serialise UnscaledFont";
355 : }
356 : }
357 0 : mRecorder->AddStoredObject(unscaledFont);
358 : }
359 :
360 0 : mRecorder->RecordEvent(RecordedScaledFontCreation(aFont, unscaledFont));
361 :
362 0 : RecordingFontUserData *userData = new RecordingFontUserData;
363 0 : userData->refPtr = aFont;
364 0 : userData->recorder = mRecorder;
365 0 : aFont->AddUserData(userDataKey, userData, &RecordingFontUserDataDestroyFunc);
366 0 : userData->recorder->AddScaledFont(aFont);
367 : }
368 :
369 0 : mRecorder->RecordEvent(RecordedFillGlyphs(this, aFont, aPattern, aOptions, aBuffer.mGlyphs, aBuffer.mNumGlyphs));
370 0 : }
371 :
372 : void
373 0 : DrawTargetRecording::Mask(const Pattern &aSource,
374 : const Pattern &aMask,
375 : const DrawOptions &aOptions)
376 : {
377 0 : EnsurePatternDependenciesStored(aSource);
378 0 : EnsurePatternDependenciesStored(aMask);
379 :
380 0 : mRecorder->RecordEvent(RecordedMask(this, aSource, aMask, aOptions));
381 0 : }
382 :
383 : void
384 0 : DrawTargetRecording::MaskSurface(const Pattern &aSource,
385 : SourceSurface *aMask,
386 : Point aOffset,
387 : const DrawOptions &aOptions)
388 : {
389 0 : EnsurePatternDependenciesStored(aSource);
390 0 : EnsureSurfaceStoredRecording(mRecorder, aMask, "MaskSurface");
391 :
392 0 : mRecorder->RecordEvent(RecordedMaskSurface(this, aSource, aMask, aOffset, aOptions));
393 0 : }
394 :
395 : void
396 0 : DrawTargetRecording::Stroke(const Path *aPath,
397 : const Pattern &aPattern,
398 : const StrokeOptions &aStrokeOptions,
399 : const DrawOptions &aOptions)
400 : {
401 0 : RefPtr<PathRecording> pathRecording = EnsurePathStored(aPath);
402 0 : EnsurePatternDependenciesStored(aPattern);
403 :
404 0 : mRecorder->RecordEvent(RecordedStroke(this, pathRecording, aPattern, aStrokeOptions, aOptions));
405 0 : }
406 :
407 : already_AddRefed<SourceSurface>
408 0 : DrawTargetRecording::Snapshot()
409 : {
410 0 : RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(mSize, mFormat, mRecorder);
411 :
412 0 : mRecorder->RecordEvent(RecordedSnapshot(retSurf, this));
413 :
414 0 : return retSurf.forget();
415 : }
416 :
417 : already_AddRefed<SourceSurface>
418 0 : DrawTargetRecording::IntoLuminanceSource(LuminanceType aLuminanceType, float aOpacity)
419 : {
420 0 : RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(mSize, SurfaceFormat::A8, mRecorder);
421 :
422 0 : mRecorder->RecordEvent(RecordedIntoLuminanceSource(retSurf, this, aLuminanceType, aOpacity));
423 :
424 0 : return retSurf.forget();
425 : }
426 :
427 : void
428 0 : DrawTargetRecording::DetachAllSnapshots()
429 : {
430 0 : }
431 :
432 : void
433 0 : DrawTargetRecording::DrawSurface(SourceSurface *aSurface,
434 : const Rect &aDest,
435 : const Rect &aSource,
436 : const DrawSurfaceOptions &aSurfOptions,
437 : const DrawOptions &aOptions)
438 : {
439 0 : EnsureSurfaceStoredRecording(mRecorder, aSurface, "DrawSurface");
440 :
441 0 : mRecorder->RecordEvent(RecordedDrawSurface(this, aSurface, aDest, aSource, aSurfOptions, aOptions));
442 0 : }
443 :
444 : void
445 0 : DrawTargetRecording::DrawSurfaceWithShadow(SourceSurface *aSurface,
446 : const Point &aDest,
447 : const Color &aColor,
448 : const Point &aOffset,
449 : Float aSigma,
450 : CompositionOp aOp)
451 : {
452 0 : EnsureSurfaceStoredRecording(mRecorder, aSurface, "DrawSurfaceWithShadow");
453 :
454 0 : mRecorder->RecordEvent(RecordedDrawSurfaceWithShadow(this, aSurface, aDest, aColor, aOffset, aSigma, aOp));
455 0 : }
456 :
457 : void
458 0 : DrawTargetRecording::DrawFilter(FilterNode *aNode,
459 : const Rect &aSourceRect,
460 : const Point &aDestPoint,
461 : const DrawOptions &aOptions)
462 : {
463 0 : MOZ_ASSERT(mRecorder->HasStoredObject(aNode));
464 :
465 0 : mRecorder->RecordEvent(RecordedDrawFilter(this, aNode, aSourceRect, aDestPoint, aOptions));
466 0 : }
467 :
468 : already_AddRefed<FilterNode>
469 0 : DrawTargetRecording::CreateFilter(FilterType aType)
470 : {
471 0 : RefPtr<FilterNode> retNode = new FilterNodeRecording(mRecorder);
472 :
473 0 : mRecorder->RecordEvent(RecordedFilterNodeCreation(retNode, aType));
474 :
475 0 : return retNode.forget();
476 : }
477 :
478 : void
479 0 : DrawTargetRecording::ClearRect(const Rect &aRect)
480 : {
481 0 : mRecorder->RecordEvent(RecordedClearRect(this, aRect));
482 0 : }
483 :
484 : void
485 0 : DrawTargetRecording::CopySurface(SourceSurface *aSurface,
486 : const IntRect &aSourceRect,
487 : const IntPoint &aDestination)
488 : {
489 0 : EnsureSurfaceStoredRecording(mRecorder, aSurface, "CopySurface");
490 :
491 0 : mRecorder->RecordEvent(RecordedCopySurface(this, aSurface, aSourceRect, aDestination));
492 0 : }
493 :
494 : void
495 0 : DrawTargetRecording::PushClip(const Path *aPath)
496 : {
497 0 : RefPtr<PathRecording> pathRecording = EnsurePathStored(aPath);
498 :
499 0 : mRecorder->RecordEvent(RecordedPushClip(this, pathRecording));
500 0 : }
501 :
502 : void
503 0 : DrawTargetRecording::PushClipRect(const Rect &aRect)
504 : {
505 0 : mRecorder->RecordEvent(RecordedPushClipRect(this, aRect));
506 0 : }
507 :
508 : void
509 0 : DrawTargetRecording::PopClip()
510 : {
511 0 : mRecorder->RecordEvent(RecordedPopClip(static_cast<DrawTarget*>(this)));
512 0 : }
513 :
514 : void
515 0 : DrawTargetRecording::PushLayer(bool aOpaque, Float aOpacity,
516 : SourceSurface* aMask,
517 : const Matrix& aMaskTransform,
518 : const IntRect& aBounds, bool aCopyBackground)
519 : {
520 0 : if (aMask) {
521 0 : EnsureSurfaceStoredRecording(mRecorder, aMask, "PushLayer");
522 : }
523 :
524 0 : mRecorder->RecordEvent(RecordedPushLayer(this, aOpaque, aOpacity, aMask,
525 : aMaskTransform, aBounds,
526 0 : aCopyBackground));
527 0 : }
528 :
529 : void
530 0 : DrawTargetRecording::PopLayer()
531 : {
532 0 : mRecorder->RecordEvent(RecordedPopLayer(static_cast<DrawTarget*>(this)));
533 0 : }
534 :
535 : already_AddRefed<SourceSurface>
536 0 : DrawTargetRecording::CreateSourceSurfaceFromData(unsigned char *aData,
537 : const IntSize &aSize,
538 : int32_t aStride,
539 : SurfaceFormat aFormat) const
540 : {
541 0 : RefPtr<SourceSurface> surf = DataSourceSurfaceRecording::Init(aData, aSize, aStride, aFormat);
542 :
543 0 : RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(aSize, aFormat, mRecorder);
544 :
545 0 : mRecorder->RecordEvent(RecordedSourceSurfaceCreation(retSurf, aData, aStride, aSize, aFormat));
546 :
547 0 : return retSurf.forget();
548 : }
549 :
550 : already_AddRefed<SourceSurface>
551 0 : DrawTargetRecording::OptimizeSourceSurface(SourceSurface *aSurface) const
552 : {
553 0 : RefPtr<SourceSurface> surf(aSurface);
554 0 : return surf.forget();
555 : }
556 :
557 : already_AddRefed<SourceSurface>
558 0 : DrawTargetRecording::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const
559 : {
560 0 : MOZ_ASSERT(false);
561 : return nullptr;
562 : }
563 :
564 : already_AddRefed<DrawTarget>
565 0 : DrawTargetRecording::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
566 : {
567 0 : RefPtr<DrawTarget> similarDT = new DrawTargetRecording(this, aSize, aFormat);
568 0 : return similarDT.forget();
569 : }
570 :
571 : already_AddRefed<PathBuilder>
572 0 : DrawTargetRecording::CreatePathBuilder(FillRule aFillRule) const
573 : {
574 0 : RefPtr<PathBuilder> builder = mFinalDT->CreatePathBuilder(aFillRule);
575 0 : return MakeAndAddRef<PathBuilderRecording>(builder, aFillRule);
576 : }
577 :
578 : already_AddRefed<GradientStops>
579 0 : DrawTargetRecording::CreateGradientStops(GradientStop *aStops,
580 : uint32_t aNumStops,
581 : ExtendMode aExtendMode) const
582 : {
583 0 : RefPtr<GradientStops> retStops = new GradientStopsRecording(mRecorder);
584 :
585 0 : mRecorder->RecordEvent(RecordedGradientStopsCreation(retStops, aStops, aNumStops, aExtendMode));
586 :
587 0 : return retStops.forget();
588 : }
589 :
590 : void
591 0 : DrawTargetRecording::SetTransform(const Matrix &aTransform)
592 : {
593 0 : mRecorder->RecordEvent(RecordedSetTransform(this, aTransform));
594 0 : DrawTarget::SetTransform(aTransform);
595 0 : }
596 :
597 : already_AddRefed<PathRecording>
598 0 : DrawTargetRecording::EnsurePathStored(const Path *aPath)
599 : {
600 0 : RefPtr<PathRecording> pathRecording;
601 0 : if (aPath->GetBackendType() == BackendType::RECORDING) {
602 0 : pathRecording = const_cast<PathRecording*>(static_cast<const PathRecording*>(aPath));
603 0 : if (mRecorder->HasStoredObject(aPath)) {
604 0 : return pathRecording.forget();
605 : }
606 : } else {
607 0 : MOZ_ASSERT(!mRecorder->HasStoredObject(aPath));
608 0 : FillRule fillRule = aPath->GetFillRule();
609 0 : RefPtr<PathBuilder> builder = mFinalDT->CreatePathBuilder(fillRule);
610 : RefPtr<PathBuilderRecording> builderRecording =
611 0 : new PathBuilderRecording(builder, fillRule);
612 0 : aPath->StreamToSink(builderRecording);
613 0 : pathRecording = builderRecording->Finish().downcast<PathRecording>();
614 : }
615 :
616 0 : mRecorder->RecordEvent(RecordedPathCreation(pathRecording.get()));
617 0 : mRecorder->AddStoredObject(pathRecording);
618 0 : pathRecording->mStoredRecorders.push_back(mRecorder);
619 :
620 0 : return pathRecording.forget();
621 : }
622 :
623 : void
624 0 : DrawTargetRecording::EnsurePatternDependenciesStored(const Pattern &aPattern)
625 : {
626 0 : switch (aPattern.GetType()) {
627 : case PatternType::COLOR:
628 : // No dependencies here.
629 0 : return;
630 : case PatternType::LINEAR_GRADIENT:
631 : {
632 0 : MOZ_ASSERT(mRecorder->HasStoredObject(static_cast<const LinearGradientPattern*>(&aPattern)->mStops));
633 0 : return;
634 : }
635 : case PatternType::RADIAL_GRADIENT:
636 : {
637 0 : MOZ_ASSERT(mRecorder->HasStoredObject(static_cast<const RadialGradientPattern*>(&aPattern)->mStops));
638 0 : return;
639 : }
640 : case PatternType::SURFACE:
641 : {
642 0 : const SurfacePattern *pat = static_cast<const SurfacePattern*>(&aPattern);
643 0 : EnsureSurfaceStoredRecording(mRecorder, pat->mSurface, "EnsurePatternDependenciesStored");
644 0 : return;
645 : }
646 : }
647 : }
648 :
649 : } // namespace gfx
650 : } // namespace mozilla
|