Bug 1170455 - Part 4: Track the type of the generic vertex attribute. r=jgilbert
authorDan Glastonbury <dglastonbury@mozilla.com>
Mon, 20 Jul 2015 17:56:17 +1000
changeset 254051 bef0545626b5b65ad7cdfdbc5cac762b71ddd349
parent 254050 5c815e17ac8ada59568283c8af94068d935d9062
child 254052 0757d904847209c50980a33abed579d381aab4dc
push id29087
push usercbook@mozilla.com
push dateWed, 22 Jul 2015 12:01:23 +0000
treeherdermozilla-central@e7434cafdf2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert
bugs1170455
milestone42.0a1
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
Bug 1170455 - Part 4: Track the type of the generic vertex attribute. r=jgilbert So the correct typed array can be returned from GetVertexAttrib.
dom/canvas/WebGL2ContextVertices.cpp
dom/canvas/WebGLContext.h
dom/canvas/WebGLContextValidate.cpp
dom/canvas/WebGLContextVertices.cpp
--- a/dom/canvas/WebGL2ContextVertices.cpp
+++ b/dom/canvas/WebGL2ContextVertices.cpp
@@ -5,35 +5,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebGL2Context.h"
 
 #include "GLContext.h"
 #include "WebGLVertexArray.h"
 #include "WebGLVertexAttribData.h"
 
-namespace mozilla {
-
-typedef union { GLint i; GLfloat f; GLuint u; } fi_t;
+#include "mozilla/Casting.h"
 
-static inline
-GLfloat PuntToFloat(GLint i)
-{
-   fi_t tmp;
-   tmp.i = i;
-   return tmp.f;
-}
-
-static inline
-GLfloat PuntToFloat(GLuint u)
-{
-   fi_t tmp;
-   tmp.u = u;
-   return tmp.f;
-}
+namespace mozilla {
 
 bool
 WebGL2Context::ValidateAttribPointerType(bool integerMode, GLenum type,
                                          GLsizei* out_alignment, const char* info)
 {
   MOZ_ASSERT(out_alignment);
 
   switch (type) {
@@ -92,17 +76,16 @@ WebGL2Context::VertexAttribIPointer(GLui
   }
 
   MOZ_ASSERT(mBoundVertexArray);
   mBoundVertexArray->EnsureAttrib(index);
 
   InvalidateBufferFetching();
 
   WebGLVertexAttribData& vd = mBoundVertexArray->mAttribs[index];
-
   vd.buf = mBoundArrayBuffer;
   vd.stride = stride;
   vd.size = size;
   vd.byteOffset = offset;
   vd.type = type;
   vd.normalized = false;
   vd.integer = true;
 
@@ -111,81 +94,104 @@ WebGL2Context::VertexAttribIPointer(GLui
 }
 
 void
 WebGL2Context::VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
 {
   if (IsContextLost())
     return;
 
+  if (!ValidateAttribIndex(index, "vertexAttribI4i"))
+    return;
+
+  mVertexAttribType[index] = LOCAL_GL_INT;
+
   if (index || gl->IsGLES()) {
     MakeContextCurrent();
     gl->fVertexAttribI4i(index, x, y, z, w);
   } else {
-    mVertexAttrib0Vector[0] = PuntToFloat(x);
-    mVertexAttrib0Vector[1] = PuntToFloat(y);
-    mVertexAttrib0Vector[2] = PuntToFloat(z);
-    mVertexAttrib0Vector[3] = PuntToFloat(w);
+    mVertexAttrib0Vector[0] = BitwiseCast<GLfloat>(x);
+    mVertexAttrib0Vector[1] = BitwiseCast<GLfloat>(y);
+    mVertexAttrib0Vector[2] = BitwiseCast<GLfloat>(z);
+    mVertexAttrib0Vector[3] = BitwiseCast<GLfloat>(w);
   }
 }
 
 void
 WebGL2Context::VertexAttribI4iv(GLuint index, size_t length, const GLint* v)
 {
+  if (!ValidateAttribIndex(index, "vertexAttribI4iv"))
+    return;
+
   if (!ValidateAttribArraySetter("vertexAttribI4iv", 4, length))
     return;
 
+  mVertexAttribType[index] = LOCAL_GL_INT;
+
   if (index || gl->IsGLES()) {
     MakeContextCurrent();
     gl->fVertexAttribI4iv(index, v);
   } else {
-    mVertexAttrib0Vector[0] = PuntToFloat(v[0]);
-    mVertexAttrib0Vector[1] = PuntToFloat(v[1]);
-    mVertexAttrib0Vector[2] = PuntToFloat(v[2]);
-    mVertexAttrib0Vector[3] = PuntToFloat(v[3]);
+    mVertexAttrib0Vector[0] = BitwiseCast<GLfloat>(v[0]);
+    mVertexAttrib0Vector[1] = BitwiseCast<GLfloat>(v[1]);
+    mVertexAttrib0Vector[2] = BitwiseCast<GLfloat>(v[2]);
+    mVertexAttrib0Vector[3] = BitwiseCast<GLfloat>(v[3]);
   }
 }
 
 void
 WebGL2Context::VertexAttribI4iv(GLuint index, const dom::Sequence<GLint>& v)
 {
   VertexAttribI4iv(index, v.Length(), v.Elements());
 }
 
 void
 WebGL2Context::VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
 {
   if (IsContextLost())
     return;
 
+  if (!ValidateAttribIndex(index, "vertexAttribI4ui"))
+    return;
+
+  mVertexAttribType[index] = LOCAL_GL_UNSIGNED_INT;
+
   if (index || gl->IsGLES()) {
     MakeContextCurrent();
     gl->fVertexAttribI4ui(index, x, y, z, w);
   } else {
-    mVertexAttrib0Vector[0] = PuntToFloat(x);
-    mVertexAttrib0Vector[1] = PuntToFloat(y);
-    mVertexAttrib0Vector[2] = PuntToFloat(z);
-    mVertexAttrib0Vector[3] = PuntToFloat(w);
+    mVertexAttrib0Vector[0] = BitwiseCast<GLfloat>(x);
+    mVertexAttrib0Vector[1] = BitwiseCast<GLfloat>(y);
+    mVertexAttrib0Vector[2] = BitwiseCast<GLfloat>(z);
+    mVertexAttrib0Vector[3] = BitwiseCast<GLfloat>(w);
   }
 }
 
 void
 WebGL2Context::VertexAttribI4uiv(GLuint index, size_t length, const GLuint* v)
 {
   if (IsContextLost())
     return;
 
+  if (!ValidateAttribIndex(index, "vertexAttribI4uiv"))
+    return;
+
+  if (!ValidateAttribIndex(index, "vertexAttribI4uiv"))
+    return;
+
+  mVertexAttribType[index] = LOCAL_GL_UNSIGNED_INT;
+
   if (index || gl->IsGLES()) {
     MakeContextCurrent();
     gl->fVertexAttribI4uiv(index, v);
   } else {
-    mVertexAttrib0Vector[0] = PuntToFloat(v[0]);
-    mVertexAttrib0Vector[1] = PuntToFloat(v[1]);
-    mVertexAttrib0Vector[2] = PuntToFloat(v[2]);
-    mVertexAttrib0Vector[3] = PuntToFloat(v[3]);
+    mVertexAttrib0Vector[0] = BitwiseCast<GLfloat>(v[0]);
+    mVertexAttrib0Vector[1] = BitwiseCast<GLfloat>(v[1]);
+    mVertexAttrib0Vector[2] = BitwiseCast<GLfloat>(v[2]);
+    mVertexAttrib0Vector[3] = BitwiseCast<GLfloat>(v[3]);
   }
 }
 
 void
 WebGL2Context::VertexAttribI4uiv(GLuint index, const dom::Sequence<GLuint>& v)
 {
   VertexAttribI4uiv(index, v.Length(), v.Elements());
 }
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -1456,22 +1456,31 @@ protected:
     UniquePtr<FakeBlackTexture> mBlackTransparentTextureCubeMap;
 
     void
     BindFakeBlackTexturesHelper(GLenum target,
                                 const nsTArray<WebGLRefPtr<WebGLTexture> >& boundTexturesArray,
                                 UniquePtr<FakeBlackTexture>& opaqueTextureScopedPtr,
                                 UniquePtr<FakeBlackTexture>& transparentTextureScopedPtr);
 
+    // Generic Vertex Attributes
+    UniquePtr<GLenum[]> mVertexAttribType;
     GLfloat mVertexAttrib0Vector[4];
     GLfloat mFakeVertexAttrib0BufferObjectVector[4];
     size_t mFakeVertexAttrib0BufferObjectSize;
     GLuint mFakeVertexAttrib0BufferObject;
     WebGLVertexAttrib0Status mFakeVertexAttrib0BufferStatus;
 
+    void GetVertexAttribFloat(GLuint index, GLfloat* out_result);
+    void GetVertexAttribInt(GLuint index, GLint* out_result);
+    void GetVertexAttribUint(GLuint index, GLuint* out_result);
+    JSObject* GetVertexAttribFloat32Array(JSContext* cx, GLuint index);
+    JSObject* GetVertexAttribInt32Array(JSContext* cx, GLuint index);
+    JSObject* GetVertexAttribUint32Array(JSContext* cx, GLuint index);
+
     GLint mStencilRefFront;
     GLint mStencilRefBack;
     GLuint mStencilValueMaskFront;
     GLuint mStencilValueMaskBack;
     GLuint mStencilWriteMaskFront;
     GLuint mStencilWriteMaskBack;
     realGLboolean mColorWriteMask[4];
     realGLboolean mDepthWriteMask;
--- a/dom/canvas/WebGLContextValidate.cpp
+++ b/dom/canvas/WebGLContextValidate.cpp
@@ -1936,17 +1936,19 @@ WebGLContext::InitAndValidateGL()
     if (IsWebGL2() &&
         !InitWebGL2())
     {
         // Todo: Bug 898404: Only allow WebGL2 on GL>=3.0 on desktop GL.
         return false;
     }
 
     // Default value for all disabled vertex attributes is [0, 0, 0, 1]
+    mVertexAttribType = MakeUnique<GLenum[]>(mGLMaxVertexAttribs);
     for (int32_t index = 0; index < mGLMaxVertexAttribs; ++index) {
+        mVertexAttribType[index] = LOCAL_GL_FLOAT;
         VertexAttrib4f(index, 0, 0, 0, 1);
     }
 
     mDefaultVertexArray = WebGLVertexArray::Create(this);
     mDefaultVertexArray->mAttribs.SetLength(mGLMaxVertexAttribs);
     mBoundVertexArray = mDefaultVertexArray;
 
     // OpenGL core profiles remove the default VAO object from version
--- a/dom/canvas/WebGLContextVertices.cpp
+++ b/dom/canvas/WebGLContextVertices.cpp
@@ -11,27 +11,93 @@
 #include "WebGLFramebuffer.h"
 #include "WebGLProgram.h"
 #include "WebGLRenderbuffer.h"
 #include "WebGLShader.h"
 #include "WebGLTexture.h"
 #include "WebGLVertexArray.h"
 #include "WebGLVertexAttribData.h"
 
+#include "mozilla/Casting.h"
+
 namespace mozilla {
 
 void
+WebGLContext::GetVertexAttribFloat(GLuint index, GLfloat* out_result)
+{
+    if (index) {
+        gl->fGetVertexAttribfv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, out_result);
+    } else {
+        out_result[0] = mVertexAttrib0Vector[0];
+        out_result[1] = mVertexAttrib0Vector[1];
+        out_result[2] = mVertexAttrib0Vector[2];
+        out_result[3] = mVertexAttrib0Vector[3];
+    }
+}
+
+void
+WebGLContext::GetVertexAttribInt(GLuint index, GLint* out_result)
+{
+    if (index) {
+        gl->fGetVertexAttribIiv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, out_result);
+    } else {
+        out_result[0] = BitwiseCast<GLint>(mVertexAttrib0Vector[0]);
+        out_result[1] = BitwiseCast<GLint>(mVertexAttrib0Vector[1]);
+        out_result[2] = BitwiseCast<GLint>(mVertexAttrib0Vector[2]);
+        out_result[3] = BitwiseCast<GLint>(mVertexAttrib0Vector[3]);
+    }
+}
+
+void
+WebGLContext::GetVertexAttribUint(GLuint index, GLuint* out_result)
+{
+    if (index) {
+        gl->fGetVertexAttribIuiv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, out_result);
+    } else {
+        out_result[0] = BitwiseCast<GLuint>(mVertexAttrib0Vector[0]);
+        out_result[1] = BitwiseCast<GLuint>(mVertexAttrib0Vector[1]);
+        out_result[2] = BitwiseCast<GLuint>(mVertexAttrib0Vector[2]);
+        out_result[3] = BitwiseCast<GLuint>(mVertexAttrib0Vector[3]);
+    }
+}
+
+JSObject*
+WebGLContext::GetVertexAttribFloat32Array(JSContext* cx, GLuint index)
+{
+    GLfloat attrib[4];
+    GetVertexAttribFloat(index, &attrib[0]);
+    return dom::Float32Array::Create(cx, this, 4, attrib);
+}
+
+JSObject*
+WebGLContext::GetVertexAttribInt32Array(JSContext* cx, GLuint index)
+{
+    GLint attrib[4];
+    GetVertexAttribInt(index, &attrib[0]);
+    return dom::Int32Array::Create(cx, this, 4, attrib);
+}
+
+JSObject*
+WebGLContext::GetVertexAttribUint32Array(JSContext* cx, GLuint index) {
+    GLuint attrib[4];
+    GetVertexAttribUint(index, &attrib[0]);
+    return dom::Uint32Array::Create(cx, this, 4, attrib);
+}
+
+void
 WebGLContext::VertexAttrib1f(GLuint index, GLfloat x0)
 {
     if (IsContextLost())
         return;
 
     if (!ValidateAttribIndex(index, "vertexAttrib1f"))
         return;
 
+    mVertexAttribType[index] = LOCAL_GL_FLOAT;
+
     MakeContextCurrent();
 
     if (index) {
         gl->fVertexAttrib1f(index, x0);
     } else {
         mVertexAttrib0Vector[0] = x0;
         mVertexAttrib0Vector[1] = 0;
         mVertexAttrib0Vector[2] = 0;
@@ -45,16 +111,18 @@ void
 WebGLContext::VertexAttrib2f(GLuint index, GLfloat x0, GLfloat x1)
 {
     if (IsContextLost())
         return;
 
     if (!ValidateAttribIndex(index, "vertexAttrib2f"))
         return;
 
+    mVertexAttribType[index] = LOCAL_GL_FLOAT;
+
     MakeContextCurrent();
 
     if (index) {
         gl->fVertexAttrib2f(index, x0, x1);
     } else {
         mVertexAttrib0Vector[0] = x0;
         mVertexAttrib0Vector[1] = x1;
         mVertexAttrib0Vector[2] = 0;
@@ -68,16 +136,18 @@ void
 WebGLContext::VertexAttrib3f(GLuint index, GLfloat x0, GLfloat x1, GLfloat x2)
 {
     if (IsContextLost())
         return;
 
     if (!ValidateAttribIndex(index, "vertexAttrib3f"))
         return;
 
+    mVertexAttribType[index] = LOCAL_GL_FLOAT;
+
     MakeContextCurrent();
 
     if (index) {
         gl->fVertexAttrib3f(index, x0, x1, x2);
     } else {
         mVertexAttrib0Vector[0] = x0;
         mVertexAttrib0Vector[1] = x1;
         mVertexAttrib0Vector[2] = x2;
@@ -92,16 +162,18 @@ WebGLContext::VertexAttrib4f(GLuint inde
                              GLfloat x2, GLfloat x3)
 {
     if (IsContextLost())
         return;
 
     if (!ValidateAttribIndex(index, "vertexAttrib4f"))
         return;
 
+    mVertexAttribType[index] = LOCAL_GL_FLOAT;
+
     MakeContextCurrent();
 
     if (index) {
         gl->fVertexAttrib4f(index, x0, x1, x2, x3);
     } else {
         mVertexAttrib0Vector[0] = x0;
         mVertexAttrib0Vector[1] = x1;
         mVertexAttrib0Vector[2] = x2;
@@ -117,16 +189,18 @@ WebGLContext::VertexAttrib1fv_base(GLuin
                                    const GLfloat* ptr)
 {
     if (!ValidateAttribArraySetter("VertexAttrib1fv", 1, arrayLength))
         return;
 
     if (!ValidateAttribIndex(index, "vertexAttrib1fv"))
         return;
 
+    mVertexAttribType[index] = LOCAL_GL_FLOAT;
+
     MakeContextCurrent();
     if (index) {
         gl->fVertexAttrib1fv(index, ptr);
     } else {
         mVertexAttrib0Vector[0] = ptr[0];
         mVertexAttrib0Vector[1] = GLfloat(0);
         mVertexAttrib0Vector[2] = GLfloat(0);
         mVertexAttrib0Vector[3] = GLfloat(1);
@@ -140,16 +214,18 @@ WebGLContext::VertexAttrib2fv_base(GLuin
                                    const GLfloat* ptr)
 {
     if (!ValidateAttribArraySetter("VertexAttrib2fv", 2, arrayLength))
         return;
 
     if (!ValidateAttribIndex(index, "vertexAttrib2fv"))
         return;
 
+    mVertexAttribType[index] = LOCAL_GL_FLOAT;
+
     MakeContextCurrent();
     if (index) {
         gl->fVertexAttrib2fv(index, ptr);
     } else {
         mVertexAttrib0Vector[0] = ptr[0];
         mVertexAttrib0Vector[1] = ptr[1];
         mVertexAttrib0Vector[2] = GLfloat(0);
         mVertexAttrib0Vector[3] = GLfloat(1);
@@ -163,16 +239,18 @@ WebGLContext::VertexAttrib3fv_base(GLuin
                                    const GLfloat* ptr)
 {
     if (!ValidateAttribArraySetter("VertexAttrib3fv", 3, arrayLength))
         return;
 
     if (!ValidateAttribIndex(index, "vertexAttrib3fv"))
         return;
 
+    mVertexAttribType[index] = LOCAL_GL_FLOAT;
+
     MakeContextCurrent();
     if (index) {
         gl->fVertexAttrib3fv(index, ptr);
     } else {
         mVertexAttrib0Vector[0] = ptr[0];
         mVertexAttrib0Vector[1] = ptr[1];
         mVertexAttrib0Vector[2] = ptr[2];
         mVertexAttrib0Vector[3] = GLfloat(1);
@@ -186,16 +264,18 @@ WebGLContext::VertexAttrib4fv_base(GLuin
                                    const GLfloat* ptr)
 {
     if (!ValidateAttribArraySetter("VertexAttrib4fv", 4, arrayLength))
         return;
 
     if (!ValidateAttribIndex(index, "vertexAttrib4fv"))
         return;
 
+    mVertexAttribType[index] = LOCAL_GL_FLOAT;
+
     MakeContextCurrent();
     if (index) {
         gl->fVertexAttrib4fv(index, ptr);
     } else {
         mVertexAttrib0Vector[0] = ptr[0];
         mVertexAttrib0Vector[1] = ptr[1];
         mVertexAttrib0Vector[2] = ptr[2];
         mVertexAttrib0Vector[3] = ptr[3];
@@ -279,29 +359,33 @@ WebGLContext::GetVertexAttrib(JSContext*
 
     case LOCAL_GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
         if (IsExtensionEnabled(WebGLExtensionID::ANGLE_instanced_arrays))
             return JS::Int32Value(mBoundVertexArray->mAttribs[index].divisor);
         break;
 
     case LOCAL_GL_CURRENT_VERTEX_ATTRIB:
         {
-            GLfloat vec[4] = {0, 0, 0, 1};
-            if (index) {
-                gl->fGetVertexAttribfv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, &vec[0]);
-            } else {
-                vec[0] = mVertexAttrib0Vector[0];
-                vec[1] = mVertexAttrib0Vector[1];
-                vec[2] = mVertexAttrib0Vector[2];
-                vec[3] = mVertexAttrib0Vector[3];
+            JS::RootedObject obj(cx);
+            switch (mVertexAttribType[index]) {
+            case LOCAL_GL_FLOAT:
+                obj = GetVertexAttribFloat32Array(cx, index);
+                break;
+
+            case LOCAL_GL_INT:
+                obj =  GetVertexAttribInt32Array(cx, index);
+                break;
+
+            case LOCAL_GL_UNSIGNED_INT:
+                obj = GetVertexAttribUint32Array(cx, index);
+                break;
             }
-            JSObject* obj = dom::Float32Array::Create(cx, this, 4, vec);
-            if (!obj) {
+
+            if (!obj)
                 rv.Throw(NS_ERROR_OUT_OF_MEMORY);
-            }
             return JS::ObjectOrNullValue(obj);
         }
 
     case LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED:
         return JS::BooleanValue(mBoundVertexArray->mAttribs[index].enabled);
 
     case LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
         return JS::BooleanValue(mBoundVertexArray->mAttribs[index].normalized);