Implement RenderbufferGL.

BUG=angleproject:886

Change-Id: I7480943d678b2cdf6e997c3f8316acdef32f5f0d
Reviewed-on: https://chromium-review.googlesource.com/260889
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Brandon Jones <bajones@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Renderbuffer.cpp b/src/libANGLE/Renderbuffer.cpp
index f37c023..6a0cde8 100644
--- a/src/libANGLE/Renderbuffer.cpp
+++ b/src/libANGLE/Renderbuffer.cpp
@@ -72,6 +72,11 @@
     return mRenderbuffer;
 }
 
+const rx::RenderbufferImpl *Renderbuffer::getImplementation() const
+{
+    return mRenderbuffer;
+}
+
 GLsizei Renderbuffer::getWidth() const
 {
     return mWidth;
diff --git a/src/libANGLE/Renderbuffer.h b/src/libANGLE/Renderbuffer.h
index 8517c41..f2d51d4 100644
--- a/src/libANGLE/Renderbuffer.h
+++ b/src/libANGLE/Renderbuffer.h
@@ -42,6 +42,7 @@
     Error setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height);
 
     rx::RenderbufferImpl *getImplementation();
+    const rx::RenderbufferImpl *getImplementation() const;
 
     GLsizei getWidth() const;
     GLsizei getHeight() const;
diff --git a/src/libANGLE/renderer/gl/FramebufferGL.cpp b/src/libANGLE/renderer/gl/FramebufferGL.cpp
index 08497e9..99ad76f 100644
--- a/src/libANGLE/renderer/gl/FramebufferGL.cpp
+++ b/src/libANGLE/renderer/gl/FramebufferGL.cpp
@@ -74,14 +74,11 @@
         }
         else if (attachment->type() == GL_RENDERBUFFER)
         {
-            // TODO: support RenderbufferGL
-            UNIMPLEMENTED();
+            const gl::Renderbuffer *renderbuffer = GetAs<gl::RenderbufferAttachment>(attachment)->getRenderbuffer();
+            const RenderbufferGL *renderbufferGL = GetImplAs<RenderbufferGL>(renderbuffer);
 
-            //const gl::Renderbuffer *renderbuffer = GetAs<gl::RenderbufferAttachment>(attachment)->getRenderbuffer();
-            //const RenderbufferGL *renderbufferGL = GetImplAs<RenderbufferGL>(renderbuffer);
-
-            //functions->framebufferRenderbuffer(GL_FRAMEBUFFER, attachmentPoint, GL_RENDERBUFFER,
-            //                                   renderbufferGL->getRenderbufferID());
+            functions->framebufferRenderbuffer(GL_FRAMEBUFFER, attachmentPoint, GL_RENDERBUFFER,
+                                               renderbufferGL->getRenderbufferID());
         }
         else
         {
diff --git a/src/libANGLE/renderer/gl/RenderbufferGL.cpp b/src/libANGLE/renderer/gl/RenderbufferGL.cpp
index 88d4789..b580ea8 100644
--- a/src/libANGLE/renderer/gl/RenderbufferGL.cpp
+++ b/src/libANGLE/renderer/gl/RenderbufferGL.cpp
@@ -9,27 +9,48 @@
 #include "libANGLE/renderer/gl/RenderbufferGL.h"
 
 #include "common/debug.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
 
 namespace rx
 {
 
-RenderbufferGL::RenderbufferGL()
-    : RenderbufferImpl()
-{}
+RenderbufferGL::RenderbufferGL(const FunctionsGL *functions, StateManagerGL *stateManager)
+    : RenderbufferImpl(),
+      mFunctions(functions),
+      mStateManager(stateManager),
+      mRenderbufferID(0)
+{
+    mFunctions->genRenderbuffers(1, &mRenderbufferID);
+}
 
 RenderbufferGL::~RenderbufferGL()
-{}
+{
+    if (mRenderbufferID != 0)
+    {
+        mFunctions->deleteRenderbuffers(1, &mRenderbufferID);
+        mRenderbufferID = 0;
+    }
+}
 
 gl::Error RenderbufferGL::setStorage(GLenum internalformat, size_t width, size_t height)
 {
-    UNIMPLEMENTED();
-    return gl::Error(GL_INVALID_OPERATION);
+    mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID);
+    mFunctions->renderbufferStorage(GL_RENDERBUFFER, internalformat, width, height);
+    return gl::Error(GL_NO_ERROR);
 }
 
 gl::Error RenderbufferGL::setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height)
 {
-    UNIMPLEMENTED();
-    return gl::Error(GL_INVALID_OPERATION);
+    mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID);
+    mFunctions->renderbufferStorageMultisample(GL_RENDERBUFFER, samples, internalformat, width, height);
+    return gl::Error(GL_NO_ERROR);
+}
+
+GLuint RenderbufferGL::getRenderbufferID() const
+{
+    return mRenderbufferID;
 }
 
 }
diff --git a/src/libANGLE/renderer/gl/RenderbufferGL.h b/src/libANGLE/renderer/gl/RenderbufferGL.h
index 1dd76ba..d7724d4 100644
--- a/src/libANGLE/renderer/gl/RenderbufferGL.h
+++ b/src/libANGLE/renderer/gl/RenderbufferGL.h
@@ -14,17 +14,27 @@
 namespace rx
 {
 
+class FunctionsGL;
+class StateManagerGL;
+
 class RenderbufferGL : public RenderbufferImpl
 {
   public:
-    RenderbufferGL();
+    RenderbufferGL(const FunctionsGL *functions, StateManagerGL *stateManager);
     ~RenderbufferGL() override;
 
     virtual gl::Error setStorage(GLenum internalformat, size_t width, size_t height) override;
     virtual gl::Error setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height) override;
 
+    GLuint getRenderbufferID() const;
+
   private:
     DISALLOW_COPY_AND_ASSIGN(RenderbufferGL);
+
+    const FunctionsGL *mFunctions;
+    StateManagerGL *mStateManager;
+
+    GLuint mRenderbufferID;
 };
 
 }
diff --git a/src/libANGLE/renderer/gl/RendererGL.cpp b/src/libANGLE/renderer/gl/RendererGL.cpp
index f3bd7b3..19626e1 100644
--- a/src/libANGLE/renderer/gl/RendererGL.cpp
+++ b/src/libANGLE/renderer/gl/RendererGL.cpp
@@ -130,7 +130,7 @@
 
 RenderbufferImpl *RendererGL::createRenderbuffer()
 {
-    return new RenderbufferGL();
+    return new RenderbufferGL(mFunctions, mStateManager);
 }
 
 BufferImpl *RendererGL::createBuffer()
diff --git a/src/libANGLE/renderer/gl/StateManagerGL.cpp b/src/libANGLE/renderer/gl/StateManagerGL.cpp
index a8a2096..46ed508 100644
--- a/src/libANGLE/renderer/gl/StateManagerGL.cpp
+++ b/src/libANGLE/renderer/gl/StateManagerGL.cpp
@@ -30,6 +30,7 @@
       mUnpackAlignment(4),
       mUnpackRowLength(0),
       mFramebuffers(),
+      mRenderbuffer(0),
       mScissor(0, 0, 0, 0),
       mViewport(0, 0, 0, 0),
       mClearColor(0.0f, 0.0f, 0.0f, 0.0f),
@@ -122,6 +123,16 @@
     }
 }
 
+void StateManagerGL::bindRenderbuffer(GLenum type, GLuint renderbuffer)
+{
+    ASSERT(type == GL_RENDERBUFFER);
+    if (mRenderbuffer != renderbuffer)
+    {
+        mRenderbuffer = renderbuffer;
+        mFunctions->bindRenderbuffer(type, mRenderbuffer);
+    }
+}
+
 void StateManagerGL::setClearState(const gl::State &state, GLbitfield mask)
 {
     // Only apply the state required to do a clear
diff --git a/src/libANGLE/renderer/gl/StateManagerGL.h b/src/libANGLE/renderer/gl/StateManagerGL.h
index 58ceae5..464aa7d 100644
--- a/src/libANGLE/renderer/gl/StateManagerGL.h
+++ b/src/libANGLE/renderer/gl/StateManagerGL.h
@@ -40,6 +40,7 @@
     void bindTexture(GLenum type, GLuint texture);
     void setPixelUnpackState(GLint alignment, GLint rowLength);
     void bindFramebuffer(GLenum type, GLuint framebuffer);
+    void bindRenderbuffer(GLenum type, GLuint renderbuffer);
 
     void setClearState(const gl::State &state, GLbitfield mask);
 
@@ -74,6 +75,7 @@
     GLint mUnpackRowLength;
 
     std::map<GLenum, GLuint> mFramebuffers;
+    GLuint mRenderbuffer;
 
     gl::Rectangle mScissor;
     gl::Rectangle mViewport;
diff --git a/src/libANGLE/renderer/gl/renderergl_utils.cpp b/src/libANGLE/renderer/gl/renderergl_utils.cpp
index 3b8271f..a4db1fe 100644
--- a/src/libANGLE/renderer/gl/renderergl_utils.cpp
+++ b/src/libANGLE/renderer/gl/renderergl_utils.cpp
@@ -39,7 +39,7 @@
     caps->maxCubeMapTextureSize = QuerySingleGLInt(functions, GL_MAX_CUBE_MAP_TEXTURE_SIZE);
     caps->maxArrayTextureLayers = QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS);
     caps->maxLODBias = 2.0f;
-    caps->maxRenderbufferSize = 2048;
+    caps->maxRenderbufferSize = QuerySingleGLInt(functions, GL_MAX_RENDERBUFFER_SIZE);
     caps->maxDrawBuffers = QuerySingleGLInt(functions, GL_MAX_DRAW_BUFFERS);
     caps->maxColorAttachments = QuerySingleGLInt(functions, GL_MAX_COLOR_ATTACHMENTS);
     caps->maxViewportWidth = caps->max2DTextureSize;