Bug 1234485 - Part 7. Implement CSSMaskLayerUserData to store css positioned mask user data. r=mstange
authorcku <cku@mozilla.com>
Tue, 01 Nov 2016 16:43:34 +0800
changeset 348377 02b45619e3f0822e02876a8870af08d6fe9d4e94
parent 348376 6e607ef327c8fbb3a5ae7d5896c3bde01e7c2c8a
child 348378 43b1c0654aa6b21046e67d977f7cc9f621dfc598
push id10298
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:33:03 +0000
treeherdermozilla-aurora@7e29173b1641 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1234485
milestone52.0a1
Bug 1234485 - Part 7. Implement CSSMaskLayerUserData to store css positioned mask user data. r=mstange MozReview-Commit-ID: JZVcAfipKYX
layout/base/FrameLayerBuilder.cpp
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -92,16 +92,22 @@ uint8_t gImageLayerUserData;
  */
 uint8_t gLayerManagerUserData;
 /**
  * The address of gMaskLayerUserData is used as the user
  * data key for mask layers managed by FrameLayerBuilder.
  * The user data is a MaskLayerUserData.
  */
 uint8_t gMaskLayerUserData;
+/**
+ * The address of gCSSMaskLayerUserData is used as the user
+ * data key for mask layers of css masking managed by FrameLayerBuilder.
+ * The user data is a CSSMaskLayerUserData.
+ */
+uint8_t gCSSMaskLayerUserData;
 
 // a global cache of image containers used for mask layers
 static MaskLayerImageCache* gMaskLayerImageCache = nullptr;
 
 static inline MaskLayerImageCache* GetMaskLayerImageCache()
 {
   if (!gMaskLayerImageCache) {
     gMaskLayerImageCache = new MaskLayerImageCache();
@@ -1523,16 +1529,110 @@ struct MaskLayerUserData : public LayerU
   // scale from the masked layer which is applied to the mask
   float mScaleX, mScaleY;
   // The ContainerLayerParameters offset which is applied to the mask's transform.
   nsIntPoint mOffset;
   int32_t mAppUnitsPerDevPixel;
 };
 
 /*
+ * User data for layers which will be used as masks for css positioned mask.
+ */
+struct CSSMaskLayerUserData : public LayerUserData
+{
+  CSSMaskLayerUserData()
+    : mImageLayers(nsStyleImageLayers::LayerType::Mask)
+  { }
+
+  CSSMaskLayerUserData(nsIFrame* aFrame, const nsRect& aBound)
+    : mImageLayers(aFrame->StyleSVGReset()->mMask),
+      mContentRect(aFrame->GetContentRectRelativeToSelf()),
+      mPaddingRect(aFrame->GetPaddingRectRelativeToSelf()),
+      mBorderRect(aFrame->GetRectRelativeToSelf()),
+      mMarginRect(aFrame->GetMarginRectRelativeToSelf()),
+      mBounds(aBound)
+  {
+    Hash(aFrame);
+  }
+
+  CSSMaskLayerUserData& operator=(const CSSMaskLayerUserData& aOther)
+  {
+    mImageLayers = aOther.mImageLayers;
+
+    mContentRect = aOther.mContentRect;
+    mPaddingRect = aOther.mPaddingRect;
+    mBorderRect = aOther.mBorderRect;
+    mMarginRect = aOther.mMarginRect;
+
+    mBounds = aOther.mBounds;
+
+    mHash = aOther.mHash;
+
+    return *this;
+  }
+
+  bool
+  operator==(const CSSMaskLayerUserData& aOther) const
+  {
+    if (mHash != aOther.mHash) {
+      return false;
+    }
+
+    if (mImageLayers.mLayers != aOther.mImageLayers.mLayers) {
+      return false;
+    }
+
+    if (!mContentRect.IsEqualEdges(aOther.mContentRect) ||
+        !mPaddingRect.IsEqualEdges(aOther.mPaddingRect) ||
+        !mBorderRect.IsEqualEdges(aOther.mBorderRect) ||
+        !mMarginRect.IsEqualEdges(aOther.mMarginRect)) {
+      return false;
+    }
+
+    if (!mBounds.IsEqualEdges(aOther.mBounds)) {
+      return false;
+    }
+
+    return true;
+  }
+
+private:
+  void Hash(nsIFrame* aFrame)
+  {
+    uint32_t hash = 0;
+
+    const nsStyleImageLayers& imageLayers = aFrame->StyleSVGReset()->mMask;
+    for (uint32_t i = 0; i < imageLayers.mLayers.Length(); i++) {
+      const nsStyleImageLayers::Layer& newLayer = imageLayers.mLayers[i];
+      hash = AddToHash(hash, HashBytes(&newLayer, sizeof(newLayer)));
+    }
+
+    hash = AddToHash(hash, HashBytes(&mContentRect, sizeof(mContentRect)));
+    hash = AddToHash(hash, HashBytes(&mPaddingRect, sizeof(mPaddingRect)));
+    hash = AddToHash(hash, HashBytes(&mBorderRect, sizeof(mBorderRect)));
+    hash = AddToHash(hash, HashBytes(&mMarginRect, sizeof(mMarginRect)));
+
+    hash = AddToHash(hash, HashBytes(&mBounds, sizeof(mBounds)));
+
+    mHash = hash;
+  }
+
+  nsStyleImageLayers mImageLayers;
+
+  nsRect mContentRect;
+  nsRect mPaddingRect;
+  nsRect mBorderRect;
+  nsRect mMarginRect;
+
+  nsRect mBounds;
+
+  uint32_t mHash;
+};
+
+/*
  * A helper object to create a draw target for painting mask and create a
  * image container to hold the drawing result. The caller can then bind this
  * image container with a image mask layer via ImageLayer::SetContainer.
  */
 class MaskImageData
 {
 public:
   MaskImageData(const gfx::IntSize& aSize, LayerManager* aLayerManager)