Fix for bug 659580 (Flush CanvasImageCache on shutdown). r=roc.
authorPeter Van der Beken <peterv@propagandism.org>
Wed, 13 Apr 2011 17:34:06 -0700
changeset 70786 5229dcb709891cfcbd4b119821bbce136f5a3a24
parent 70785 a03bb9c49e4232a7a4ffb68dc056e55cfd455867
child 70787 acd3f233289bf9cfaf589dfc48fcc68177f9648b
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersroc
bugs659580
milestone7.0a1
Fix for bug 659580 (Flush CanvasImageCache on shutdown). r=roc.
content/canvas/src/CanvasImageCache.cpp
content/canvas/src/CanvasImageCache.h
layout/build/nsLayoutStatics.cpp
--- a/content/canvas/src/CanvasImageCache.cpp
+++ b/content/canvas/src/CanvasImageCache.cpp
@@ -128,25 +128,33 @@ public:
     mCache.RemoveEntry(ImageCacheKey(aObject->mImage, aObject->mCanvas));
   }
 
   nsTHashtable<ImageCacheEntry> mCache;
 };
 
 static ImageCache* gImageCache = nsnull;
 
+class CanvasImageCacheShutdownObserver : public nsIObserver
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIOBSERVER
+};
+
 void
 CanvasImageCache::NotifyDrawImage(nsIDOMElement* aImage,
                                   nsHTMLCanvasElement* aCanvas,
                                   imgIRequest* aRequest,
                                   gfxASurface* aSurface,
                                   const gfxIntSize& aSize)
 {
   if (!gImageCache) {
     gImageCache = new ImageCache();
+    nsContentUtils::RegisterShutdownObserver(new CanvasImageCacheShutdownObserver());
   }
 
   ImageCacheEntry* entry = gImageCache->mCache.PutEntry(ImageCacheKey(aImage, aCanvas));
   if (entry) {
     if (entry->mData->mSurface) {
       // We are overwriting an existing entry.
       gImageCache->RemoveObject(entry->mData);
     }
@@ -181,16 +189,26 @@ CanvasImageCache::Lookup(nsIDOMElement* 
     return nsnull;
 
   gImageCache->MarkUsed(entry->mData);
 
   *aSize = entry->mData->mSize;
   return entry->mData->mSurface;
 }
 
-void
-CanvasImageCache::Shutdown()
+NS_IMPL_ISUPPORTS1(CanvasImageCacheShutdownObserver, nsIObserver)
+
+NS_IMETHODIMP
+CanvasImageCacheShutdownObserver::Observe(nsISupports *aSubject,
+                                          const char *aTopic,
+                                          const PRUnichar *aData)
 {
-  delete gImageCache;
-  gImageCache = nsnull;
+  if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
+    delete gImageCache;
+    gImageCache = nsnull;
+
+    nsContentUtils::UnregisterShutdownObserver(this);
+  }
+
+  return NS_OK;
 }
 
 }
--- a/content/canvas/src/CanvasImageCache.h
+++ b/content/canvas/src/CanvasImageCache.h
@@ -64,15 +64,13 @@ public:
    * Check whether aImage has recently been drawn into aCanvas. If we return
    * a non-null surface, then the image was recently drawn into the canvas
    * (with the same image request) and the returned surface contains the image
    * data, and the image size will be returned in aSize.
    */
   static gfxASurface* Lookup(nsIDOMElement* aImage,
                              nsHTMLCanvasElement* aCanvas,
                              gfxIntSize* aSize);
-
-  static void Shutdown();
 };
 
 }
 
 #endif /* CANVASIMAGECACHE_H_ */
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -116,17 +116,16 @@
 
 #include "nsError.h"
 
 #include "nsCycleCollector.h"
 #include "nsJSEnvironment.h"
 #include "nsContentSink.h"
 #include "nsFrameMessageManager.h"
 #include "nsRefreshDriver.h"
-#include "CanvasImageCache.h"
 
 #include "nsHyphenationManager.h"
 
 extern void NS_ShutdownChainItemPool();
 
 using namespace mozilla;
 
 nsrefcnt nsLayoutStatics::sLayoutStaticRefcnt = 0;
@@ -276,17 +275,16 @@ nsLayoutStatics::Initialize()
   NS_SealStaticAtomTable();
 
   return NS_OK;
 }
 
 void
 nsLayoutStatics::Shutdown()
 {
-  CanvasImageCache::Shutdown();
   nsFrameScriptExecutor::Shutdown();
   nsFocusManager::Shutdown();
 #ifdef MOZ_XUL
   nsXULPopupManager::Shutdown();
 #endif
   nsDOMStorageManager::Shutdown();
   txMozillaXSLTProcessor::Shutdown();
   nsDOMAttribute::Shutdown();