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

Re: [Public WebGL] For review: ANGLE_timer_query extension



I think it might make sense that if you do callbacks, that the callbacks are tied to requestAnimationFrame. You usually don't care to receive callbacks unless just before you actually would want to work with the captured data right? And usually the next chance you'll get to work with the data is in a requestAnimationFrame callback.


On Wed, Apr 3, 2013 at 7:18 PM, Gregg Tavares <gman@google.com> wrote:
There's another issue with the polling API. It exposes inconsistent behavior. 

Devs can decide not to check whether a query result is available and just read the result. For example they could assume if they ended a query last frame that reading the result next frame will be valid without checking that it actually is valid. This may work on some % of systems but fail on another % of systems. It might also fail on the same system depending on various random factors. 

Adding such inconsistent behavior into WebGL doesn't seem like a good idea.



        



On Wed, Apr 3, 2013 at 9:45 AM, Florian Bösch <pyalot@gmail.com> wrote:
Well, does the callback proposal actually improve things? Let's see.

var samples = new Float32Array(1024);
var sampleIdx = 0;

var sampleDone = function(timeElapsed){
  samples[sampleIdx] = timeElapsed;
  sampleIdx = (sampleIdx+1)%samples.length;
  ext.deleteQueryAngle(this);
}

var draw = function(){
  var query = var query = ext.createQueryANGLE();
  query.>

  ext.beginQueryANGLE(ext.TIME_ELAPSED_ANGLE, query);
  gl.drawElements(...);
  ext.endQueryANGLE(ext.TIME_ELAPSED_ANGLE);
}

I think that's nicer. Less mucking about with with keeping query objects in a container. Assuming of course that queries will become available in order of things actually completing, and not in some random order. So the browser will have to remember the sequency and not call back to it out of order. I'm assuming that wouldn't be a problem right?


On Wed, Apr 3, 2013 at 6:34 PM, Gregg Tavares <gman@google.com> wrote:
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?