Backed out changeset 88cf7f2fe48f for build bustage
authorWes Kocher <wkocher@mozilla.com>
Fri, 09 Jan 2015 19:15:54 -0800
changeset 248930 8d48c34f44ed06ffe1257afc96b9615b0b26628f
parent 248929 88cf7f2fe48fa70a2c2a2bfec038996fd12d45a7
child 248931 4f1b2f93ae484bb16b10bde6a1272139ceb2abdd
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone37.0a1
backs out88cf7f2fe48fa70a2c2a2bfec038996fd12d45a7
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 88cf7f2fe48f for build bustage
dom/canvas/WebGL2ContextFramebuffers.cpp
dom/canvas/WebGLContext.cpp
dom/canvas/WebGLContext.h
dom/canvas/WebGLContextDraw.cpp
dom/canvas/WebGLContextFramebufferOperations.cpp
dom/canvas/WebGLContextGL.cpp
dom/canvas/WebGLContextState.cpp
dom/canvas/WebGLContextUtils.cpp
dom/canvas/WebGLContextValidate.cpp
dom/canvas/WebGLFramebuffer.cpp
gfx/gl/GLScreenBuffer.cpp
gfx/gl/GLScreenBuffer.h
--- a/dom/canvas/WebGL2ContextFramebuffers.cpp
+++ b/dom/canvas/WebGL2ContextFramebuffers.cpp
@@ -1,337 +1,28 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebGL2Context.h"
-
 #include "GLContext.h"
-#include "WebGLContextUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
-// Returns one of FLOAT, INT, UNSIGNED_INT.
-// Fixed-points (normalized ints) are considered FLOAT.
-static GLenum
-ValueTypeForFormat(GLenum internalFormat)
-{
-    switch (internalFormat) {
-    // Fixed-point
-    case LOCAL_GL_R8:
-    case LOCAL_GL_RG8:
-    case LOCAL_GL_RGB565:
-    case LOCAL_GL_RGB8:
-    case LOCAL_GL_RGBA4:
-    case LOCAL_GL_RGB5_A1:
-    case LOCAL_GL_RGBA8:
-    case LOCAL_GL_RGB10_A2:
-    case LOCAL_GL_ALPHA8:
-    case LOCAL_GL_LUMINANCE8:
-    case LOCAL_GL_LUMINANCE8_ALPHA8:
-    case LOCAL_GL_SRGB8:
-    case LOCAL_GL_SRGB8_ALPHA8:
-    case LOCAL_GL_R8_SNORM:
-    case LOCAL_GL_RG8_SNORM:
-    case LOCAL_GL_RGB8_SNORM:
-    case LOCAL_GL_RGBA8_SNORM:
-
-    // Floating-point
-    case LOCAL_GL_R16F:
-    case LOCAL_GL_RG16F:
-    case LOCAL_GL_RGB16F:
-    case LOCAL_GL_RGBA16F:
-    case LOCAL_GL_ALPHA16F_EXT:
-    case LOCAL_GL_LUMINANCE16F_EXT:
-    case LOCAL_GL_LUMINANCE_ALPHA16F_EXT:
-
-    case LOCAL_GL_R32F:
-    case LOCAL_GL_RG32F:
-    case LOCAL_GL_RGB32F:
-    case LOCAL_GL_RGBA32F:
-    case LOCAL_GL_ALPHA32F_EXT:
-    case LOCAL_GL_LUMINANCE32F_EXT:
-    case LOCAL_GL_LUMINANCE_ALPHA32F_EXT:
-
-    case LOCAL_GL_R11F_G11F_B10F:
-    case LOCAL_GL_RGB9_E5:
-        return LOCAL_GL_FLOAT;
-
-    // Int
-    case LOCAL_GL_R8I:
-    case LOCAL_GL_RG8I:
-    case LOCAL_GL_RGB8I:
-    case LOCAL_GL_RGBA8I:
-
-    case LOCAL_GL_R16I:
-    case LOCAL_GL_RG16I:
-    case LOCAL_GL_RGB16I:
-    case LOCAL_GL_RGBA16I:
-
-    case LOCAL_GL_R32I:
-    case LOCAL_GL_RG32I:
-    case LOCAL_GL_RGB32I:
-    case LOCAL_GL_RGBA32I:
-        return LOCAL_GL_INT;
-
-    // Unsigned int
-    case LOCAL_GL_R8UI:
-    case LOCAL_GL_RG8UI:
-    case LOCAL_GL_RGB8UI:
-    case LOCAL_GL_RGBA8UI:
-
-    case LOCAL_GL_R16UI:
-    case LOCAL_GL_RG16UI:
-    case LOCAL_GL_RGB16UI:
-    case LOCAL_GL_RGBA16UI:
-
-    case LOCAL_GL_R32UI:
-    case LOCAL_GL_RG32UI:
-    case LOCAL_GL_RGB32UI:
-    case LOCAL_GL_RGBA32UI:
-
-    case LOCAL_GL_RGB10_A2UI:
-        return LOCAL_GL_UNSIGNED_INT;
-
-    default:
-        MOZ_CRASH("Bad `internalFormat`.");
-    }
-}
-
 // -------------------------------------------------------------------------
 // Framebuffer objects
 
-static bool
-GetFBInfoForBlit(const WebGLFramebuffer* fb, WebGLContext* webgl,
-                 const char* const fbInfo, GLsizei* const out_samples,
-                 GLenum* const out_colorFormat, GLenum* const out_depthFormat,
-                 GLenum* const out_stencilFormat)
-{
-    auto status = fb->PrecheckFramebufferStatus();
-    if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
-        webgl->ErrorInvalidOperation("blitFramebuffer: %s is not"
-                                     " framebuffer-complete.", fbInfo);
-        return false;
-    }
-
-    *out_samples = 1; // TODO
-
-    if (fb->ColorAttachment(0).IsDefined()) {
-        const auto& attachement = fb->ColorAttachment(0);
-        *out_colorFormat = attachement.EffectiveInternalFormat().get();
-    } else {
-        *out_colorFormat = 0;
-    }
-
-    if (fb->DepthStencilAttachment().IsDefined()) {
-        const auto& attachement = fb->DepthStencilAttachment();
-        *out_depthFormat = attachement.EffectiveInternalFormat().get();
-        *out_stencilFormat = *out_depthFormat;
-    } else {
-        if (fb->DepthAttachment().IsDefined()) {
-            const auto& attachement = fb->DepthAttachment();
-            *out_depthFormat = attachement.EffectiveInternalFormat().get();
-        } else {
-            *out_depthFormat = 0;
-        }
-
-        if (fb->StencilAttachment().IsDefined()) {
-            const auto& attachement = fb->StencilAttachment();
-            *out_stencilFormat = attachement.EffectiveInternalFormat().get();
-        } else {
-            *out_stencilFormat = 0;
-        }
-    }
-    return true;
-}
-
 void
 WebGL2Context::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                                GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                                GLbitfield mask, GLenum filter)
 {
-    const GLbitfield validBits = LOCAL_GL_COLOR_BUFFER_BIT |
-                                 LOCAL_GL_DEPTH_BUFFER_BIT |
-                                 LOCAL_GL_STENCIL_BUFFER_BIT;
-    if ((mask | validBits) != validBits) {
-        ErrorInvalidValue("blitFramebuffer: Invalid bit set in mask.");
-        return;
-    }
-
-    switch (filter) {
-    case LOCAL_GL_NEAREST:
-    case LOCAL_GL_LINEAR:
-        break;
-    default:
-        ErrorInvalidEnumInfo("blitFramebuffer: Bad `filter`:", filter);
-        return;
-    }
-
-    const GLbitfield depthAndStencilBits = LOCAL_GL_DEPTH_BUFFER_BIT |
-                                           LOCAL_GL_STENCIL_BUFFER_BIT;
-    if (mask & depthAndStencilBits &&
-        filter != LOCAL_GL_NEAREST)
-    {
-        ErrorInvalidOperation("blitFramebuffer: DEPTH_BUFFER_BIT and"
-                              " STENCIL_BUFFER_BIT can only be used with"
-                              " NEAREST filtering.");
-        return;
-    }
-
-    if (mBoundReadFramebuffer == mBoundDrawFramebuffer) {
-        // TODO: It's actually more complicated than this. We need to check that
-        // the underlying buffers are not the same, not the framebuffers
-        // themselves.
-        ErrorInvalidOperation("blitFramebuffer: Source and destination must"
-                              " differ.");
-        return;
-    }
-
-    GLsizei srcSamples;
-    GLenum srcColorFormat;
-    GLenum srcDepthFormat;
-    GLenum srcStencilFormat;
-
-    if (mBoundReadFramebuffer) {
-        if (!GetFBInfoForBlit(mBoundReadFramebuffer, this, "READ_FRAMEBUFFER",
-                              &srcSamples, &srcColorFormat, &srcDepthFormat,
-                              &srcStencilFormat))
-        {
-            return;
-        }
-    } else {
-        srcSamples = 1; // Always 1.
-
-        // TODO: Don't hardcode these.
-        srcColorFormat = mOptions.alpha ? LOCAL_GL_RGBA8 : LOCAL_GL_RGB8;
-
-        if (mOptions.depth && mOptions.stencil) {
-            srcDepthFormat = LOCAL_GL_DEPTH24_STENCIL8;
-            srcStencilFormat = srcDepthFormat;
-        } else {
-            if (mOptions.depth) {
-                srcDepthFormat = LOCAL_GL_DEPTH_COMPONENT16;
-            }
-            if (mOptions.stencil) {
-                srcStencilFormat = LOCAL_GL_STENCIL_INDEX8;
-            }
-        }
-    }
-
-    GLsizei dstSamples;
-    GLenum dstColorFormat;
-    GLenum dstDepthFormat;
-    GLenum dstStencilFormat;
-
-    if (mBoundDrawFramebuffer) {
-        if (!GetFBInfoForBlit(mBoundDrawFramebuffer, this, "DRAW_FRAMEBUFFER",
-                              &dstSamples, &dstColorFormat, &dstDepthFormat,
-                              &dstStencilFormat))
-        {
-            return;
-        }
-    } else {
-        dstSamples = gl->Screen()->Samples();
-
-        // TODO: Don't hardcode these.
-        dstColorFormat = mOptions.alpha ? LOCAL_GL_RGBA8 : LOCAL_GL_RGB8;
-
-        if (mOptions.depth && mOptions.stencil) {
-            dstDepthFormat = LOCAL_GL_DEPTH24_STENCIL8;
-            dstStencilFormat = dstDepthFormat;
-        } else {
-            if (mOptions.depth) {
-                dstDepthFormat = LOCAL_GL_DEPTH_COMPONENT16;
-            }
-            if (mOptions.stencil) {
-                dstStencilFormat = LOCAL_GL_STENCIL_INDEX8;
-            }
-        }
-    }
-
-
-    if (mask & LOCAL_GL_COLOR_BUFFER_BIT) {
-        const GLenum srcColorType = srcColorFormat ? ValueTypeForFormat(srcColorFormat)
-                                                   : 0;
-        const GLenum dstColorType = dstColorFormat ? ValueTypeForFormat(dstColorFormat)
-                                                   : 0;
-        if (dstColorType != srcColorType) {
-            ErrorInvalidOperation("blitFramebuffer: Color buffer value type"
-                                  " mismatch.");
-            return;
-        }
-
-        const bool srcIsInt = srcColorType == LOCAL_GL_INT ||
-                              srcColorType == LOCAL_GL_UNSIGNED_INT;
-        if (srcIsInt && filter != LOCAL_GL_NEAREST) {
-            ErrorInvalidOperation("blitFramebuffer: Integer read buffers can only"
-                                  " be filtered with NEAREST.");
-            return;
-        }
-    }
-
-    /* GLES 3.0.4, p199:
-     *   Calling BlitFramebuffer will result in an INVALID_OPERATION error if
-     *   mask includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT, and the source
-     *   and destination depth and stencil buffer formats do not match.
-     *
-     * jgilbert: The wording is such that if only DEPTH_BUFFER_BIT is specified,
-     * the stencil formats must match. This seems wrong. It could be a spec bug,
-     * or I could be missing an interaction in one of the earlier paragraphs.
-     */
-    if (mask & LOCAL_GL_DEPTH_BUFFER_BIT &&
-        dstDepthFormat != srcDepthFormat)
-    {
-        ErrorInvalidOperation("blitFramebuffer: Depth buffer formats must match"
-                              " if selected.");
-        return;
-    }
-
-    if (mask & LOCAL_GL_STENCIL_BUFFER_BIT &&
-        dstStencilFormat != srcStencilFormat)
-    {
-        ErrorInvalidOperation("blitFramebuffer: Stencil buffer formats must"
-                              " match if selected.");
-        return;
-    }
-
-    if (dstSamples != 1) {
-        ErrorInvalidOperation("blitFramebuffer: DRAW_FRAMEBUFFER may not have"
-                              " multiple samples.");
-        return;
-    }
-
-    if (srcSamples != 1) {
-        if (mask & LOCAL_GL_COLOR_BUFFER_BIT &&
-            dstColorFormat != srcColorFormat)
-        {
-            ErrorInvalidOperation("blitFramebuffer: Color buffer formats must"
-                                  " match if selected, when reading from a"
-                                  " multisampled source.");
-            return;
-        }
-
-        if (dstX0 != srcX0 ||
-            dstX1 != srcX1 ||
-            dstY0 != srcY0 ||
-            dstY1 != srcY1)
-        {
-            ErrorInvalidOperation("blitFramebuffer: If the source is"
-                                  " multisampled, then the source and dest"
-                                  " regions must match exactly.");
-            return;
-        }
-    }
-
-    MakeContextCurrent();
-    gl->fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1,
-                         dstX0, dstY0, dstX1, dstY1,
-                         mask, filter);
+    MOZ_CRASH("Not Implemented.");
 }
 
 void
 WebGL2Context::FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
 {
     MOZ_CRASH("Not Implemented.");
 }
 
@@ -361,96 +52,50 @@ TranslateDefaultAttachments(const dom::S
     }
 }
 
 void
 WebGL2Context::InvalidateFramebuffer(GLenum target, const dom::Sequence<GLenum>& attachments)
 {
     if (IsContextLost())
         return;
-
     MakeContextCurrent();
 
-    if (!ValidateFramebufferTarget(target, "framebufferRenderbuffer"))
-        return;
-
-    const WebGLFramebuffer* fb;
-    bool isDefaultFB;
-    switch (target) {
-    case LOCAL_GL_FRAMEBUFFER:
-    case LOCAL_GL_DRAW_FRAMEBUFFER:
-        fb = mBoundDrawFramebuffer;
-        isDefaultFB = gl->Screen()->IsDrawFramebufferDefault();
-        break;
-
-    case LOCAL_GL_READ_FRAMEBUFFER:
-        fb = mBoundReadFramebuffer;
-        isDefaultFB = gl->Screen()->IsReadFramebufferDefault();
-        break;
-
-    default:
-        MOZ_CRASH("Bad target.");
+    if (target != LOCAL_GL_FRAMEBUFFER)
+        return ErrorInvalidEnumInfo("invalidateFramebuffer: target", target);
+    for (size_t i = 0; i < attachments.Length(); i++) {
+        if (!ValidateFramebufferAttachment(attachments[i], "invalidateFramebuffer"))
+            return;
     }
 
-    for (size_t i = 0; i < attachments.Length(); i++) {
-        if (!ValidateFramebufferAttachment(fb, attachments[i],
-                                           "invalidateFramebuffer"))
-        {
-            return;
-        }
-    }
-
-    if (!fb && !isDefaultFB) {
+    if (!mBoundFramebuffer && !gl->IsDrawingToDefaultFramebuffer()) {
         dom::Sequence<GLenum> tmpAttachments;
         TranslateDefaultAttachments(attachments, &tmpAttachments);
         gl->fInvalidateFramebuffer(target, tmpAttachments.Length(), tmpAttachments.Elements());
     } else {
         gl->fInvalidateFramebuffer(target, attachments.Length(), attachments.Elements());
     }
 }
 
 void
 WebGL2Context::InvalidateSubFramebuffer(GLenum target, const dom::Sequence<GLenum>& attachments,
                                         GLint x, GLint y, GLsizei width, GLsizei height)
 {
     if (IsContextLost())
         return;
-
     MakeContextCurrent();
 
-    if (!ValidateFramebufferTarget(target, "framebufferRenderbuffer"))
-        return;
-
-    const WebGLFramebuffer* fb;
-    bool isDefaultFB;
-    switch (target) {
-    case LOCAL_GL_FRAMEBUFFER:
-    case LOCAL_GL_DRAW_FRAMEBUFFER:
-        fb = mBoundDrawFramebuffer;
-        isDefaultFB = gl->Screen()->IsDrawFramebufferDefault();
-        break;
-
-    case LOCAL_GL_READ_FRAMEBUFFER:
-        fb = mBoundReadFramebuffer;
-        isDefaultFB = gl->Screen()->IsReadFramebufferDefault();
-        break;
-
-    default:
-        MOZ_CRASH("Bad target.");
+    if (target != LOCAL_GL_FRAMEBUFFER)
+        return ErrorInvalidEnumInfo("invalidateFramebuffer: target", target);
+    for (size_t i = 0; i < attachments.Length(); i++) {
+        if (!ValidateFramebufferAttachment(attachments[i], "invalidateSubFramebuffer"))
+            return;
     }
 
-    for (size_t i = 0; i < attachments.Length(); i++) {
-        if (!ValidateFramebufferAttachment(fb, attachments[i],
-                                           "invalidateSubFramebuffer"))
-        {
-            return;
-        }
-    }
-
-    if (!fb && !isDefaultFB) {
+    if (!mBoundFramebuffer && !gl->IsDrawingToDefaultFramebuffer()) {
         dom::Sequence<GLenum> tmpAttachments;
         TranslateDefaultAttachments(attachments, &tmpAttachments);
         gl->fInvalidateSubFramebuffer(target, tmpAttachments.Length(), tmpAttachments.Elements(),
                                       x, y, width, height);
     } else {
         gl->fInvalidateSubFramebuffer(target, attachments.Length(), attachments.Elements(),
                                       x, y, width, height);
     }
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -325,18 +325,17 @@ WebGLContext::DestroyResourcesAndContext
     mBoundCopyReadBuffer = nullptr;
     mBoundCopyWriteBuffer = nullptr;
     mBoundPixelPackBuffer = nullptr;
     mBoundPixelUnpackBuffer = nullptr;
     mBoundTransformFeedbackBuffer = nullptr;
     mBoundUniformBuffer = nullptr;
     mCurrentProgram = nullptr;
     mActiveProgramLinkInfo = nullptr;
-    mBoundDrawFramebuffer = nullptr;
-    mBoundReadFramebuffer = nullptr;
+    mBoundFramebuffer = nullptr;
     mActiveOcclusionQuery = nullptr;
     mBoundRenderbuffer = nullptr;
     mBoundVertexArray = nullptr;
     mDefaultVertexArray = nullptr;
     mBoundTransformFeedback = nullptr;
     mDefaultTransformFeedback = nullptr;
 
     if (mBoundTransformFeedbackBuffers) {
@@ -1883,18 +1882,17 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(We
   mBoundArrayBuffer,
   mBoundCopyReadBuffer,
   mBoundCopyWriteBuffer,
   mBoundPixelPackBuffer,
   mBoundPixelUnpackBuffer,
   mBoundTransformFeedbackBuffer,
   mBoundUniformBuffer,
   mCurrentProgram,
-  mBoundDrawFramebuffer,
-  mBoundReadFramebuffer,
+  mBoundFramebuffer,
   mBoundRenderbuffer,
   mBoundVertexArray,
   mDefaultVertexArray,
   mActiveOcclusionQuery,
   mActiveTransformFeedbackQuery)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLContext)
     NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -312,18 +312,17 @@ public:
 
     bool PresentScreenBuffer();
 
     // a number that increments every time we have an event that causes
     // all context resources to be lost.
     uint32_t Generation() { return mGeneration.value(); }
 
     // Returns null if the current bound FB is not likely complete.
-    const WebGLRectangleObject* CurValidDrawFBRectObject() const;
-    const WebGLRectangleObject* CurValidReadFBRectObject() const;
+    const WebGLRectangleObject* CurValidFBRectObject() const;
 
     static const size_t kMaxColorAttachments = 16;
 
     // This is similar to GLContext::ClearSafely, but tries to minimize the
     // amount of work it does.
     // It only clears the buffers we specify, and can reset its state without
     // first having to query anything, as WebGL knows its state at all times.
     void ForceClearFramebufferWithDefaultValues(GLbitfield mask,
@@ -418,18 +417,17 @@ public:
     void Finish();
     void FramebufferRenderbuffer(GLenum target, GLenum attachment,
                                  GLenum rbTarget, WebGLRenderbuffer* rb);
     void FramebufferTexture2D(GLenum target, GLenum attachment,
                               GLenum texImageTarget, WebGLTexture* tex,
                               GLint level);
 
     // Framebuffer validation
-    bool ValidateFramebufferAttachment(const WebGLFramebuffer* fb,
-                                       GLenum attachment, const char* funcName);
+    bool ValidateFramebufferAttachment(GLenum attachment, const char* funcName);
 
     void FrontFace(GLenum mode);
     void GenerateMipmap(GLenum target);
     already_AddRefed<WebGLActiveInfo> GetActiveAttrib(WebGLProgram* prog,
                                                       GLuint index);
     already_AddRefed<WebGLActiveInfo> GetActiveUniform(WebGLProgram* prog,
                                                        GLuint index);
 
@@ -1416,20 +1414,17 @@ protected:
     nsTArray<WebGLRefPtr<WebGLTexture> > mBoundCubeMapTextures;
     nsTArray<WebGLRefPtr<WebGLTexture> > mBound3DTextures;
 
     WebGLRefPtr<WebGLProgram> mCurrentProgram;
     RefPtr<const webgl::LinkedProgramInfo> mActiveProgramLinkInfo;
 
     uint32_t mMaxFramebufferColorAttachments;
 
-    bool ValidateFramebufferTarget(GLenum target, const char* const info);
-
-    WebGLRefPtr<WebGLFramebuffer> mBoundDrawFramebuffer;
-    WebGLRefPtr<WebGLFramebuffer> mBoundReadFramebuffer;
+    WebGLRefPtr<WebGLFramebuffer> mBoundFramebuffer;
     WebGLRefPtr<WebGLRenderbuffer> mBoundRenderbuffer;
     WebGLRefPtr<WebGLTransformFeedback> mBoundTransformFeedback;
     WebGLRefPtr<WebGLVertexArray> mBoundVertexArray;
 
     LinkedList<WebGLTexture> mTextures;
     LinkedList<WebGLBuffer> mBuffers;
     LinkedList<WebGLProgram> mPrograms;
     LinkedList<WebGLQuery> mQueries;
--- a/dom/canvas/WebGLContextDraw.cpp
+++ b/dom/canvas/WebGLContextDraw.cpp
@@ -93,18 +93,18 @@ bool WebGLContext::DrawArrays_check(GLin
 
     if (uint32_t(primcount) > mMaxFetchedInstances) {
         ErrorInvalidOperation("%s: bound instance attribute buffers do not have sufficient size for given primcount", info);
         return false;
     }
 
     MakeContextCurrent();
 
-    if (mBoundDrawFramebuffer) {
-        if (!mBoundDrawFramebuffer->CheckAndInitializeAttachments()) {
+    if (mBoundFramebuffer) {
+        if (!mBoundFramebuffer->CheckAndInitializeAttachments()) {
             ErrorInvalidFramebufferOperation("%s: incomplete framebuffer", info);
             return false;
         }
     } else {
         ClearBackbufferIfNeeded();
     }
 
     if (!DoFakeVertexAttrib0(checked_firstPlusCount.value())) {
@@ -274,18 +274,18 @@ WebGLContext::DrawElements_check(GLsizei
         GenerateWarning("%s: bound element array buffer previously used with a type other than "
                         "%s, this will affect performance.",
                         info,
                         WebGLContext::EnumName(type));
     }
 
     MakeContextCurrent();
 
-    if (mBoundDrawFramebuffer) {
-        if (!mBoundDrawFramebuffer->CheckAndInitializeAttachments()) {
+    if (mBoundFramebuffer) {
+        if (!mBoundFramebuffer->CheckAndInitializeAttachments()) {
             ErrorInvalidFramebufferOperation("%s: incomplete framebuffer", info);
             return false;
         }
     } else {
         ClearBackbufferIfNeeded();
     }
 
     if (!DoFakeVertexAttrib0(mMaxFetchedVertices)) {
@@ -364,17 +364,17 @@ WebGLContext::DrawElementsInstanced(GLen
     Draw_cleanup();
 }
 
 void WebGLContext::Draw_cleanup()
 {
     UndoFakeVertexAttrib0();
     UnbindFakeBlackTextures();
 
-    if (!mBoundDrawFramebuffer) {
+    if (!mBoundFramebuffer) {
         Invalidate();
         mShouldPresent = true;
         MOZ_ASSERT(!mBackbufferNeedsClear);
     }
 
     if (gl->WorkAroundDriverBugs()) {
         if (gl->Renderer() == gl::GLRenderer::Tegra) {
             mDrawCallsSinceLastFlush++;
@@ -382,17 +382,17 @@ void WebGLContext::Draw_cleanup()
             if (mDrawCallsSinceLastFlush >= MAX_DRAW_CALLS_SINCE_FLUSH) {
                 gl->fFlush();
                 mDrawCallsSinceLastFlush = 0;
             }
         }
     }
 
     // Let's check the viewport
-    const WebGLRectangleObject* rect = CurValidDrawFBRectObject();
+    const WebGLRectangleObject* rect = CurValidFBRectObject();
     if (rect) {
         if (mViewportWidth > rect->Width() ||
             mViewportHeight > rect->Height())
         {
             if (!mAlreadyWarnedAboutViewportLargerThanDest) {
                 GenerateWarning("Drawing to a destination rect smaller than the viewport rect. "
                                 "(This warning will only be given once)");
                 mAlreadyWarnedAboutViewportLargerThanDest = true;
--- a/dom/canvas/WebGLContextFramebufferOperations.cpp
+++ b/dom/canvas/WebGLContextFramebufferOperations.cpp
@@ -24,18 +24,18 @@ WebGLContext::Clear(GLbitfield mask)
         return ErrorInvalidValue("clear: invalid mask bits");
 
     if (mask == 0) {
         GenerateWarning("Calling gl.clear(0) has no effect.");
     } else if (mRasterizerDiscardEnabled) {
         GenerateWarning("Calling gl.clear() with RASTERIZER_DISCARD enabled has no effects.");
     }
 
-    if (mBoundDrawFramebuffer) {
-        if (!mBoundDrawFramebuffer->CheckAndInitializeAttachments())
+    if (mBoundFramebuffer) {
+        if (!mBoundFramebuffer->CheckAndInitializeAttachments())
             return ErrorInvalidFramebufferOperation("clear: incomplete framebuffer");
 
         gl->fClear(mask);
         return;
     } else {
         ClearBackbufferIfNeeded();
     }
 
@@ -126,21 +126,22 @@ WebGLContext::DepthMask(WebGLboolean b)
 void
 WebGLContext::DrawBuffers(const dom::Sequence<GLenum>& buffers)
 {
     if (IsContextLost())
         return;
 
     const size_t buffersLength = buffers.Length();
 
-    if (!buffersLength) {
+    if (buffersLength == 0) {
         return ErrorInvalidValue("drawBuffers: invalid <buffers> (buffers must not be empty)");
     }
 
-    if (!mBoundDrawFramebuffer) {
+    if (mBoundFramebuffer == 0)
+    {
         // OK: we are rendering in the default framebuffer
 
         /* EXT_draw_buffers :
          If the GL is bound to the default framebuffer, then <buffersLength> must be 1
          and the constant must be BACK or NONE. When draw buffer zero is
          BACK, color values are written into the sole buffer for single-
          buffered contexts, or into the back buffer for double-buffered
          contexts. If DrawBuffersEXT is supplied with a constant other than
--- a/dom/canvas/WebGLContextGL.cpp
+++ b/dom/canvas/WebGLContextGL.cpp
@@ -50,47 +50,34 @@
 #include "mozilla/Endian.h"
 #include "mozilla/fallible.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 using namespace mozilla::gl;
 
-static const WebGLRectangleObject*
-CurValidFBRectObject(const WebGLContext* webgl,
-                     const WebGLFramebuffer* boundFB)
+const WebGLRectangleObject*
+WebGLContext::CurValidFBRectObject() const
 {
     const WebGLRectangleObject* rect = nullptr;
 
-    if (boundFB) {
+    if (mBoundFramebuffer) {
         // We don't really need to ask the driver.
         // Use 'precheck' to just check that our internal state looks good.
-        FBStatus precheckStatus = boundFB->PrecheckFramebufferStatus();
+        FBStatus precheckStatus = mBoundFramebuffer->PrecheckFramebufferStatus();
         if (precheckStatus == LOCAL_GL_FRAMEBUFFER_COMPLETE)
-            rect = &boundFB->RectangleObject();
+            rect = &mBoundFramebuffer->RectangleObject();
     } else {
-        rect = static_cast<const WebGLRectangleObject*>(webgl);
+        rect = static_cast<const WebGLRectangleObject*>(this);
     }
 
     return rect;
 }
 
-const WebGLRectangleObject*
-WebGLContext::CurValidDrawFBRectObject() const
-{
-    return CurValidFBRectObject(this, mBoundDrawFramebuffer);
-}
-
-const WebGLRectangleObject*
-WebGLContext::CurValidReadFBRectObject() const
-{
-    return CurValidFBRectObject(this, mBoundReadFramebuffer);
-}
-
 //
 //  WebGL API
 //
 
 void
 WebGLContext::ActiveTexture(GLenum texture)
 {
     if (IsContextLost())
@@ -140,18 +127,18 @@ WebGLContext::BindAttribLocation(WebGLPr
 }
 
 void
 WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer* wfb)
 {
     if (IsContextLost())
         return;
 
-    if (!ValidateFramebufferTarget(target, "bindFramebuffer"))
-        return;
+    if (target != LOCAL_GL_FRAMEBUFFER)
+        return ErrorInvalidEnum("bindFramebuffer: target must be GL_FRAMEBUFFER");
 
     if (!ValidateObjectAllowDeletedOrNull("bindFramebuffer", wfb))
         return;
 
     // silently ignore a deleted frame buffer
     if (wfb && wfb->IsDeleted())
         return;
 
@@ -160,30 +147,17 @@ WebGLContext::BindFramebuffer(GLenum tar
     if (!wfb) {
         gl->fBindFramebuffer(target, 0);
     } else {
         wfb->BindTo(target);
         GLuint framebuffername = wfb->GLName();
         gl->fBindFramebuffer(target, framebuffername);
     }
 
-    switch (target) {
-    case LOCAL_GL_FRAMEBUFFER:
-        mBoundDrawFramebuffer = wfb;
-        mBoundReadFramebuffer = wfb;
-        break;
-    case LOCAL_GL_DRAW_FRAMEBUFFER:
-        mBoundDrawFramebuffer = wfb;
-        break;
-    case LOCAL_GL_READ_FRAMEBUFFER:
-        mBoundReadFramebuffer = wfb;
-        break;
-    default:
-        break;
-    }
+    mBoundFramebuffer = wfb;
 }
 
 void
 WebGLContext::BindRenderbuffer(GLenum target, WebGLRenderbuffer* wrb)
 {
     if (IsContextLost())
         return;
 
@@ -340,48 +314,40 @@ WebGLContext::BlendFuncSeparate(GLenum s
 }
 
 GLenum
 WebGLContext::CheckFramebufferStatus(GLenum target)
 {
     if (IsContextLost())
         return LOCAL_GL_FRAMEBUFFER_UNSUPPORTED;
 
-    if (!ValidateFramebufferTarget(target, "invalidateFramebuffer"))
+    if (target != LOCAL_GL_FRAMEBUFFER) {
+        ErrorInvalidEnum("checkFramebufferStatus: target must be FRAMEBUFFER");
         return 0;
-
-    WebGLFramebuffer* fb;
-    switch (target) {
-    case LOCAL_GL_FRAMEBUFFER:
-    case LOCAL_GL_DRAW_FRAMEBUFFER:
-        fb = mBoundDrawFramebuffer;
-        break;
-
-    case LOCAL_GL_READ_FRAMEBUFFER:
-        fb = mBoundReadFramebuffer;
-        break;
-
-    default:
-        MOZ_CRASH("Bad target.");
     }
 
-    if (!fb)
+    if (!mBoundFramebuffer)
         return LOCAL_GL_FRAMEBUFFER_COMPLETE;
 
-    return fb->CheckFramebufferStatus().get();
+    return mBoundFramebuffer->CheckFramebufferStatus().get();
 }
 
 void
-WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
+WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
+                                     GLint level,
                                      TexInternalFormat internalformat,
-                                     GLint xoffset, GLint yoffset, GLint x,
-                                     GLint y, GLsizei width, GLsizei height,
+                                     GLint xoffset,
+                                     GLint yoffset,
+                                     GLint x,
+                                     GLint y,
+                                     GLsizei width,
+                                     GLsizei height,
                                      bool sub)
 {
-    const WebGLRectangleObject* framebufferRect = CurValidReadFBRectObject();
+    const WebGLRectangleObject* framebufferRect = CurValidFBRectObject();
     GLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
     GLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
 
     WebGLTexImageFunc func = sub
                              ? WebGLTexImageFunc::CopyTexSubImage
                              : WebGLTexImageFunc::CopyTexImage;
     WebGLTexDimensions dims = WebGLTexDimensions::Tex2D;
     const char* info = InfoFrom(func, dims);
@@ -396,35 +362,35 @@ WebGLContext::CopyTexSubImage2D_base(Tex
                           func, dims))
     {
         return;
     }
 
     if (!ValidateCopyTexImage(internalformat.get(), func, dims))
         return;
 
-    if (!mBoundReadFramebuffer)
+    if (!mBoundFramebuffer)
         ClearBackbufferIfNeeded();
 
     MakeContextCurrent();
 
     WebGLTexture* tex = ActiveBoundTextureForTexImageTarget(texImageTarget);
 
     if (!tex)
         return ErrorInvalidOperation("%s: no texture is bound to this target");
 
     if (tex->IsImmutable()) {
         if (!sub) {
             return ErrorInvalidOperation("copyTexImage2D: disallowed because the texture bound to this target has already been made immutable by texStorage2D");
         }
     }
 
     TexType framebuffertype = LOCAL_GL_NONE;
-    if (mBoundReadFramebuffer) {
-        TexInternalFormat framebuffereffectiveformat = mBoundReadFramebuffer->ColorAttachment(0).EffectiveInternalFormat();
+    if (mBoundFramebuffer) {
+        TexInternalFormat framebuffereffectiveformat = mBoundFramebuffer->ColorAttachment(0).EffectiveInternalFormat();
         framebuffertype = TypeFromInternalFormat(framebuffereffectiveformat);
     } else {
         // FIXME - here we're assuming that the default framebuffer is backed by UNSIGNED_BYTE
         // that might not always be true, say if we had a 16bpp default framebuffer.
         framebuffertype = LOCAL_GL_UNSIGNED_BYTE;
     }
 
     TexInternalFormat effectiveInternalFormat =
@@ -538,17 +504,17 @@ WebGLContext::CopyTexImage2D(GLenum rawT
                           func, dims))
     {
         return;
     }
 
     if (!ValidateCopyTexImage(internalformat, func, dims))
         return;
 
-    if (!mBoundReadFramebuffer)
+    if (!mBoundFramebuffer)
         ClearBackbufferIfNeeded();
 
     CopyTexSubImage2D_base(rawTexImgTarget, level, internalformat, 0, 0, x, y, width, height, false);
 }
 
 void
 WebGLContext::CopyTexSubImage2D(GLenum rawTexImgTarget,
                                 GLint level,
@@ -602,17 +568,17 @@ WebGLContext::CopyTexSubImage2D(GLenum r
     GLsizei texHeight = imageInfo.Height();
 
     if (xoffset + width > texWidth || xoffset + width < 0)
       return ErrorInvalidValue("copyTexSubImage2D: xoffset+width is too large");
 
     if (yoffset + height > texHeight || yoffset + height < 0)
       return ErrorInvalidValue("copyTexSubImage2D: yoffset+height is too large");
 
-    if (!mBoundReadFramebuffer)
+    if (!mBoundFramebuffer)
         ClearBackbufferIfNeeded();
 
     if (imageInfo.HasUninitializedImageData()) {
         bool coversWholeImage = xoffset == 0 &&
                                 yoffset == 0 &&
                                 width == texWidth &&
                                 height == texHeight;
         if (coversWholeImage) {
@@ -678,47 +644,35 @@ WebGLContext::DeleteFramebuffer(WebGLFra
     if (!ValidateObjectAllowDeletedOrNull("deleteFramebuffer", fbuf))
         return;
 
     if (!fbuf || fbuf->IsDeleted())
         return;
 
     fbuf->RequestDelete();
 
-    if (mBoundReadFramebuffer == mBoundDrawFramebuffer) {
-        if (mBoundDrawFramebuffer == fbuf) {
-            BindFramebuffer(LOCAL_GL_FRAMEBUFFER,
-                            static_cast<WebGLFramebuffer*>(nullptr));
-        }
-    } else if (mBoundDrawFramebuffer == fbuf) {
-        BindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER,
+    if (mBoundFramebuffer == fbuf)
+        BindFramebuffer(LOCAL_GL_FRAMEBUFFER,
                         static_cast<WebGLFramebuffer*>(nullptr));
-    } else if (mBoundReadFramebuffer == fbuf) {
-        BindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER,
-                        static_cast<WebGLFramebuffer*>(nullptr));
-    }
 }
 
 void
 WebGLContext::DeleteRenderbuffer(WebGLRenderbuffer* rbuf)
 {
     if (IsContextLost())
         return;
 
     if (!ValidateObjectAllowDeletedOrNull("deleteRenderbuffer", rbuf))
         return;
 
     if (!rbuf || rbuf->IsDeleted())
         return;
 
-    if (mBoundDrawFramebuffer)
-        mBoundDrawFramebuffer->DetachRenderbuffer(rbuf);
-
-    if (mBoundReadFramebuffer)
-        mBoundReadFramebuffer->DetachRenderbuffer(rbuf);
+    if (mBoundFramebuffer)
+        mBoundFramebuffer->DetachRenderbuffer(rbuf);
 
     // Invalidate framebuffer status cache
     rbuf->NotifyFBsStatusChanged();
 
     if (mBoundRenderbuffer == rbuf)
         BindRenderbuffer(LOCAL_GL_RENDERBUFFER,
                          static_cast<WebGLRenderbuffer*>(nullptr));
 
@@ -732,21 +686,18 @@ WebGLContext::DeleteTexture(WebGLTexture
         return;
 
     if (!ValidateObjectAllowDeletedOrNull("deleteTexture", tex))
         return;
 
     if (!tex || tex->IsDeleted())
         return;
 
-    if (mBoundDrawFramebuffer)
-        mBoundDrawFramebuffer->DetachTexture(tex);
-
-    if (mBoundReadFramebuffer)
-        mBoundReadFramebuffer->DetachTexture(tex);
+    if (mBoundFramebuffer)
+        mBoundFramebuffer->DetachTexture(tex);
 
     // Invalidate framebuffer status cache
     tex->NotifyFBsStatusChanged();
 
     GLuint activeTexture = mActiveTexture;
     for (int32_t i = 0; i < mGLMaxTextureUnits; i++) {
         if ((mBound2DTextures[i] == tex && tex->Target() == LOCAL_GL_TEXTURE_2D) ||
             (mBoundCubeMapTextures[i] == tex && tex->Target() == LOCAL_GL_TEXTURE_CUBE_MAP) ||
@@ -836,98 +787,58 @@ WebGLContext::DepthRange(GLfloat zNear, 
 
 void
 WebGLContext::FramebufferRenderbuffer(GLenum target, GLenum attachment,
                                       GLenum rbtarget, WebGLRenderbuffer* wrb)
 {
     if (IsContextLost())
         return;
 
-    if (!ValidateFramebufferTarget(target, "framebufferRenderbuffer"))
+    if (!mBoundFramebuffer)
+        return ErrorInvalidOperation("framebufferRenderbuffer: cannot modify framebuffer 0");
+
+    if (target != LOCAL_GL_FRAMEBUFFER)
+        return ErrorInvalidEnumInfo("framebufferRenderbuffer: target", target);
+
+    if (rbtarget != LOCAL_GL_RENDERBUFFER)
+        return ErrorInvalidEnumInfo("framebufferRenderbuffer: renderbuffer target:", rbtarget);
+
+    if (!ValidateFramebufferAttachment(attachment, "framebufferRenderbuffer"))
         return;
 
-    WebGLFramebuffer* fb;
-    switch (target) {
-    case LOCAL_GL_FRAMEBUFFER:
-    case LOCAL_GL_DRAW_FRAMEBUFFER:
-        fb = mBoundDrawFramebuffer;
-        break;
-
-    case LOCAL_GL_READ_FRAMEBUFFER:
-        fb = mBoundReadFramebuffer;
-        break;
-
-    default:
-        MOZ_CRASH("Bad target.");
-    }
-
-    if (!fb) {
-        return ErrorInvalidOperation("framebufferRenderbuffer: cannot modify"
-                                     " framebuffer 0.");
-    }
-
-    if (rbtarget != LOCAL_GL_RENDERBUFFER) {
-        return ErrorInvalidEnumInfo("framebufferRenderbuffer: rbtarget:",
-                                    rbtarget);
-    }
-
-    if (!ValidateFramebufferAttachment(fb, attachment,
-                                       "framebufferRenderbuffer"))
-    {
-        return;
-    }
-
-    fb->FramebufferRenderbuffer(attachment, rbtarget, wrb);
+    return mBoundFramebuffer->FramebufferRenderbuffer(attachment, rbtarget, wrb);
 }
 
 void
 WebGLContext::FramebufferTexture2D(GLenum target,
                                    GLenum attachment,
                                    GLenum textarget,
                                    WebGLTexture* tobj,
                                    GLint level)
 {
     if (IsContextLost())
         return;
 
-    if (!ValidateFramebufferTarget(target, "framebufferTexture2D"))
-        return;
-
-    WebGLFramebuffer* fb;
-    switch (target) {
-    case LOCAL_GL_FRAMEBUFFER:
-    case LOCAL_GL_DRAW_FRAMEBUFFER:
-        fb = mBoundDrawFramebuffer;
-        break;
-
-    case LOCAL_GL_READ_FRAMEBUFFER:
-        fb = mBoundReadFramebuffer;
-        break;
-
-    default:
-        MOZ_CRASH("Bad target.");
-    }
-
-    if (!fb) {
-        return ErrorInvalidOperation("framebufferTexture2D: cannot modify"
-                                     " framebuffer 0.");
-    }
+    if (!mBoundFramebuffer)
+        return ErrorInvalidOperation("framebufferRenderbuffer: cannot modify framebuffer 0");
+
+    if (target != LOCAL_GL_FRAMEBUFFER)
+        return ErrorInvalidEnumInfo("framebufferTexture2D: target", target);
 
     if (textarget != LOCAL_GL_TEXTURE_2D &&
         (textarget < LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
          textarget > LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))
     {
-        return ErrorInvalidEnumInfo("framebufferTexture2D: textarget:",
-                                    textarget);
+        return ErrorInvalidEnumInfo("framebufferTexture2D: invalid texture target", textarget);
     }
 
-    if (!ValidateFramebufferAttachment(fb, attachment, "framebufferTexture2D"))
+    if (!ValidateFramebufferAttachment(attachment, "framebufferTexture2D"))
         return;
 
-    fb->FramebufferTexture2D(attachment, textarget, tobj, level);
+    return mBoundFramebuffer->FramebufferTexture2D(attachment, textarget, tobj, level);
 }
 
 void
 WebGLContext::FrontFace(GLenum mode)
 {
     if (IsContextLost())
         return;
 
@@ -1106,52 +1017,35 @@ WebGLContext::GetFramebufferAttachmentPa
                                                 GLenum target,
                                                 GLenum attachment,
                                                 GLenum pname,
                                                 ErrorResult& rv)
 {
     if (IsContextLost())
         return JS::NullValue();
 
-    if (!ValidateFramebufferTarget(target, "getFramebufferAttachmentParameter"))
+    if (target != LOCAL_GL_FRAMEBUFFER) {
+        ErrorInvalidEnumInfo("getFramebufferAttachmentParameter: target", target);
         return JS::NullValue();
-
-    WebGLFramebuffer* fb;
-    switch (target) {
-    case LOCAL_GL_FRAMEBUFFER:
-    case LOCAL_GL_DRAW_FRAMEBUFFER:
-        fb = mBoundDrawFramebuffer;
-        break;
-
-    case LOCAL_GL_READ_FRAMEBUFFER:
-        fb = mBoundReadFramebuffer;
-        break;
-
-    default:
-        MOZ_CRASH("Bad target.");
     }
 
-    if (!fb) {
-        ErrorInvalidOperation("getFramebufferAttachmentParameter: cannot query"
-                              " framebuffer 0.");
+    if (!mBoundFramebuffer) {
+        ErrorInvalidOperation("getFramebufferAttachmentParameter: cannot query framebuffer 0");
         return JS::NullValue();
     }
 
-    if (!ValidateFramebufferAttachment(fb, attachment,
-                                       "getFramebufferAttachmentParameter"))
-    {
+    if (!ValidateFramebufferAttachment(attachment, "getFramebufferAttachmentParameter"))
         return JS::NullValue();
-    }
 
     if (IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers))
-        fb->EnsureColorAttachments(attachment - LOCAL_GL_COLOR_ATTACHMENT0);
+        mBoundFramebuffer->EnsureColorAttachments(attachment - LOCAL_GL_COLOR_ATTACHMENT0);
 
     MakeContextCurrent();
 
-    const WebGLFramebuffer::Attachment& fba = fb->GetAttachment(attachment);
+    const WebGLFramebuffer::Attachment& fba = mBoundFramebuffer->GetAttachment(attachment);
 
     if (fba.Renderbuffer()) {
         switch (pname) {
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT:
                 if (IsExtensionEnabled(WebGLExtensionID::EXT_sRGB)) {
                     const GLenum internalFormat = fba.Renderbuffer()->InternalFormat();
                     return (internalFormat == LOCAL_GL_SRGB_EXT ||
                             internalFormat == LOCAL_GL_SRGB_ALPHA_EXT ||
@@ -1879,17 +1773,17 @@ WebGLContext::ReadPixels(GLint x, GLint 
     }
 
     if (width < 0 || height < 0)
         return ErrorInvalidValue("readPixels: negative size passed");
 
     if (pixels.IsNull())
         return ErrorInvalidValue("readPixels: null destination buffer");
 
-    const WebGLRectangleObject* framebufferRect = CurValidReadFBRectObject();
+    const WebGLRectangleObject* framebufferRect = CurValidFBRectObject();
     GLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
     GLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
 
     uint32_t channels = 0;
 
     // Check the format param
     switch (format) {
         case LOCAL_GL_ALPHA:
@@ -1967,36 +1861,36 @@ WebGLContext::ReadPixels(GLint x, GLint 
 
     void* data = pixbuf.Data();
     if (!data) {
         ErrorOutOfMemory("readPixels: buffer storage is null. Did we run out of memory?");
         return rv.Throw(NS_ERROR_OUT_OF_MEMORY);
     }
 
     bool isSourceTypeFloat = false;
-    if (mBoundReadFramebuffer &&
-        mBoundReadFramebuffer->ColorAttachmentCount() &&
-        mBoundReadFramebuffer->ColorAttachment(0).IsDefined())
+    if (mBoundFramebuffer &&
+        mBoundFramebuffer->ColorAttachmentCount() &&
+        mBoundFramebuffer->ColorAttachment(0).IsDefined())
     {
-        isSourceTypeFloat = mBoundReadFramebuffer->ColorAttachment(0).IsReadableFloat();
+        isSourceTypeFloat = mBoundFramebuffer->ColorAttachment(0).IsReadableFloat();
     }
 
     if (isReadTypeFloat != isSourceTypeFloat)
         return ErrorInvalidOperation("readPixels: Invalid type floatness");
 
     // Check the format and type params to assure they are an acceptable pair (as per spec)
     MakeContextCurrent();
 
-    if (mBoundReadFramebuffer) {
+    if (mBoundFramebuffer) {
         // prevent readback of arbitrary video memory through uninitialized renderbuffers!
-        if (!mBoundReadFramebuffer->CheckAndInitializeAttachments())
+        if (!mBoundFramebuffer->CheckAndInitializeAttachments())
             return ErrorInvalidFramebufferOperation("readPixels: incomplete framebuffer");
 
         GLenum readPlaneBits = LOCAL_GL_COLOR_BUFFER_BIT;
-        if (!mBoundReadFramebuffer->HasCompletePlanes(readPlaneBits)) {
+        if (!mBoundFramebuffer->HasCompletePlanes(readPlaneBits)) {
             return ErrorInvalidOperation("readPixels: Read source attachment doesn't have the"
                                          " correct color/depth/stencil type.");
         }
     } else {
       ClearBackbufferIfNeeded();
     }
 
     bool isFormatAndTypeValid = false;
@@ -2109,18 +2003,18 @@ WebGLContext::ReadPixels(GLint x, GLint 
     // GL_ALPHA to readpixels currently, but we had the code written for it already.
 
     const bool formatHasAlpha = format == LOCAL_GL_ALPHA ||
                                 format == LOCAL_GL_RGBA;
     if (!formatHasAlpha)
         return;
 
     bool needAlphaFilled;
-    if (mBoundReadFramebuffer) {
-        needAlphaFilled = !mBoundReadFramebuffer->ColorAttachment(0).HasAlpha();
+    if (mBoundFramebuffer) {
+        needAlphaFilled = !mBoundFramebuffer->ColorAttachment(0).HasAlpha();
     } else {
         needAlphaFilled = !mOptions.alpha;
     }
 
     if (!needAlphaFilled)
         return;
 
     size_t stride = checked_alignedRowSize.value(); // In bytes!
--- a/dom/canvas/WebGLContextState.cpp
+++ b/dom/canvas/WebGLContextState.cpp
@@ -69,25 +69,25 @@ StringValue(JSContext* cx, const char* c
 
     return JS::StringValue(str);
 }
 
 bool
 WebGLContext::GetStencilBits(GLint* out_stencilBits)
 {
     *out_stencilBits = 0;
-    if (mBoundDrawFramebuffer) {
-        if (mBoundDrawFramebuffer->HasDepthStencilConflict()) {
+    if (mBoundFramebuffer) {
+        if (mBoundFramebuffer->HasDepthStencilConflict()) {
             // Error, we don't know which stencil buffer's bits to use
             ErrorInvalidFramebufferOperation("getParameter: framebuffer has two stencil buffers bound");
             return false;
         }
 
-        if (mBoundDrawFramebuffer->StencilAttachment().IsDefined() ||
-            mBoundDrawFramebuffer->DepthStencilAttachment().IsDefined())
+        if (mBoundFramebuffer->StencilAttachment().IsDefined() ||
+            mBoundFramebuffer->DepthStencilAttachment().IsDefined())
         {
             *out_stencilBits = 8;
         }
     } else if (mOptions.stencil) {
         *out_stencilBits = 8;
     }
 
     return true;
@@ -145,17 +145,17 @@ WebGLContext::GetParameter(JSContext* cx
             return JS::Int32Value(mGLMaxColorAttachments);
 
         } else if (pname == LOCAL_GL_MAX_DRAW_BUFFERS) {
             return JS::Int32Value(mGLMaxDrawBuffers);
 
         } else if (pname >= LOCAL_GL_DRAW_BUFFER0 &&
                    pname < GLenum(LOCAL_GL_DRAW_BUFFER0 + mGLMaxDrawBuffers))
         {
-            if (mBoundDrawFramebuffer) {
+            if (mBoundFramebuffer) {
                 GLint iv = 0;
                 gl->fGetIntegerv(pname, &iv);
                 return JS::Int32Value(iv);
             }
 
             GLint iv = 0;
             gl->fGetIntegerv(pname, &iv);
 
@@ -185,20 +185,16 @@ WebGLContext::GetParameter(JSContext* cx
                 GLint val;
                 gl->fGetIntegerv(pname, &val);
                 return JS::NumberValue(uint32_t(val));
             }
 
             case LOCAL_GL_TEXTURE_BINDING_3D: {
                 return WebGLObjectAsJSValue(cx, mBound3DTextures[mActiveTexture].get(), rv);
             }
-
-            // DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING.
-            case LOCAL_GL_READ_FRAMEBUFFER_BINDING:
-                return WebGLObjectAsJSValue(cx, mBoundReadFramebuffer.get(), rv);
         }
     }
 
     switch (pname) {
         //
         // String params
         //
         case LOCAL_GL_VENDOR:
@@ -508,19 +504,18 @@ WebGLContext::GetParameter(JSContext* cx
         case LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING: {
             return WebGLObjectAsJSValue(cx, mBoundVertexArray->mElementArrayBuffer.get(), rv);
         }
 
         case LOCAL_GL_RENDERBUFFER_BINDING: {
             return WebGLObjectAsJSValue(cx, mBoundRenderbuffer.get(), rv);
         }
 
-        // DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING.
         case LOCAL_GL_FRAMEBUFFER_BINDING: {
-            return WebGLObjectAsJSValue(cx, mBoundDrawFramebuffer.get(), rv);
+            return WebGLObjectAsJSValue(cx, mBoundFramebuffer.get(), rv);
         }
 
         case LOCAL_GL_CURRENT_PROGRAM: {
             return WebGLObjectAsJSValue(cx, mCurrentProgram.get(), rv);
         }
 
         case LOCAL_GL_TEXTURE_BINDING_2D: {
             return WebGLObjectAsJSValue(cx, mBound2DTextures[mActiveTexture].get(), rv);
--- a/dom/canvas/WebGLContextUtils.cpp
+++ b/dom/canvas/WebGLContextUtils.cpp
@@ -593,24 +593,21 @@ WebGLContext::EnumName(GLenum glenum)
         XX(COMPRESSED_RGB_PVRTC_2BPPV1);
         XX(COMPRESSED_RGB_PVRTC_4BPPV1);
         XX(COMPRESSED_RGB_S3TC_DXT1_EXT);
         XX(DEPTH_COMPONENT);
         XX(DEPTH_COMPONENT16);
         XX(DEPTH_COMPONENT32);
         XX(DEPTH_STENCIL);
         XX(DEPTH24_STENCIL8);
-        XX(DRAW_FRAMEBUFFER);
         XX(ETC1_RGB8_OES);
         XX(FLOAT);
-        XX(FRAMEBUFFER);
         XX(HALF_FLOAT);
         XX(LUMINANCE);
         XX(LUMINANCE_ALPHA);
-        XX(READ_FRAMEBUFFER);
         XX(RGB);
         XX(RGB16F);
         XX(RGB32F);
         XX(RGBA);
         XX(RGBA16F);
         XX(RGBA32F);
         XX(SRGB);
         XX(SRGB_ALPHA);
@@ -769,16 +766,18 @@ WebGLContext::EnumName(GLenum glenum)
         XX(FRAMEBUFFER_ATTACHMENT_BLUE_SIZE);
         XX(FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE);
         XX(FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE);
         XX(FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE);
         XX(FRAMEBUFFER_DEFAULT);
         XX(DEPTH_STENCIL_ATTACHMENT);
         XX(UNSIGNED_NORMALIZED);
         XX(DRAW_FRAMEBUFFER_BINDING);
+        XX(READ_FRAMEBUFFER);
+        XX(DRAW_FRAMEBUFFER);
         XX(READ_FRAMEBUFFER_BINDING);
         XX(RENDERBUFFER_SAMPLES);
         XX(FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER);
         XX(MAX_COLOR_ATTACHMENTS);
         XX(COLOR_ATTACHMENT1);
         XX(COLOR_ATTACHMENT2);
         XX(COLOR_ATTACHMENT3);
         XX(COLOR_ATTACHMENT4);
@@ -1024,31 +1023,20 @@ WebGLContext::AssertCachedBindings()
     GetAndFlushUnderlyingGLErrors();
 
     if (IsExtensionEnabled(WebGLExtensionID::OES_vertex_array_object)) {
         GLuint bound = mBoundVertexArray ? mBoundVertexArray->GLName() : 0;
         AssertUintParamCorrect(gl, LOCAL_GL_VERTEX_ARRAY_BINDING, bound);
     }
 
     // Bound object state
-    if (IsWebGL2()) {
-        GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->GLName()
-                                             : 0;
-        AssertUintParamCorrect(gl, LOCAL_GL_DRAW_FRAMEBUFFER_BINDING, bound);
+    GLuint bound = mBoundFramebuffer ? mBoundFramebuffer->GLName() : 0;
+    AssertUintParamCorrect(gl, LOCAL_GL_FRAMEBUFFER_BINDING, bound);
 
-        bound = mBoundReadFramebuffer ? mBoundReadFramebuffer->GLName() : 0;
-        AssertUintParamCorrect(gl, LOCAL_GL_READ_FRAMEBUFFER_BINDING, bound);
-    } else {
-        MOZ_ASSERT(mBoundDrawFramebuffer == mBoundReadFramebuffer);
-        GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->GLName()
-                                             : 0;
-        AssertUintParamCorrect(gl, LOCAL_GL_FRAMEBUFFER_BINDING, bound);
-    }
-
-    GLuint bound = mCurrentProgram ? mCurrentProgram->GLName : 0;
+    bound = mCurrentProgram ? mCurrentProgram->mGLName : 0;
     AssertUintParamCorrect(gl, LOCAL_GL_CURRENT_PROGRAM, bound);
 
     // Textures
     GLenum activeTexture = mActiveTexture + LOCAL_GL_TEXTURE0;
     AssertUintParamCorrect(gl, LOCAL_GL_ACTIVE_TEXTURE, activeTexture);
 
     WebGLTexture* curTex = ActiveBoundTextureForTarget(LOCAL_GL_TEXTURE_2D);
     bound = curTex ? curTex->GLName() : 0;
--- a/dom/canvas/WebGLContextValidate.cpp
+++ b/dom/canvas/WebGLContextValidate.cpp
@@ -368,20 +368,20 @@ WebGLContext::ValidateDrawModeEnum(GLenu
     }
 }
 
 /**
  * Return true if the framebuffer attachment is valid. Attachment must
  * be one of depth/stencil/depth_stencil/color attachment.
  */
 bool
-WebGLContext::ValidateFramebufferAttachment(const WebGLFramebuffer* fb, GLenum attachment,
+WebGLContext::ValidateFramebufferAttachment(GLenum attachment,
                                             const char* funcName)
 {
-    if (!fb) {
+    if (!mBoundFramebuffer) {
         switch (attachment) {
         case LOCAL_GL_COLOR:
         case LOCAL_GL_DEPTH:
         case LOCAL_GL_STENCIL:
             return true;
 
         default:
             ErrorInvalidEnum("%s: attachment: invalid enum value 0x%x.",
@@ -1280,36 +1280,37 @@ bool
 WebGLContext::ValidateCopyTexImage(GLenum format, WebGLTexImageFunc func,
                                    WebGLTexDimensions dims)
 {
     MOZ_ASSERT(IsCopyFunc(func));
 
     // Default framebuffer format
     GLenum fboFormat = mOptions.alpha ? LOCAL_GL_RGBA : LOCAL_GL_RGB;
 
-    if (mBoundReadFramebuffer) {
-        if (!mBoundReadFramebuffer->CheckAndInitializeAttachments()) {
+    if (mBoundFramebuffer) {
+        if (!mBoundFramebuffer->CheckAndInitializeAttachments()) {
             ErrorInvalidFramebufferOperation("%s: Incomplete framebuffer.",
                                              InfoFrom(func, dims));
             return false;
         }
 
         GLenum readPlaneBits = LOCAL_GL_COLOR_BUFFER_BIT;
-        if (!mBoundReadFramebuffer->HasCompletePlanes(readPlaneBits)) {
+        if (!mBoundFramebuffer->HasCompletePlanes(readPlaneBits)) {
             ErrorInvalidOperation("%s: Read source attachment doesn't have the"
                                   " correct color/depth/stencil type.",
                                   InfoFrom(func, dims));
             return false;
         }
 
-        // Get the correct format for the framebuffer, as it's not the default one.
+        // Get the correct format for the framebuffer, as it's not the default
+        // one.
         const WebGLFramebuffer::Attachment& color0 =
-            mBoundReadFramebuffer->GetAttachment(LOCAL_GL_COLOR_ATTACHMENT0);
+            mBoundFramebuffer->GetAttachment(LOCAL_GL_COLOR_ATTACHMENT0);
 
-        fboFormat = mBoundReadFramebuffer->GetFormatForAttachment(color0);
+        fboFormat = mBoundFramebuffer->GetFormatForAttachment(color0);
     }
 
     // Make sure the format of the framebuffer is a superset of the format
     // requested by the CopyTex[Sub]Image2D functions.
     const GLComponents formatComps = GLComponents(format);
     const GLComponents fboComps = GLComponents(fboFormat);
     if (!formatComps.IsSubsetOf(fboComps)) {
         ErrorInvalidOperation("%s: Format %s is not a subset of the current"
@@ -1768,18 +1769,17 @@ WebGLContext::InitAndValidateGL()
     mBound2DTextures.Clear();
     mBoundCubeMapTextures.Clear();
     mBound3DTextures.Clear();
 
     mBoundArrayBuffer = nullptr;
     mBoundTransformFeedbackBuffer = nullptr;
     mCurrentProgram = nullptr;
 
-    mBoundDrawFramebuffer = nullptr;
-    mBoundReadFramebuffer = nullptr;
+    mBoundFramebuffer = nullptr;
     mBoundRenderbuffer = nullptr;
 
     MakeContextCurrent();
 
     // on desktop OpenGL, we always keep vertex attrib 0 array enabled
     if (!gl->IsGLES())
         gl->fEnableVertexAttribArray(0);
 
@@ -1961,37 +1961,9 @@ WebGLContext::InitAndValidateGL()
     mBoundVertexArray = mDefaultVertexArray;
 
     if (mLoseContextOnMemoryPressure)
         mContextObserver->RegisterMemoryPressureEvent();
 
     return true;
 }
 
-bool
-WebGLContext::ValidateFramebufferTarget(GLenum target,
-                                        const char* const info)
-{
-    bool isValid = true;
-    switch (target) {
-    case LOCAL_GL_FRAMEBUFFER:
-        break;
-
-    case LOCAL_GL_DRAW_FRAMEBUFFER:
-    case LOCAL_GL_READ_FRAMEBUFFER:
-        isValid = IsWebGL2();
-        break;
-
-    default:
-        isValid = false;
-        break;
-    }
-
-    if (MOZ_LIKELY(isValid)) {
-        return true;
-    }
-
-    ErrorInvalidEnum("%s: Invalid target: %s (0x%04x).", info, EnumName(target),
-                     target);
-    return false;
-}
-
 } // namespace mozilla
--- a/dom/canvas/WebGLFramebuffer.cpp
+++ b/dom/canvas/WebGLFramebuffer.cpp
@@ -450,18 +450,17 @@ WebGLFramebuffer::DetachAllAttachments()
     DetachAttachment(mDepthStencilAttachment);
 }
 
 void
 WebGLFramebuffer::FramebufferRenderbuffer(FBAttachment attachPoint,
                                           RBTarget rbtarget,
                                           WebGLRenderbuffer* rb)
 {
-    MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
-               mContext->mBoundReadFramebuffer == this);
+    MOZ_ASSERT(mContext->mBoundFramebuffer == this);
 
     if (!mContext->ValidateObjectAllowNull("framebufferRenderbuffer: renderbuffer",
                                            rb))
     {
         return;
     }
 
     /* Get the requested attachment. If result is NULL, attachment is invalid
@@ -492,18 +491,17 @@ WebGLFramebuffer::FramebufferRenderbuffe
     attachment->SetRenderbuffer(rb);
 }
 
 void
 WebGLFramebuffer::FramebufferTexture2D(FBAttachment attachPoint,
                                        TexImageTarget texImageTarget,
                                        WebGLTexture* tex, GLint level)
 {
-    MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
-               mContext->mBoundReadFramebuffer == this);
+    MOZ_ASSERT(mContext->mBoundFramebuffer == this);
 
     if (!mContext->ValidateObjectAllowNull("framebufferTexture2D: texture",
                                            tex))
     {
         return;
     }
 
     if (tex) {
@@ -561,17 +559,17 @@ WebGLFramebuffer::GetAttachmentOrNull(FB
 
     case LOCAL_GL_STENCIL_ATTACHMENT:
         return &mStencilAttachment;
 
     default:
         break;
     }
 
-    if (!mContext->ValidateFramebufferAttachment(this, attachPoint.get(),
+    if (!mContext->ValidateFramebufferAttachment(attachPoint.get(),
                                                  "getAttachmentOrNull"))
     {
         return nullptr;
     }
 
     size_t colorAttachmentId = attachPoint.get() - LOCAL_GL_COLOR_ATTACHMENT0;
     EnsureColorAttachments(colorAttachmentId);
 
@@ -590,17 +588,17 @@ WebGLFramebuffer::GetAttachment(FBAttach
 
     case LOCAL_GL_STENCIL_ATTACHMENT:
         return mStencilAttachment;
 
     default:
         break;
     }
 
-    if (!mContext->ValidateFramebufferAttachment(this, attachPoint.get(),
+    if (!mContext->ValidateFramebufferAttachment(attachPoint.get(),
                                                  "getAttachment"))
     {
         MOZ_ASSERT(false);
         return mColorAttachments[0];
     }
 
     size_t colorAttachmentId = attachPoint.get() - LOCAL_GL_COLOR_ATTACHMENT0;
     if (colorAttachmentId >= mColorAttachments.Length()) {
@@ -763,18 +761,17 @@ WebGLFramebuffer::RectangleObject() cons
     // has a consistent rect.
     MOZ_ASSERT(AllImageRectsMatch(), "Did you mean `GetAnyRectObject`?");
     return GetAnyRectObject();
 }
 
 FBStatus
 WebGLFramebuffer::PrecheckFramebufferStatus() const
 {
-    MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
-               mContext->mBoundReadFramebuffer == this);
+    MOZ_ASSERT(mContext->mBoundFramebuffer == this);
 
     if (!HasDefinedAttachments())
         return LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; // No attachments
 
     if (HasIncompleteAttachments())
         return LOCAL_GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
 
     if (!AllImageRectsMatch())
@@ -807,19 +804,17 @@ WebGLFramebuffer::CheckFramebufferStatus
 }
 
 bool
 WebGLFramebuffer::HasCompletePlanes(GLbitfield mask)
 {
     if (CheckFramebufferStatus() != LOCAL_GL_FRAMEBUFFER_COMPLETE)
         return false;
 
-    MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
-               mContext->mBoundReadFramebuffer == this);
-
+    MOZ_ASSERT(mContext->mBoundFramebuffer == this);
     bool hasPlanes = true;
     if (mask & LOCAL_GL_COLOR_BUFFER_BIT) {
         hasPlanes &= ColorAttachmentCount() &&
                      ColorAttachment(0).IsDefined();
     }
 
     if (mask & LOCAL_GL_DEPTH_BUFFER_BIT) {
         hasPlanes &= DepthAttachment().IsDefined() ||
@@ -832,18 +827,17 @@ WebGLFramebuffer::HasCompletePlanes(GLbi
     }
 
     return hasPlanes;
 }
 
 bool
 WebGLFramebuffer::CheckAndInitializeAttachments()
 {
-    MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
-               mContext->mBoundReadFramebuffer == this);
+    MOZ_ASSERT(mContext->mBoundFramebuffer == this);
 
     if (CheckFramebufferStatus() != LOCAL_GL_FRAMEBUFFER_COMPLETE)
         return false;
 
     // Cool! We've checked out ok. Just need to initialize.
     const size_t colorAttachmentCount = mColorAttachments.Length();
 
     // Check if we need to initialize anything
--- a/gfx/gl/GLScreenBuffer.cpp
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -615,21 +615,17 @@ DrawBuffer::Create(GLContext* const gl,
 
     CreateRenderbuffersForOffscreen(gl, formats, size, caps.antialias,
                                     pColorMSRB, pDepthRB, pStencilRB);
 
     GLuint fb = 0;
     gl->fGenFramebuffers(1, &fb);
     gl->AttachBuffersToFB(0, colorMSRB, depthRB, stencilRB, fb);
 
-    GLsizei samples = formats.samples;
-    if (!samples)
-        samples = 1;
-
-    UniquePtr<DrawBuffer> ret( new DrawBuffer(gl, size, samples, fb, colorMSRB,
+    UniquePtr<DrawBuffer> ret( new DrawBuffer(gl, size, fb, colorMSRB,
                                               depthRB, stencilRB) );
 
     GLenum err = localError.GetError();
     MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_OUT_OF_MEMORY);
     if (err || !gl->IsFramebufferComplete(fb))
         return false;
 
     *out_buffer = Move(ret);
--- a/gfx/gl/GLScreenBuffer.h
+++ b/gfx/gl/GLScreenBuffer.h
@@ -41,33 +41,30 @@ public:
                        const GLFormats& formats,
                        const gfx::IntSize& size,
                        UniquePtr<DrawBuffer>* out_buffer);
 
 protected:
     GLContext* const mGL;
 public:
     const gfx::IntSize mSize;
-    const GLsizei mSamples;
     const GLuint mFB;
 protected:
     const GLuint mColorMSRB;
     const GLuint mDepthRB;
     const GLuint mStencilRB;
 
     DrawBuffer(GLContext* gl,
                const gfx::IntSize& size,
-               GLsizei samples,
                GLuint fb,
                GLuint colorMSRB,
                GLuint depthRB,
                GLuint stencilRB)
         : mGL(gl)
         , mSize(size)
-        , mSamples(samples)
         , mFB(fb)
         , mColorMSRB(colorMSRB)
         , mDepthRB(depthRB)
         , mStencilRB(stencilRB)
     {}
 
 public:
     virtual ~DrawBuffer();
@@ -196,23 +193,16 @@ public:
 
         return mDraw->mFB;
     }
 
     GLuint ReadFB() const {
         return mRead->mFB;
     }
 
-    GLsizei Samples() const {
-        if (!mDraw)
-            return 1;
-
-        return mDraw->mSamples;
-    }
-
     void DeletingFB(GLuint fb);
 
     const gfx::IntSize& Size() const {
         MOZ_ASSERT(mRead);
         MOZ_ASSERT(!mDraw || mDraw->mSize == mRead->Size());
         return mRead->Size();
     }