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

Re: [Public WebGL] OES_texture_half_float doesn't allow Tex(Sub)Image2D to take ArrayBuffers as input

On 2/20/2014 7:02 PM, Kenneth Russell wrote:
And on that note, I'm going to propose an extension soonish to do the ArrayBuffer case -- add entry points that take an ArrayBuffer, offset, length.  I've seen JS code that runs into this where it loads a blob of data from network/file/wherever and then wants to upload it needing to create a bunch of unnecessary views.  We're also running into this a lot with Emscripten/asm.js code, where the views end up being unnecessary GC objects created/destroyed where we have no need of any GC objects.
Allocation of these objects should be cheap in most _javascript_ engines
today, and as I pointed out before, taking ArrayBufferView here
instead of ArrayBuffer offers some semblance of type checking of the
incoming data. Also, uploading and updating textures is already a
relatively expensive operation. Do you have data that shows a marked
performance increase by adding overloads taking raw ArrayBuffers?

Despite cheap nursery GC objects, one reason for using a ArrayBuffer + offset + length instead of a new GC object is that it lets us make that call when creating a new GC object would be problematic. asm.js is one such context; with some API calls, we could reference the asm.js heap directly as the AB, and internally emit a call straight from the asm.js code block to the webgl function without having to jit some regular JS in between.  Doing *that* part is not that expensive, but it limits some experimentation we'd like to do around shared arraybuffers and similar (basically, figuring out what limits we can impose on them reasonably).  That said, as long as ArrayBufferView wasn't really a view (that is, as long as you can't read/write the contents using one -- it would need to purely be an opaque buffer region, really just an ArrayBuffer), we could optimize that creation out... but would be nice to avoid it in the first place.

I guess the pros and cons look like this, and they're directly opposite of each other:

ArrayBuffer + offset + length
pro - no GC objects created (perf-neutral, but nice for asm.js context)
middle ground - errors (incorrect offset, length, alignment) come purely as GL errors (INVALID_VALUE)
neg - no way to pass a simple object around that's a subregion of an ArrayBuffer (e.g. to be able to create views of it using its built-in offset)

con - GC object is created (perf-neutral, more work for asm.js context)
middle ground, somewhat con - errors come as a mix; offset/length errors come as JS exceptions during ABV construction, alignment errors come as GL errors (though that's similar to what happens today with the typed views)
pro - you can create an ABV and pass it around masquerading as a full AB, so that things can create views of a sub-region without worrying about managing the offset themselves

Honestly, looking at that list, I'd be tempted to suggest just doing both -- add ArrayBufferView (or some other name) that has no getters or setters, but that merely references a portion of an AB and otherwise behaves like an ArrayBuffer; allow passing it in to the API.  Add additional API entry points for passing in ab/offset/length.  (Heck, you could mix and match.. use an ArrayBufferView + offset + length, if an ABV can be used as an AB.)

    - Vlad