Bug 1285320 - Part 1: Add struct "CachedBorderImageData" to keep cached data for border in nsStyleImage. r=dholbert, a=ritu
authorKevin Chen <kechen@mozilla.com>
Sun, 31 Jul 2016 20:23:00 -0400
changeset 347753 20dbba05457b32b4350868102fcd3886b796ac3b
parent 347752 0e4499ae0f81b2fe9e349f66934f7a2bfbf04035
child 347754 2065ffb539e10304f2e02007791f8ae045144da5
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert, ritu
bugs1285320
milestone50.0a2
Bug 1285320 - Part 1: Add struct "CachedBorderImageData" to keep cached data for border in nsStyleImage. r=dholbert, a=ritu
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/nsStyleStructInlines.h
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1907,16 +1907,40 @@ nsStyleGradient::HasCalc()
       return true;
     }
   }
   return mBgPosX.IsCalcUnit() || mBgPosY.IsCalcUnit() || mAngle.IsCalcUnit() ||
          mRadiusX.IsCalcUnit() || mRadiusY.IsCalcUnit();
 }
 
 // --------------------
+// CachedBorderImageData
+//
+void
+CachedBorderImageData::PurgeCachedImages()
+{
+  mSubImages.Clear();
+}
+
+void
+CachedBorderImageData::SetSubImage(uint8_t aIndex, imgIContainer* aSubImage)
+{
+  mSubImages.ReplaceObjectAt(aSubImage, aIndex);
+}
+
+imgIContainer*
+CachedBorderImageData::GetSubImage(uint8_t aIndex)
+{
+  imgIContainer* subImage = nullptr;
+  if (aIndex < mSubImages.Count())
+    subImage = mSubImages[aIndex];
+  return subImage;
+}
+
+// --------------------
 // nsStyleImage
 //
 
 nsStyleImage::nsStyleImage()
   : mType(eStyleImageType_Null)
   , mCropRect(nullptr)
 #ifdef DEBUG
   , mImageTracked(false)
@@ -2005,17 +2029,19 @@ nsStyleImage::SetImageData(imgRequestPro
   if (mType != eStyleImageType_Null) {
     SetNull();
   }
 
   if (aImage) {
     mImage = aImage;
     mType = eStyleImageType_Image;
   }
-  mSubImages.Clear();
+  if (mCachedBIData) {
+    mCachedBIData->PurgeCachedImages();
+  }
 }
 
 void
 nsStyleImage::TrackImage(nsPresContext* aContext)
 {
   // Sanity
   MOZ_ASSERT(!mImageTracked, "Already tracking image!");
   MOZ_ASSERT(mType == eStyleImageType_Image,
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -241,16 +241,26 @@ private:
 
 enum nsStyleImageType {
   eStyleImageType_Null,
   eStyleImageType_Image,
   eStyleImageType_Gradient,
   eStyleImageType_Element
 };
 
+struct CachedBorderImageData
+{
+  void PurgeCachedImages();
+  void SetSubImage(uint8_t aIndex, imgIContainer* aSubImage);
+  imgIContainer* GetSubImage(uint8_t aIndex);
+
+private:
+  nsCOMArray<imgIContainer> mSubImages;
+};
+
 /**
  * Represents a paintable image of one of the following types.
  * (1) A real image loaded from an external source.
  * (2) A CSS linear or radial gradient.
  * (3) An element within a document, or an <img>, <video>, or <canvas> element
  *     not in a document.
  * (*) Optionally a crop rect can be set to paint a partial (rectangular)
  * region of an image. (Currently, this feature is only supported with an
@@ -356,19 +366,21 @@ struct nsStyleImage
 
   // These methods are used for the caller to caches the sub images created
   // during a border-image paint operation
   inline void SetSubImage(uint8_t aIndex, imgIContainer* aSubImage) const;
   inline imgIContainer* GetSubImage(uint8_t aIndex) const;
 
 private:
   void DoCopy(const nsStyleImage& aOther);
-
-  // Cache for border-image painting.
-  nsCOMArray<imgIContainer> mSubImages;
+  void EnsureCachedBIData() const;
+
+  // This variable keeps some cache data for border image and is lazily
+  // allocated since it is only used in border image case.
+  mozilla::UniquePtr<CachedBorderImageData> mCachedBIData;
 
   nsStyleImageType mType;
   union {
     imgRequestProxy* mImage;
     nsStyleGradient* mGradient;
     char16_t* mElementId;
   };
 
--- a/layout/style/nsStyleStructInlines.h
+++ b/layout/style/nsStyleStructInlines.h
@@ -12,28 +12,35 @@
 #define nsStyleStructInlines_h_
 
 #include "nsIFrame.h"
 #include "nsStyleStruct.h"
 #include "nsIContent.h" // for GetParent()
 #include "nsTextFrame.h" // for nsTextFrame::ShouldSuppressLineBreak
 
 inline void
+nsStyleImage::EnsureCachedBIData() const
+{
+  if (!mCachedBIData) {
+    const_cast<nsStyleImage*>(this)->mCachedBIData =
+      mozilla::MakeUnique<CachedBorderImageData>();
+  }
+}
+
+inline void
 nsStyleImage::SetSubImage(uint8_t aIndex, imgIContainer* aSubImage) const
 {
-  const_cast<nsStyleImage*>(this)->mSubImages.ReplaceObjectAt(aSubImage, aIndex);
+  EnsureCachedBIData();
+  mCachedBIData->SetSubImage(aIndex, aSubImage);
 }
 
 inline imgIContainer*
 nsStyleImage::GetSubImage(uint8_t aIndex) const
 {
-  imgIContainer* subImage = nullptr;
-  if (aIndex < mSubImages.Count())
-    subImage = mSubImages[aIndex];
-  return subImage;
+  return (mCachedBIData) ? mCachedBIData->GetSubImage(aIndex) : nullptr;
 }
 
 bool
 nsStyleText::HasTextShadow() const
 {
   return mTextShadow;
 }