Bug 1237193 - Fix WebGL getActiveUniforms return type. r=jgilbert, r=smaug
authorEthan Lin <ethlin@mozilla.com>
Mon, 15 Feb 2016 15:14:00 +0100
changeset 284355 a3f46ba96f9572ad00ce1190f3b22a55117de8fe
parent 284354 46180e3cd0c6adda64977bd6ecd82aec201d6f3a
child 284356 a24be316086fb99ffd3e0ce75220d2074e9b8174
push id71923
push usercbook@mozilla.com
push dateTue, 16 Feb 2016 15:44:45 +0000
treeherdermozilla-inbound@a24be316086f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert, smaug
bugs1237193
milestone47.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 1237193 - Fix WebGL getActiveUniforms return type. r=jgilbert, r=smaug
dom/canvas/WebGL2Context.h
dom/canvas/WebGL2ContextUniforms.cpp
dom/webidl/WebGL2RenderingContext.webidl
--- a/dom/canvas/WebGL2Context.h
+++ b/dom/canvas/WebGL2Context.h
@@ -355,19 +355,22 @@ public:
     void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, GLintptr offset, GLsizeiptr size);
 */
     virtual JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv) override;
     void GetIndexedParameter(GLenum target, GLuint index,
                              dom::Nullable<dom::OwningWebGLBufferOrLongLong>& retval);
     void GetUniformIndices(WebGLProgram* program,
                            const dom::Sequence<nsString>& uniformNames,
                            dom::Nullable< nsTArray<GLuint> >& retval);
-    void GetActiveUniforms(WebGLProgram* program,
-                           const dom::Sequence<GLuint>& uniformIndices, GLenum pname,
-                           dom::Nullable< nsTArray<GLint> >& retval);
+    void GetActiveUniforms(JSContext* cx,
+                           WebGLProgram* program,
+                           const dom::Sequence<GLuint>& uniformIndices,
+                           GLenum pname,
+                           JS::MutableHandleValue retval);
+
     GLuint GetUniformBlockIndex(WebGLProgram* program, const nsAString& uniformBlockName);
     void GetActiveUniformBlockParameter(JSContext*, WebGLProgram* program,
                                         GLuint uniformBlockIndex, GLenum pname,
                                         dom::Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval,
                                         ErrorResult& rv);
     void GetActiveUniformBlockName(WebGLProgram* program, GLuint uniformBlockIndex,
                                    nsAString& retval);
     void UniformBlockBinding(WebGLProgram* program, GLuint uniformBlockIndex,
--- a/dom/canvas/WebGL2ContextUniforms.cpp
+++ b/dom/canvas/WebGL2ContextUniforms.cpp
@@ -313,45 +313,101 @@ WebGL2Context::GetUniformIndices(WebGLPr
         return;
 
     if (!uniformNames.Length())
         return;
 
     program->GetUniformIndices(uniformNames, retval);
 }
 
+static bool
+ValidateUniformEnum(WebGLContext* webgl, GLenum pname, const char* info)
+{
+    switch (pname) {
+    case LOCAL_GL_UNIFORM_TYPE:
+    case LOCAL_GL_UNIFORM_SIZE:
+    case LOCAL_GL_UNIFORM_BLOCK_INDEX:
+    case LOCAL_GL_UNIFORM_OFFSET:
+    case LOCAL_GL_UNIFORM_ARRAY_STRIDE:
+    case LOCAL_GL_UNIFORM_MATRIX_STRIDE:
+    case LOCAL_GL_UNIFORM_IS_ROW_MAJOR:
+        return true;
+
+    default:
+        webgl->ErrorInvalidEnum("%s: invalid pname: %s", info, webgl->EnumName(pname));
+        return false;
+    }
+}
+
 void
-WebGL2Context::GetActiveUniforms(WebGLProgram* program,
+WebGL2Context::GetActiveUniforms(JSContext* cx,
+                                 WebGLProgram* program,
                                  const dom::Sequence<GLuint>& uniformIndices,
                                  GLenum pname,
-                                 dom::Nullable< nsTArray<GLint> >& retval)
+                                 JS::MutableHandleValue retval)
 {
-    retval.SetNull();
+    retval.set(JS::NullValue());
     if (IsContextLost())
         return;
 
-    if (pname == LOCAL_GL_UNIFORM_NAME_LENGTH) {
-        ErrorInvalidEnumInfo("getActiveUniforms: pname", pname);
+    if (!ValidateUniformEnum(this, pname, "getActiveUniforms"))
         return;
-    }
 
     if (!ValidateObject("getActiveUniforms: program", program))
         return;
 
     size_t count = uniformIndices.Length();
     if (!count)
         return;
 
     GLuint progname = program->mGLName;
-    nsTArray<GLint>& arr = retval.SetValue();
-    arr.SetLength(count);
+    Vector<GLint> samples;
+    if (!samples.resize(count)) {
+        return;
+    }
 
     MakeContextCurrent();
     gl->fGetActiveUniformsiv(progname, count, uniformIndices.Elements(), pname,
-                             arr.Elements());
+                             samples.begin());
+
+    JS::Rooted<JSObject*> array(cx, JS_NewArrayObject(cx, count));
+    if (!array) {
+        return;
+    }
+
+    switch (pname) {
+    case LOCAL_GL_UNIFORM_TYPE:
+    case LOCAL_GL_UNIFORM_SIZE:
+    case LOCAL_GL_UNIFORM_BLOCK_INDEX:
+    case LOCAL_GL_UNIFORM_OFFSET:
+    case LOCAL_GL_UNIFORM_ARRAY_STRIDE:
+    case LOCAL_GL_UNIFORM_MATRIX_STRIDE:
+        for (uint32_t i = 0; i < count; ++i) {
+            JS::RootedValue value(cx);
+            value = JS::Int32Value(samples[i]);
+            if (!JS_DefineElement(cx, array, i, value, JSPROP_ENUMERATE)) {
+                return;
+            }
+        }
+        break;
+    case LOCAL_GL_UNIFORM_IS_ROW_MAJOR:
+        for (uint32_t i = 0; i < count; ++i) {
+            JS::RootedValue value(cx);
+            value = JS::BooleanValue(samples[i]);
+            if (!JS_DefineElement(cx, array, i, value, JSPROP_ENUMERATE)) {
+                return;
+            }
+        }
+        break;
+
+    default:
+        return;
+    }
+
+    retval.setObjectOrNull(array);
 }
 
 GLuint
 WebGL2Context::GetUniformBlockIndex(WebGLProgram* program,
                                     const nsAString& uniformBlockName)
 {
     if (IsContextLost())
         return 0;
--- a/dom/webidl/WebGL2RenderingContext.webidl
+++ b/dom/webidl/WebGL2RenderingContext.webidl
@@ -470,17 +470,17 @@ interface WebGL2RenderingContext : WebGL
     /* Uniform Buffer Objects and Transform Feedback Buffers */
     void bindBufferBase(GLenum target, GLuint index, WebGLBuffer? buffer);
     void bindBufferRange(GLenum target, GLuint index, WebGLBuffer? buffer, GLintptr offset, GLsizeiptr size);
     // Return from getIndexedParameter is WebGLBuffer or GLintptr or GLsizeiptr) but
     // GLintptr and GLsizeiptr are the same underlying type of long long, so only specify
     // GLintptr here, otherwise interface generator returns error.
     (WebGLBuffer or GLintptr)? getIndexedParameter(GLenum target, GLuint index);
     sequence<GLuint>? getUniformIndices(WebGLProgram? program, sequence<DOMString> uniformNames);
-    sequence<GLint>? getActiveUniforms(WebGLProgram? program, sequence<GLuint> uniformIndices, GLenum pname);
+    any getActiveUniforms(WebGLProgram? program, sequence<GLuint> uniformIndices, GLenum pname);
     GLuint getUniformBlockIndex(WebGLProgram? program, DOMString uniformBlockName);
     [Throws]
     (GLuint or Uint32Array or GLboolean)? getActiveUniformBlockParameter(WebGLProgram? program, GLuint uniformBlockIndex, GLenum pname);
     DOMString? getActiveUniformBlockName(WebGLProgram? program, GLuint uniformBlockIndex);
     void uniformBlockBinding(WebGLProgram? program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
 
     /* Vertex Array Objects */
     WebGLVertexArrayObject? createVertexArray();