Replaced raw pointers to RefCountObject to BindingPointer.

This fixes the ANGLE crashes in Chrome when using canvas 2D.

The issue was this:

Renderbuffer *mColorbufferProxy = new RenderBuffer(...); // Reference count is zero.

BindingPointer<RenderBuffer> tempRef;
tempRef.set(mColorbufferProxy); // Reference count is one.

tempRef.set(NULL); // Reference count is zero and object is destroyed, leaving mColorbufferProxy dangling.

I also initially suspected the problem was that FBOs are not treated as shared and the implementation of shared FBOs is still in the patch. I believe GLES2 supports shared FBOs.

My reading of the GLES2 spec is that when a shared object is deleted, it loses its id but retains its state if left bound elsewhere. I added that to RefCountObject.



Review URL: http://codereview.appspot.com/2120045

git-svn-id: https://angleproject.googlecode.com/svn/trunk@417 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 7b692a2..b004a4a 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -122,11 +122,8 @@
     // In order that access to these initial textures not be lost, they are treated as texture
     // objects all of whose names are 0.
 
-    mTexture2DZero = new Texture2D(0);
-    mTextureCubeMapZero = new TextureCubeMap(0);
-
-    mColorbufferZero = NULL;
-    mDepthStencilbufferZero = NULL;
+    mTexture2DZero.set(new Texture2D(0));
+    mTextureCubeMapZero.set(new TextureCubeMap(0));
 
     mState.activeSampler = 0;
     bindArrayBuffer(0);
@@ -137,11 +134,6 @@
     bindDrawFramebuffer(0);
     bindRenderbuffer(0);
 
-    for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
-    {
-        mIncompleteTextures[type] = NULL;
-    }
-
     mState.currentProgram = 0;
 
     mState.packAlignment = 4;
@@ -179,11 +171,6 @@
         mState.currentProgram = 0;
     }
 
-    while (!mFramebufferMap.empty())
-    {
-        deleteFramebuffer(mFramebufferMap.begin()->first);
-    }
-
     while (!mFenceMap.empty())
     {
         deleteFence(mFenceMap.begin()->first);
@@ -205,7 +192,7 @@
 
     for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
     {
-        delete mIncompleteTextures[type];
+        mIncompleteTextures[type].set(NULL);
     }
 
     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
@@ -218,9 +205,12 @@
     mState.texture2D.set(NULL);
     mState.textureCubeMap.set(NULL);
     mState.renderbuffer.set(NULL);
+    mState.readFramebuffer.set(NULL);
+    mState.drawFramebuffer.set(NULL);
 
-    delete mTexture2DZero;
-    delete mTextureCubeMapZero;
+    mTexture2DZero.set(NULL);
+    mTextureCubeMapZero.set(NULL);
+    mFramebufferZero.set(NULL);
 
     delete mBufferBackEnd;
     delete mVertexDataManager;
@@ -723,12 +713,12 @@
 
 GLuint Context::getReadFramebufferHandle() const
 {
-    return mState.readFramebuffer;
+    return mState.readFramebuffer.id();
 }
 
 GLuint Context::getDrawFramebufferHandle() const
 {
-    return mState.drawFramebuffer;
+    return mState.drawFramebuffer.id();
 }
 
 GLuint Context::getRenderbufferHandle() const
@@ -818,19 +808,9 @@
     return mResourceManager->createRenderbuffer();
 }
 
-// Returns an unused framebuffer name
 GLuint Context::createFramebuffer()
 {
-    unsigned int handle = 1;
-
-    while (mFramebufferMap.find(handle) != mFramebufferMap.end())
-    {
-        handle++;
-    }
-
-    mFramebufferMap[handle] = NULL;
-
-    return handle;
+    return mResourceManager->createFramebuffer();
 }
 
 GLuint Context::createFence()
@@ -889,15 +869,12 @@
 
 void Context::deleteFramebuffer(GLuint framebuffer)
 {
-    FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
-
-    if (framebufferObject != mFramebufferMap.end())
+    if (mResourceManager->getFramebuffer(framebuffer))
     {
         detachFramebuffer(framebuffer);
-
-        delete framebufferObject->second;
-        mFramebufferMap.erase(framebufferObject);
     }
+
+    mResourceManager->deleteFramebuffer(framebuffer);
 }
 
 void Context::deleteFence(GLuint fence)
@@ -936,14 +913,14 @@
     return mResourceManager->getRenderbuffer(handle);
 }
 
-Framebuffer *Context::getReadFramebuffer()
+Framebuffer *Context::getFramebuffer(GLuint handle)
 {
-    return getFramebuffer(mState.readFramebuffer);
-}
+    if (handle == 0)
+    {
+        return mFramebufferZero.get();
+    }
 
-Framebuffer *Context::getDrawFramebuffer()
-{
-    return getFramebuffer(mState.drawFramebuffer);
+    return mResourceManager->getFramebuffer(handle);
 }
 
 void Context::bindArrayBuffer(unsigned int buffer)
@@ -980,22 +957,16 @@
 
 void Context::bindReadFramebuffer(GLuint framebuffer)
 {
-    if (!getFramebuffer(framebuffer))
-    {
-        mFramebufferMap[framebuffer] = new Framebuffer();
-    }
-
-    mState.readFramebuffer = framebuffer;
+    mResourceManager->checkFramebufferAllocation(framebuffer);
+    
+    mState.readFramebuffer.set(getFramebuffer(framebuffer));
 }
 
 void Context::bindDrawFramebuffer(GLuint framebuffer)
 {
-    if (!getFramebuffer(framebuffer))
-    {
-        mFramebufferMap[framebuffer] = new Framebuffer();
-    }
-
-    mState.drawFramebuffer = framebuffer;
+    mResourceManager->checkFramebufferAllocation(framebuffer);
+    
+    mState.drawFramebuffer.set(getFramebuffer(framebuffer));
 }
 
 void Context::bindRenderbuffer(GLuint renderbuffer)
@@ -1029,8 +1000,17 @@
 
 void Context::setFramebufferZero(Framebuffer *buffer)
 {
-    delete mFramebufferMap[0];
-    mFramebufferMap[0] = buffer;
+    if (mState.readFramebuffer.get() == mFramebufferZero.get())
+    {
+        mState.readFramebuffer.set(buffer);
+    }
+    
+    if (mState.drawFramebuffer.get() == mFramebufferZero.get())
+    {
+        mState.drawFramebuffer.set(buffer);
+    }
+    
+    mFramebufferZero.set(buffer);
 }
 
 void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
@@ -1039,20 +1019,6 @@
     renderbufferObject->setStorage(renderbuffer);
 }
 
-Framebuffer *Context::getFramebuffer(unsigned int handle)
-{
-    FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle);
-
-    if (framebuffer == mFramebufferMap.end())
-    {
-        return NULL;
-    }
-    else
-    {
-        return framebuffer->second;
-    }
-}
-
 Fence *Context::getFence(unsigned int handle)
 {
     FenceMap::iterator fence = mFenceMap.find(handle);
@@ -1086,7 +1052,7 @@
 {
     if (mState.texture2D.id() == 0)   // Special case: 0 refers to different initial textures based on the target
     {
-        return mTexture2DZero;
+        return mTexture2DZero.get();
     }
 
     return static_cast<Texture2D*>(mState.texture2D.get());
@@ -1096,7 +1062,7 @@
 {
     if (mState.textureCubeMap.id() == 0)   // Special case: 0 refers to different initial textures based on the target
     {
-        return mTextureCubeMapZero;
+        return mTextureCubeMapZero.get();
     }
 
     return static_cast<TextureCubeMap*>(mState.textureCubeMap.get());
@@ -1111,14 +1077,24 @@
         switch (type)
         {
           default: UNREACHABLE();
-          case SAMPLER_2D: return mTexture2DZero;
-          case SAMPLER_CUBE: return mTextureCubeMapZero;
+          case SAMPLER_2D: return mTexture2DZero.get();
+          case SAMPLER_CUBE: return mTextureCubeMapZero.get();
         }
     }
 
     return mState.samplerTexture[type][sampler].get();
 }
 
+Framebuffer *Context::getReadFramebuffer()
+{
+    return mState.readFramebuffer.get();
+}
+
+Framebuffer *Context::getDrawFramebuffer()
+{
+   return mState.drawFramebuffer.get();
+}
+
 bool Context::getBooleanv(GLenum pname, GLboolean *params)
 {
     switch (pname)
@@ -1214,8 +1190,8 @@
       case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.id();              break;
       case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.id();       break;
       //case GL_FRAMEBUFFER_BINDING:              // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
-      case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:     *params = mState.drawFramebuffer;               break;
-      case GL_READ_FRAMEBUFFER_BINDING_ANGLE:     *params = mState.readFramebuffer;               break;
+      case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:     *params = mState.drawFramebuffer.id();        break;
+      case GL_READ_FRAMEBUFFER_BINDING_ANGLE:     *params = mState.readFramebuffer.id();        break;
       case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.id();             break;
       case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;
       case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
@@ -2998,12 +2974,12 @@
     // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
     // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
 
-    if (mState.readFramebuffer == framebuffer)
+    if (mState.readFramebuffer.id() == framebuffer)
     {
         bindReadFramebuffer(0);
     }
 
-    if (mState.drawFramebuffer == framebuffer)
+    if (mState.drawFramebuffer.id() == framebuffer)
     {
         bindDrawFramebuffer(0);
     }
@@ -3041,7 +3017,7 @@
 
 Texture *Context::getIncompleteTexture(SamplerType type)
 {
-    Texture *t = mIncompleteTextures[type];
+    Texture *t = mIncompleteTextures[type].get();
 
     if (t == NULL)
     {
@@ -3077,7 +3053,7 @@
             break;
         }
 
-        mIncompleteTextures[type] = t;
+        mIncompleteTextures[type].set(t);
     }
 
     return t;