|
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "DrawTargetRecording.h" |
|
7 #include "PathRecording.h" |
|
8 #include <stdio.h> |
|
9 |
|
10 #include "Logging.h" |
|
11 #include "Tools.h" |
|
12 #include "Filters.h" |
|
13 |
|
14 namespace mozilla { |
|
15 namespace gfx { |
|
16 |
|
17 class SourceSurfaceRecording : public SourceSurface |
|
18 { |
|
19 public: |
|
20 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceRecording) |
|
21 SourceSurfaceRecording(SourceSurface *aFinalSurface, DrawEventRecorderPrivate *aRecorder) |
|
22 : mFinalSurface(aFinalSurface), mRecorder(aRecorder) |
|
23 { |
|
24 } |
|
25 |
|
26 ~SourceSurfaceRecording() |
|
27 { |
|
28 mRecorder->RecordEvent(RecordedSourceSurfaceDestruction(this)); |
|
29 } |
|
30 |
|
31 virtual SurfaceType GetType() const { return SurfaceType::RECORDING; } |
|
32 virtual IntSize GetSize() const { return mFinalSurface->GetSize(); } |
|
33 virtual SurfaceFormat GetFormat() const { return mFinalSurface->GetFormat(); } |
|
34 virtual TemporaryRef<DataSourceSurface> GetDataSurface() { return mFinalSurface->GetDataSurface(); } |
|
35 |
|
36 RefPtr<SourceSurface> mFinalSurface; |
|
37 RefPtr<DrawEventRecorderPrivate> mRecorder; |
|
38 }; |
|
39 |
|
40 class GradientStopsRecording : public GradientStops |
|
41 { |
|
42 public: |
|
43 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStopsRecording) |
|
44 GradientStopsRecording(GradientStops *aFinalGradientStops, DrawEventRecorderPrivate *aRecorder) |
|
45 : mFinalGradientStops(aFinalGradientStops), mRecorder(aRecorder) |
|
46 { |
|
47 } |
|
48 |
|
49 ~GradientStopsRecording() |
|
50 { |
|
51 mRecorder->RecordEvent(RecordedGradientStopsDestruction(this)); |
|
52 } |
|
53 |
|
54 virtual BackendType GetBackendType() const { return BackendType::RECORDING; } |
|
55 |
|
56 RefPtr<GradientStops> mFinalGradientStops; |
|
57 RefPtr<DrawEventRecorderPrivate> mRecorder; |
|
58 }; |
|
59 |
|
60 static SourceSurface * |
|
61 GetSourceSurface(SourceSurface *aSurface) |
|
62 { |
|
63 if (aSurface->GetType() != SurfaceType::RECORDING) { |
|
64 return aSurface; |
|
65 } |
|
66 |
|
67 return static_cast<SourceSurfaceRecording*>(aSurface)->mFinalSurface; |
|
68 } |
|
69 |
|
70 static GradientStops * |
|
71 GetGradientStops(GradientStops *aStops) |
|
72 { |
|
73 if (aStops->GetBackendType() != BackendType::RECORDING) { |
|
74 return aStops; |
|
75 } |
|
76 |
|
77 return static_cast<GradientStopsRecording*>(aStops)->mFinalGradientStops; |
|
78 } |
|
79 |
|
80 class FilterNodeRecording : public FilterNode |
|
81 { |
|
82 public: |
|
83 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeRecording) |
|
84 using FilterNode::SetAttribute; |
|
85 |
|
86 FilterNodeRecording(FilterNode *aFinalFilterNode, DrawEventRecorderPrivate *aRecorder) |
|
87 : mFinalFilterNode(aFinalFilterNode), mRecorder(aRecorder) |
|
88 { |
|
89 } |
|
90 |
|
91 ~FilterNodeRecording() |
|
92 { |
|
93 mRecorder->RecordEvent(RecordedFilterNodeDestruction(this)); |
|
94 } |
|
95 |
|
96 virtual void SetInput(uint32_t aIndex, SourceSurface *aSurface) |
|
97 { |
|
98 mRecorder->RecordEvent(RecordedFilterNodeSetInput(this, aIndex, aSurface)); |
|
99 mFinalFilterNode->SetInput(aIndex, GetSourceSurface(aSurface)); |
|
100 } |
|
101 virtual void SetInput(uint32_t aIndex, FilterNode *aFilter) |
|
102 { |
|
103 FilterNode *finalNode = aFilter; |
|
104 if (aFilter->GetBackendType() != FILTER_BACKEND_RECORDING) { |
|
105 gfxWarning() << "Non recording filter node used with recording DrawTarget!"; |
|
106 } else { |
|
107 finalNode = static_cast<FilterNodeRecording*>(aFilter)->mFinalFilterNode; |
|
108 } |
|
109 |
|
110 mRecorder->RecordEvent(RecordedFilterNodeSetInput(this, aIndex, aFilter)); |
|
111 mFinalFilterNode->SetInput(aIndex, finalNode); |
|
112 } |
|
113 |
|
114 |
|
115 #define FORWARD_SET_ATTRIBUTE(type, argtype) \ |
|
116 virtual void SetAttribute(uint32_t aIndex, type aValue) { \ |
|
117 mRecorder->RecordEvent(RecordedFilterNodeSetAttribute(this, aIndex, aValue, RecordedFilterNodeSetAttribute::ARGTYPE_##argtype)); \ |
|
118 mFinalFilterNode->SetAttribute(aIndex, aValue); \ |
|
119 } |
|
120 |
|
121 FORWARD_SET_ATTRIBUTE(bool, BOOL); |
|
122 FORWARD_SET_ATTRIBUTE(uint32_t, UINT32); |
|
123 FORWARD_SET_ATTRIBUTE(Float, FLOAT); |
|
124 FORWARD_SET_ATTRIBUTE(const Size&, SIZE); |
|
125 FORWARD_SET_ATTRIBUTE(const IntSize&, INTSIZE); |
|
126 FORWARD_SET_ATTRIBUTE(const IntPoint&, INTPOINT); |
|
127 FORWARD_SET_ATTRIBUTE(const Rect&, RECT); |
|
128 FORWARD_SET_ATTRIBUTE(const IntRect&, INTRECT); |
|
129 FORWARD_SET_ATTRIBUTE(const Point&, POINT); |
|
130 FORWARD_SET_ATTRIBUTE(const Matrix5x4&, MATRIX5X4); |
|
131 FORWARD_SET_ATTRIBUTE(const Point3D&, POINT3D); |
|
132 FORWARD_SET_ATTRIBUTE(const Color&, COLOR); |
|
133 |
|
134 #undef FORWARD_SET_ATTRIBUTE |
|
135 |
|
136 virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) { |
|
137 mRecorder->RecordEvent(RecordedFilterNodeSetAttribute(this, aIndex, aFloat, aSize)); |
|
138 mFinalFilterNode->SetAttribute(aIndex, aFloat, aSize); |
|
139 } |
|
140 |
|
141 virtual FilterBackend GetBackendType() MOZ_OVERRIDE { return FILTER_BACKEND_RECORDING; } |
|
142 |
|
143 RefPtr<FilterNode> mFinalFilterNode; |
|
144 RefPtr<DrawEventRecorderPrivate> mRecorder; |
|
145 }; |
|
146 |
|
147 static FilterNode* |
|
148 GetFilterNode(FilterNode* aNode) |
|
149 { |
|
150 if (aNode->GetBackendType() != FILTER_BACKEND_RECORDING) { |
|
151 gfxWarning() << "Non recording filter node used with recording DrawTarget!"; |
|
152 return aNode; |
|
153 } |
|
154 |
|
155 return static_cast<FilterNodeRecording*>(aNode)->mFinalFilterNode; |
|
156 } |
|
157 |
|
158 struct AdjustedPattern |
|
159 { |
|
160 AdjustedPattern(const Pattern &aPattern) |
|
161 : mPattern(nullptr) |
|
162 { |
|
163 mOrigPattern = const_cast<Pattern*>(&aPattern); |
|
164 } |
|
165 |
|
166 ~AdjustedPattern() { |
|
167 if (mPattern) { |
|
168 mPattern->~Pattern(); |
|
169 } |
|
170 } |
|
171 |
|
172 operator Pattern*() |
|
173 { |
|
174 switch(mOrigPattern->GetType()) { |
|
175 case PatternType::COLOR: |
|
176 return mOrigPattern; |
|
177 case PatternType::SURFACE: |
|
178 { |
|
179 SurfacePattern *surfPat = static_cast<SurfacePattern*>(mOrigPattern); |
|
180 mPattern = |
|
181 new (mSurfPat) SurfacePattern(GetSourceSurface(surfPat->mSurface), |
|
182 surfPat->mExtendMode, surfPat->mMatrix, |
|
183 surfPat->mFilter); |
|
184 return mPattern; |
|
185 } |
|
186 case PatternType::LINEAR_GRADIENT: |
|
187 { |
|
188 LinearGradientPattern *linGradPat = static_cast<LinearGradientPattern*>(mOrigPattern); |
|
189 mPattern = |
|
190 new (mLinGradPat) LinearGradientPattern(linGradPat->mBegin, linGradPat->mEnd, |
|
191 GetGradientStops(linGradPat->mStops), |
|
192 linGradPat->mMatrix); |
|
193 return mPattern; |
|
194 } |
|
195 case PatternType::RADIAL_GRADIENT: |
|
196 { |
|
197 RadialGradientPattern *radGradPat = static_cast<RadialGradientPattern*>(mOrigPattern); |
|
198 mPattern = |
|
199 new (mRadGradPat) RadialGradientPattern(radGradPat->mCenter1, radGradPat->mCenter2, |
|
200 radGradPat->mRadius1, radGradPat->mRadius2, |
|
201 GetGradientStops(radGradPat->mStops), |
|
202 radGradPat->mMatrix); |
|
203 return mPattern; |
|
204 } |
|
205 default: |
|
206 return new (mColPat) ColorPattern(Color()); |
|
207 } |
|
208 |
|
209 return mPattern; |
|
210 } |
|
211 |
|
212 union { |
|
213 char mColPat[sizeof(ColorPattern)]; |
|
214 char mLinGradPat[sizeof(LinearGradientPattern)]; |
|
215 char mRadGradPat[sizeof(RadialGradientPattern)]; |
|
216 char mSurfPat[sizeof(SurfacePattern)]; |
|
217 }; |
|
218 |
|
219 Pattern *mOrigPattern; |
|
220 Pattern *mPattern; |
|
221 }; |
|
222 |
|
223 DrawTargetRecording::DrawTargetRecording(DrawEventRecorder *aRecorder, DrawTarget *aDT, bool aHasData) |
|
224 : mRecorder(static_cast<DrawEventRecorderPrivate*>(aRecorder)) |
|
225 , mFinalDT(aDT) |
|
226 { |
|
227 RefPtr<SourceSurface> snapshot = aHasData ? mFinalDT->Snapshot() : nullptr; |
|
228 mRecorder->RecordEvent(RecordedDrawTargetCreation(this, mFinalDT->GetType(), mFinalDT->GetSize(), mFinalDT->GetFormat(), |
|
229 aHasData, snapshot)); |
|
230 mFormat = mFinalDT->GetFormat(); |
|
231 } |
|
232 |
|
233 DrawTargetRecording::~DrawTargetRecording() |
|
234 { |
|
235 mRecorder->RecordEvent(RecordedDrawTargetDestruction(this)); |
|
236 } |
|
237 |
|
238 void |
|
239 DrawTargetRecording::FillRect(const Rect &aRect, |
|
240 const Pattern &aPattern, |
|
241 const DrawOptions &aOptions) |
|
242 { |
|
243 mRecorder->RecordEvent(RecordedFillRect(this, aRect, aPattern, aOptions)); |
|
244 mFinalDT->FillRect(aRect, *AdjustedPattern(aPattern), aOptions); |
|
245 } |
|
246 |
|
247 void |
|
248 DrawTargetRecording::StrokeRect(const Rect &aRect, |
|
249 const Pattern &aPattern, |
|
250 const StrokeOptions &aStrokeOptions, |
|
251 const DrawOptions &aOptions) |
|
252 { |
|
253 mRecorder->RecordEvent(RecordedStrokeRect(this, aRect, aPattern, aStrokeOptions, aOptions)); |
|
254 mFinalDT->StrokeRect(aRect, *AdjustedPattern(aPattern), aStrokeOptions, aOptions); |
|
255 } |
|
256 |
|
257 void |
|
258 DrawTargetRecording::StrokeLine(const Point &aBegin, |
|
259 const Point &aEnd, |
|
260 const Pattern &aPattern, |
|
261 const StrokeOptions &aStrokeOptions, |
|
262 const DrawOptions &aOptions) |
|
263 { |
|
264 mRecorder->RecordEvent(RecordedStrokeLine(this, aBegin, aEnd, aPattern, aStrokeOptions, aOptions)); |
|
265 mFinalDT->StrokeLine(aBegin, aEnd, *AdjustedPattern(aPattern), aStrokeOptions, aOptions); |
|
266 } |
|
267 |
|
268 Path* |
|
269 DrawTargetRecording::GetPathForPathRecording(const Path *aPath) const |
|
270 { |
|
271 if (aPath->GetBackendType() != BackendType::RECORDING) { |
|
272 return nullptr; |
|
273 } |
|
274 |
|
275 return static_cast<const PathRecording*>(aPath)->mPath; |
|
276 } |
|
277 |
|
278 void |
|
279 DrawTargetRecording::Fill(const Path *aPath, |
|
280 const Pattern &aPattern, |
|
281 const DrawOptions &aOptions) |
|
282 { |
|
283 EnsureStored(aPath); |
|
284 |
|
285 mRecorder->RecordEvent(RecordedFill(this, const_cast<Path*>(aPath), aPattern, aOptions)); |
|
286 mFinalDT->Fill(GetPathForPathRecording(aPath), *AdjustedPattern(aPattern), aOptions); |
|
287 } |
|
288 |
|
289 struct RecordingFontUserData |
|
290 { |
|
291 void *refPtr; |
|
292 RefPtr<DrawEventRecorderPrivate> recorder; |
|
293 }; |
|
294 |
|
295 void RecordingFontUserDataDestroyFunc(void *aUserData) |
|
296 { |
|
297 RecordingFontUserData *userData = |
|
298 static_cast<RecordingFontUserData*>(aUserData); |
|
299 |
|
300 // TODO support font in b2g recordings |
|
301 #ifndef MOZ_WIDGET_GONK |
|
302 userData->recorder->RecordEvent(RecordedScaledFontDestruction(userData->refPtr)); |
|
303 #endif |
|
304 |
|
305 delete userData; |
|
306 } |
|
307 |
|
308 void |
|
309 DrawTargetRecording::FillGlyphs(ScaledFont *aFont, |
|
310 const GlyphBuffer &aBuffer, |
|
311 const Pattern &aPattern, |
|
312 const DrawOptions &aOptions, |
|
313 const GlyphRenderingOptions *aRenderingOptions) |
|
314 { |
|
315 if (!aFont->GetUserData(reinterpret_cast<UserDataKey*>(mRecorder.get()))) { |
|
316 // TODO support font in b2g recordings |
|
317 #ifndef MOZ_WIDGET_GONK |
|
318 mRecorder->RecordEvent(RecordedScaledFontCreation(aFont, aFont)); |
|
319 #endif |
|
320 RecordingFontUserData *userData = new RecordingFontUserData; |
|
321 userData->refPtr = aFont; |
|
322 userData->recorder = mRecorder; |
|
323 aFont->AddUserData(reinterpret_cast<UserDataKey*>(mRecorder.get()), userData, |
|
324 &RecordingFontUserDataDestroyFunc); |
|
325 } |
|
326 |
|
327 // TODO support font in b2g recordings |
|
328 #ifndef MOZ_WIDGET_GONK |
|
329 mRecorder->RecordEvent(RecordedFillGlyphs(this, aFont, aPattern, aOptions, aBuffer.mGlyphs, aBuffer.mNumGlyphs)); |
|
330 #endif |
|
331 mFinalDT->FillGlyphs(aFont, aBuffer, aPattern, aOptions, aRenderingOptions); |
|
332 } |
|
333 |
|
334 void |
|
335 DrawTargetRecording::Mask(const Pattern &aSource, |
|
336 const Pattern &aMask, |
|
337 const DrawOptions &aOptions) |
|
338 { |
|
339 mRecorder->RecordEvent(RecordedMask(this, aSource, aMask, aOptions)); |
|
340 mFinalDT->Mask(*AdjustedPattern(aSource), *AdjustedPattern(aMask), aOptions); |
|
341 } |
|
342 |
|
343 void |
|
344 DrawTargetRecording::MaskSurface(const Pattern &aSource, |
|
345 SourceSurface *aMask, |
|
346 Point aOffset, |
|
347 const DrawOptions &aOptions) |
|
348 { |
|
349 mRecorder->RecordEvent(RecordedMaskSurface(this, aSource, aMask, aOffset, aOptions)); |
|
350 mFinalDT->MaskSurface(*AdjustedPattern(aSource), GetSourceSurface(aMask), aOffset, aOptions); |
|
351 } |
|
352 |
|
353 void |
|
354 DrawTargetRecording::Stroke(const Path *aPath, |
|
355 const Pattern &aPattern, |
|
356 const StrokeOptions &aStrokeOptions, |
|
357 const DrawOptions &aOptions) |
|
358 { |
|
359 EnsureStored(aPath); |
|
360 |
|
361 mRecorder->RecordEvent(RecordedStroke(this, const_cast<Path*>(aPath), aPattern, aStrokeOptions, aOptions)); |
|
362 mFinalDT->Stroke(GetPathForPathRecording(aPath), *AdjustedPattern(aPattern), aStrokeOptions, aOptions); |
|
363 } |
|
364 |
|
365 TemporaryRef<SourceSurface> |
|
366 DrawTargetRecording::Snapshot() |
|
367 { |
|
368 RefPtr<SourceSurface> surf = mFinalDT->Snapshot(); |
|
369 |
|
370 RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder); |
|
371 |
|
372 mRecorder->RecordEvent(RecordedSnapshot(retSurf, this)); |
|
373 |
|
374 return retSurf; |
|
375 } |
|
376 |
|
377 void |
|
378 DrawTargetRecording::DrawSurface(SourceSurface *aSurface, |
|
379 const Rect &aDest, |
|
380 const Rect &aSource, |
|
381 const DrawSurfaceOptions &aSurfOptions, |
|
382 const DrawOptions &aOptions) |
|
383 { |
|
384 mRecorder->RecordEvent(RecordedDrawSurface(this, aSurface, aDest, aSource, aSurfOptions, aOptions)); |
|
385 mFinalDT->DrawSurface(GetSourceSurface(aSurface), aDest, aSource, aSurfOptions, aOptions); |
|
386 } |
|
387 |
|
388 void |
|
389 DrawTargetRecording::DrawSurfaceWithShadow(SourceSurface *aSurface, |
|
390 const Point &aDest, |
|
391 const Color &aColor, |
|
392 const Point &aOffset, |
|
393 Float aSigma, |
|
394 CompositionOp aOp) |
|
395 { |
|
396 mRecorder->RecordEvent(RecordedDrawSurfaceWithShadow(this, aSurface, aDest, aColor, aOffset, aSigma, aOp)); |
|
397 mFinalDT->DrawSurfaceWithShadow(GetSourceSurface(aSurface), aDest, aColor, aOffset, aSigma, aOp); |
|
398 } |
|
399 |
|
400 void |
|
401 DrawTargetRecording::DrawFilter(FilterNode *aNode, |
|
402 const Rect &aSourceRect, |
|
403 const Point &aDestPoint, |
|
404 const DrawOptions &aOptions) |
|
405 { |
|
406 mRecorder->RecordEvent(RecordedDrawFilter(this, aNode, aSourceRect, aDestPoint, aOptions)); |
|
407 mFinalDT->DrawFilter(GetFilterNode(aNode), aSourceRect, aDestPoint, aOptions); |
|
408 } |
|
409 |
|
410 TemporaryRef<FilterNode> |
|
411 DrawTargetRecording::CreateFilter(FilterType aType) |
|
412 { |
|
413 RefPtr<FilterNode> node = mFinalDT->CreateFilter(aType); |
|
414 |
|
415 RefPtr<FilterNode> retNode = new FilterNodeRecording(node, mRecorder); |
|
416 |
|
417 mRecorder->RecordEvent(RecordedFilterNodeCreation(retNode, aType)); |
|
418 |
|
419 return retNode; |
|
420 } |
|
421 |
|
422 void |
|
423 DrawTargetRecording::ClearRect(const Rect &aRect) |
|
424 { |
|
425 mRecorder->RecordEvent(RecordedClearRect(this, aRect)); |
|
426 mFinalDT->ClearRect(aRect); |
|
427 } |
|
428 |
|
429 void |
|
430 DrawTargetRecording::CopySurface(SourceSurface *aSurface, |
|
431 const IntRect &aSourceRect, |
|
432 const IntPoint &aDestination) |
|
433 { |
|
434 mRecorder->RecordEvent(RecordedCopySurface(this, aSurface, aSourceRect, aDestination)); |
|
435 mFinalDT->CopySurface(GetSourceSurface(aSurface), aSourceRect, aDestination); |
|
436 } |
|
437 |
|
438 void |
|
439 DrawTargetRecording::PushClip(const Path *aPath) |
|
440 { |
|
441 EnsureStored(aPath); |
|
442 |
|
443 mRecorder->RecordEvent(RecordedPushClip(this, const_cast<Path*>(aPath))); |
|
444 mFinalDT->PushClip(GetPathForPathRecording(aPath)); |
|
445 } |
|
446 |
|
447 void |
|
448 DrawTargetRecording::PushClipRect(const Rect &aRect) |
|
449 { |
|
450 mRecorder->RecordEvent(RecordedPushClipRect(this, aRect)); |
|
451 mFinalDT->PushClipRect(aRect); |
|
452 } |
|
453 |
|
454 void |
|
455 DrawTargetRecording::PopClip() |
|
456 { |
|
457 mRecorder->RecordEvent(RecordedPopClip(this)); |
|
458 mFinalDT->PopClip(); |
|
459 } |
|
460 |
|
461 TemporaryRef<SourceSurface> |
|
462 DrawTargetRecording::CreateSourceSurfaceFromData(unsigned char *aData, |
|
463 const IntSize &aSize, |
|
464 int32_t aStride, |
|
465 SurfaceFormat aFormat) const |
|
466 { |
|
467 RefPtr<SourceSurface> surf = mFinalDT->CreateSourceSurfaceFromData(aData, aSize, aStride, aFormat); |
|
468 |
|
469 RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder); |
|
470 |
|
471 mRecorder->RecordEvent(RecordedSourceSurfaceCreation(retSurf, aData, aStride, aSize, aFormat)); |
|
472 |
|
473 return retSurf; |
|
474 } |
|
475 |
|
476 TemporaryRef<SourceSurface> |
|
477 DrawTargetRecording::OptimizeSourceSurface(SourceSurface *aSurface) const |
|
478 { |
|
479 RefPtr<SourceSurface> surf = mFinalDT->OptimizeSourceSurface(aSurface); |
|
480 |
|
481 RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder); |
|
482 |
|
483 RefPtr<DataSourceSurface> dataSurf = surf->GetDataSurface(); |
|
484 |
|
485 if (!dataSurf) { |
|
486 // Let's try get it off the original surface. |
|
487 dataSurf = aSurface->GetDataSurface(); |
|
488 } |
|
489 |
|
490 if (!dataSurf) { |
|
491 gfxWarning() << "Recording failed to record SourceSurface created from OptimizeSourceSurface"; |
|
492 // Insert a bogus source surface. |
|
493 uint8_t *sourceData = new uint8_t[surf->GetSize().width * surf->GetSize().height * BytesPerPixel(surf->GetFormat())]; |
|
494 memset(sourceData, 0, surf->GetSize().width * surf->GetSize().height * BytesPerPixel(surf->GetFormat())); |
|
495 mRecorder->RecordEvent( |
|
496 RecordedSourceSurfaceCreation(retSurf, sourceData, |
|
497 surf->GetSize().width * BytesPerPixel(surf->GetFormat()), |
|
498 surf->GetSize(), surf->GetFormat())); |
|
499 delete [] sourceData; |
|
500 } else { |
|
501 mRecorder->RecordEvent( |
|
502 RecordedSourceSurfaceCreation(retSurf, dataSurf->GetData(), dataSurf->Stride(), |
|
503 dataSurf->GetSize(), dataSurf->GetFormat())); |
|
504 } |
|
505 |
|
506 return retSurf; |
|
507 } |
|
508 |
|
509 TemporaryRef<SourceSurface> |
|
510 DrawTargetRecording::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const |
|
511 { |
|
512 RefPtr<SourceSurface> surf = mFinalDT->CreateSourceSurfaceFromNativeSurface(aSurface); |
|
513 |
|
514 RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder); |
|
515 |
|
516 RefPtr<DataSourceSurface> dataSurf = surf->GetDataSurface(); |
|
517 |
|
518 if (!dataSurf) { |
|
519 gfxWarning() << "Recording failed to record SourceSurface created from OptimizeSourceSurface"; |
|
520 // Insert a bogus source surface. |
|
521 uint8_t *sourceData = new uint8_t[surf->GetSize().width * surf->GetSize().height * BytesPerPixel(surf->GetFormat())]; |
|
522 memset(sourceData, 0, surf->GetSize().width * surf->GetSize().height * BytesPerPixel(surf->GetFormat())); |
|
523 mRecorder->RecordEvent( |
|
524 RecordedSourceSurfaceCreation(retSurf, sourceData, |
|
525 surf->GetSize().width * BytesPerPixel(surf->GetFormat()), |
|
526 surf->GetSize(), surf->GetFormat())); |
|
527 delete [] sourceData; |
|
528 } else { |
|
529 mRecorder->RecordEvent( |
|
530 RecordedSourceSurfaceCreation(retSurf, dataSurf->GetData(), dataSurf->Stride(), |
|
531 dataSurf->GetSize(), dataSurf->GetFormat())); |
|
532 } |
|
533 |
|
534 return retSurf; |
|
535 } |
|
536 |
|
537 TemporaryRef<DrawTarget> |
|
538 DrawTargetRecording::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const |
|
539 { |
|
540 RefPtr<DrawTarget> dt = mFinalDT->CreateSimilarDrawTarget(aSize, aFormat); |
|
541 |
|
542 RefPtr<DrawTarget> retDT = new DrawTargetRecording(mRecorder.get(), dt); |
|
543 |
|
544 return retDT; |
|
545 } |
|
546 |
|
547 TemporaryRef<PathBuilder> |
|
548 DrawTargetRecording::CreatePathBuilder(FillRule aFillRule) const |
|
549 { |
|
550 RefPtr<PathBuilder> builder = mFinalDT->CreatePathBuilder(aFillRule); |
|
551 return new PathBuilderRecording(builder, aFillRule); |
|
552 } |
|
553 |
|
554 TemporaryRef<GradientStops> |
|
555 DrawTargetRecording::CreateGradientStops(GradientStop *aStops, |
|
556 uint32_t aNumStops, |
|
557 ExtendMode aExtendMode) const |
|
558 { |
|
559 RefPtr<GradientStops> stops = mFinalDT->CreateGradientStops(aStops, aNumStops, aExtendMode); |
|
560 |
|
561 RefPtr<GradientStops> retStops = new GradientStopsRecording(stops, mRecorder); |
|
562 |
|
563 mRecorder->RecordEvent(RecordedGradientStopsCreation(retStops, aStops, aNumStops, aExtendMode)); |
|
564 |
|
565 return retStops; |
|
566 } |
|
567 |
|
568 void |
|
569 DrawTargetRecording::SetTransform(const Matrix &aTransform) |
|
570 { |
|
571 mRecorder->RecordEvent(RecordedSetTransform(this, aTransform)); |
|
572 DrawTarget::SetTransform(aTransform); |
|
573 mFinalDT->SetTransform(aTransform); |
|
574 } |
|
575 |
|
576 void |
|
577 DrawTargetRecording::EnsureStored(const Path *aPath) |
|
578 { |
|
579 if (!mRecorder->HasStoredPath(aPath)) { |
|
580 if (aPath->GetBackendType() != BackendType::RECORDING) { |
|
581 gfxWarning() << "Cannot record this fill path properly!"; |
|
582 } else { |
|
583 PathRecording *recPath = const_cast<PathRecording*>(static_cast<const PathRecording*>(aPath)); |
|
584 mRecorder->RecordEvent(RecordedPathCreation(recPath)); |
|
585 mRecorder->AddStoredPath(aPath); |
|
586 recPath->mStoredRecorders.push_back(mRecorder); |
|
587 } |
|
588 } |
|
589 } |
|
590 |
|
591 } |
|
592 } |