mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 769021; fix a memory leak with mask sharing. r=khuey
This commit is contained in:
parent
3fdbcff687
commit
210b488f66
@ -3296,28 +3296,24 @@ ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aCl
|
||||
gfxMatrix imageTransform = maskTransform;
|
||||
imageTransform.Scale(mParameters.mXScale, mParameters.mYScale);
|
||||
|
||||
nsAutoPtr<MaskLayerImageCache::MaskLayerImageKey> newKey(
|
||||
new MaskLayerImageCache::MaskLayerImageKey(aLayer->Manager()->GetBackendType()));
|
||||
|
||||
// copy and transform the rounded rects
|
||||
nsTArray<MaskLayerImageCache::PixelRoundedRect> roundedRects;
|
||||
for (uint32_t i = 0; i < newData.mRoundedClipRects.Length(); ++i) {
|
||||
roundedRects.AppendElement(
|
||||
newKey->mRoundedClipRects.AppendElement(
|
||||
MaskLayerImageCache::PixelRoundedRect(newData.mRoundedClipRects[i],
|
||||
mContainerFrame->PresContext()));
|
||||
roundedRects[i].ScaleAndTranslate(imageTransform);
|
||||
newKey->mRoundedClipRects[i].ScaleAndTranslate(imageTransform);
|
||||
}
|
||||
|
||||
// check to see if we can reuse a mask image
|
||||
const MaskLayerImageCache::MaskLayerImageKey* key =
|
||||
new MaskLayerImageCache::MaskLayerImageKey(roundedRects, aLayer->Manager()->GetBackendType());
|
||||
const MaskLayerImageCache::MaskLayerImageKey* lookupKey = key;
|
||||
const MaskLayerImageCache::MaskLayerImageKey* lookupKey = newKey;
|
||||
|
||||
// check to see if we can reuse a mask image
|
||||
nsRefPtr<ImageContainer> container =
|
||||
GetMaskLayerImageCache()->FindImageFor(&lookupKey);
|
||||
|
||||
if (container) {
|
||||
// track the returned key for the mask image
|
||||
delete key;
|
||||
key = lookupKey;
|
||||
} else {
|
||||
if (!container) {
|
||||
// no existing mask image, so build a new one
|
||||
nsRefPtr<gfxASurface> surface =
|
||||
aLayer->Manager()->CreateOptimalMaskSurface(surfaceSize);
|
||||
@ -3348,7 +3344,7 @@ ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aCl
|
||||
static_cast<CairoImage*>(image.get())->SetData(data);
|
||||
container->SetCurrentImageInTransaction(image);
|
||||
|
||||
GetMaskLayerImageCache()->PutImage(key, container);
|
||||
GetMaskLayerImageCache()->PutImage(newKey.forget(), container);
|
||||
}
|
||||
|
||||
maskLayer->SetContainer(container);
|
||||
@ -3358,7 +3354,7 @@ ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aCl
|
||||
userData->mScaleX = newData.mScaleX;
|
||||
userData->mScaleY = newData.mScaleY;
|
||||
userData->mRoundedClipRects.SwapElements(newData.mRoundedClipRects);
|
||||
userData->mImageKey = key;
|
||||
userData->mImageKey = lookupKey;
|
||||
|
||||
aLayer->SetMaskLayer(maskLayer);
|
||||
SetClipCount(thebesData, aRoundedRectClipCount);
|
||||
|
@ -12,10 +12,13 @@ namespace mozilla {
|
||||
|
||||
MaskLayerImageCache::MaskLayerImageCache()
|
||||
{
|
||||
MOZ_COUNT_CTOR(MaskLayerImageCache);
|
||||
mMaskImageContainers.Init();
|
||||
}
|
||||
MaskLayerImageCache::~MaskLayerImageCache()
|
||||
{}
|
||||
{
|
||||
MOZ_COUNT_DTOR(MaskLayerImageCache);
|
||||
}
|
||||
|
||||
|
||||
/* static */ PLDHashOperator
|
||||
|
@ -50,10 +50,24 @@ public:
|
||||
aPresContext->AppUnitsToGfxUnits(aRRect.mRect.width),
|
||||
aPresContext->AppUnitsToGfxUnits(aRRect.mRect.height))
|
||||
{
|
||||
MOZ_COUNT_CTOR(PixelRoundedRect);
|
||||
NS_FOR_CSS_HALF_CORNERS(corner) {
|
||||
mRadii[corner] = aPresContext->AppUnitsToGfxUnits(aRRect.mRadii[corner]);
|
||||
}
|
||||
}
|
||||
PixelRoundedRect(const PixelRoundedRect& aPRR)
|
||||
: mRect(aPRR.mRect)
|
||||
{
|
||||
MOZ_COUNT_CTOR(PixelRoundedRect);
|
||||
NS_FOR_CSS_HALF_CORNERS(corner) {
|
||||
mRadii[corner] = aPRR.mRadii[corner];
|
||||
}
|
||||
}
|
||||
|
||||
~PixelRoundedRect()
|
||||
{
|
||||
MOZ_COUNT_DTOR(PixelRoundedRect);
|
||||
}
|
||||
|
||||
// Applies the scale and translate components of aTransform.
|
||||
// It is an error to pass a matrix which does more than just scale
|
||||
@ -99,6 +113,9 @@ public:
|
||||
gfxRect mRect;
|
||||
// Indices into mRadii are the NS_CORNER_* constants in nsStyleConsts.h
|
||||
gfxFloat mRadii[8];
|
||||
|
||||
private:
|
||||
PixelRoundedRect() MOZ_DELETE;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -111,14 +128,27 @@ public:
|
||||
* pointers to a key object (the +1 being from the hashtable entry), but this
|
||||
* invariant may be temporarily broken.
|
||||
*/
|
||||
class MaskLayerImageKey
|
||||
struct MaskLayerImageKey
|
||||
{
|
||||
public:
|
||||
MaskLayerImageKey(const nsTArray<PixelRoundedRect>& aRoundedClipRects, layers::LayersBackend aBackend)
|
||||
MaskLayerImageKey(layers::LayersBackend aBackend)
|
||||
: mBackend(aBackend)
|
||||
, mLayerCount(0)
|
||||
, mRoundedClipRects(aRoundedClipRects)
|
||||
{}
|
||||
, mRoundedClipRects()
|
||||
{
|
||||
MOZ_COUNT_CTOR(MaskLayerImageKey);
|
||||
}
|
||||
MaskLayerImageKey(const MaskLayerImageKey& aKey)
|
||||
: mBackend(aKey.mBackend)
|
||||
, mLayerCount(aKey.mLayerCount)
|
||||
, mRoundedClipRects(aKey.mRoundedClipRects)
|
||||
{
|
||||
MOZ_COUNT_CTOR(MaskLayerImageKey);
|
||||
}
|
||||
|
||||
~MaskLayerImageKey()
|
||||
{
|
||||
MOZ_COUNT_DTOR(MaskLayerImageKey);
|
||||
}
|
||||
|
||||
void AddRef() const { ++mLayerCount; }
|
||||
void Release() const
|
||||
@ -172,12 +202,19 @@ protected:
|
||||
typedef const MaskLayerImageKey& KeyType;
|
||||
typedef const MaskLayerImageKey* KeyTypePointer;
|
||||
|
||||
MaskLayerImageEntry(KeyTypePointer aKey) : mKey(aKey) {}
|
||||
MaskLayerImageEntry(KeyTypePointer aKey) : mKey(aKey)
|
||||
{
|
||||
MOZ_COUNT_CTOR(MaskLayerImageEntry);
|
||||
}
|
||||
MaskLayerImageEntry(const MaskLayerImageEntry& aOther)
|
||||
: mKey(aOther.mKey.get())
|
||||
{
|
||||
NS_ERROR("ALLOW_MEMMOVE == true, should never be called");
|
||||
}
|
||||
~MaskLayerImageEntry()
|
||||
{
|
||||
MOZ_COUNT_DTOR(MaskLayerImageEntry);
|
||||
}
|
||||
|
||||
// KeyEquals(): does this entry match this key?
|
||||
bool KeyEquals(KeyTypePointer aKey) const
|
||||
|
Loading…
Reference in New Issue
Block a user