gfx/2d/DrawTargetRecording.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial