content/canvas/src/WebGLContextFramebufferOperations.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "WebGLContext.h"
     7 #include "WebGLTexture.h"
     8 #include "WebGLRenderbuffer.h"
     9 #include "WebGLFramebuffer.h"
    10 #include "GLContext.h"
    12 using namespace mozilla;
    14 void
    15 WebGLContext::Clear(GLbitfield mask)
    16 {
    17     if (IsContextLost())
    18         return;
    20     MakeContextCurrent();
    22     uint32_t m = mask & (LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT);
    23     if (mask != m)
    24         return ErrorInvalidValue("clear: invalid mask bits");
    26     if (mask == 0) {
    27         GenerateWarning("Calling gl.clear(0) has no effect.");
    28     } else if (mRasterizerDiscardEnabled) {
    29         GenerateWarning("Calling gl.clear() with RASTERIZER_DISCARD enabled has no effects.");
    30     }
    32     if (mBoundFramebuffer) {
    33         if (!mBoundFramebuffer->CheckAndInitializeAttachments())
    34             return ErrorInvalidFramebufferOperation("clear: incomplete framebuffer");
    36         gl->fClear(mask);
    37         return;
    38     } else {
    39         ClearBackbufferIfNeeded();
    40     }
    42     // Ok, we're clearing the default framebuffer/screen.
    44     gl->fClear(mask);
    46     Invalidate();
    47     mShouldPresent = true;
    48 }
    50 static GLclampf
    51 GLClampFloat(GLclampf val)
    52 {
    53     if (val < 0.0)
    54         return 0.0;
    56     if (val > 1.0)
    57         return 1.0;
    59     return val;
    60 }
    62 void
    63 WebGLContext::ClearColor(GLclampf r, GLclampf g,
    64                              GLclampf b, GLclampf a)
    65 {
    66     if (IsContextLost())
    67         return;
    69     MakeContextCurrent();
    70     mColorClearValue[0] = GLClampFloat(r);
    71     mColorClearValue[1] = GLClampFloat(g);
    72     mColorClearValue[2] = GLClampFloat(b);
    73     mColorClearValue[3] = GLClampFloat(a);
    74     gl->fClearColor(r, g, b, a);
    75 }
    77 void
    78 WebGLContext::ClearDepth(GLclampf v)
    79 {
    80     if (IsContextLost())
    81         return;
    83     MakeContextCurrent();
    84     mDepthClearValue = GLClampFloat(v);
    85     gl->fClearDepth(v);
    86 }
    88 void
    89 WebGLContext::ClearStencil(GLint v)
    90 {
    91     if (IsContextLost())
    92         return;
    94     MakeContextCurrent();
    95     mStencilClearValue = v;
    96     gl->fClearStencil(v);
    97 }
    99 void
   100 WebGLContext::ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboolean a)
   101 {
   102     if (IsContextLost())
   103         return;
   105     MakeContextCurrent();
   106     mColorWriteMask[0] = r;
   107     mColorWriteMask[1] = g;
   108     mColorWriteMask[2] = b;
   109     mColorWriteMask[3] = a;
   110     gl->fColorMask(r, g, b, a);
   111 }
   113 void
   114 WebGLContext::DepthMask(WebGLboolean b)
   115 {
   116     if (IsContextLost())
   117         return;
   119     MakeContextCurrent();
   120     mDepthWriteMask = b;
   121     gl->fDepthMask(b);
   122 }
   124 void
   125 WebGLContext::DrawBuffers(const dom::Sequence<GLenum>& buffers)
   126 {
   127     if (IsContextLost())
   128         return;
   130     const size_t buffersLength = buffers.Length();
   132     if (buffersLength == 0) {
   133         return ErrorInvalidValue("drawBuffers: invalid <buffers> (buffers must not be empty)");
   134     }
   136     if (mBoundFramebuffer == 0)
   137     {
   138         // OK: we are rendering in the default framebuffer
   140         /* EXT_draw_buffers :
   141          If the GL is bound to the default framebuffer, then <buffersLength> must be 1
   142          and the constant must be BACK or NONE. When draw buffer zero is
   143          BACK, color values are written into the sole buffer for single-
   144          buffered contexts, or into the back buffer for double-buffered
   145          contexts. If DrawBuffersEXT is supplied with a constant other than
   146          BACK and NONE, the error INVALID_OPERATION is generated.
   147          */
   148         if (buffersLength != 1) {
   149             return ErrorInvalidValue("drawBuffers: invalid <buffers> (main framebuffer: buffers.length must be 1)");
   150         }
   152         MakeContextCurrent();
   154         if (buffers[0] == LOCAL_GL_NONE) {
   155             const GLenum drawBuffersCommand = LOCAL_GL_NONE;
   156             gl->fDrawBuffers(1, &drawBuffersCommand);
   157             return;
   158         }
   159         else if (buffers[0] == LOCAL_GL_BACK) {
   160             const GLenum drawBuffersCommand = LOCAL_GL_COLOR_ATTACHMENT0;
   161             gl->fDrawBuffers(1, &drawBuffersCommand);
   162             return;
   163         }
   164         return ErrorInvalidOperation("drawBuffers: invalid operation (main framebuffer: buffers[0] must be GL_NONE or GL_BACK)");
   165     }
   167     // OK: we are rendering in a framebuffer object
   169     if (buffersLength > size_t(mGLMaxDrawBuffers)) {
   170         /* EXT_draw_buffers :
   171          The maximum number of draw buffers is implementation-dependent. The
   172          number of draw buffers supported can be queried by calling
   173          GetIntegerv with the symbolic constant MAX_DRAW_BUFFERS_EXT. An
   174          INVALID_VALUE error is generated if <buffersLength> is greater than
   175          MAX_DRAW_BUFFERS_EXT.
   176          */
   177         return ErrorInvalidValue("drawBuffers: invalid <buffers> (buffers.length > GL_MAX_DRAW_BUFFERS)");
   178     }
   180     for (uint32_t i = 0; i < buffersLength; i++)
   181     {
   182         /* EXT_draw_buffers :
   183          If the GL is bound to a draw framebuffer object, the <i>th buffer listed
   184          in <bufs> must be COLOR_ATTACHMENT<i>_EXT or NONE. Specifying a
   185          buffer out of order, BACK, or COLOR_ATTACHMENT<m>_EXT where <m> is
   186          greater than or equal to the value of MAX_COLOR_ATTACHMENTS_EXT,
   187          will generate the error INVALID_OPERATION.
   188          */
   189         /* WEBGL_draw_buffers :
   190          The value of the MAX_COLOR_ATTACHMENTS_WEBGL parameter must be greater than or equal to that of the MAX_DRAW_BUFFERS_WEBGL parameter.
   191          */
   192         if (buffers[i] != LOCAL_GL_NONE &&
   193             buffers[i] != GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + i)) {
   194             return ErrorInvalidOperation("drawBuffers: invalid operation (buffers[i] must be GL_NONE or GL_COLOR_ATTACHMENTi)");
   195         }
   196     }
   198     MakeContextCurrent();
   200     gl->fDrawBuffers(buffersLength, buffers.Elements());
   201 }
   203 void
   204 WebGLContext::StencilMask(GLuint mask)
   205 {
   206     if (IsContextLost())
   207         return;
   209     mStencilWriteMaskFront = mask;
   210     mStencilWriteMaskBack = mask;
   212     MakeContextCurrent();
   213     gl->fStencilMask(mask);
   214 }
   216 void
   217 WebGLContext::StencilMaskSeparate(GLenum face, GLuint mask)
   218 {
   219     if (IsContextLost())
   220         return;
   222     if (!ValidateFaceEnum(face, "stencilMaskSeparate: face"))
   223         return;
   225     switch (face) {
   226         case LOCAL_GL_FRONT_AND_BACK:
   227             mStencilWriteMaskFront = mask;
   228             mStencilWriteMaskBack = mask;
   229             break;
   230         case LOCAL_GL_FRONT:
   231             mStencilWriteMaskFront = mask;
   232             break;
   233         case LOCAL_GL_BACK:
   234             mStencilWriteMaskBack = mask;
   235             break;
   236     }
   238     MakeContextCurrent();
   239     gl->fStencilMaskSeparate(face, mask);
   240 }

mercurial