Bug 1220629 - Part 6: Implement PushLayer/PopLayer API in several wrapper DT types. r=jrmuizel draft
authorBas Schouten <bschouten@mozilla.com>
Wed, 06 Jan 2016 00:23:33 +0100
changeset 319147 5a421568fa20b23d7ceef71eb58014e29dbc1c76
parent 319146 ec545e1bde6741e9bc461b1a6ab966e7b6c9236a
child 319148 f14504896f107b12e2cd597f0cd3ba09ac9f5f09
push id8986
push userbschouten@mozilla.com
push dateTue, 05 Jan 2016 23:23:40 +0000
reviewersjrmuizel
bugs1220629
milestone46.0a1
Bug 1220629 - Part 6: Implement PushLayer/PopLayer API in several wrapper DT types. r=jrmuizel
gfx/2d/DrawTargetD2D1.cpp
gfx/2d/DrawTargetD2D1.h
gfx/2d/DrawTargetDual.cpp
gfx/2d/DrawTargetDual.h
gfx/2d/DrawTargetTiled.cpp
gfx/2d/DrawTargetTiled.h
--- a/gfx/2d/DrawTargetD2D1.cpp
+++ b/gfx/2d/DrawTargetD2D1.cpp
@@ -771,28 +771,33 @@ DrawTargetD2D1::PushLayer(bool aOpaque, 
   }
 
   PushAllClips();
 
   mDC->PushLayer(D2D1::LayerParameters1(D2D1::InfiniteRect(), clip, D2D1_ANTIALIAS_MODE_ALIASED, D2DMatrix(maskTransform), aOpacity, mask, options), nullptr);
   PushedLayer pushedLayer;
   pushedLayer.mClipsArePushed = false;
   pushedLayer.mIsOpaque = aOpaque;
+  pushedLayer.mOldPermitSubpixelAA = mPermitSubpixelAA;
+  mPermitSubpixelAA = aOpaque;
+
   mDC->CreateCommandList(getter_AddRefs(pushedLayer.mCurrentList));
   mPushedLayers.push_back(pushedLayer);
 
   mDC->SetTarget(CurrentTarget());
 }
 
 void
 DrawTargetD2D1::PopLayer()
 {
   MOZ_ASSERT(CurrentLayer().mPushedClips.size() == 0);
 
   RefPtr<ID2D1CommandList> list = CurrentLayer().mCurrentList;
+  mPermitSubpixelAA = CurrentLayer().mOldPermitSubpixelAA;
+
   mPushedLayers.pop_back();
   mDC->SetTarget(CurrentTarget());
 
   list->Close();
   mDC->SetTransform(D2D1::IdentityMatrix());
   mTransformDirty = true;
 
   DCCommandSink sink(mDC);
--- a/gfx/2d/DrawTargetD2D1.h
+++ b/gfx/2d/DrawTargetD2D1.h
@@ -238,23 +238,24 @@ private:
       bool mIsPixelAligned;
     };
     RefPtr<PathD2D> mPath;
   };
 
   // List of pushed layers.
   struct PushedLayer
   {
-    PushedLayer() : mClipsArePushed(false), mIsOpaque(false) {}
+    PushedLayer() : mClipsArePushed(false), mIsOpaque(false), mOldPermitSubpixelAA(false) {}
 
     std::vector<PushedClip> mPushedClips;
     RefPtr<ID2D1CommandList> mCurrentList;
     // True if the current clip stack is pushed to the CurrentTarget().
     bool mClipsArePushed;
     bool mIsOpaque;
+    bool mOldPermitSubpixelAA;
   };
   std::vector<PushedLayer> mPushedLayers;
   PushedLayer& CurrentLayer()
   {
     return mPushedLayers.back();
   }
 
   // The latest snapshot of this surface. This needs to be told when this
--- a/gfx/2d/DrawTargetDual.cpp
+++ b/gfx/2d/DrawTargetDual.cpp
@@ -10,16 +10,21 @@
 namespace mozilla {
 namespace gfx {
 
 class DualSurface
 {
 public:
   inline explicit DualSurface(SourceSurface *aSurface)
   {
+    if (!aSurface) {
+      mA = mB = nullptr;
+      return;
+    }
+
     if (aSurface->GetType() != SurfaceType::DUAL_DT) {
       mA = mB = aSurface;
       return;
     }
 
     SourceSurfaceDual *ssDual =
       static_cast<SourceSurfaceDual*>(aSurface);
     mA = ssDual->mA;
@@ -176,16 +181,26 @@ void
 DrawTargetDual::Mask(const Pattern &aSource, const Pattern &aMask, const DrawOptions &aOptions)
 {
   DualPattern source(aSource);
   DualPattern mask(aMask);
   mA->Mask(*source.mA, *mask.mA, aOptions);
   mB->Mask(*source.mB, *mask.mB, aOptions);
 }
 
+void
+DrawTargetDual::PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
+                          const Matrix& aMaskTransform, const IntRect& aBounds,
+                          bool aCopyBackground)
+{
+  DualSurface mask(aMask);
+  mA->PushLayer(aOpaque, aOpacity, mask.mA, aMaskTransform, aBounds, aCopyBackground);
+  mB->PushLayer(aOpaque, aOpacity, mask.mB, aMaskTransform, aBounds, aCopyBackground);
+}
+
 already_AddRefed<DrawTarget>
 DrawTargetDual::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
 {
   RefPtr<DrawTarget> dtA = mA->CreateSimilarDrawTarget(aSize, aFormat);
   RefPtr<DrawTarget> dtB = mB->CreateSimilarDrawTarget(aSize, aFormat);
 
   if (!dtA || !dtB) {
     gfxWarning() << "Failure to allocate a similar DrawTargetDual. Size: " << aSize;
--- a/gfx/2d/DrawTargetDual.h
+++ b/gfx/2d/DrawTargetDual.h
@@ -49,16 +49,17 @@ public:
     return MakeAndAddRef<SourceSurfaceDual>(mA, mB);
   }
   virtual IntSize GetSize() override { return mA->GetSize(); }
      
   FORWARD_FUNCTION(Flush)
   FORWARD_FUNCTION1(PushClip, const Path *, aPath)
   FORWARD_FUNCTION1(PushClipRect, const Rect &, aRect)
   FORWARD_FUNCTION(PopClip)
+  FORWARD_FUNCTION(PopLayer)
   FORWARD_FUNCTION1(ClearRect, const Rect &, aRect)
 
   virtual void SetTransform(const Matrix &aTransform) override {
     mTransform = aTransform;
     mA->SetTransform(aTransform);
     mB->SetTransform(aTransform);
   }
 
@@ -99,17 +100,23 @@ public:
 
   virtual void Fill(const Path *aPath, const Pattern &aPattern, const DrawOptions &aOptions) override;
 
   virtual void FillGlyphs(ScaledFont *aScaledFont, const GlyphBuffer &aBuffer,
                           const Pattern &aPattern, const DrawOptions &aOptions,
                           const GlyphRenderingOptions *aRenderingOptions) override;
   
   virtual void Mask(const Pattern &aSource, const Pattern &aMask, const DrawOptions &aOptions) override;
-     
+
+  virtual void PushLayer(bool aOpaque, Float aOpacity,
+                         SourceSurface* aMask,
+                         const Matrix& aMaskTransform,
+                         const IntRect& aBounds = IntRect(),
+                         bool aCopyBackground = false) override;
+
   virtual already_AddRefed<SourceSurface>
     CreateSourceSurfaceFromData(unsigned char *aData,
                                 const IntSize &aSize,
                                 int32_t aStride,
                                 SurfaceFormat aFormat) const override
   {
     return mA->CreateSourceSurfaceFromData(aData, aSize, aStride, aFormat);
   }
@@ -150,16 +157,18 @@ public:
   {
     return nullptr;
   }
 
   virtual bool IsDualDrawTarget() const override
   {
     return true;
   }
+
+  virtual bool IsCurrentGroupOpaque() override { return mA->IsCurrentGroupOpaque(); }
      
 private:
   RefPtr<DrawTarget> mA;
   RefPtr<DrawTarget> mB;
 };
      
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/2d/DrawTargetTiled.cpp
+++ b/gfx/2d/DrawTargetTiled.cpp
@@ -300,10 +300,34 @@ DrawTargetTiled::Fill(const Path* aPath,
                                    mTiles[i].mTileOrigin.y,
                                    mTiles[i].mDrawTarget->GetSize().width,
                                    mTiles[i].mDrawTarget->GetSize().height))) {
       mTiles[i].mDrawTarget->Fill(aPath, aPattern, aDrawOptions);
     }
   }
 }
 
+void
+DrawTargetTiled::PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
+                           const Matrix& aMaskTransform, const IntRect& aBounds,
+                           bool aCopyBackground)
+{
+  // XXX - not sure this is what we want or whether we want to continue drawing to a larger
+  // intermediate surface, that would require tweaking the code in here a little though.
+  for (size_t i = 0; i < mTiles.size(); i++) {
+    IntRect bounds = aBounds;
+    bounds.MoveBy(-mTiles[i].mTileOrigin);
+    mTiles[i].mDrawTarget->PushLayer(aOpaque, aOpacity, aMask, aMaskTransform, aBounds);
+  }
+}
+
+void
+DrawTargetTiled::PopLayer()
+{
+  // XXX - not sure this is what we want or whether we want to continue drawing to a larger
+  // intermediate surface, that would require tweaking the code in here a little though.
+  for (size_t i = 0; i < mTiles.size(); i++) {
+    mTiles[i].mDrawTarget->PopLayer();
+  }
+}
+
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/2d/DrawTargetTiled.h
+++ b/gfx/2d/DrawTargetTiled.h
@@ -98,16 +98,23 @@ public:
                           const DrawOptions &aOptions = DrawOptions(),
                           const GlyphRenderingOptions *aRenderingOptions = nullptr) override;
   virtual void Mask(const Pattern &aSource,
                     const Pattern &aMask,
                     const DrawOptions &aOptions = DrawOptions()) override;
   virtual void PushClip(const Path *aPath) override;
   virtual void PushClipRect(const Rect &aRect) override;
   virtual void PopClip() override;
+  virtual void PushLayer(bool aOpaque, Float aOpacity,
+                         SourceSurface* aMask,
+                         const Matrix& aMaskTransform,
+                         const IntRect& aBounds = IntRect(),
+                         bool aCopyBackground = false) override;
+  virtual void PopLayer() override;
+
 
   virtual void SetTransform(const Matrix &aTransform) override;
 
   virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
                                                                   const IntSize &aSize,
                                                                   int32_t aStride,
                                                                   SurfaceFormat aFormat) const override
   {