Bug 1362245. Stop running commands during recording for BlobImage. r=lsalzman
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Mon, 12 Jun 2017 17:53:21 -0400
changeset 412310 fc0a10e36093
parent 412309 6dca7816cb61
child 412311 b1940873102d
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsalzman
bugs1362245
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1362245. Stop running commands during recording for BlobImage. r=lsalzman This keeps around mFinalDT but mostly doesn't use it (except for when creating a PathBuilder). All playback is ripped out and we'll no longer hold references to things to mFinalDT::GraidentStops or SourceSurfaces etc.
gfx/2d/2D.h
gfx/2d/DrawTargetRecording.cpp
gfx/2d/DrawTargetRecording.h
gfx/2d/Factory.cpp
gfx/layers/wr/WebRenderDisplayItemLayer.cpp
gfx/layers/wr/WebRenderPaintedLayerBlob.cpp
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -1494,17 +1494,17 @@ public:
 
   static already_AddRefed<DrawTarget>
     CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat);
 
   static already_AddRefed<DrawTarget>
     CreateWrapAndRecordDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT);
 
   static already_AddRefed<DrawTarget>
-    CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT);
+    CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT, IntSize aSize);
 
   static already_AddRefed<DrawTarget>
     CreateDrawTargetForData(BackendType aBackend, unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat, bool aUninitialized = false);
 
   static already_AddRefed<ScaledFont>
     CreateScaledFontForNativeFont(const NativeFont &aNativeFont,
                                   const RefPtr<UnscaledFont>& aUnscaledFont,
                                   Float aSize);
--- a/gfx/2d/DrawTargetRecording.cpp
+++ b/gfx/2d/DrawTargetRecording.cpp
@@ -76,128 +76,136 @@ EnsureSurfaceStoredRecording(DrawEventRe
                         userData, &RecordingSourceSurfaceUserDataFunc);
   return;
 }
 
 class SourceSurfaceRecording : public SourceSurface
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceRecording)
-  SourceSurfaceRecording(SourceSurface *aFinalSurface, DrawEventRecorderPrivate *aRecorder)
-    : mFinalSurface(aFinalSurface), mRecorder(aRecorder)
+  SourceSurfaceRecording(IntSize aSize, SurfaceFormat aFormat, DrawEventRecorderPrivate *aRecorder)
+    : mSize(aSize), mFormat(aFormat), mRecorder(aRecorder)
   {
     mRecorder->AddStoredObject(this);
   }
 
   ~SourceSurfaceRecording()
   {
     mRecorder->RemoveStoredObject(this);
     mRecorder->RecordEvent(RecordedSourceSurfaceDestruction(this));
   }
 
   virtual SurfaceType GetType() const { return SurfaceType::RECORDING; }
-  virtual IntSize GetSize() const { return mFinalSurface->GetSize(); }
-  virtual SurfaceFormat GetFormat() const { return mFinalSurface->GetFormat(); }
-  virtual already_AddRefed<DataSourceSurface> GetDataSurface() { return mFinalSurface->GetDataSurface(); }
+  virtual IntSize GetSize() const { return mSize; }
+  virtual SurfaceFormat GetFormat() const { return mFormat; }
+  virtual already_AddRefed<DataSourceSurface> GetDataSurface() { return nullptr; }
 
-  RefPtr<SourceSurface> mFinalSurface;
+  IntSize mSize;
+  SurfaceFormat mFormat;
   RefPtr<DrawEventRecorderPrivate> mRecorder;
 };
 
+class DataSourceSurfaceRecording : public DataSourceSurface
+{
+public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceRecording, override)
+  DataSourceSurfaceRecording(UniquePtr<uint8_t[]> aData, IntSize aSize,
+                             int32_t aStride, SurfaceFormat aFormat)
+    : mData(Move(aData))
+    , mSize(aSize)
+    , mStride(aStride)
+    , mFormat(aFormat)
+  {
+  }
+
+  ~DataSourceSurfaceRecording()
+  {
+  }
+
+  static already_AddRefed<DataSourceSurface>
+  Init(uint8_t *aData, IntSize aSize, int32_t aStride, SurfaceFormat aFormat)
+  {
+    //XXX: do we need to ensure any alignment here?
+    auto data = MakeUnique<uint8_t[]>(aStride * aSize.height * BytesPerPixel(aFormat));
+    if (data) {
+      memcpy(data.get(), aData, aStride * aSize.height * BytesPerPixel(aFormat));
+      RefPtr<DataSourceSurfaceRecording> surf = new DataSourceSurfaceRecording(Move(data), aSize, aStride, aFormat);
+      return surf.forget();
+    }
+    return nullptr;
+  }
+
+  virtual SurfaceType GetType() const override { return SurfaceType::RECORDING; }
+  virtual IntSize GetSize() const override { return mSize; }
+  virtual int32_t Stride() override { return mStride; }
+  virtual SurfaceFormat GetFormat() const override { return mFormat; }
+  virtual uint8_t* GetData() override { return mData.get(); }
+
+  UniquePtr<uint8_t[]> mData;
+  IntSize mSize;
+  int32_t mStride;
+  SurfaceFormat mFormat;
+};
+
+
 class GradientStopsRecording : public GradientStops
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStopsRecording)
-  GradientStopsRecording(GradientStops *aFinalGradientStops, DrawEventRecorderPrivate *aRecorder)
-    : mFinalGradientStops(aFinalGradientStops), mRecorder(aRecorder)
+  explicit GradientStopsRecording(DrawEventRecorderPrivate *aRecorder)
+    : mRecorder(aRecorder)
   {
     mRecorder->AddStoredObject(this);
   }
 
   ~GradientStopsRecording()
   {
     mRecorder->RemoveStoredObject(this);
     mRecorder->RecordEvent(RecordedGradientStopsDestruction(this));
   }
 
   virtual BackendType GetBackendType() const { return BackendType::RECORDING; }
 
-  RefPtr<GradientStops> mFinalGradientStops;
   RefPtr<DrawEventRecorderPrivate> mRecorder;
 };
 
-static SourceSurface *
-GetSourceSurfaceRecording(SourceSurface *aSurface)
-{
-  if (aSurface->GetType() != SurfaceType::RECORDING) {
-    return aSurface;
-  }
-
-  return static_cast<SourceSurfaceRecording*>(aSurface)->mFinalSurface;
-}
-
-static GradientStops *
-GetGradientStopsRecording(GradientStops *aStops)
-{
-  if (aStops->GetBackendType() != BackendType::RECORDING) {
-    return aStops;
-  }
-
-  return static_cast<GradientStopsRecording*>(aStops)->mFinalGradientStops;
-}
-
 class FilterNodeRecording : public FilterNode
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeRecording, override)
   using FilterNode::SetAttribute;
 
-  FilterNodeRecording(FilterNode *aFinalFilterNode, DrawEventRecorderPrivate *aRecorder)
-    : mFinalFilterNode(aFinalFilterNode), mRecorder(aRecorder)
+  explicit FilterNodeRecording(DrawEventRecorderPrivate *aRecorder)
+    : mRecorder(aRecorder)
   {
     mRecorder->AddStoredObject(this);
   }
 
   ~FilterNodeRecording()
   {
     mRecorder->RemoveStoredObject(this);
     mRecorder->RecordEvent(RecordedFilterNodeDestruction(this));
   }
 
-  static FilterNode*
-  GetFilterNode(FilterNode* aNode)
-  {
-    if (aNode->GetBackendType() != FILTER_BACKEND_RECORDING) {
-      gfxWarning() << "Non recording filter node used with recording DrawTarget!";
-      return aNode;
-    }
-
-    return static_cast<FilterNodeRecording*>(aNode)->mFinalFilterNode;
-  }
-
   virtual void SetInput(uint32_t aIndex, SourceSurface *aSurface) override
   {
     EnsureSurfaceStoredRecording(mRecorder, aSurface,  "SetInput");
 
     mRecorder->RecordEvent(RecordedFilterNodeSetInput(this, aIndex, aSurface));
-    mFinalFilterNode->SetInput(aIndex, GetSourceSurfaceRecording(aSurface));
   }
   virtual void SetInput(uint32_t aIndex, FilterNode *aFilter) override
   {
     MOZ_ASSERT(mRecorder->HasStoredObject(aFilter));
 
     mRecorder->RecordEvent(RecordedFilterNodeSetInput(this, aIndex, aFilter));
-    mFinalFilterNode->SetInput(aIndex, GetFilterNode(aFilter));
   }
 
-
 #define FORWARD_SET_ATTRIBUTE(type, argtype) \
   virtual void SetAttribute(uint32_t aIndex, type aValue) override { \
     mRecorder->RecordEvent(RecordedFilterNodeSetAttribute(this, aIndex, aValue, RecordedFilterNodeSetAttribute::ARGTYPE_##argtype)); \
-    mFinalFilterNode->SetAttribute(aIndex, aValue); \
   }
 
   FORWARD_SET_ATTRIBUTE(bool, BOOL);
   FORWARD_SET_ATTRIBUTE(uint32_t, UINT32);
   FORWARD_SET_ATTRIBUTE(Float, FLOAT);
   FORWARD_SET_ATTRIBUTE(const Size&, SIZE);
   FORWARD_SET_ATTRIBUTE(const IntSize&, INTSIZE);
   FORWARD_SET_ATTRIBUTE(const IntPoint&, INTPOINT);
@@ -208,166 +216,97 @@ public:
   FORWARD_SET_ATTRIBUTE(const Matrix5x4&, MATRIX5X4);
   FORWARD_SET_ATTRIBUTE(const Point3D&, POINT3D);
   FORWARD_SET_ATTRIBUTE(const Color&, COLOR);
 
 #undef FORWARD_SET_ATTRIBUTE
 
   virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) override {
     mRecorder->RecordEvent(RecordedFilterNodeSetAttribute(this, aIndex, aFloat, aSize));
-    mFinalFilterNode->SetAttribute(aIndex, aFloat, aSize);
   }
 
   virtual FilterBackend GetBackendType() override { return FILTER_BACKEND_RECORDING; }
 
-  RefPtr<FilterNode> mFinalFilterNode;
   RefPtr<DrawEventRecorderPrivate> mRecorder;
 };
 
-struct AdjustedPatternRecording
-{
-  explicit AdjustedPatternRecording(const Pattern &aPattern)
-    : mPattern(nullptr)
-  {
-    mOrigPattern = const_cast<Pattern*>(&aPattern);
-  }
-
-  ~AdjustedPatternRecording() {
-    if (mPattern) {
-      mPattern->~Pattern();
-    }
-  }
-
-  operator Pattern*()
-  {
-    switch(mOrigPattern->GetType()) {
-    case PatternType::COLOR:
-      return mOrigPattern;
-    case PatternType::SURFACE:
-      {
-        SurfacePattern *surfPat = static_cast<SurfacePattern*>(mOrigPattern);
-        mPattern =
-          new (mSurfPat) SurfacePattern(GetSourceSurfaceRecording(surfPat->mSurface),
-                                        surfPat->mExtendMode, surfPat->mMatrix,
-                                        surfPat->mSamplingFilter,
-                                        surfPat->mSamplingRect);
-        return mPattern;
-      }
-    case PatternType::LINEAR_GRADIENT:
-      {
-        LinearGradientPattern *linGradPat = static_cast<LinearGradientPattern*>(mOrigPattern);
-        mPattern =
-          new (mLinGradPat) LinearGradientPattern(linGradPat->mBegin, linGradPat->mEnd,
-                                                  GetGradientStopsRecording(linGradPat->mStops),
-                                                  linGradPat->mMatrix);
-        return mPattern;
-      }
-    case PatternType::RADIAL_GRADIENT:
-      {
-        RadialGradientPattern *radGradPat = static_cast<RadialGradientPattern*>(mOrigPattern);
-        mPattern =
-          new (mRadGradPat) RadialGradientPattern(radGradPat->mCenter1, radGradPat->mCenter2,
-                                                  radGradPat->mRadius1, radGradPat->mRadius2,
-                                                  GetGradientStopsRecording(radGradPat->mStops),
-                                                  radGradPat->mMatrix);
-        return mPattern;
-      }
-    default:
-      return new (mColPat) ColorPattern(Color());
-    }
-
-    return mPattern;
-  }
-
-  union {
-    char mColPat[sizeof(ColorPattern)];
-    char mLinGradPat[sizeof(LinearGradientPattern)];
-    char mRadGradPat[sizeof(RadialGradientPattern)];
-    char mSurfPat[sizeof(SurfacePattern)];
-  };
-
-  Pattern *mOrigPattern;
-  Pattern *mPattern;
-};
-
-DrawTargetRecording::DrawTargetRecording(DrawEventRecorder *aRecorder, DrawTarget *aDT, bool aHasData)
+DrawTargetRecording::DrawTargetRecording(DrawEventRecorder *aRecorder, DrawTarget *aDT, IntSize aSize, bool aHasData)
   : mRecorder(static_cast<DrawEventRecorderPrivate*>(aRecorder))
   , mFinalDT(aDT)
+  , mSize(aSize)
 {
   RefPtr<SourceSurface> snapshot = aHasData ? mFinalDT->Snapshot() : nullptr;
   mRecorder->RecordEvent(RecordedDrawTargetCreation(this,
                                                     mFinalDT->GetBackendType(),
-                                                    mFinalDT->GetSize(),
+                                                    mSize,
                                                     mFinalDT->GetFormat(),
                                                     aHasData, snapshot));
   mFormat = mFinalDT->GetFormat();
 }
 
 DrawTargetRecording::DrawTargetRecording(const DrawTargetRecording *aDT,
-                                         DrawTarget *aSimilarDT)
+                                         IntSize aSize,
+                                         SurfaceFormat aFormat)
   : mRecorder(aDT->mRecorder)
-  , mFinalDT(aSimilarDT)
+  , mFinalDT(aDT->mFinalDT)
+  , mSize(aSize)
 {
   mRecorder->RecordEvent(RecordedCreateSimilarDrawTarget(this,
-                                                         mFinalDT->GetSize(),
-                                                         mFinalDT->GetFormat()));
-  mFormat = mFinalDT->GetFormat();
+                                                         aSize,
+                                                         aFormat));
+  mFormat = aFormat;
 }
 
 DrawTargetRecording::~DrawTargetRecording()
 {
   mRecorder->RecordEvent(RecordedDrawTargetDestruction(this));
 }
 
 void
 DrawTargetRecording::FillRect(const Rect &aRect,
                               const Pattern &aPattern,
                               const DrawOptions &aOptions)
 {
   EnsurePatternDependenciesStored(aPattern);
 
   mRecorder->RecordEvent(RecordedFillRect(this, aRect, aPattern, aOptions));
-  mFinalDT->FillRect(aRect, *AdjustedPatternRecording(aPattern), aOptions);
 }
 
 void
 DrawTargetRecording::StrokeRect(const Rect &aRect,
                                 const Pattern &aPattern,
                                 const StrokeOptions &aStrokeOptions,
                                 const DrawOptions &aOptions)
 {
   EnsurePatternDependenciesStored(aPattern);
 
   mRecorder->RecordEvent(RecordedStrokeRect(this, aRect, aPattern, aStrokeOptions, aOptions));
-  mFinalDT->StrokeRect(aRect, *AdjustedPatternRecording(aPattern), aStrokeOptions, aOptions);
 }
 
 void
 DrawTargetRecording::StrokeLine(const Point &aBegin,
                                 const Point &aEnd,
                                 const Pattern &aPattern,
                                 const StrokeOptions &aStrokeOptions,
                                 const DrawOptions &aOptions)
 {
   EnsurePatternDependenciesStored(aPattern);
 
   mRecorder->RecordEvent(RecordedStrokeLine(this, aBegin, aEnd, aPattern, aStrokeOptions, aOptions));
-  mFinalDT->StrokeLine(aBegin, aEnd, *AdjustedPatternRecording(aPattern), aStrokeOptions, aOptions);
 }
 
 void
 DrawTargetRecording::Fill(const Path *aPath,
                           const Pattern &aPattern,
                           const DrawOptions &aOptions)
 {
   RefPtr<PathRecording> pathRecording = EnsurePathStored(aPath);
   EnsurePatternDependenciesStored(aPattern);
 
   mRecorder->RecordEvent(RecordedFill(this, pathRecording, aPattern, aOptions));
-  mFinalDT->Fill(pathRecording->mPath, *AdjustedPatternRecording(aPattern), aOptions);
 }
 
 struct RecordingFontUserData
 {
   void *refPtr;
   RefPtr<DrawEventRecorderPrivate> recorder;
 };
 
@@ -422,290 +361,241 @@ DrawTargetRecording::FillGlyphs(ScaledFo
     RecordingFontUserData *userData = new RecordingFontUserData;
     userData->refPtr = aFont;
     userData->recorder = mRecorder;
     aFont->AddUserData(userDataKey, userData, &RecordingFontUserDataDestroyFunc);
     userData->recorder->AddScaledFont(aFont);
   }
 
   mRecorder->RecordEvent(RecordedFillGlyphs(this, aFont, aPattern, aOptions, aBuffer.mGlyphs, aBuffer.mNumGlyphs));
-  mFinalDT->FillGlyphs(aFont, aBuffer, *AdjustedPatternRecording(aPattern), aOptions, aRenderingOptions);
 }
 
 void
 DrawTargetRecording::Mask(const Pattern &aSource,
                           const Pattern &aMask,
                           const DrawOptions &aOptions)
 {
   EnsurePatternDependenciesStored(aSource);
   EnsurePatternDependenciesStored(aMask);
 
   mRecorder->RecordEvent(RecordedMask(this, aSource, aMask, aOptions));
-  mFinalDT->Mask(*AdjustedPatternRecording(aSource), *AdjustedPatternRecording(aMask), aOptions);
 }
 
 void
 DrawTargetRecording::MaskSurface(const Pattern &aSource,
                                  SourceSurface *aMask,
                                  Point aOffset,
                                  const DrawOptions &aOptions)
 {
   EnsurePatternDependenciesStored(aSource);
   EnsureSurfaceStoredRecording(mRecorder, aMask, "MaskSurface");
 
   mRecorder->RecordEvent(RecordedMaskSurface(this, aSource, aMask, aOffset, aOptions));
-  mFinalDT->MaskSurface(*AdjustedPatternRecording(aSource), GetSourceSurfaceRecording(aMask), aOffset, aOptions);
 }
 
 void
 DrawTargetRecording::Stroke(const Path *aPath,
                             const Pattern &aPattern,
                             const StrokeOptions &aStrokeOptions,
                             const DrawOptions &aOptions)
 {
   RefPtr<PathRecording> pathRecording = EnsurePathStored(aPath);
   EnsurePatternDependenciesStored(aPattern);
 
   mRecorder->RecordEvent(RecordedStroke(this, pathRecording, aPattern, aStrokeOptions, aOptions));
-  mFinalDT->Stroke(pathRecording->mPath, *AdjustedPatternRecording(aPattern), aStrokeOptions, aOptions);
 }
 
 already_AddRefed<SourceSurface>
 DrawTargetRecording::Snapshot()
 {
-  RefPtr<SourceSurface> surf = mFinalDT->Snapshot();
-
-  RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder);
+  RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(mSize, mFormat, mRecorder);
 
   mRecorder->RecordEvent(RecordedSnapshot(retSurf, this));
 
   return retSurf.forget();
 }
 
 already_AddRefed<SourceSurface>
 DrawTargetRecording::IntoLuminanceSource(LuminanceType aLuminanceType, float aOpacity)
 {
-  RefPtr<SourceSurface> surf = mFinalDT->IntoLuminanceSource(aLuminanceType, aOpacity);
-
-  RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder);
+  RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(mSize, SurfaceFormat::A8, mRecorder);
 
   mRecorder->RecordEvent(RecordedIntoLuminanceSource(retSurf, this, aLuminanceType, aOpacity));
 
   return retSurf.forget();
 }
 
 void
 DrawTargetRecording::DetachAllSnapshots()
 {
-  mFinalDT->DetachAllSnapshots();
 }
 
 void
 DrawTargetRecording::DrawSurface(SourceSurface *aSurface,
                                  const Rect &aDest,
                                  const Rect &aSource,
                                  const DrawSurfaceOptions &aSurfOptions,
                                  const DrawOptions &aOptions)
 {
   EnsureSurfaceStoredRecording(mRecorder, aSurface, "DrawSurface");
 
   mRecorder->RecordEvent(RecordedDrawSurface(this, aSurface, aDest, aSource, aSurfOptions, aOptions));
-  mFinalDT->DrawSurface(GetSourceSurfaceRecording(aSurface), aDest, aSource, aSurfOptions, aOptions);
 }
 
 void
 DrawTargetRecording::DrawSurfaceWithShadow(SourceSurface *aSurface,
                                            const Point &aDest,
                                            const Color &aColor,
                                            const Point &aOffset,
                                            Float aSigma,
                                            CompositionOp aOp)
 {
   EnsureSurfaceStoredRecording(mRecorder, aSurface, "DrawSurfaceWithShadow");
 
   mRecorder->RecordEvent(RecordedDrawSurfaceWithShadow(this, aSurface, aDest, aColor, aOffset, aSigma, aOp));
-  mFinalDT->DrawSurfaceWithShadow(GetSourceSurfaceRecording(aSurface), aDest, aColor, aOffset, aSigma, aOp);
 }
 
 void
 DrawTargetRecording::DrawFilter(FilterNode *aNode,
                                 const Rect &aSourceRect,
                                 const Point &aDestPoint,
                                 const DrawOptions &aOptions)
 {
   MOZ_ASSERT(mRecorder->HasStoredObject(aNode));
 
   mRecorder->RecordEvent(RecordedDrawFilter(this, aNode, aSourceRect, aDestPoint, aOptions));
-  mFinalDT->DrawFilter(FilterNodeRecording::GetFilterNode(aNode), aSourceRect, aDestPoint, aOptions);
 }
 
 already_AddRefed<FilterNode>
 DrawTargetRecording::CreateFilter(FilterType aType)
 {
-  RefPtr<FilterNode> node = mFinalDT->CreateFilter(aType);
-
-  RefPtr<FilterNode> retNode = new FilterNodeRecording(node, mRecorder);
+  RefPtr<FilterNode> retNode = new FilterNodeRecording(mRecorder);
 
   mRecorder->RecordEvent(RecordedFilterNodeCreation(retNode, aType));
 
   return retNode.forget();
 }
 
 void
 DrawTargetRecording::ClearRect(const Rect &aRect)
 {
   mRecorder->RecordEvent(RecordedClearRect(this, aRect));
-  mFinalDT->ClearRect(aRect);
 }
 
 void
 DrawTargetRecording::CopySurface(SourceSurface *aSurface,
                                  const IntRect &aSourceRect,
                                  const IntPoint &aDestination)
 {
   EnsureSurfaceStoredRecording(mRecorder, aSurface, "CopySurface");
 
   mRecorder->RecordEvent(RecordedCopySurface(this, aSurface, aSourceRect, aDestination));
-  mFinalDT->CopySurface(GetSourceSurfaceRecording(aSurface), aSourceRect, aDestination);
 }
 
 void
 DrawTargetRecording::PushClip(const Path *aPath)
 {
   RefPtr<PathRecording> pathRecording = EnsurePathStored(aPath);
 
   mRecorder->RecordEvent(RecordedPushClip(this, pathRecording));
-  mFinalDT->PushClip(pathRecording->mPath);
 }
 
 void
 DrawTargetRecording::PushClipRect(const Rect &aRect)
 {
   mRecorder->RecordEvent(RecordedPushClipRect(this, aRect));
-  mFinalDT->PushClipRect(aRect);
 }
 
 void
 DrawTargetRecording::PopClip()
 {
   mRecorder->RecordEvent(RecordedPopClip(this));
-  mFinalDT->PopClip();
 }
 
 void
 DrawTargetRecording::PushLayer(bool aOpaque, Float aOpacity,
                                SourceSurface* aMask,
                                const Matrix& aMaskTransform,
                                const IntRect& aBounds, bool aCopyBackground)
 {
   if (aMask) {
     EnsureSurfaceStoredRecording(mRecorder, aMask, "PushLayer");
   }
 
   mRecorder->RecordEvent(RecordedPushLayer(this, aOpaque, aOpacity, aMask,
                                            aMaskTransform, aBounds,
                                            aCopyBackground));
-  mFinalDT->PushLayer(aOpaque, aOpacity, aMask, aMaskTransform, aBounds,
-                      aCopyBackground);
 }
 
 void
 DrawTargetRecording::PopLayer()
 {
   mRecorder->RecordEvent(RecordedPopLayer(this));
-  mFinalDT->PopLayer();
 }
 
 already_AddRefed<SourceSurface>
 DrawTargetRecording::CreateSourceSurfaceFromData(unsigned char *aData,
                                                  const IntSize &aSize,
                                                  int32_t aStride,
                                                  SurfaceFormat aFormat) const
 {
-  RefPtr<SourceSurface> surf = mFinalDT->CreateSourceSurfaceFromData(aData, aSize, aStride, aFormat);
+  RefPtr<SourceSurface> surf = DataSourceSurfaceRecording::Init(aData, aSize, aStride, aFormat);
 
-  RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder);
+  RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(aSize, aFormat, mRecorder);
 
   mRecorder->RecordEvent(RecordedSourceSurfaceCreation(retSurf, aData, aStride, aSize, aFormat));
 
   return retSurf.forget();
 }
 
 already_AddRefed<SourceSurface>
 DrawTargetRecording::OptimizeSourceSurface(SourceSurface *aSurface) const
 {
-  RefPtr<SourceSurface> surf = mFinalDT->OptimizeSourceSurface(aSurface);
-
-  RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder);
-
-  RefPtr<DataSourceSurface> dataSurf = surf->GetDataSurface();
-
-  if (!dataSurf) {
-    // Let's try get it off the original surface.
-    dataSurf = aSurface->GetDataSurface();
-  }
-
-  StoreSourceSurfaceRecording(mRecorder, retSurf, dataSurf, "OptimizeSourceSurface");
-
-  return retSurf.forget();
+  RefPtr<SourceSurface> surf(aSurface);
+  return surf.forget();
 }
 
 already_AddRefed<SourceSurface>
 DrawTargetRecording::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const
 {
-  RefPtr<SourceSurface> surf = mFinalDT->CreateSourceSurfaceFromNativeSurface(aSurface);
-
-  RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder);
-
-  RefPtr<DataSourceSurface> dataSurf = surf->GetDataSurface();
-  StoreSourceSurfaceRecording(mRecorder, retSurf, dataSurf, "CreateSourceSurfaceFromNativeSurface");
-
-  return retSurf.forget();
+  MOZ_ASSERT(false);
+  return nullptr;
 }
 
 already_AddRefed<DrawTarget>
 DrawTargetRecording::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
 {
-  RefPtr<DrawTarget> similarDT =
-    mFinalDT->CreateSimilarDrawTarget(aSize, aFormat);
-  if (!similarDT) {
-    return nullptr;
-  }
-
-  similarDT = new DrawTargetRecording(this, similarDT);
+  RefPtr<DrawTarget> similarDT = new DrawTargetRecording(this, aSize, aFormat);
   return similarDT.forget();
 }
 
 already_AddRefed<PathBuilder>
 DrawTargetRecording::CreatePathBuilder(FillRule aFillRule) const
 {
   RefPtr<PathBuilder> builder = mFinalDT->CreatePathBuilder(aFillRule);
   return MakeAndAddRef<PathBuilderRecording>(builder, aFillRule);
 }
 
 already_AddRefed<GradientStops>
 DrawTargetRecording::CreateGradientStops(GradientStop *aStops,
                                          uint32_t aNumStops,
                                          ExtendMode aExtendMode) const
 {
-  RefPtr<GradientStops> stops = mFinalDT->CreateGradientStops(aStops, aNumStops, aExtendMode);
-
-  RefPtr<GradientStops> retStops = new GradientStopsRecording(stops, mRecorder);
+  RefPtr<GradientStops> retStops = new GradientStopsRecording(mRecorder);
 
   mRecorder->RecordEvent(RecordedGradientStopsCreation(retStops, aStops, aNumStops, aExtendMode));
 
   return retStops.forget();
 }
 
 void
 DrawTargetRecording::SetTransform(const Matrix &aTransform)
 {
   mRecorder->RecordEvent(RecordedSetTransform(this, aTransform));
   DrawTarget::SetTransform(aTransform);
-  mFinalDT->SetTransform(aTransform);
 }
 
 already_AddRefed<PathRecording>
 DrawTargetRecording::EnsurePathStored(const Path *aPath)
 {
   RefPtr<PathRecording> pathRecording;
   if (aPath->GetBackendType() == BackendType::RECORDING) {
     pathRecording = const_cast<PathRecording*>(static_cast<const PathRecording*>(aPath));
--- a/gfx/2d/DrawTargetRecording.h
+++ b/gfx/2d/DrawTargetRecording.h
@@ -12,22 +12,22 @@
 
 namespace mozilla {
 namespace gfx {
 
 class DrawTargetRecording : public DrawTarget
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetRecording, override)
-  DrawTargetRecording(DrawEventRecorder *aRecorder, DrawTarget *aDT, bool aHasData = false);
+  DrawTargetRecording(DrawEventRecorder *aRecorder, DrawTarget *aDT, IntSize aSize, bool aHasData = false);
 
   ~DrawTargetRecording();
 
   virtual DrawTargetType GetType() const override { return mFinalDT->GetType(); }
-  virtual BackendType GetBackendType() const override { return mFinalDT->GetBackendType(); }
+  virtual BackendType GetBackendType() const override { return BackendType::RECORDING; }
   virtual bool IsRecording() const override { return true; }
 
   virtual already_AddRefed<SourceSurface> Snapshot() override;
   virtual already_AddRefed<SourceSurface> IntoLuminanceSource(LuminanceType aLuminanceType, float aOpacity) override;
 
   virtual void DetachAllSnapshots() override;
 
   virtual IntSize GetSize() override { return mFinalDT->GetSize(); }
@@ -310,29 +310,29 @@ public:
 
   virtual bool IsCurrentGroupOpaque() override {
     return mFinalDT->IsCurrentGroupOpaque();
   }
 
 private:
   /**
    * Used for creating a DrawTargetRecording for a CreateSimilarDrawTarget call.
-   * We have to call CreateSimilarDrawTarget on mFinalDT up front and pass it in
-   * as it can fail.
    *
    * @param aDT DrawTargetRecording on which CreateSimilarDrawTarget was called
-   * @param aSimilarDT Similar DrawTarget created from aDT.mFinalDT.
+   * @param aSize size of the the similar DrawTarget
+   * @param aFormat format of the similar DrawTarget
    */
   DrawTargetRecording(const DrawTargetRecording *aDT,
-                      DrawTarget *aSimilarDT);
+                      IntSize aSize, SurfaceFormat aFormat);
 
   Path *GetPathForPathRecording(const Path *aPath) const;
   already_AddRefed<PathRecording> EnsurePathStored(const Path *aPath);
   void EnsurePatternDependenciesStored(const Pattern &aPattern);
 
   RefPtr<DrawEventRecorderPrivate> mRecorder;
   RefPtr<DrawTarget> mFinalDT;
+  IntSize mSize;
 };
 
 } // namespace gfx
 } // namespace mozilla
 
 #endif /* MOZILLA_GFX_DRAWTARGETRECORDING_H_ */
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -402,19 +402,19 @@ Factory::CreateDrawTarget(BackendType aB
 
 already_AddRefed<DrawTarget>
 Factory::CreateWrapAndRecordDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT)
 {
   return MakeAndAddRef<DrawTargetWrapAndRecord>(aRecorder, aDT);
 }
 
 already_AddRefed<DrawTarget>
-Factory::CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT)
+Factory::CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT, IntSize aSize)
 {
-  return MakeAndAddRef<DrawTargetRecording>(aRecorder, aDT);
+  return MakeAndAddRef<DrawTargetRecording>(aRecorder, aDT, aSize);
 }
 
 already_AddRefed<DrawTarget>
 Factory::CreateDrawTargetForData(BackendType aBackend,
                                  unsigned char *aData,
                                  const IntSize &aSize,
                                  int32_t aStride,
                                  SurfaceFormat aFormat,
--- a/gfx/layers/wr/WebRenderDisplayItemLayer.cpp
+++ b/gfx/layers/wr/WebRenderDisplayItemLayer.cpp
@@ -146,17 +146,17 @@ WebRenderDisplayItemLayer::PushItemAsBlo
       PixelCastJustification::WebRenderHasUnitResolution);
   LayerIntSize imageSize = RoundedToInt(bounds.Size());
   LayerRect imageRect;
   imageRect.SizeTo(LayerSize(imageSize));
 
   RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
   RefPtr<gfx::DrawTarget> dummyDt =
     gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, imageSize.ToUnknownSize(), gfx::SurfaceFormat::B8G8R8X8);
-  RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt);
+  RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, imageSize.ToUnknownSize());
   LayerPoint offset = ViewAs<LayerPixel>(
       LayoutDevicePoint::FromAppUnits(mItem->ToReferenceFrame(), appUnitsPerDevPixel),
       PixelCastJustification::WebRenderHasUnitResolution);
 
   {
     dt->ClearRect(imageRect.ToUnknownRect());
     RefPtr<gfxContext> context = gfxContext::CreateOrNull(dt, offset.ToUnknownPoint());
     MOZ_ASSERT(context);
--- a/gfx/layers/wr/WebRenderPaintedLayerBlob.cpp
+++ b/gfx/layers/wr/WebRenderPaintedLayerBlob.cpp
@@ -45,17 +45,17 @@ WebRenderPaintedLayerBlob::RenderLayer(w
     WrManager()->SetTransactionIncomplete();
     return;
   }
 
   IntSize imageSize(size.ToUnknownSize());
   if (!regionToPaint.IsEmpty() && WrManager()->GetPaintedLayerCallback()) {
     RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
     RefPtr<gfx::DrawTarget> dummyDt = gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, imageSize, gfx::SurfaceFormat::B8G8R8X8);
-    RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt);
+    RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, imageSize);
 
     dt->ClearRect(Rect(0, 0, imageSize.width, imageSize.height));
     dt->SetTransform(Matrix().PreTranslate(-bounds.x, -bounds.y));
     RefPtr<gfxContext> ctx = gfxContext::CreatePreservingTransformOrNull(dt);
     MOZ_ASSERT(ctx); // already checked the target above
 
     WrManager()->GetPaintedLayerCallback()(this,
                                            ctx,