content/canvas/src/WebGLContextVertices.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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"
     8 #include "GLContext.h"
     9 #include "mozilla/CheckedInt.h"
    10 #include "WebGLBuffer.h"
    11 #include "WebGLFramebuffer.h"
    12 #include "WebGLProgram.h"
    13 #include "WebGLRenderbuffer.h"
    14 #include "WebGLShader.h"
    15 #include "WebGLTexture.h"
    16 #include "WebGLUniformInfo.h"
    17 #include "WebGLVertexArray.h"
    18 #include "WebGLVertexAttribData.h"
    20 using namespace mozilla;
    21 using namespace dom;
    23 void
    24 WebGLContext::VertexAttrib1f(GLuint index, GLfloat x0)
    25 {
    26     if (IsContextLost())
    27         return;
    29     MakeContextCurrent();
    31     if (index) {
    32         gl->fVertexAttrib1f(index, x0);
    33     } else {
    34         mVertexAttrib0Vector[0] = x0;
    35         mVertexAttrib0Vector[1] = 0;
    36         mVertexAttrib0Vector[2] = 0;
    37         mVertexAttrib0Vector[3] = 1;
    38         if (gl->IsGLES())
    39             gl->fVertexAttrib1f(index, x0);
    40     }
    41 }
    43 void
    44 WebGLContext::VertexAttrib2f(GLuint index, GLfloat x0, GLfloat x1)
    45 {
    46     if (IsContextLost())
    47         return;
    49     MakeContextCurrent();
    51     if (index) {
    52         gl->fVertexAttrib2f(index, x0, x1);
    53     } else {
    54         mVertexAttrib0Vector[0] = x0;
    55         mVertexAttrib0Vector[1] = x1;
    56         mVertexAttrib0Vector[2] = 0;
    57         mVertexAttrib0Vector[3] = 1;
    58         if (gl->IsGLES())
    59             gl->fVertexAttrib2f(index, x0, x1);
    60     }
    61 }
    63 void
    64 WebGLContext::VertexAttrib3f(GLuint index, GLfloat x0, GLfloat x1, GLfloat x2)
    65 {
    66     if (IsContextLost())
    67         return;
    69     MakeContextCurrent();
    71     if (index) {
    72         gl->fVertexAttrib3f(index, x0, x1, x2);
    73     } else {
    74         mVertexAttrib0Vector[0] = x0;
    75         mVertexAttrib0Vector[1] = x1;
    76         mVertexAttrib0Vector[2] = x2;
    77         mVertexAttrib0Vector[3] = 1;
    78         if (gl->IsGLES())
    79             gl->fVertexAttrib3f(index, x0, x1, x2);
    80     }
    81 }
    83 void
    84 WebGLContext::VertexAttrib4f(GLuint index, GLfloat x0, GLfloat x1,
    85                              GLfloat x2, GLfloat x3)
    86 {
    87     if (IsContextLost())
    88         return;
    90     MakeContextCurrent();
    92     if (index) {
    93         gl->fVertexAttrib4f(index, x0, x1, x2, x3);
    94     } else {
    95         mVertexAttrib0Vector[0] = x0;
    96         mVertexAttrib0Vector[1] = x1;
    97         mVertexAttrib0Vector[2] = x2;
    98         mVertexAttrib0Vector[3] = x3;
    99         if (gl->IsGLES())
   100             gl->fVertexAttrib4f(index, x0, x1, x2, x3);
   101     }
   102 }
   105 void
   106 WebGLContext::VertexAttrib1fv_base(GLuint idx, uint32_t arrayLength,
   107                                    const GLfloat* ptr)
   108 {
   109     if (!ValidateAttribArraySetter("VertexAttrib1fv", 1, arrayLength))
   110         return;
   112     MakeContextCurrent();
   113     if (idx) {
   114         gl->fVertexAttrib1fv(idx, ptr);
   115     } else {
   116         mVertexAttrib0Vector[0] = ptr[0];
   117         mVertexAttrib0Vector[1] = GLfloat(0);
   118         mVertexAttrib0Vector[2] = GLfloat(0);
   119         mVertexAttrib0Vector[3] = GLfloat(1);
   120         if (gl->IsGLES())
   121             gl->fVertexAttrib1fv(idx, ptr);
   122     }
   123 }
   125 void
   126 WebGLContext::VertexAttrib2fv_base(GLuint idx, uint32_t arrayLength,
   127                                    const GLfloat* ptr)
   128 {
   129     if (!ValidateAttribArraySetter("VertexAttrib2fv", 2, arrayLength))
   130         return;
   132     MakeContextCurrent();
   133     if (idx) {
   134         gl->fVertexAttrib2fv(idx, ptr);
   135     } else {
   136         mVertexAttrib0Vector[0] = ptr[0];
   137         mVertexAttrib0Vector[1] = ptr[1];
   138         mVertexAttrib0Vector[2] = GLfloat(0);
   139         mVertexAttrib0Vector[3] = GLfloat(1);
   140         if (gl->IsGLES())
   141             gl->fVertexAttrib2fv(idx, ptr);
   142     }
   143 }
   145 void
   146 WebGLContext::VertexAttrib3fv_base(GLuint idx, uint32_t arrayLength,
   147                                    const GLfloat* ptr)
   148 {
   149     if (!ValidateAttribArraySetter("VertexAttrib3fv", 3, arrayLength))
   150         return;
   152     MakeContextCurrent();
   153     if (idx) {
   154         gl->fVertexAttrib3fv(idx, ptr);
   155     } else {
   156         mVertexAttrib0Vector[0] = ptr[0];
   157         mVertexAttrib0Vector[1] = ptr[1];
   158         mVertexAttrib0Vector[2] = ptr[2];
   159         mVertexAttrib0Vector[3] = GLfloat(1);
   160         if (gl->IsGLES())
   161             gl->fVertexAttrib3fv(idx, ptr);
   162     }
   163 }
   165 void
   166 WebGLContext::VertexAttrib4fv_base(GLuint idx, uint32_t arrayLength,
   167                                    const GLfloat* ptr)
   168 {
   169     if (!ValidateAttribArraySetter("VertexAttrib4fv", 4, arrayLength))
   170         return;
   172     MakeContextCurrent();
   173     if (idx) {
   174         gl->fVertexAttrib4fv(idx, ptr);
   175     } else {
   176         mVertexAttrib0Vector[0] = ptr[0];
   177         mVertexAttrib0Vector[1] = ptr[1];
   178         mVertexAttrib0Vector[2] = ptr[2];
   179         mVertexAttrib0Vector[3] = ptr[3];
   180         if (gl->IsGLES())
   181             gl->fVertexAttrib4fv(idx, ptr);
   182     }
   183 }
   185 void
   186 WebGLContext::EnableVertexAttribArray(GLuint index)
   187 {
   188     if (IsContextLost())
   189         return;
   191     if (!ValidateAttribIndex(index, "enableVertexAttribArray"))
   192         return;
   194     MakeContextCurrent();
   195     InvalidateBufferFetching();
   197     gl->fEnableVertexAttribArray(index);
   198     MOZ_ASSERT(mBoundVertexArray->HasAttrib(index)); // should have been validated earlier
   199     mBoundVertexArray->mAttribs[index].enabled = true;
   200 }
   202 void
   203 WebGLContext::DisableVertexAttribArray(GLuint index)
   204 {
   205     if (IsContextLost())
   206         return;
   208     if (!ValidateAttribIndex(index, "disableVertexAttribArray"))
   209         return;
   211     MakeContextCurrent();
   212     InvalidateBufferFetching();
   214     if (index || gl->IsGLES())
   215         gl->fDisableVertexAttribArray(index);
   217     MOZ_ASSERT(mBoundVertexArray->HasAttrib(index)); // should have been validated earlier
   218     mBoundVertexArray->mAttribs[index].enabled = false;
   219 }
   222 JS::Value
   223 WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
   224                               ErrorResult& rv)
   225 {
   226     if (IsContextLost())
   227         return JS::NullValue();
   229     if (!ValidateAttribIndex(index, "getVertexAttrib"))
   230         return JS::NullValue();
   232     MakeContextCurrent();
   234     switch (pname) {
   235         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
   236         {
   237             return WebGLObjectAsJSValue(cx, mBoundVertexArray->mAttribs[index].buf.get(), rv);
   238         }
   240         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE:
   241         {
   242             return JS::Int32Value(mBoundVertexArray->mAttribs[index].stride);
   243         }
   245         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE:
   246         {
   247             if (!ValidateAttribIndex(index, "getVertexAttrib"))
   248                 return JS::NullValue();
   250             if (!mBoundVertexArray->mAttribs[index].enabled)
   251                 return JS::Int32Value(4);
   253             // Don't break; fall through.
   254         }
   255         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE:
   256         {
   257             GLint i = 0;
   258             gl->fGetVertexAttribiv(index, pname, &i);
   259             if (pname == LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE)
   260                 return JS::Int32Value(i);
   261             MOZ_ASSERT(pname == LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE);
   262             return JS::NumberValue(uint32_t(i));
   263         }
   265         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
   266         {
   267             if (IsExtensionEnabled(WebGLExtensionID::ANGLE_instanced_arrays))
   268             {
   269                 return JS::Int32Value(mBoundVertexArray->mAttribs[index].divisor);
   270             }
   271             break;
   272         }
   274         case LOCAL_GL_CURRENT_VERTEX_ATTRIB:
   275         {
   276             GLfloat vec[4] = {0, 0, 0, 1};
   277             if (index) {
   278                 gl->fGetVertexAttribfv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, &vec[0]);
   279             } else {
   280                 vec[0] = mVertexAttrib0Vector[0];
   281                 vec[1] = mVertexAttrib0Vector[1];
   282                 vec[2] = mVertexAttrib0Vector[2];
   283                 vec[3] = mVertexAttrib0Vector[3];
   284             }
   285             JSObject* obj = Float32Array::Create(cx, this, 4, vec);
   286             if (!obj) {
   287                 rv.Throw(NS_ERROR_OUT_OF_MEMORY);
   288             }
   289             return JS::ObjectOrNullValue(obj);
   290         }
   292         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED:
   293         {
   294             return JS::BooleanValue(mBoundVertexArray->mAttribs[index].enabled);
   295         }
   297         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
   298         {
   299             return JS::BooleanValue(mBoundVertexArray->mAttribs[index].normalized);
   300         }
   302         default:
   303             break;
   304     }
   306     ErrorInvalidEnumInfo("getVertexAttrib: parameter", pname);
   308     return JS::NullValue();
   309 }
   311 WebGLsizeiptr
   312 WebGLContext::GetVertexAttribOffset(GLuint index, GLenum pname)
   313 {
   314     if (IsContextLost())
   315         return 0;
   317     if (!ValidateAttribIndex(index, "getVertexAttribOffset"))
   318         return 0;
   320     if (pname != LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER) {
   321         ErrorInvalidEnum("getVertexAttribOffset: bad parameter");
   322         return 0;
   323     }
   325     return mBoundVertexArray->mAttribs[index].byteOffset;
   326 }
   328 void
   329 WebGLContext::VertexAttribPointer(GLuint index, GLint size, GLenum type,
   330                                   WebGLboolean normalized, GLsizei stride,
   331                                   WebGLintptr byteOffset)
   332 {
   333     if (IsContextLost())
   334         return;
   336     if (mBoundArrayBuffer == nullptr)
   337         return ErrorInvalidOperation("vertexAttribPointer: must have valid GL_ARRAY_BUFFER binding");
   339     GLsizei requiredAlignment = 1;
   340     switch (type) {
   341         case LOCAL_GL_BYTE:
   342         case LOCAL_GL_UNSIGNED_BYTE:
   343             requiredAlignment = 1;
   344             break;
   345         case LOCAL_GL_SHORT:
   346         case LOCAL_GL_UNSIGNED_SHORT:
   347             requiredAlignment = 2;
   348             break;
   349             // XXX case LOCAL_GL_FIXED:
   350         case LOCAL_GL_FLOAT:
   351             requiredAlignment = 4;
   352             break;
   353         default:
   354             return ErrorInvalidEnumInfo("vertexAttribPointer: type", type);
   355     }
   357     // requiredAlignment should always be a power of two.
   358     GLsizei requiredAlignmentMask = requiredAlignment - 1;
   360     if (!ValidateAttribIndex(index, "vertexAttribPointer")) {
   361         return;
   362     }
   364     if (size < 1 || size > 4)
   365         return ErrorInvalidValue("vertexAttribPointer: invalid element size");
   367     if (stride < 0 || stride > 255) // see WebGL spec section 6.6 "Vertex Attribute Data Stride"
   368         return ErrorInvalidValue("vertexAttribPointer: negative or too large stride");
   370     if (byteOffset < 0)
   371         return ErrorInvalidValue("vertexAttribPointer: negative offset");
   373     if (stride & requiredAlignmentMask) {
   374         return ErrorInvalidOperation("vertexAttribPointer: stride doesn't satisfy the alignment "
   375                                      "requirement of given type");
   376     }
   378     if (byteOffset & requiredAlignmentMask) {
   379         return ErrorInvalidOperation("vertexAttribPointer: byteOffset doesn't satisfy the alignment "
   380                                      "requirement of given type");
   382     }
   384     InvalidateBufferFetching();
   386     /* XXX make work with bufferSubData & heterogeneous types
   387      if (type != mBoundArrayBuffer->GLType())
   388      return ErrorInvalidOperation("vertexAttribPointer: type must match bound VBO type: %d != %d", type, mBoundArrayBuffer->GLType());
   389      */
   391     WebGLVertexAttribData &vd = mBoundVertexArray->mAttribs[index];
   393     vd.buf = mBoundArrayBuffer;
   394     vd.stride = stride;
   395     vd.size = size;
   396     vd.byteOffset = byteOffset;
   397     vd.type = type;
   398     vd.normalized = normalized;
   400     MakeContextCurrent();
   402     gl->fVertexAttribPointer(index, size, type, normalized,
   403                              stride,
   404                              reinterpret_cast<void*>(byteOffset));
   405 }
   407 void
   408 WebGLContext::VertexAttribDivisor(GLuint index, GLuint divisor)
   409 {
   410     if (IsContextLost())
   411         return;
   413     if (!ValidateAttribIndex(index, "vertexAttribDivisor")) {
   414         return;
   415     }
   417     WebGLVertexAttribData& vd = mBoundVertexArray->mAttribs[index];
   418     vd.divisor = divisor;
   420     InvalidateBufferFetching();
   422     MakeContextCurrent();
   424     gl->fVertexAttribDivisor(index, divisor);
   425 }

mercurial