[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Public WebGL] Re: WebGL IDL for uniform1fv is not valid WebIDL



On Mon, Apr 2, 2012 at 5:26 PM, Boris Zbarsky <bzbarsky@mit.edu> wrote:
>
> On 4/2/12 7:20 PM, Cameron McCormack wrote:
>>
>> I want to allow object with indexed properties to be passed to objects
>> expecting a sequence<T> or T[] type, so that you can do for example:
>>
>> void f(sequence<Node> nodes);
>>
>> and be able to pass in a JS Array of Node objects or a NodeList. I make
>> interfaces with indexed properties not distinguishable from sequences
>> and arrays so that there isn't a value that would match both types.
>
>
> Or you could make it distinguishable and check for the right interface
> before trying the generic conversion.
>
>
>> I think removing the Float32Array overload will make passing JS Arrays
>> of Numbers and Float32Array objects work.
>
>
> But require copies in the process, no?  That seems highly undesirable in
> this case.
>
>
>> But note that *any* object
>> that has indexed properties will be allowed to be passed here, e.g. a
>> Uint8Array. If we want to disallow that, then I think that is
>> incompatible with the NodeList example above.
>
>
> Not if we place requirements on the return values of the indexed properties
> or something.  But that can get complicated.
>
>
>> But if we're fine with
>> Uint8Array being passed in and matching the float[] overload
>
>
> That seems up to the WebGL folks here.....
>
>
>> then just
>> changing those types to be distinguishable, and making the argument
>> resolution algorithm match the specific interface types before the
>> "catch all" array/sequence types should work.
>
>
> Indeed.

My first preference would be to not have the typed array view types
match the float[] overloads. The intent here was to provide
convenience methods only for passing in JavaScript arrays. Supporting
passing in the other view types will add a non-trivial amount of code,
and might make errors less obvious to developers. (TypeError is pretty
obvious.)

However, if this is fundamentally incompatible with the way Web IDL is
supposed to work, then my preference would be to change the argument
resolution algorithm in the way you (Cameron) describe, so that the
Float32Array case can at least be fast. These particular entry points
aren't absolutely performance critical, but it's important to give
developers a way to make their programs as fast as possible.

The test case I experimented with is attached (rename to test.html). I
note that Chrome throws TypeError for the two API calls and TOT WebKit
allows the calls, so clearly this area needs to be clarified. Also, I
have no idea what WebKit is actually doing with the incoming
Uint8Array. (It may be making a JS upcall per element.)

-Ken
<head>
<script language="javascript">
function run() {
  var canvas = document.getElementById("test");
  var gl = canvas.getContext("experimental-webgl");
  var vertexText = [
    "attribute vec3 a_position;",
    "uniform vec3 u_offset;",
    "void main() {",
    "  gl_Position = vec4(a_position + u_offset, 1.0);",
    "}",
  ].join("\n");
  var vertexShader = gl.createShader(gl.VERTEX_SHADER);
  gl.shaderSource(vertexShader, vertexText);
  gl.compileShader(vertexShader);
  if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
    throw "Error compiling vertex shader";
  }

  var fragmentText = [
    "precision mediump float;",
    "void main() {",
    "  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);",
    "}",
  ].join("\n");
  var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
  gl.shaderSource(fragmentShader, fragmentText);
  gl.compileShader(fragmentShader);
  if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
    throw "Error compiling fragment shader";
  }

  var program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  gl.linkProgram(program);

  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    throw "Error linking program";
  }

  var attrLoc = gl.getAttribLocation(program, "a_position");
  if (attrLoc < 0) {
    throw "Unknown vertex attribute location";
  }
  var uniformLoc = gl.getUniformLocation(program, "u_offset");
  if (uniformLoc == null) {
    throw "Unknown uniform location";
  }

  var arr = new Uint8Array(3);
  for (var ii = 0; ii < arr.length; ++ii) {
    arr[ii] = ii;
  }

  gl.useProgram(program);

  try {
    gl.vertexAttrib3fv(attrLoc, arr);
    window.console.log("vertexAttrib3fv succeeded");
    window.console.log("gl.getError() = " + gl.getError());
  } catch (e) {
    // TypeError in Chrome and Safari
    window.console.log("Exception during vertexAttrib3fv: " + e);
  }

  try {
    gl.uniform3fv(uniformLoc, arr);
    window.console.log("uniform3fv succeeded");
    window.console.log("gl.getError() = " + gl.getError());
  } catch (e) {
    // TypeError in Chrome and Safari
    window.console.log("Exception during uniform3fv: " + e);
  }
}
</script>
</head>
<body onload="run()">
<canvas id="test" width="256" height="256">
</canvas>
<p>
</p>
</body>