From 155069d388233313065e29c71752e4b9472b4701 Mon Sep 17 00:00:00 2001 From: Michael Layzell Date: Sun, 12 Jul 2015 21:09:57 -0700 Subject: [PATCH] Bug 1073219 - Use a simple RAII struct instead of nsRefPtr to manage mLayerCount for MaskLayerImageKey. r=dholbert --- layout/base/FrameLayerBuilder.cpp | 5 ++-- layout/base/MaskLayerImageCache.cpp | 8 ------ layout/base/MaskLayerImageCache.h | 42 ++++++++++++++++++++++++++--- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index c9bdfbf48511..01ab32dc98ea 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -1380,7 +1380,8 @@ struct MaskLayerUserData : public LayerUserData mAppUnitsPerDevPixel == aOther.mAppUnitsPerDevPixel; } - nsRefPtr mImageKey; + // Keeps a MaskLayerImageKey alive by managing its mLayerCount member-var + MaskLayerImageCache::MaskLayerImageKeyRef mImageKey; // properties of the mask layer; the mask layer may be re-used if these // remain unchanged. nsTArray mRoundedClipRects; @@ -5914,7 +5915,7 @@ ContainerState::CreateMaskLayer(Layer *aLayer, userData->mOffset = newData.mOffset; userData->mAppUnitsPerDevPixel = newData.mAppUnitsPerDevPixel; userData->mRoundedClipRects.SwapElements(newData.mRoundedClipRects); - userData->mImageKey = lookupKey; + userData->mImageKey.Reset(lookupKey); return maskLayer.forget(); } diff --git a/layout/base/MaskLayerImageCache.cpp b/layout/base/MaskLayerImageCache.cpp index 32bf9d4ddee7..c6bf49debba8 100644 --- a/layout/base/MaskLayerImageCache.cpp +++ b/layout/base/MaskLayerImageCache.cpp @@ -57,14 +57,6 @@ MaskLayerImageCache::PutImage(const MaskLayerImageKey* aKey, ImageContainer* aCo entry->mContainer = aContainer; } -// This case is particularly 'clever' because it uses AddRef/Release to track the use -// not to release the object. -template<> -struct HasDangerousPublicDestructor -{ - static const bool value = true; -}; - MaskLayerImageCache::MaskLayerImageKey::MaskLayerImageKey() : mLayerCount(0) , mRoundedClipRects() diff --git a/layout/base/MaskLayerImageCache.h b/layout/base/MaskLayerImageCache.h index 8b9b9b24cc0e..1c11fbb78e51 100644 --- a/layout/base/MaskLayerImageCache.h +++ b/layout/base/MaskLayerImageCache.h @@ -136,8 +136,8 @@ public: ~MaskLayerImageKey(); - void AddRef() const { ++mLayerCount; } - void Release() const + void IncLayerCount() const { ++mLayerCount; } + void DecLayerCount() const { NS_ASSERTION(mLayerCount > 0, "Inconsistent layer count"); --mLayerCount; @@ -163,7 +163,43 @@ public: nsTArray mRoundedClipRects; }; - + /** + * This struct maintains a reference to a MaskLayerImageKey, via a variant on + * refcounting. When a key is passed in via Reset(), we increment the + * passed-in key's mLayerCount, and we decrement its mLayerCount when we're + * destructed (or when the key is replaced via a second Reset() call). + * + * However, unlike standard refcounting smart-pointers, this object does + * *not* delete the tracked MaskLayerImageKey -- instead, deletion happens + * in MaskLayerImageCache::Sweep(), for any keys whose mLayerCount is 0. + */ + struct MaskLayerImageKeyRef + { + ~MaskLayerImageKeyRef() + { + if (mRawPtr) { + mRawPtr->DecLayerCount(); + } + } + + MaskLayerImageKeyRef() : mRawPtr(nullptr) {} + MaskLayerImageKeyRef(const MaskLayerImageKeyRef&) = delete; + void operator=(const MaskLayerImageKeyRef&) = delete; + + void Reset(const MaskLayerImageKey* aPtr) + { + MOZ_ASSERT(aPtr, "Cannot initialize a MaskLayerImageKeyRef with a null pointer"); + aPtr->IncLayerCount(); + if (mRawPtr) { + mRawPtr->DecLayerCount(); + } + mRawPtr = aPtr; + } + + private: + const MaskLayerImageKey* mRawPtr; + }; + // Find an image container for aKey, returns nullptr if there is no suitable // cached image. If there is an image, then aKey is set to point at the stored // key for the image.