Bug 1285320 - Part 1: Add struct "CachedBorderImageData" to keep cached data for border in nsStyleImage. r=dholbert
--- 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;
}