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

Re: [Public WebGL] For review: ANGLE_timer_query extension



Florian,

This isn't about whether a good programmer like you can write correct code. It's about whether bad programmers will write code that browser vendors are stuck supporting.

The API proposed by ANGLE_timer_query is the same API used for occlusion queries. The only difference is a 3 emums. Bad devs will do this

   for each object () {
      drawOccluder();
      spinWaitForAnswer();
      if (!occluded()) {
           doHeavyDraw();
      }
   }

If that happens to run fast enough on some browser/driver combo they'll ship it. Then users will complain they can't interact with the browser because it's stuck waiting for _javascript_. This is the same reason why the browser vendors are sad there's a synchronous XHR function. It kills UX. They'd get rid of it if they could but MS made that mistake 15 years ago so were stuck with it. Let's not make the same mistake.







On Wed, Apr 3, 2013 at 2:55 AM, Florian Bösch <pyalot@gmail.com> wrote:
I don't agree that not having callbacks would lead to while(true){} use. But I might not fully understand the API. Here is what you would normally do with measured values:

- Compute an average sliding window
- Compute statistic measures such as variance and deviation

To do that a ring-buffer is usually used to store N previous sample points. It works about like this everytime you have a sample point.

buffer[i] = samplePoint;
i = (i+1)%buffer.length;

And then you compute/draw whatever from that buffer. A sliding average can be efficiently implemented this way by subtracting the old value from the average and adding the new value, like so:

sumAvg += samplePoint - buffer[i];
average = sumAvg/buffer.length;
buffer[i] = samplePoint;
i = (i+1)%buffer.length;

To do that with the query object API I'd imagine you'd do this:

var queries = [];
var samples = new Float32Array(1024);
var sampleIdx = 0;

var draw = function(){
  var query = var query = ext.createQueryANGLE();
  queries.push(query);
  ext.beginQueryANGLE(ext.TIME_ELAPSED_ANGLE, query);
  gl.drawElements(...);
  ext.endQueryANGLE(ext.TIME_ELAPSED_ANGLE);

  while(queries.length > 0){
    query = queries[0];
    if(ext.getQueryParameterANGLE(query, ext.QUERY_RESULT_AVAILABLE_ANGLE)){
      queries.shift();
      var timeElapsed = ext.getQueryParameterANGLE(query, ext.QUERY_RESULT_ANGLE);
      var samples[sampleIdx] = timeElapsed;
      sampleIdx = (sampleIdx+1)%samples.length;
    }
    else{
      break;
    }
  }
}

I think that would be fairly acceptable code. Do I miss something?