Bug 705904 - [6/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 82015 4efe225df2e82c5de995f6057056251a59dd2278
parent 82014 905f0d81cc47730abaa9b4cc58610e9bfab69fee
child 82016 432d88a73914212f73ebf3fef49925e00aea1b78
push idunknown
push userunknown
push dateunknown
reviewersjgilbert
bugs705904
milestone11.0a1
Bug 705904 - [6/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 WebGLFramebuffer.
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,18 +231,16 @@ WebGLContext::WebGLContext()
     mActiveTexture = 0;
     mWebGLError = LOCAL_GL_NO_ERROR;
     mPixelStoreFlipY = false;
     mPixelStorePremultiplyAlpha = false;
     mPixelStoreColorspaceConversion = BROWSER_DEFAULT_WEBGL;
 
     mShaderValidation = true;
 
-    mMapFramebuffers.Init();
-
     mBlackTexturesAreInitialized = false;
     mFakeBlackStatus = DoNotNeedFakeBlack;
 
     mVertexAttrib0Vector[0] = 0;
     mVertexAttrib0Vector[1] = 0;
     mVertexAttrib0Vector[2] = 0;
     mVertexAttrib0Vector[3] = 1;
     mFakeVertexAttrib0BufferObjectVector[0] = 0;
@@ -304,32 +302,16 @@ WebGLContext::WebGLContext()
 WebGLContext::~WebGLContext()
 {
     DestroyResourcesAndContext();
     WebGLMemoryReporter::RemoveWebGLContext(this);
     TerminateRobustnessTimer();
     mContextRestorer = nsnull;
 }
 
-template<typename WebGLObjectType>
-static PLDHashOperator
-WebGLObjectDeleteFunction(const PRUint32& aKey, WebGLObjectType *aValue, void *)
-{
-    aValue->DeleteOnce();
-    return PL_DHASH_NEXT;
-}
-
-template<typename WebGLObjectType>
-void
-DeleteWebGLObjectsHashTable(nsRefPtrHashtable<nsUint32HashKey, WebGLObjectType>& table)
-{
-    table.EnumerateRead(WebGLObjectDeleteFunction<WebGLObjectType>, nsnull);
-    table.Clear();
-}
-
 void
 WebGLContext::DestroyResourcesAndContext()
 {
     if (!gl)
         return;
 
     gl->MakeCurrent();
 
@@ -344,17 +326,18 @@ WebGLContext::DestroyResourcesAndContext
     mAttribBuffers.Clear();
 
     while (mTextures.Length())
         mTextures.Last()->DeleteOnce();
     while (mBuffers.Length())
         mBuffers.Last()->DeleteOnce();
     while (mRenderbuffers.Length())
         mRenderbuffers.Last()->DeleteOnce();
-    DeleteWebGLObjectsHashTable(mMapFramebuffers);
+    while (mFramebuffers.Length())
+        mFramebuffers.Last()->DeleteOnce();
     while (mShaders.Length())
         mShaders.Last()->DeleteOnce();
     while (mPrograms.Length())
         mPrograms.Last()->DeleteOnce();
 
     if (mBlackTexturesAreInitialized) {
         gl->fDeleteTextures(1, &mBlackTexture2D);
         gl->fDeleteTextures(1, &mBlackTextureCubeMap);
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -823,18 +823,18 @@ protected:
 
     WebGLRefPtr<WebGLFramebuffer> mBoundFramebuffer;
     WebGLRefPtr<WebGLRenderbuffer> mBoundRenderbuffer;
 
     WebGLFastArray<WebGLTexture*> mTextures;
     WebGLFastArray<WebGLBuffer*> mBuffers;
     WebGLFastArray<WebGLProgram*> mPrograms;
     WebGLFastArray<WebGLShader*> mShaders;
-    nsRefPtrHashtable<nsUint32HashKey, WebGLFramebuffer> mMapFramebuffers;
     WebGLFastArray<WebGLRenderbuffer*> mRenderbuffers;
+    WebGLFastArray<WebGLFramebuffer*> mFramebuffers;
 
     // PixelStore parameters
     PRUint32 mPixelStorePackAlignment, mPixelStoreUnpackAlignment, mPixelStoreColorspaceConversion;
     bool mPixelStoreFlipY, mPixelStorePremultiplyAlpha;
 
     FakeBlackStatus mFakeBlackStatus;
 
     WebGLuint mBlackTexture2D, mBlackTextureCubeMap;
@@ -1960,30 +1960,31 @@ public:
         , mHasEverBeenBound(false)
         , mColorAttachment(LOCAL_GL_COLOR_ATTACHMENT0)
         , mDepthAttachment(LOCAL_GL_DEPTH_ATTACHMENT)
         , mStencilAttachment(LOCAL_GL_STENCIL_ATTACHMENT)
         , mDepthStencilAttachment(LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
     {
         mContext->MakeContextCurrent();
         mContext->gl->fGenFramebuffers(1, &mGLName);
+        mMonotonicHandle = mContext->mFramebuffers.AppendElement(this);
     }
 
     ~WebGLFramebuffer() {
         DeleteOnce();
     }
 
     void Delete() {
         mColorAttachment.Reset();
         mDepthAttachment.Reset();
         mStencilAttachment.Reset();
         mDepthStencilAttachment.Reset();
-
         mContext->MakeContextCurrent();
         mContext->gl->fDeleteFramebuffers(1, &mGLName);
+        mContext->mFramebuffers.RemoveElement(mMonotonicHandle);
     }
 
     bool HasEverBeenBound() { return mHasEverBeenBound; }
     void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
     WebGLuint GLName() { return mGLName; }
 
     WebGLsizei width() { return mColorAttachment.width(); }
     WebGLsizei height() { return mColorAttachment.height(); }
@@ -2242,16 +2243,18 @@ protected:
     bool mHasEverBeenBound;
 
     // we only store pointers to attached renderbuffers, not to attached textures, because
     // we will only need to initialize renderbuffers. Textures are already initialized.
     WebGLFramebufferAttachment mColorAttachment,
                                mDepthAttachment,
                                mStencilAttachment,
                                mDepthStencilAttachment;
+
+    WebGLMonotonicHandle mMonotonicHandle;
 };
 
 class WebGLUniformLocation
     : public nsIWebGLUniformLocation
     , public WebGLContextBoundObject
 {
 public:
     WebGLUniformLocation(WebGLContext *context, WebGLProgram *program, GLint location)
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -1164,17 +1164,16 @@ WebGLContext::DeleteFramebuffer(nsIWebGL
     bool isNull, isDeleted;
     if (!GetConcreteObjectAndGLName("deleteFramebuffer", fbobj, &fbuf, &fbufname, &isNull, &isDeleted))
         return NS_OK;
 
     if (isNull || isDeleted)
         return NS_OK;
 
     fbuf->RequestDelete();
-    mMapFramebuffers.Remove(fbufname);
 
     if (mBoundFramebuffer == fbuf)
         BindFramebuffer(LOCAL_GL_FRAMEBUFFER, nsnull);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -4303,17 +4302,16 @@ WebGLContext::CreateFramebuffer(nsIWebGL
 {
     if (mContextLost)
         return NS_OK;
 
     *retval = 0;
 
     WebGLFramebuffer *globj = new WebGLFramebuffer(this);
     NS_ADDREF(*retval = globj);
-    mMapFramebuffers.Put(globj->GLName(), globj);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::CreateRenderbuffer(nsIWebGLRenderbuffer **retval)
 {
     if (mContextLost)
--- a/content/canvas/src/WebGLContextValidate.cpp
+++ b/content/canvas/src/WebGLContextValidate.cpp
@@ -520,18 +520,16 @@ WebGLContext::InitAndValidateGL()
 
     mBoundArrayBuffer = nsnull;
     mBoundElementArrayBuffer = nsnull;
     mCurrentProgram = nsnull;
 
     mBoundFramebuffer = nsnull;
     mBoundRenderbuffer = nsnull;
 
-    mMapFramebuffers.Clear();
-
     MakeContextCurrent();
 
     // on desktop OpenGL, we always keep vertex attrib 0 array enabled
     if (!gl->IsGLES2()) {
         gl->fEnableVertexAttribArray(0);
     }
 
     if (MinCapabilityMode()) {