Bug 705904 - [3/6] - Kill nsRefPtrHashtables of WebGL objects, allow unreferenced objects to be freed, fix about:memory reporting of deleted objects - r=jgilbert
authorBenoit Jacob <bjacob@mozilla.com>
Sun, 04 Dec 2011 14:15:43 -0500
changeset 82012 111be7b1a9e89843248d214cc6f50244b8eccb17
parent 82011 eaf41f64aad7d983a7b1d0a01195c4231cc5f13b
child 82013 724663b7a0ce7c074f4103c40cd2968765401f02
push idunknown
push userunknown
push dateunknown
reviewersjgilbert
bugs705904
milestone11.0a1
Bug 705904 - [3/6] - Kill nsRefPtrHashtables of WebGL objects, allow unreferenced objects to be freed, fix about:memory reporting of deleted objects - r=jgilbert This patch takes care of WebGLProgram.
content/canvas/src/WebGLContext.cpp
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/WebGLContextValidate.cpp
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -231,17 +231,16 @@ WebGLContext::WebGLContext()
     mActiveTexture = 0;
     mWebGLError = LOCAL_GL_NO_ERROR;
     mPixelStoreFlipY = false;
     mPixelStorePremultiplyAlpha = false;
     mPixelStoreColorspaceConversion = BROWSER_DEFAULT_WEBGL;
 
     mShaderValidation = true;
 
-    mMapPrograms.Init();
     mMapShaders.Init();
     mMapFramebuffers.Init();
     mMapRenderbuffers.Init();
 
     mBlackTexturesAreInitialized = false;
     mFakeBlackStatus = DoNotNeedFakeBlack;
 
     mVertexAttrib0Vector[0] = 0;
@@ -348,17 +347,18 @@ WebGLContext::DestroyResourcesAndContext
 
     while (mTextures.Length())
         mTextures.Last()->DeleteOnce();
     while (mBuffers.Length())
         mBuffers.Last()->DeleteOnce();
     DeleteWebGLObjectsHashTable(mMapRenderbuffers);
     DeleteWebGLObjectsHashTable(mMapFramebuffers);
     DeleteWebGLObjectsHashTable(mMapShaders);
-    DeleteWebGLObjectsHashTable(mMapPrograms);
+    while (mPrograms.Length())
+        mPrograms.Last()->DeleteOnce();
 
     if (mBlackTexturesAreInitialized) {
         gl->fDeleteTextures(1, &mBlackTexture2D);
         gl->fDeleteTextures(1, &mBlackTextureCubeMap);
         mBlackTexturesAreInitialized = false;
     }
 
     if (mFakeVertexAttrib0BufferObject) {
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -821,17 +821,17 @@ protected:
 
     PRUint32 mMaxFramebufferColorAttachments;
 
     WebGLRefPtr<WebGLFramebuffer> mBoundFramebuffer;
     WebGLRefPtr<WebGLRenderbuffer> mBoundRenderbuffer;
 
     WebGLFastArray<WebGLTexture*> mTextures;
     WebGLFastArray<WebGLBuffer*> mBuffers;
-    nsRefPtrHashtable<nsUint32HashKey, WebGLProgram> mMapPrograms;
+    WebGLFastArray<WebGLProgram*> mPrograms;
     nsRefPtrHashtable<nsUint32HashKey, WebGLShader> mMapShaders;
     nsRefPtrHashtable<nsUint32HashKey, WebGLFramebuffer> mMapFramebuffers;
     nsRefPtrHashtable<nsUint32HashKey, WebGLRenderbuffer> mMapRenderbuffers;
 
     // PixelStore parameters
     PRUint32 mPixelStorePackAlignment, mPixelStoreUnpackAlignment, mPixelStoreColorspaceConversion;
     bool mPixelStoreFlipY, mPixelStorePremultiplyAlpha;
 
@@ -1640,27 +1640,29 @@ public:
         , mAttribMaxNameLength(0)
         , mUniformCount(0)
         , mAttribCount(0)
     {
 
         mMapUniformLocations.Init();
         mContext->MakeContextCurrent();
         mGLName = mContext->gl->fCreateProgram();
+        mMonotonicHandle = mContext->mPrograms.AppendElement(this);
     }
 
     ~WebGLProgram() {
         DeleteOnce();
     }
 
     void Delete() {
         DetachShaders();
         mContext->MakeContextCurrent();
         mContext->gl->fDeleteProgram(mGLName);
         mMapUniformLocations.EnumerateRead(NotifyUniformLocationOfProgramDeletion, nsnull);
+        mContext->mPrograms.RemoveElement(mMonotonicHandle);
     }
 
     void DetachShaders() {
         mAttachedShaders.Clear();
     }
 
     WebGLuint GLName() { return mGLName; }
     const nsTArray<WebGLRefPtr<WebGLShader> >& AttachedShaders() const { return mAttachedShaders; }
@@ -1748,16 +1750,17 @@ protected:
     // so the XPCOM refcount is all what matters for them, that's why plain nsRefPtr's are enough here.
     nsRefPtrHashtable<nsUint32HashKey, WebGLUniformLocation> mMapUniformLocations;
 
     GLint mUniformMaxNameLength;
     GLint mAttribMaxNameLength;
     GLint mUniformCount;
     GLint mAttribCount;
     std::vector<bool> mAttribsInUse;
+    WebGLMonotonicHandle mMonotonicHandle;
 
 private:
     static PLDHashOperator
     NotifyUniformLocationOfProgramDeletion(const PRUint32& aKey, WebGLUniformLocation *aValue, void *);
 };
 
 class WebGLRenderbuffer
     : public nsIWebGLRenderbuffer
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -1080,17 +1080,16 @@ WebGLContext::CreateProgram(nsIWebGLProg
 {
     if (mContextLost)
         return NS_OK;
 
     *retval = nsnull;
 
     WebGLProgram *prog = new WebGLProgram(this);
     NS_ADDREF(*retval = prog);
-    mMapPrograms.Put(prog->GLName(), prog);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::CreateShader(WebGLenum type, nsIWebGLShader **retval)
 {
     if (mContextLost)
@@ -1250,17 +1249,16 @@ WebGLContext::DeleteProgram(nsIWebGLProg
     bool isNull, isDeleted;
     if (!GetConcreteObjectAndGLName("deleteProgram", pobj, &prog, &progname, &isNull, &isDeleted))
         return NS_OK;
 
     if (isNull || isDeleted)
         return NS_OK;
 
     prog->RequestDelete();
-    mMapPrograms.Remove(progname);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::DeleteShader(nsIWebGLShader *sobj)
 {
     if (mContextLost)
--- a/content/canvas/src/WebGLContextValidate.cpp
+++ b/content/canvas/src/WebGLContextValidate.cpp
@@ -520,17 +520,16 @@ WebGLContext::InitAndValidateGL()
 
     mBoundArrayBuffer = nsnull;
     mBoundElementArrayBuffer = nsnull;
     mCurrentProgram = nsnull;
 
     mBoundFramebuffer = nsnull;
     mBoundRenderbuffer = nsnull;
 
-    mMapPrograms.Clear();
     mMapShaders.Clear();
     mMapFramebuffers.Clear();
     mMapRenderbuffers.Clear();
 
     MakeContextCurrent();
 
     // on desktop OpenGL, we always keep vertex attrib 0 array enabled
     if (!gl->IsGLES2()) {