Bug 1429508 - Make SnapshotTiled::GetDataSurface return a surface the size of backed tiles only. r?jrmuizel draft
authorJamie Nicol <jnicol@mozilla.com>
Mon, 05 Feb 2018 17:50:41 +0000
changeset 751478 8b64cc3e93885b80882cb8699fbc109129760e2e
parent 751477 f96c58ea2448f342f4dea3e461318a2c3db1850a
child 751479 21cb882c9a4ba9b251e61f08c680ab2d920f255e
push id97975
push userbmo:jnicol@mozilla.com
push dateTue, 06 Feb 2018 11:35:20 +0000
reviewersjrmuizel
bugs1429508
milestone60.0a1
Bug 1429508 - Make SnapshotTiled::GetDataSurface return a surface the size of backed tiles only. r?jrmuizel Fix the DrawTargetTiled::mRect initialization, and expose through the virtual function GetRect(). Make SnapshotTiled::GetDataSurface() allocate a surface the size of this rect, rather the XMost and YMost. Callers of SourceSurface::GetDataSurface() can query SourceSurface::GetRect() and apply the necessary offset themselves. MozReview-Commit-ID: C31FGirQ0oK
gfx/2d/2D.h
gfx/2d/DrawTargetTiled.cpp
gfx/2d/DrawTargetTiled.h
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -364,16 +364,19 @@ class DrawTargetCaptureImpl;
 class SourceSurface : public external::AtomicRefCounted<SourceSurface>
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurface)
   virtual ~SourceSurface() {}
 
   virtual SurfaceType GetType() const = 0;
   virtual IntSize GetSize() const = 0;
+  virtual IntRect GetRect() const {
+    return IntRect(IntPoint(0, 0), GetSize());
+  }
   virtual SurfaceFormat GetFormat() const = 0;
 
   /** This returns false if some event has made this source surface invalid for
    * usage with current DrawTargets. For example in the case of Direct2D this
    * could return false if we have switched devices since this surface was
    * created.
    */
   virtual bool IsValid() const { return true; }
@@ -933,16 +936,19 @@ public:
    */
   virtual already_AddRefed<SourceSurface> Snapshot() = 0;
 
   // Snapshots the contents and returns an alpha mask
   // based on the RGB values.
   virtual already_AddRefed<SourceSurface> IntoLuminanceSource(LuminanceType aLuminanceType,
                                                               float aOpacity);
   virtual IntSize GetSize() const = 0;
+  virtual IntRect GetRect() const {
+    return IntRect(IntPoint(0, 0), GetSize());
+  }
 
   /**
    * If possible returns the bits to this DrawTarget for direct manipulation. While
    * the bits is locked any modifications to this DrawTarget is forbidden.
    * Release takes the original data pointer for safety.
    */
   virtual bool LockBits(uint8_t** aData, IntSize* aSize,
                         int32_t* aStride, SurfaceFormat* aFormat,
--- a/gfx/2d/DrawTargetTiled.cpp
+++ b/gfx/2d/DrawTargetTiled.cpp
@@ -33,18 +33,22 @@ DrawTargetTiled::Init(const TileSet& aTi
     if (mTiles[0].mDrawTarget->GetFormat() != mTiles.back().mDrawTarget->GetFormat() ||
         mTiles[0].mDrawTarget->GetBackendType() != mTiles.back().mDrawTarget->GetBackendType()) {
       return false;
     }
     uint32_t newXMost = max(mRect.XMost(),
                             mTiles[i].mTileOrigin.x + mTiles[i].mDrawTarget->GetSize().width);
     uint32_t newYMost = max(mRect.YMost(),
                             mTiles[i].mTileOrigin.y + mTiles[i].mDrawTarget->GetSize().height);
-    mRect.MoveTo(min(mRect.X(), mTiles[i].mTileOrigin.x),
-                 min(mRect.Y(), mTiles[i].mTileOrigin.y));
+    if (i == 0) {
+      mRect.MoveTo(mTiles[0].mTileOrigin.x, mTiles[0].mTileOrigin.y);
+    } else {
+      mRect.MoveTo(min(mRect.X(), mTiles[i].mTileOrigin.x),
+                   min(mRect.Y(), mTiles[i].mTileOrigin.y));
+    }
     mRect.SetRightEdge(newXMost);
     mRect.SetBottomEdge(newYMost);
     mTiles[i].mDrawTarget->SetTransform(Matrix::Translation(-mTiles[i].mTileOrigin.x,
                                                             -mTiles[i].mTileOrigin.y));
   }
   mFormat = mTiles[0].mDrawTarget->GetFormat();
   SetPermitSubpixelAA(IsOpaque(mFormat));
   return true;
--- a/gfx/2d/DrawTargetTiled.h
+++ b/gfx/2d/DrawTargetTiled.h
@@ -46,16 +46,19 @@ public:
   virtual DrawTargetType GetType() const override { return mTiles[0].mDrawTarget->GetType(); }
   virtual BackendType GetBackendType() const override { return mTiles[0].mDrawTarget->GetBackendType(); }
   virtual already_AddRefed<SourceSurface> Snapshot() override;
   virtual void DetachAllSnapshots() override;
   virtual IntSize GetSize() const override {
     MOZ_ASSERT(mRect.Width() > 0 && mRect.Height() > 0);
     return IntSize(mRect.XMost(), mRect.YMost());
   }
+  virtual IntRect GetRect() const override {
+    return mRect;
+  }
 
   virtual void Flush() override;
   virtual void DrawSurface(SourceSurface *aSurface,
                            const Rect &aDest,
                            const Rect &aSource,
                            const DrawSurfaceOptions &aSurfOptions,
                            const DrawOptions &aOptions) override;
   virtual void DrawFilter(FilterNode *aNode,
@@ -193,45 +196,48 @@ public:
     }
   }
 
   virtual SurfaceType GetType() const override { return SurfaceType::TILED; }
   virtual IntSize GetSize() const override {
     MOZ_ASSERT(mRect.Width() > 0 && mRect.Height() > 0);
     return IntSize(mRect.XMost(), mRect.YMost());
   }
+  virtual IntRect GetRect() const override {
+    return mRect;
+  }
   virtual SurfaceFormat GetFormat() const override { return mSnapshots[0]->GetFormat(); }
 
   virtual already_AddRefed<DataSourceSurface> GetDataSurface() override
   {
-    RefPtr<DataSourceSurface> surf = Factory::CreateDataSourceSurface(GetSize(), GetFormat());
+    RefPtr<DataSourceSurface> surf = Factory::CreateDataSourceSurface(mRect.Size(), GetFormat());
     if (!surf) {
       gfxCriticalError() << "DrawTargetTiled::GetDataSurface failed to allocate surface";
       return nullptr;
     }
 
     DataSourceSurface::MappedSurface mappedSurf;
     if (!surf->Map(DataSourceSurface::MapType::WRITE, &mappedSurf)) {
       gfxCriticalError() << "DrawTargetTiled::GetDataSurface failed to map surface";
       return nullptr;
     }
 
     {
       RefPtr<DrawTarget> dt =
         Factory::CreateDrawTargetForData(BackendType::CAIRO, mappedSurf.mData,
-        GetSize(), mappedSurf.mStride, GetFormat());
+        mRect.Size(), mappedSurf.mStride, GetFormat());
 
       if (!dt) {
         gfxWarning() << "DrawTargetTiled::GetDataSurface failed in CreateDrawTargetForData";
         surf->Unmap();
         return nullptr;
       }
       for (size_t i = 0; i < mSnapshots.size(); i++) {
         RefPtr<DataSourceSurface> dataSurf = mSnapshots[i]->GetDataSurface();
-        dt->CopySurface(dataSurf, IntRect(IntPoint(0, 0), mSnapshots[i]->GetSize()), mOrigins[i]);
+        dt->CopySurface(dataSurf, IntRect(IntPoint(0, 0), mSnapshots[i]->GetSize()), mOrigins[i] - mRect.TopLeft());
       }
     }
     surf->Unmap();
 
     return surf.forget();
   }
 
   std::vector<RefPtr<SourceSurface>> mSnapshots;