stackgl / gl-vao

Vertex array object wrapper for WebGL
http://stack.gl/gl-vao/
MIT License
24 stars 4 forks source link

Cache getParameter calls ? #1

Closed mattdesl closed 10 years ago

mattdesl commented 10 years ago

Since bind may be called many times per frame, I think it would be worth considering caching the call to getParameter:

var nattribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS)|0

In general it's poor practice to query GL state within your render loop.

mikolalysenko commented 10 years ago

That's correct, but gl.MAX_VERTEX_ATTRIBS is a constant, not a state parameter and it isn't very expensive to read it out whenever you need it (ie caching is pointless). As an example, I tried comparing directly calling gl.getParameter vs caching the result in a WeakMap. Here are the results:

var WeakMap = require('weakmap')

var NUM_ITERS = 1e5

var canvas = document.createElement('canvas')
var gl = canvas.getContext('webgl')

function testWeakMap() {

  //Two versions
  var wm = new WeakMap()
  wm.set(gl, gl.getParameter(gl.MAX_VERTEX_ATTRIBS))

  var start = +Date.now()
  var count = 0
  for(var i=0; i<NUM_ITERS; ++i) {
    count += wm.get(gl)
  }
  var end = +Date.now()

  return [count, (end-start)/NUM_ITERS]
}

function testGetParameter() {

  var start = +Date.now()
  var count = 0
  for(var i=0; i<NUM_ITERS; ++i) {
    count += gl.getParameter(gl.MAX_VERTEX_ATTRIBS)
  }
  var end = +Date.now()

  return [count, (end-start)/NUM_ITERS]
}

var wmResult = testWeakMap()
console.log("weakmap time:", wmResult[1], 'ms/access')

var paramResult = testGetParameter()
console.log("getParameter time:", paramResult[1], 'ms/access')

And here are the results (Chrome 36):

weakmap time: 0.00108 ms/access
getParameter time: 0.0001ms/access

You could maybe speed it up a bit by caching per gl context, but it gets messy and I really doubt it would be worth it at the end of the day (especially considering how much more complexity it would add for such a tiny savings).

mattdesl commented 10 years ago

Just saw it flagged 100+ times per frame in a GL inspector stack trace.

No point in changing tho. I think we should come back to redundant GL calls later, on a big scene, to see if they make any real impact.

Sent from my iPhone

On Aug 14, 2014, at 8:51 AM, Mikola Lysenko notifications@github.com wrote:

That's correct, but gl.MAX_VERTEX_ATTRIBS is a constant, not a state parameter and it isn't very expensive to read it out whenever you need it (ie caching is pointless). As an example, I tried comparing directly calling gl.getParameter vs caching the result in a WeakMap. Here are the results:

var WeakMap = require('weakmap')

var NUM_ITERS = 1e5

var canvas = document.createElement('canvas') var gl = canvas.getContext('webgl')

function testWeakMap() {

//Two versions var wm = new WeakMap() wm.set(gl, gl.getParameter(gl.MAX_VERTEX_ATTRIBS))

var start = +Date.now() var count = 0 for(var i=0; i<NUM_ITERS; ++i) { count += wm.get(gl) } var end = +Date.now()

return [count, (end-start)/NUM_ITERS] }

function testGetParameter() {

var start = +Date.now() var count = 0 for(var i=0; i<NUM_ITERS; ++i) { count += gl.getParameter(gl.MAX_VERTEX_ATTRIBS) } var end = +Date.now()

return [count, (end-start)/NUM_ITERS] }

var wmResult = testWeakMap() console.log("weakmap time:", wmResult[1], 'ms/access')

var paramResult = testGetParameter() console.log("getParameter time:", paramResult[1], 'ms/access') And here are the results (Chrome 36):

weakmap time: 0.00108 ms/access getParameter time: 0.0001ms/access You could maybe speed it up a bit by caching per gl context, but it gets messy and I really doubt it would be worth it at the end of the day (especially considering how much more complexity it would add for such a tiny savings).

— Reply to this email directly or view it on GitHub.

mikolalysenko commented 10 years ago

Ah, that is a good reason then to look at maybe caching it. If it pollutes logging info in debugging tools, then maybe it is worth it just to improve diagnostics (or alternatively getting smarter tools/filters!)