WEBGL_subscribe_uniform WebGL working group (public_webgl 'at' khronos.org) Owen Glofcheski, Google Members of the WebGL working group NN

This extension exposes the ability to subscribe to a set of uniform targets which can be used to populate uniforms within shader programs. This extension is generic, but currently only supports mouse position as a subscription target.

Background:

The depth of the web pipeline makes it difficult to support low latency interaction as event information retrieved via javascript is outdated by the time it's displayed to clients. By populating event information later in the pipeline one can reduce perceived input latency.

This extension creates a new buffer type 'Valuebuffer' to maintain the active state for predefined subscription targets. Since a mechanism for buffering uniform information isn't available pre 2.0 (UBOs) an additional data type was needed. See 'New Types' for additional information.

When this extension is enabled:

[NoInterfaceObject] interface WEBGL_subscribe_uniform { const GLenum SUBSCRIBED_VALUES_BUFFER = 0x924B; // subscription targets const GLenum MOUSE_POSITION = 0x924C; WebGLValuebuffer? createValuebuffer(); void deleteValuebuffer(WebGLValuebuffer? buffer); void isValuebuffer(WebGLValuebuffer? buffer); void bindValuebuffer(GLenum target, WebGLValuebuffer? buffer); void subscribeValue(GLenum traget, GLenum subscription); void populateSubscribedValues(GLenum target); void uniformValuebuffer(WebGLUniformLocation? location, GLenum target, GLenum subscription); }; // interface WEBGL_subscribe_uniform Creates and returns a Valuebuffer object. Deletes a Valuebuffer object. Returns whether an object is a Valuebuffer object. Lets you use a named Valuebuffer object. Subscribes the currently bound Valuebuffer object to a subscription target. Populates the currently bound Valuebuffer object with the state of the subscriptions to which it is subscribed. Modifies the value of a uniform variable or uniform variable array using the state of the subscription target in the currently bound Valuebuffer object.

This interface is used to maintain a reference to internal Valuebuffer subscription states.

A Valuebuffer abstracts the mapping of subscription targets to internal state and acts as a single storage object for subscription information (e.g. current mouse position). Clients can then use the objects data to populate uniform variables.

Post WebGL API 2.0, this abstraction could exist as a layer ontop of UBOs which managers the mapping of subscription targets to internal state and the mapping of subscription targets to offsets within the buffer. The UBO would be used to store the active buffer state as well as the uniform location mapping. Clients would be required to state all their subscription targets at once to allocate the appropriate amount of memory. Aside from this small change the implementation is essentially the same, with UBOs replacing Valuebuffers and relevant create, delete, bind methods being replaced. Additionally, the inclusion of UBOs would replace the need for uniformValueBuffer(...).

SUBSCRIBED_VALUES_BUFFER is accepted as the target parameter to bindValuebuffer

SUBSCRIBED_VALUES_BUFFER is accepted as the target parameter to subscribeValuebuffer

MOUSE_POSITION is accepted as the subscription parameter to subscribeValuebuffer

SUBSCRIBED_VALUES_BUFFER is accepted as the target parameter to populateSubscribedValues

SUBSCRIBED_VALUES_BUFFER is accepted as the target parameter to uniformValuebuffer

MOUSE_POSITION is accepted as the subscription parameter to uniformValuebuffer

<script id="vshader" type="x-shader/x-vertex">
  uniform ivec2 uMousePosition;

  void main()
  {
    gl_Position = vec4(uMousePosition, 0, 1);
  }
</script>

function init(gl) {
  shader.uMousePosition = gl.getUniformLocation(shader, "uMousePosition");
  ...

  var ext = gl.getExtension('WEBGL_subscribe_uniform');
    
  // Create the value buffer and subscribe.
  var valuebuffer = ext.createValuebuffer();
  ext.bindValuebuffer(SUBSCRIBED_VALUES_BUFFER, valuebuffer);
  ext.subscribeValue(MOUSE_POSITION);
  ...
}
     
function draw(gl) {   
  // Populate buffer and populate uniform
  ext.bindValuebuffer(SUBSCRIBED_VALUES_BUFFER, valuebuffer);
  ext.populateSubscribedValues(SUBSCRIBED_VALUES_BUFFER);
  ext.uniformValuebuffer(shader.uMousePosition,
                         SUBSCRIBED_VALUES_BUFFER,
                         MOUSE_POSITION);

  gl.drawElements(...);
}
  
Initial revision. Moved to rejected state. Does not have a champion at this point. Was difficult to reason about how to use the extension, given that the on-screen rendering would be farther ahead than the application's state. Seems that the best solution is to focus on reducing the depth, and therefore latency, of the browser's rendering pipeline.