1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/2d/DrawTargetRecording.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,592 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "DrawTargetRecording.h" 1.10 +#include "PathRecording.h" 1.11 +#include <stdio.h> 1.12 + 1.13 +#include "Logging.h" 1.14 +#include "Tools.h" 1.15 +#include "Filters.h" 1.16 + 1.17 +namespace mozilla { 1.18 +namespace gfx { 1.19 + 1.20 +class SourceSurfaceRecording : public SourceSurface 1.21 +{ 1.22 +public: 1.23 + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceRecording) 1.24 + SourceSurfaceRecording(SourceSurface *aFinalSurface, DrawEventRecorderPrivate *aRecorder) 1.25 + : mFinalSurface(aFinalSurface), mRecorder(aRecorder) 1.26 + { 1.27 + } 1.28 + 1.29 + ~SourceSurfaceRecording() 1.30 + { 1.31 + mRecorder->RecordEvent(RecordedSourceSurfaceDestruction(this)); 1.32 + } 1.33 + 1.34 + virtual SurfaceType GetType() const { return SurfaceType::RECORDING; } 1.35 + virtual IntSize GetSize() const { return mFinalSurface->GetSize(); } 1.36 + virtual SurfaceFormat GetFormat() const { return mFinalSurface->GetFormat(); } 1.37 + virtual TemporaryRef<DataSourceSurface> GetDataSurface() { return mFinalSurface->GetDataSurface(); } 1.38 + 1.39 + RefPtr<SourceSurface> mFinalSurface; 1.40 + RefPtr<DrawEventRecorderPrivate> mRecorder; 1.41 +}; 1.42 + 1.43 +class GradientStopsRecording : public GradientStops 1.44 +{ 1.45 +public: 1.46 + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStopsRecording) 1.47 + GradientStopsRecording(GradientStops *aFinalGradientStops, DrawEventRecorderPrivate *aRecorder) 1.48 + : mFinalGradientStops(aFinalGradientStops), mRecorder(aRecorder) 1.49 + { 1.50 + } 1.51 + 1.52 + ~GradientStopsRecording() 1.53 + { 1.54 + mRecorder->RecordEvent(RecordedGradientStopsDestruction(this)); 1.55 + } 1.56 + 1.57 + virtual BackendType GetBackendType() const { return BackendType::RECORDING; } 1.58 + 1.59 + RefPtr<GradientStops> mFinalGradientStops; 1.60 + RefPtr<DrawEventRecorderPrivate> mRecorder; 1.61 +}; 1.62 + 1.63 +static SourceSurface * 1.64 +GetSourceSurface(SourceSurface *aSurface) 1.65 +{ 1.66 + if (aSurface->GetType() != SurfaceType::RECORDING) { 1.67 + return aSurface; 1.68 + } 1.69 + 1.70 + return static_cast<SourceSurfaceRecording*>(aSurface)->mFinalSurface; 1.71 +} 1.72 + 1.73 +static GradientStops * 1.74 +GetGradientStops(GradientStops *aStops) 1.75 +{ 1.76 + if (aStops->GetBackendType() != BackendType::RECORDING) { 1.77 + return aStops; 1.78 + } 1.79 + 1.80 + return static_cast<GradientStopsRecording*>(aStops)->mFinalGradientStops; 1.81 +} 1.82 + 1.83 +class FilterNodeRecording : public FilterNode 1.84 +{ 1.85 +public: 1.86 + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeRecording) 1.87 + using FilterNode::SetAttribute; 1.88 + 1.89 + FilterNodeRecording(FilterNode *aFinalFilterNode, DrawEventRecorderPrivate *aRecorder) 1.90 + : mFinalFilterNode(aFinalFilterNode), mRecorder(aRecorder) 1.91 + { 1.92 + } 1.93 + 1.94 + ~FilterNodeRecording() 1.95 + { 1.96 + mRecorder->RecordEvent(RecordedFilterNodeDestruction(this)); 1.97 + } 1.98 + 1.99 + virtual void SetInput(uint32_t aIndex, SourceSurface *aSurface) 1.100 + { 1.101 + mRecorder->RecordEvent(RecordedFilterNodeSetInput(this, aIndex, aSurface)); 1.102 + mFinalFilterNode->SetInput(aIndex, GetSourceSurface(aSurface)); 1.103 + } 1.104 + virtual void SetInput(uint32_t aIndex, FilterNode *aFilter) 1.105 + { 1.106 + FilterNode *finalNode = aFilter; 1.107 + if (aFilter->GetBackendType() != FILTER_BACKEND_RECORDING) { 1.108 + gfxWarning() << "Non recording filter node used with recording DrawTarget!"; 1.109 + } else { 1.110 + finalNode = static_cast<FilterNodeRecording*>(aFilter)->mFinalFilterNode; 1.111 + } 1.112 + 1.113 + mRecorder->RecordEvent(RecordedFilterNodeSetInput(this, aIndex, aFilter)); 1.114 + mFinalFilterNode->SetInput(aIndex, finalNode); 1.115 + } 1.116 + 1.117 + 1.118 +#define FORWARD_SET_ATTRIBUTE(type, argtype) \ 1.119 + virtual void SetAttribute(uint32_t aIndex, type aValue) { \ 1.120 + mRecorder->RecordEvent(RecordedFilterNodeSetAttribute(this, aIndex, aValue, RecordedFilterNodeSetAttribute::ARGTYPE_##argtype)); \ 1.121 + mFinalFilterNode->SetAttribute(aIndex, aValue); \ 1.122 + } 1.123 + 1.124 + FORWARD_SET_ATTRIBUTE(bool, BOOL); 1.125 + FORWARD_SET_ATTRIBUTE(uint32_t, UINT32); 1.126 + FORWARD_SET_ATTRIBUTE(Float, FLOAT); 1.127 + FORWARD_SET_ATTRIBUTE(const Size&, SIZE); 1.128 + FORWARD_SET_ATTRIBUTE(const IntSize&, INTSIZE); 1.129 + FORWARD_SET_ATTRIBUTE(const IntPoint&, INTPOINT); 1.130 + FORWARD_SET_ATTRIBUTE(const Rect&, RECT); 1.131 + FORWARD_SET_ATTRIBUTE(const IntRect&, INTRECT); 1.132 + FORWARD_SET_ATTRIBUTE(const Point&, POINT); 1.133 + FORWARD_SET_ATTRIBUTE(const Matrix5x4&, MATRIX5X4); 1.134 + FORWARD_SET_ATTRIBUTE(const Point3D&, POINT3D); 1.135 + FORWARD_SET_ATTRIBUTE(const Color&, COLOR); 1.136 + 1.137 +#undef FORWARD_SET_ATTRIBUTE 1.138 + 1.139 + virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) { 1.140 + mRecorder->RecordEvent(RecordedFilterNodeSetAttribute(this, aIndex, aFloat, aSize)); 1.141 + mFinalFilterNode->SetAttribute(aIndex, aFloat, aSize); 1.142 + } 1.143 + 1.144 + virtual FilterBackend GetBackendType() MOZ_OVERRIDE { return FILTER_BACKEND_RECORDING; } 1.145 + 1.146 + RefPtr<FilterNode> mFinalFilterNode; 1.147 + RefPtr<DrawEventRecorderPrivate> mRecorder; 1.148 +}; 1.149 + 1.150 +static FilterNode* 1.151 +GetFilterNode(FilterNode* aNode) 1.152 +{ 1.153 + if (aNode->GetBackendType() != FILTER_BACKEND_RECORDING) { 1.154 + gfxWarning() << "Non recording filter node used with recording DrawTarget!"; 1.155 + return aNode; 1.156 + } 1.157 + 1.158 + return static_cast<FilterNodeRecording*>(aNode)->mFinalFilterNode; 1.159 +} 1.160 + 1.161 +struct AdjustedPattern 1.162 +{ 1.163 + AdjustedPattern(const Pattern &aPattern) 1.164 + : mPattern(nullptr) 1.165 + { 1.166 + mOrigPattern = const_cast<Pattern*>(&aPattern); 1.167 + } 1.168 + 1.169 + ~AdjustedPattern() { 1.170 + if (mPattern) { 1.171 + mPattern->~Pattern(); 1.172 + } 1.173 + } 1.174 + 1.175 + operator Pattern*() 1.176 + { 1.177 + switch(mOrigPattern->GetType()) { 1.178 + case PatternType::COLOR: 1.179 + return mOrigPattern; 1.180 + case PatternType::SURFACE: 1.181 + { 1.182 + SurfacePattern *surfPat = static_cast<SurfacePattern*>(mOrigPattern); 1.183 + mPattern = 1.184 + new (mSurfPat) SurfacePattern(GetSourceSurface(surfPat->mSurface), 1.185 + surfPat->mExtendMode, surfPat->mMatrix, 1.186 + surfPat->mFilter); 1.187 + return mPattern; 1.188 + } 1.189 + case PatternType::LINEAR_GRADIENT: 1.190 + { 1.191 + LinearGradientPattern *linGradPat = static_cast<LinearGradientPattern*>(mOrigPattern); 1.192 + mPattern = 1.193 + new (mLinGradPat) LinearGradientPattern(linGradPat->mBegin, linGradPat->mEnd, 1.194 + GetGradientStops(linGradPat->mStops), 1.195 + linGradPat->mMatrix); 1.196 + return mPattern; 1.197 + } 1.198 + case PatternType::RADIAL_GRADIENT: 1.199 + { 1.200 + RadialGradientPattern *radGradPat = static_cast<RadialGradientPattern*>(mOrigPattern); 1.201 + mPattern = 1.202 + new (mRadGradPat) RadialGradientPattern(radGradPat->mCenter1, radGradPat->mCenter2, 1.203 + radGradPat->mRadius1, radGradPat->mRadius2, 1.204 + GetGradientStops(radGradPat->mStops), 1.205 + radGradPat->mMatrix); 1.206 + return mPattern; 1.207 + } 1.208 + default: 1.209 + return new (mColPat) ColorPattern(Color()); 1.210 + } 1.211 + 1.212 + return mPattern; 1.213 + } 1.214 + 1.215 + union { 1.216 + char mColPat[sizeof(ColorPattern)]; 1.217 + char mLinGradPat[sizeof(LinearGradientPattern)]; 1.218 + char mRadGradPat[sizeof(RadialGradientPattern)]; 1.219 + char mSurfPat[sizeof(SurfacePattern)]; 1.220 + }; 1.221 + 1.222 + Pattern *mOrigPattern; 1.223 + Pattern *mPattern; 1.224 +}; 1.225 + 1.226 +DrawTargetRecording::DrawTargetRecording(DrawEventRecorder *aRecorder, DrawTarget *aDT, bool aHasData) 1.227 + : mRecorder(static_cast<DrawEventRecorderPrivate*>(aRecorder)) 1.228 + , mFinalDT(aDT) 1.229 +{ 1.230 + RefPtr<SourceSurface> snapshot = aHasData ? mFinalDT->Snapshot() : nullptr; 1.231 + mRecorder->RecordEvent(RecordedDrawTargetCreation(this, mFinalDT->GetType(), mFinalDT->GetSize(), mFinalDT->GetFormat(), 1.232 + aHasData, snapshot)); 1.233 + mFormat = mFinalDT->GetFormat(); 1.234 +} 1.235 + 1.236 +DrawTargetRecording::~DrawTargetRecording() 1.237 +{ 1.238 + mRecorder->RecordEvent(RecordedDrawTargetDestruction(this)); 1.239 +} 1.240 + 1.241 +void 1.242 +DrawTargetRecording::FillRect(const Rect &aRect, 1.243 + const Pattern &aPattern, 1.244 + const DrawOptions &aOptions) 1.245 +{ 1.246 + mRecorder->RecordEvent(RecordedFillRect(this, aRect, aPattern, aOptions)); 1.247 + mFinalDT->FillRect(aRect, *AdjustedPattern(aPattern), aOptions); 1.248 +} 1.249 + 1.250 +void 1.251 +DrawTargetRecording::StrokeRect(const Rect &aRect, 1.252 + const Pattern &aPattern, 1.253 + const StrokeOptions &aStrokeOptions, 1.254 + const DrawOptions &aOptions) 1.255 +{ 1.256 + mRecorder->RecordEvent(RecordedStrokeRect(this, aRect, aPattern, aStrokeOptions, aOptions)); 1.257 + mFinalDT->StrokeRect(aRect, *AdjustedPattern(aPattern), aStrokeOptions, aOptions); 1.258 +} 1.259 + 1.260 +void 1.261 +DrawTargetRecording::StrokeLine(const Point &aBegin, 1.262 + const Point &aEnd, 1.263 + const Pattern &aPattern, 1.264 + const StrokeOptions &aStrokeOptions, 1.265 + const DrawOptions &aOptions) 1.266 +{ 1.267 + mRecorder->RecordEvent(RecordedStrokeLine(this, aBegin, aEnd, aPattern, aStrokeOptions, aOptions)); 1.268 + mFinalDT->StrokeLine(aBegin, aEnd, *AdjustedPattern(aPattern), aStrokeOptions, aOptions); 1.269 +} 1.270 + 1.271 +Path* 1.272 +DrawTargetRecording::GetPathForPathRecording(const Path *aPath) const 1.273 +{ 1.274 + if (aPath->GetBackendType() != BackendType::RECORDING) { 1.275 + return nullptr; 1.276 + } 1.277 + 1.278 + return static_cast<const PathRecording*>(aPath)->mPath; 1.279 +} 1.280 + 1.281 +void 1.282 +DrawTargetRecording::Fill(const Path *aPath, 1.283 + const Pattern &aPattern, 1.284 + const DrawOptions &aOptions) 1.285 +{ 1.286 + EnsureStored(aPath); 1.287 + 1.288 + mRecorder->RecordEvent(RecordedFill(this, const_cast<Path*>(aPath), aPattern, aOptions)); 1.289 + mFinalDT->Fill(GetPathForPathRecording(aPath), *AdjustedPattern(aPattern), aOptions); 1.290 +} 1.291 + 1.292 +struct RecordingFontUserData 1.293 +{ 1.294 + void *refPtr; 1.295 + RefPtr<DrawEventRecorderPrivate> recorder; 1.296 +}; 1.297 + 1.298 +void RecordingFontUserDataDestroyFunc(void *aUserData) 1.299 +{ 1.300 + RecordingFontUserData *userData = 1.301 + static_cast<RecordingFontUserData*>(aUserData); 1.302 + 1.303 + // TODO support font in b2g recordings 1.304 +#ifndef MOZ_WIDGET_GONK 1.305 + userData->recorder->RecordEvent(RecordedScaledFontDestruction(userData->refPtr)); 1.306 +#endif 1.307 + 1.308 + delete userData; 1.309 +} 1.310 + 1.311 +void 1.312 +DrawTargetRecording::FillGlyphs(ScaledFont *aFont, 1.313 + const GlyphBuffer &aBuffer, 1.314 + const Pattern &aPattern, 1.315 + const DrawOptions &aOptions, 1.316 + const GlyphRenderingOptions *aRenderingOptions) 1.317 +{ 1.318 + if (!aFont->GetUserData(reinterpret_cast<UserDataKey*>(mRecorder.get()))) { 1.319 + // TODO support font in b2g recordings 1.320 +#ifndef MOZ_WIDGET_GONK 1.321 + mRecorder->RecordEvent(RecordedScaledFontCreation(aFont, aFont)); 1.322 +#endif 1.323 + RecordingFontUserData *userData = new RecordingFontUserData; 1.324 + userData->refPtr = aFont; 1.325 + userData->recorder = mRecorder; 1.326 + aFont->AddUserData(reinterpret_cast<UserDataKey*>(mRecorder.get()), userData, 1.327 + &RecordingFontUserDataDestroyFunc); 1.328 + } 1.329 + 1.330 + // TODO support font in b2g recordings 1.331 +#ifndef MOZ_WIDGET_GONK 1.332 + mRecorder->RecordEvent(RecordedFillGlyphs(this, aFont, aPattern, aOptions, aBuffer.mGlyphs, aBuffer.mNumGlyphs)); 1.333 +#endif 1.334 + mFinalDT->FillGlyphs(aFont, aBuffer, aPattern, aOptions, aRenderingOptions); 1.335 +} 1.336 + 1.337 +void 1.338 +DrawTargetRecording::Mask(const Pattern &aSource, 1.339 + const Pattern &aMask, 1.340 + const DrawOptions &aOptions) 1.341 +{ 1.342 + mRecorder->RecordEvent(RecordedMask(this, aSource, aMask, aOptions)); 1.343 + mFinalDT->Mask(*AdjustedPattern(aSource), *AdjustedPattern(aMask), aOptions); 1.344 +} 1.345 + 1.346 +void 1.347 +DrawTargetRecording::MaskSurface(const Pattern &aSource, 1.348 + SourceSurface *aMask, 1.349 + Point aOffset, 1.350 + const DrawOptions &aOptions) 1.351 +{ 1.352 + mRecorder->RecordEvent(RecordedMaskSurface(this, aSource, aMask, aOffset, aOptions)); 1.353 + mFinalDT->MaskSurface(*AdjustedPattern(aSource), GetSourceSurface(aMask), aOffset, aOptions); 1.354 +} 1.355 + 1.356 +void 1.357 +DrawTargetRecording::Stroke(const Path *aPath, 1.358 + const Pattern &aPattern, 1.359 + const StrokeOptions &aStrokeOptions, 1.360 + const DrawOptions &aOptions) 1.361 +{ 1.362 + EnsureStored(aPath); 1.363 + 1.364 + mRecorder->RecordEvent(RecordedStroke(this, const_cast<Path*>(aPath), aPattern, aStrokeOptions, aOptions)); 1.365 + mFinalDT->Stroke(GetPathForPathRecording(aPath), *AdjustedPattern(aPattern), aStrokeOptions, aOptions); 1.366 +} 1.367 + 1.368 +TemporaryRef<SourceSurface> 1.369 +DrawTargetRecording::Snapshot() 1.370 +{ 1.371 + RefPtr<SourceSurface> surf = mFinalDT->Snapshot(); 1.372 + 1.373 + RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder); 1.374 + 1.375 + mRecorder->RecordEvent(RecordedSnapshot(retSurf, this)); 1.376 + 1.377 + return retSurf; 1.378 +} 1.379 + 1.380 +void 1.381 +DrawTargetRecording::DrawSurface(SourceSurface *aSurface, 1.382 + const Rect &aDest, 1.383 + const Rect &aSource, 1.384 + const DrawSurfaceOptions &aSurfOptions, 1.385 + const DrawOptions &aOptions) 1.386 +{ 1.387 + mRecorder->RecordEvent(RecordedDrawSurface(this, aSurface, aDest, aSource, aSurfOptions, aOptions)); 1.388 + mFinalDT->DrawSurface(GetSourceSurface(aSurface), aDest, aSource, aSurfOptions, aOptions); 1.389 +} 1.390 + 1.391 +void 1.392 +DrawTargetRecording::DrawSurfaceWithShadow(SourceSurface *aSurface, 1.393 + const Point &aDest, 1.394 + const Color &aColor, 1.395 + const Point &aOffset, 1.396 + Float aSigma, 1.397 + CompositionOp aOp) 1.398 +{ 1.399 + mRecorder->RecordEvent(RecordedDrawSurfaceWithShadow(this, aSurface, aDest, aColor, aOffset, aSigma, aOp)); 1.400 + mFinalDT->DrawSurfaceWithShadow(GetSourceSurface(aSurface), aDest, aColor, aOffset, aSigma, aOp); 1.401 +} 1.402 + 1.403 +void 1.404 +DrawTargetRecording::DrawFilter(FilterNode *aNode, 1.405 + const Rect &aSourceRect, 1.406 + const Point &aDestPoint, 1.407 + const DrawOptions &aOptions) 1.408 +{ 1.409 + mRecorder->RecordEvent(RecordedDrawFilter(this, aNode, aSourceRect, aDestPoint, aOptions)); 1.410 + mFinalDT->DrawFilter(GetFilterNode(aNode), aSourceRect, aDestPoint, aOptions); 1.411 +} 1.412 + 1.413 +TemporaryRef<FilterNode> 1.414 +DrawTargetRecording::CreateFilter(FilterType aType) 1.415 +{ 1.416 + RefPtr<FilterNode> node = mFinalDT->CreateFilter(aType); 1.417 + 1.418 + RefPtr<FilterNode> retNode = new FilterNodeRecording(node, mRecorder); 1.419 + 1.420 + mRecorder->RecordEvent(RecordedFilterNodeCreation(retNode, aType)); 1.421 + 1.422 + return retNode; 1.423 +} 1.424 + 1.425 +void 1.426 +DrawTargetRecording::ClearRect(const Rect &aRect) 1.427 +{ 1.428 + mRecorder->RecordEvent(RecordedClearRect(this, aRect)); 1.429 + mFinalDT->ClearRect(aRect); 1.430 +} 1.431 + 1.432 +void 1.433 +DrawTargetRecording::CopySurface(SourceSurface *aSurface, 1.434 + const IntRect &aSourceRect, 1.435 + const IntPoint &aDestination) 1.436 +{ 1.437 + mRecorder->RecordEvent(RecordedCopySurface(this, aSurface, aSourceRect, aDestination)); 1.438 + mFinalDT->CopySurface(GetSourceSurface(aSurface), aSourceRect, aDestination); 1.439 +} 1.440 + 1.441 +void 1.442 +DrawTargetRecording::PushClip(const Path *aPath) 1.443 +{ 1.444 + EnsureStored(aPath); 1.445 + 1.446 + mRecorder->RecordEvent(RecordedPushClip(this, const_cast<Path*>(aPath))); 1.447 + mFinalDT->PushClip(GetPathForPathRecording(aPath)); 1.448 +} 1.449 + 1.450 +void 1.451 +DrawTargetRecording::PushClipRect(const Rect &aRect) 1.452 +{ 1.453 + mRecorder->RecordEvent(RecordedPushClipRect(this, aRect)); 1.454 + mFinalDT->PushClipRect(aRect); 1.455 +} 1.456 + 1.457 +void 1.458 +DrawTargetRecording::PopClip() 1.459 +{ 1.460 + mRecorder->RecordEvent(RecordedPopClip(this)); 1.461 + mFinalDT->PopClip(); 1.462 +} 1.463 + 1.464 +TemporaryRef<SourceSurface> 1.465 +DrawTargetRecording::CreateSourceSurfaceFromData(unsigned char *aData, 1.466 + const IntSize &aSize, 1.467 + int32_t aStride, 1.468 + SurfaceFormat aFormat) const 1.469 +{ 1.470 + RefPtr<SourceSurface> surf = mFinalDT->CreateSourceSurfaceFromData(aData, aSize, aStride, aFormat); 1.471 + 1.472 + RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder); 1.473 + 1.474 + mRecorder->RecordEvent(RecordedSourceSurfaceCreation(retSurf, aData, aStride, aSize, aFormat)); 1.475 + 1.476 + return retSurf; 1.477 +} 1.478 + 1.479 +TemporaryRef<SourceSurface> 1.480 +DrawTargetRecording::OptimizeSourceSurface(SourceSurface *aSurface) const 1.481 +{ 1.482 + RefPtr<SourceSurface> surf = mFinalDT->OptimizeSourceSurface(aSurface); 1.483 + 1.484 + RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder); 1.485 + 1.486 + RefPtr<DataSourceSurface> dataSurf = surf->GetDataSurface(); 1.487 + 1.488 + if (!dataSurf) { 1.489 + // Let's try get it off the original surface. 1.490 + dataSurf = aSurface->GetDataSurface(); 1.491 + } 1.492 + 1.493 + if (!dataSurf) { 1.494 + gfxWarning() << "Recording failed to record SourceSurface created from OptimizeSourceSurface"; 1.495 + // Insert a bogus source surface. 1.496 + uint8_t *sourceData = new uint8_t[surf->GetSize().width * surf->GetSize().height * BytesPerPixel(surf->GetFormat())]; 1.497 + memset(sourceData, 0, surf->GetSize().width * surf->GetSize().height * BytesPerPixel(surf->GetFormat())); 1.498 + mRecorder->RecordEvent( 1.499 + RecordedSourceSurfaceCreation(retSurf, sourceData, 1.500 + surf->GetSize().width * BytesPerPixel(surf->GetFormat()), 1.501 + surf->GetSize(), surf->GetFormat())); 1.502 + delete [] sourceData; 1.503 + } else { 1.504 + mRecorder->RecordEvent( 1.505 + RecordedSourceSurfaceCreation(retSurf, dataSurf->GetData(), dataSurf->Stride(), 1.506 + dataSurf->GetSize(), dataSurf->GetFormat())); 1.507 + } 1.508 + 1.509 + return retSurf; 1.510 +} 1.511 + 1.512 +TemporaryRef<SourceSurface> 1.513 +DrawTargetRecording::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const 1.514 +{ 1.515 + RefPtr<SourceSurface> surf = mFinalDT->CreateSourceSurfaceFromNativeSurface(aSurface); 1.516 + 1.517 + RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder); 1.518 + 1.519 + RefPtr<DataSourceSurface> dataSurf = surf->GetDataSurface(); 1.520 + 1.521 + if (!dataSurf) { 1.522 + gfxWarning() << "Recording failed to record SourceSurface created from OptimizeSourceSurface"; 1.523 + // Insert a bogus source surface. 1.524 + uint8_t *sourceData = new uint8_t[surf->GetSize().width * surf->GetSize().height * BytesPerPixel(surf->GetFormat())]; 1.525 + memset(sourceData, 0, surf->GetSize().width * surf->GetSize().height * BytesPerPixel(surf->GetFormat())); 1.526 + mRecorder->RecordEvent( 1.527 + RecordedSourceSurfaceCreation(retSurf, sourceData, 1.528 + surf->GetSize().width * BytesPerPixel(surf->GetFormat()), 1.529 + surf->GetSize(), surf->GetFormat())); 1.530 + delete [] sourceData; 1.531 + } else { 1.532 + mRecorder->RecordEvent( 1.533 + RecordedSourceSurfaceCreation(retSurf, dataSurf->GetData(), dataSurf->Stride(), 1.534 + dataSurf->GetSize(), dataSurf->GetFormat())); 1.535 + } 1.536 + 1.537 + return retSurf; 1.538 +} 1.539 + 1.540 +TemporaryRef<DrawTarget> 1.541 +DrawTargetRecording::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const 1.542 +{ 1.543 + RefPtr<DrawTarget> dt = mFinalDT->CreateSimilarDrawTarget(aSize, aFormat); 1.544 + 1.545 + RefPtr<DrawTarget> retDT = new DrawTargetRecording(mRecorder.get(), dt); 1.546 + 1.547 + return retDT; 1.548 +} 1.549 + 1.550 +TemporaryRef<PathBuilder> 1.551 +DrawTargetRecording::CreatePathBuilder(FillRule aFillRule) const 1.552 +{ 1.553 + RefPtr<PathBuilder> builder = mFinalDT->CreatePathBuilder(aFillRule); 1.554 + return new PathBuilderRecording(builder, aFillRule); 1.555 +} 1.556 + 1.557 +TemporaryRef<GradientStops> 1.558 +DrawTargetRecording::CreateGradientStops(GradientStop *aStops, 1.559 + uint32_t aNumStops, 1.560 + ExtendMode aExtendMode) const 1.561 +{ 1.562 + RefPtr<GradientStops> stops = mFinalDT->CreateGradientStops(aStops, aNumStops, aExtendMode); 1.563 + 1.564 + RefPtr<GradientStops> retStops = new GradientStopsRecording(stops, mRecorder); 1.565 + 1.566 + mRecorder->RecordEvent(RecordedGradientStopsCreation(retStops, aStops, aNumStops, aExtendMode)); 1.567 + 1.568 + return retStops; 1.569 +} 1.570 + 1.571 +void 1.572 +DrawTargetRecording::SetTransform(const Matrix &aTransform) 1.573 +{ 1.574 + mRecorder->RecordEvent(RecordedSetTransform(this, aTransform)); 1.575 + DrawTarget::SetTransform(aTransform); 1.576 + mFinalDT->SetTransform(aTransform); 1.577 +} 1.578 + 1.579 +void 1.580 +DrawTargetRecording::EnsureStored(const Path *aPath) 1.581 +{ 1.582 + if (!mRecorder->HasStoredPath(aPath)) { 1.583 + if (aPath->GetBackendType() != BackendType::RECORDING) { 1.584 + gfxWarning() << "Cannot record this fill path properly!"; 1.585 + } else { 1.586 + PathRecording *recPath = const_cast<PathRecording*>(static_cast<const PathRecording*>(aPath)); 1.587 + mRecorder->RecordEvent(RecordedPathCreation(recPath)); 1.588 + mRecorder->AddStoredPath(aPath); 1.589 + recPath->mStoredRecorders.push_back(mRecorder); 1.590 + } 1.591 + } 1.592 +} 1.593 + 1.594 +} 1.595 +}