Support multisampled framebuffers with the GL backend.

Move validation of sample counts into the Renderbuffer implementations
because the exact supported sample counts are not always known.

BUG=angleoproject:886

Change-Id: I9c90d9d435e940b852343a29a6aa11d6cb1ad23b
Reviewed-on: https://chromium-review.googlesource.com/255513
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/gl/RenderbufferGL.cpp b/src/libANGLE/renderer/gl/RenderbufferGL.cpp
index b580ea8..823c0ea 100644
--- a/src/libANGLE/renderer/gl/RenderbufferGL.cpp
+++ b/src/libANGLE/renderer/gl/RenderbufferGL.cpp
@@ -9,17 +9,20 @@
 #include "libANGLE/renderer/gl/RenderbufferGL.h"
 
 #include "common/debug.h"
+#include "libANGLE/Caps.h"
 #include "libANGLE/angletypes.h"
 #include "libANGLE/renderer/gl/FunctionsGL.h"
 #include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/renderergl_utils.h"
 
 namespace rx
 {
 
-RenderbufferGL::RenderbufferGL(const FunctionsGL *functions, StateManagerGL *stateManager)
+RenderbufferGL::RenderbufferGL(const FunctionsGL *functions, StateManagerGL *stateManager, const gl::TextureCapsMap &textureCaps)
     : RenderbufferImpl(),
       mFunctions(functions),
       mStateManager(stateManager),
+      mTextureCaps(textureCaps),
       mRenderbufferID(0)
 {
     mFunctions->genRenderbuffers(1, &mRenderbufferID);
@@ -45,6 +48,25 @@
 {
     mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID);
     mFunctions->renderbufferStorageMultisample(GL_RENDERBUFFER, samples, internalformat, width, height);
+
+    const gl::TextureCaps &formatCaps = mTextureCaps.get(internalformat);
+    if (samples > formatCaps.getMaxSamples())
+    {
+        // Before version 4.2, it is unknown if the specific internal format can support the requested number
+        // of samples.  It is expected that GL_OUT_OF_MEMORY is returned if the renderbuffer cannot be created.
+        GLenum error = GL_NO_ERROR;
+        do
+        {
+            GLenum error = mFunctions->getError();
+            if (error == GL_OUT_OF_MEMORY)
+            {
+                return gl::Error(GL_OUT_OF_MEMORY);
+            }
+
+            ASSERT(error == GL_NO_ERROR);
+        } while (error != GL_NO_ERROR);
+    }
+
     return gl::Error(GL_NO_ERROR);
 }