Sharing for buffer, texture and renderbuffer objects.

TRAC #12496

Derive Renderbuffer, Texture and Buffer from RefCountObject.
This class keeps a reference count for all objects that need cross-context
reference counting, and also the object id.
Restructure Renderbuffers to create a wrapper object and a storage object.
Use BindingPointer for all binding points instead of binding by object id.

Signed-off-by: Shannon Woods
Signed-off-by: Daniel Koch

git-svn-id: https://angleproject.googlecode.com/svn/trunk@364 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Framebuffer.cpp b/src/libGLESv2/Framebuffer.cpp
index cca4a0d..8a457d5 100644
--- a/src/libGLESv2/Framebuffer.cpp
+++ b/src/libGLESv2/Framebuffer.cpp
@@ -16,85 +16,109 @@
 
 namespace gl
 {
-    Framebuffer::Framebuffer(GLuint handle) : mHandle(handle)
+
+Framebuffer::Framebuffer()
 {
     mColorbufferType = GL_NONE;
-    mColorbufferHandle = 0;
-
     mDepthbufferType = GL_NONE;
-    mDepthbufferHandle = 0;
-
     mStencilbufferType = GL_NONE;
-    mStencilbufferHandle = 0;
 }
 
 Framebuffer::~Framebuffer()
 {
+    mColorbufferPointer.set(NULL);
+    mDepthbufferPointer.set(NULL);
+    mStencilbufferPointer.set(NULL);
+}
+
+Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
+{
+    gl::Context *context = gl::getContext();
+    Renderbuffer *buffer = NULL;
+
+    if (type == GL_NONE)
+    {
+        buffer = NULL;
+    }
+    else if (type == GL_RENDERBUFFER)
+    {
+        buffer = context->getRenderbuffer(handle);
+    }
+    else if (IsTextureTarget(type))
+    {
+        buffer = context->getTexture(handle)->getColorbuffer(type);
+    }
+    else
+    {
+        UNREACHABLE();
+    }
+
+    return buffer;
 }
 
 void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer)
 {
     mColorbufferType = type;
-    mColorbufferHandle = colorbuffer;
+    mColorbufferPointer.set(lookupRenderbuffer(type, colorbuffer));
 }
 
 void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer)
 {
     mDepthbufferType = type;
-    mDepthbufferHandle = depthbuffer;
+    mDepthbufferPointer.set(lookupRenderbuffer(type, depthbuffer));
 }
 
 void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
 {
     mStencilbufferType = type;
-    mStencilbufferHandle = stencilbuffer;
+    mStencilbufferPointer.set(lookupRenderbuffer(type, stencilbuffer));
 }
 
 void Framebuffer::detachTexture(GLuint texture)
 {
-    if (mColorbufferHandle == texture && IsTextureTarget(mColorbufferType))
+    if (mColorbufferPointer.id() == texture && IsTextureTarget(mColorbufferType))
     {
         mColorbufferType = GL_NONE;
-        mColorbufferHandle = 0;
+        mColorbufferPointer.set(NULL);
     }
 
-    if (mDepthbufferHandle == texture && IsTextureTarget(mDepthbufferType))
+    if (mDepthbufferPointer.id() == texture && IsTextureTarget(mDepthbufferType))
     {
         mDepthbufferType = GL_NONE;
-        mDepthbufferHandle = 0;
+        mDepthbufferPointer.set(NULL);
     }
 
-    if (mStencilbufferHandle == texture && IsTextureTarget(mStencilbufferType))
+    if (mStencilbufferPointer.id() == texture && IsTextureTarget(mStencilbufferType))
     {
         mStencilbufferType = GL_NONE;
-        mStencilbufferHandle = 0;
+        mStencilbufferPointer.set(NULL);
     }
 }
 
 void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
 {
-    if (mColorbufferHandle == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
+    if (mColorbufferPointer.id() == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
     {
         mColorbufferType = GL_NONE;
-        mColorbufferHandle = 0;
+        mColorbufferPointer.set(NULL);
     }
 
-    if (mDepthbufferHandle == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
+    if (mDepthbufferPointer.id() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
     {
         mDepthbufferType = GL_NONE;
-        mDepthbufferHandle = 0;
+        mDepthbufferPointer.set(NULL);
     }
 
-    if (mStencilbufferHandle == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
+    if (mStencilbufferPointer.id() == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
     {
         mStencilbufferType = GL_NONE;
-        mStencilbufferHandle = 0;
+        mStencilbufferPointer.set(NULL);
     }
 }
 
 unsigned int Framebuffer::getRenderTargetSerial()
 {
-    Renderbuffer *colorbuffer = getColorbuffer();
+    Renderbuffer *colorbuffer = mColorbufferPointer.get();
 
     if (colorbuffer)
     {
@@ -106,7 +130,7 @@
 
 IDirect3DSurface9 *Framebuffer::getRenderTarget()
 {
-    Renderbuffer *colorbuffer = getColorbuffer();
+    Renderbuffer *colorbuffer = mColorbufferPointer.get();
 
     if (colorbuffer)
     {
@@ -118,8 +142,7 @@
 
 unsigned int Framebuffer::getDepthbufferSerial()
 {
-    gl::Context *context = gl::getContext();
-    DepthStencilbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
+    Renderbuffer *depthbuffer = mDepthbufferPointer.get();
 
     if (depthbuffer)
     {
@@ -131,61 +154,44 @@
 
 Colorbuffer *Framebuffer::getColorbuffer()
 {
-    gl::Context *context = gl::getContext();
-    Colorbuffer *colorbuffer = NULL;
+    Renderbuffer *rb = mColorbufferPointer.get();
 
-    if (mColorbufferType == GL_NONE)
+    if (rb != NULL && rb->isColorbuffer())
     {
-        UNREACHABLE();
-        colorbuffer = NULL;
-    }
-    else if (mColorbufferType == GL_RENDERBUFFER)
-    {
-        colorbuffer = context->getColorbuffer(mColorbufferHandle);
+        return static_cast<Colorbuffer*>(rb->getStorage());
     }
     else
     {
-        colorbuffer = context->getTexture(mColorbufferHandle)->getColorbuffer(mColorbufferType);
+        return NULL;
     }
-
-    if (colorbuffer && colorbuffer->isColorbuffer())
-    {
-        return colorbuffer;
-    }
-
-    return NULL;
 }
 
 DepthStencilbuffer *Framebuffer::getDepthbuffer()
 {
-    if (mDepthbufferType != GL_NONE)
+    Renderbuffer *rb = mDepthbufferPointer.get();
+
+    if (rb != NULL && rb->isDepthbuffer())
     {
-        gl::Context *context = gl::getContext();
-        DepthStencilbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
-
-        if (depthbuffer && depthbuffer->isDepthbuffer())
-        {
-            return depthbuffer;
-        }
+        return static_cast<DepthStencilbuffer*>(rb->getStorage());
     }
-
-    return NULL;
+    else
+    {
+        return NULL;
+    }
 }
 
 DepthStencilbuffer *Framebuffer::getStencilbuffer()
 {
-    if (mStencilbufferType != GL_NONE)
+    Renderbuffer *rb = mStencilbufferPointer.get();
+
+    if (rb != NULL && rb->isStencilbuffer())
     {
-        gl::Context *context = gl::getContext();
-        DepthStencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
-
-        if (stencilbuffer && stencilbuffer->isStencilbuffer())
-        {
-            return stencilbuffer;
-        }
+        return static_cast<DepthStencilbuffer*>(rb->getStorage());
     }
-
-    return NULL;
+    else
+    {
+        return NULL;
+    }
 }
 
 GLenum Framebuffer::getColorbufferType()
@@ -205,114 +211,128 @@
 
 GLuint Framebuffer::getColorbufferHandle()
 {
-    return mColorbufferHandle;
+    return mColorbufferPointer.id();
 }
 
 GLuint Framebuffer::getDepthbufferHandle()
 {
-    return mDepthbufferHandle;
+    return mDepthbufferPointer.id();
 }
 
 GLuint Framebuffer::getStencilbufferHandle()
 {
-    return mStencilbufferHandle;
+    return mStencilbufferPointer.id();
 }
 
 GLenum Framebuffer::completeness()
 {
-    gl::Context *context = gl::getContext();
-
     int width = 0;
     int height = 0;
 
-    if (mHandle != 0)
+    if (mColorbufferType != GL_NONE)
     {
-        if (mColorbufferType != GL_NONE)
+        Colorbuffer *colorbuffer = getColorbuffer();
+
+        if (!colorbuffer)
         {
-            Colorbuffer *colorbuffer = getColorbuffer();
-
-            if (!colorbuffer)
-            {
-                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-            }
-
-            if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
-            {
-                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-            }
-
-            width = colorbuffer->getWidth();
-            height = colorbuffer->getHeight();
-        }
-        else
-        {
-            return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
+            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
         }
 
-        DepthStencilbuffer *depthbuffer = NULL;
-        DepthStencilbuffer *stencilbuffer = NULL;
-
-        if (mDepthbufferType != GL_NONE)
+        if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
         {
-            depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
-
-            if (!depthbuffer)
-            {
-                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-            }
-
-            if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
-            {
-                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-            }
-
-            if (width == 0)
-            {
-                width = depthbuffer->getWidth();
-                height = depthbuffer->getHeight();
-            }
-            else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
-            {
-                return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
-            }
+            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
         }
 
-        if (mStencilbufferType != GL_NONE)
+        width = colorbuffer->getWidth();
+        height = colorbuffer->getHeight();
+    }
+    else
+    {
+        return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
+    }
+
+    DepthStencilbuffer *depthbuffer = NULL;
+    DepthStencilbuffer *stencilbuffer = NULL;
+
+    if (mDepthbufferType != GL_NONE)
+    {
+        depthbuffer = getDepthbuffer();
+
+        if (!depthbuffer)
         {
-            stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
-
-            if (!stencilbuffer)
-            {
-                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-            }
-
-            if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
-            {
-                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-            }
-
-            if (width == 0)
-            {
-                width = stencilbuffer->getWidth();
-                height = stencilbuffer->getHeight();
-            }
-            else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
-            {
-                return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
-            }
+            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
         }
 
-        if (mDepthbufferType == GL_RENDERBUFFER && mStencilbufferType == GL_RENDERBUFFER)
+        if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
         {
-            if (depthbuffer->getFormat() != GL_DEPTH24_STENCIL8_OES ||
-                stencilbuffer->getFormat() != GL_DEPTH24_STENCIL8_OES ||
-                depthbuffer->getSerial() != stencilbuffer->getSerial())
-            {
-                return GL_FRAMEBUFFER_UNSUPPORTED;
-            }
+            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+        }
+
+        if (width == 0)
+        {
+            width = depthbuffer->getWidth();
+            height = depthbuffer->getHeight();
+        }
+        else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
+        {
+            return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+        }
+    }
+
+    if (mStencilbufferType != GL_NONE)
+    {
+        stencilbuffer = getStencilbuffer();
+
+        if (!stencilbuffer)
+        {
+            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+        }
+
+        if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
+        {
+            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+        }
+
+        if (width == 0)
+        {
+            width = stencilbuffer->getWidth();
+            height = stencilbuffer->getHeight();
+        }
+        else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
+        {
+            return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+        }
+    }
+
+    if (mDepthbufferType == GL_RENDERBUFFER && mStencilbufferType == GL_RENDERBUFFER)
+    {
+        if (depthbuffer->getFormat() != GL_DEPTH24_STENCIL8_OES ||
+            stencilbuffer->getFormat() != GL_DEPTH24_STENCIL8_OES ||
+            depthbuffer->getSerial() != stencilbuffer->getSerial())
+        {
+            return GL_FRAMEBUFFER_UNSUPPORTED;
         }
     }
 
     return GL_FRAMEBUFFER_COMPLETE;
 }
+
+DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *depthStencil)
+{
+    mColorbufferType = GL_RENDERBUFFER;
+    mDepthbufferType = GL_RENDERBUFFER;
+    mStencilbufferType = GL_RENDERBUFFER;
+
+    mColorbufferPointer.set(new Renderbuffer(0, color));
+
+    Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil);
+    mDepthbufferPointer.set(depthStencilRenderbuffer);
+    mStencilbufferPointer.set(depthStencilRenderbuffer);
+}
+
+GLenum DefaultFramebuffer::completeness()
+{
+    return GL_FRAMEBUFFER_COMPLETE;
+}
+
 }