regl
Advanced tools
Comparing version 0.9.0 to 0.10.0
@@ -5,10 +5,8 @@ # Release notes | ||
* Implement a standard method for handling context creation errors | ||
* Add a mechanism for managing webgl extensions | ||
+ Should be able to report errors when extensions are missing | ||
+ Allow users to disable extensions for testing/mocking | ||
* Add a mechanism for users to specify minimum resource requirements (texture size, varying units, etc.) | ||
* Cubic frame buffer objects | ||
* More performance monitoring hooks | ||
+ Track currently used resource requirements | ||
+ Output should be serializable -> works as input to constructor checks | ||
* Context loss | ||
@@ -18,6 +16,3 @@ | ||
* More performance monitoring hooks | ||
+ Track currently used resource requirements | ||
+ Output should be serializable -> works as input to constructor checks | ||
* Add a mechanism for users to specify minimum resource requirements (texture size, varying units, etc.) | ||
* More validation | ||
@@ -46,4 +41,2 @@ + Should not be possible to write regl code that crashes on some systems | ||
+ Constant attributes | ||
+ RAF/regl.frame behavior | ||
+ Initialization pathways | ||
+ General code coverage | ||
@@ -60,9 +53,20 @@ | ||
+ Compound scene | ||
+ Shadow mapping | ||
+ Stencil shadows | ||
+ Point-light shadows(through cubic framebuffers) | ||
+ Turing patterns | ||
+ Asset loading (obj, ply, etc.) | ||
+ Water Reflection(though cubic-framebuffers) | ||
## Next | ||
## 0.10.0 | ||
* Add a mechanism for managing webgl extensions | ||
+ Should be able to report errors when extensions are missing | ||
+ Allow users to disable extensions for testing/mocking | ||
* Doc clean up | ||
* Add more test cases for `regl.read()` and improve validation | ||
* Implement a standard method for handling context creation errors | ||
* Fix several bugs related to `regl.frame` cancellation | ||
## 0.9.0 | ||
@@ -69,0 +73,0 @@ |
@@ -34,6 +34,51 @@ # Build environment | ||
``` | ||
* To run benchmarks, use this command: | ||
* To run the benchmarks, use this command: | ||
``` | ||
npm run bench | ||
npm run bench-node | ||
``` | ||
This will run the benchmarks in `node.js`, and output the results to `stdout` in | ||
json-format. If you want to see prettified benchmarks results, run | ||
``` | ||
npm run bench-node -- --pretty | ||
``` | ||
If you want to run the benchmarks in the browser, just run | ||
``` | ||
npm run bench-browser | ||
``` | ||
If you want to run the benchmarks on a bunch of commits in the history | ||
of the repo, do | ||
``` | ||
npm run bench-history 10 | ||
``` | ||
This script will, starting from the current HEAD, run the benchmarks | ||
through all the 10 latest commits, and write all the benchmark data as json to a | ||
file. | ||
Note that the script will run `git stash` before switching to the old | ||
commits, and then in the end it will switch to the original HEAD and run `git stash pop`, | ||
in order to ensure that no uncommited changes are lost. | ||
Also note that there is a so-called ancestor commit, and the script will NOT run any benchmarks beyond the ancestor commit. This is because that beyond this ancestor commit, the benchmarking environment had not yet been properly | ||
set up, so the benchmarking results produced by these commits should not be used. | ||
Then you can create pretty graphs from the benchmark data outputted | ||
from `bench-history`. Just do | ||
``` | ||
npm run bench-graph bench/bench-result-2f95fbcf3e60dff98c4b.json | ||
``` | ||
where `bench/bench-result-2f95fbcf3e60dff98c4b.json` is the file | ||
outputted by `bench-history`. The script will create an HTML-file with | ||
graphs made with `d3` from the data, and automatically open the HTML-file | ||
in your default browser. | ||
* The easiest way to add a new benchmark is to copy an existing benchmark (see for example `bench/clear.js`), modify it, and add an entry to `bench/list.js` | ||
@@ -40,0 +85,0 @@ |
@@ -1,45 +0,37 @@ | ||
module.exports = function createExtensionCache (gl) { | ||
var check = require('./util/check') | ||
module.exports = function createExtensionCache (gl, config) { | ||
var extensions = {} | ||
function refreshExtensions () { | ||
[ | ||
'oes_texture_float', | ||
'oes_texture_float_linear', | ||
'oes_texture_half_float', | ||
'oes_texture_half_float_linear', | ||
'oes_standard_derivatives', | ||
'oes_element_index_uint', | ||
'oes_fbo_render_mipmap', | ||
function tryLoadExtension (name_) { | ||
check.type(name_, 'string', 'extension name must be string') | ||
var name = name_.toLowerCase() | ||
if (name in extensions) { | ||
return true | ||
} | ||
var ext | ||
try { | ||
ext = extensions[name] = gl.getExtension(name) | ||
} catch (e) {} | ||
return !!ext | ||
} | ||
'webgl_depth_texture', | ||
'webgl_draw_buffers', | ||
'webgl_color_buffer_float', | ||
'ext_texture_filter_anisotropic', | ||
'ext_frag_depth', | ||
'ext_blend_minmax', | ||
'ext_shader_texture_lod', | ||
'ext_color_buffer_half_float', | ||
'ext_srgb', | ||
'ext_disjoint_timer_query', | ||
'angle_instanced_arrays', | ||
'webgl_compressed_texture_s3tc', | ||
'webgl_compressed_texture_atc', | ||
'webgl_compressed_texture_pvrtc', | ||
'webgl_compressed_texture_etc1' | ||
].forEach(function (ext) { | ||
try { | ||
extensions[ext] = gl.getExtension(ext) | ||
} catch (e) {} | ||
}) | ||
for (var i = 0; i < config.extensions.length; ++i) { | ||
var name = config.extensions[i] | ||
if (!tryLoadExtension(name)) { | ||
config.onDestroy() | ||
config.onDone('"' + name + '" extension is not supported by the current WebGL context, try upgrading your system or a different browser') | ||
return null | ||
} | ||
} | ||
refreshExtensions() | ||
config.optionalExtensions.forEach(tryLoadExtension) | ||
return { | ||
extensions: extensions, | ||
refresh: refreshExtensions | ||
refresh: function () { | ||
config.extensions.forEach(tryLoadExtension) | ||
config.optionalExtensions.forEach(tryLoadExtension) | ||
} | ||
} | ||
} |
@@ -23,2 +23,6 @@ var check = require('./util/check') | ||
var GL_HALF_FLOAT_OES = 0x8D61 | ||
var GL_UNSIGNED_BYTE = 0x1401 | ||
var GL_FLOAT = 0x1406 | ||
var GL_RGBA = 0x1908 | ||
@@ -40,2 +44,18 @@ var GL_ALPHA = 0x1906 | ||
// for every texture format, store | ||
// the number of channels | ||
var textureFormatChannels = [] | ||
textureFormatChannels[GL_ALPHA] = 1 | ||
textureFormatChannels[GL_LUMINANCE] = 1 | ||
textureFormatChannels[GL_LUMINANCE_ALPHA] = 2 | ||
textureFormatChannels[GL_RGB] = 3 | ||
textureFormatChannels[GL_RGBA] = 4 | ||
// for every texture type, store | ||
// the size in bytes. | ||
var textureTypeSizes = [] | ||
textureTypeSizes[GL_UNSIGNED_BYTE] = 1 | ||
textureTypeSizes[GL_FLOAT] = 4 | ||
textureTypeSizes[GL_HALF_FLOAT_OES] = 2 | ||
var GL_RGBA4 = 0x8056 | ||
@@ -535,2 +555,4 @@ var GL_RGB5_A1 = 0x8057 | ||
var commonColorAttachmentSize = null | ||
for (i = 0; i < colorAttachments.length; ++i) { | ||
@@ -544,2 +566,18 @@ incRefAndCheckShape(colorAttachments[i], width, height) | ||
'framebuffer color attachment ' + i + ' is invalid') | ||
if (colorAttachments[i] && colorAttachments[i].texture) { | ||
var colorAttachmentSize = | ||
textureFormatChannels[colorAttachments[i].texture._texture.format] * | ||
textureTypeSizes[colorAttachments[i].texture._texture.type] | ||
if (commonColorAttachmentSize === null) { | ||
commonColorAttachmentSize = colorAttachmentSize | ||
} else { | ||
// We need to make sure that all color attachments have the same number of bitplanes | ||
// (that is, the same numer of bits per pixel) | ||
// This is required by the GLES2.0 standard. See the beginning of Chapter 4 in that document. | ||
check(commonColorAttachmentSize === colorAttachmentSize, | ||
'all color attachments much have the same number of bits per pixel.') | ||
} | ||
} | ||
} | ||
@@ -546,0 +584,0 @@ incRefAndCheckShape(depthAttachment, width, height) |
@@ -8,5 +8,17 @@ var check = require('./util/check') | ||
module.exports = function wrapReadPixels (gl, reglPoll, context) { | ||
module.exports = function wrapReadPixels ( | ||
gl, | ||
framebufferState, | ||
reglPoll, | ||
context, | ||
glAttributes) { | ||
function readPixels (input) { | ||
// TODO check framebuffer state supports read | ||
if (framebufferState.current === null) { | ||
check( | ||
glAttributes.preserveDrawingBuffer, | ||
'you must create a webgl context with "preserveDrawingBuffer":true in order to read pixels from the drawing buffer') | ||
} else { | ||
// TODO check framebuffer supports read pixels | ||
} | ||
var x = 0 | ||
@@ -20,5 +32,2 @@ var y = 0 | ||
data = input | ||
} else if (arguments.length === 2) { | ||
width = arguments[0] | 0 | ||
height = arguments[1] | 0 | ||
} else if (input) { | ||
@@ -28,7 +37,20 @@ check.type(input, 'object', 'invalid arguments to regl.read()') | ||
y = input.y | 0 | ||
width = input.width || context.framebufferWidth | ||
height = input.height || context.framebufferHeight | ||
check( | ||
x >= 0 && x < context.framebufferWidth, | ||
'invalid x offset for regl.read') | ||
check( | ||
y >= 0 && y < context.framebufferHeight, | ||
'invalid y offset for regl.read') | ||
width = (input.width || (context.framebufferWidth - x)) | 0 | ||
height = (input.height || (context.framebufferHeight - y)) | 0 | ||
data = input.data || null | ||
} | ||
check( | ||
width > 0 && width + x <= context.framebufferWidth, | ||
'invalid width for read pixels') | ||
check( | ||
height > 0 && height + y <= context.framebufferHeight, | ||
'invalid height for read pixels') | ||
// Update WebGL state | ||
@@ -35,0 +57,0 @@ reglPoll() |
@@ -383,3 +383,3 @@ var check = require('./util/check') | ||
extend(compressedTextureFormats, { | ||
'rgb arc': GL_COMPRESSED_RGB_ATC_WEBGL, | ||
'rgb atc': GL_COMPRESSED_RGB_ATC_WEBGL, | ||
'rgba atc explicit alpha': GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL, | ||
@@ -386,0 +386,0 @@ 'rgba atc interpolated alpha': GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL |
@@ -75,2 +75,22 @@ // Error checking and parameter validation. | ||
var constructorKeys = [ | ||
'gl', | ||
'canvas', | ||
'container', | ||
'attributes', | ||
'pixelRatio', | ||
'extensions', | ||
'optionalExtensions', | ||
'profile', | ||
'onDone' | ||
] | ||
function checkConstructor (obj) { | ||
Object.keys(obj).forEach(function (key) { | ||
if (constructorKeys.indexOf(key) < 0) { | ||
raise('invalid regl constructor argument "' + key + '". must be one of ' + constructorKeys) | ||
} | ||
}) | ||
} | ||
function leftPad (str, n) { | ||
@@ -600,2 +620,3 @@ str = str + '' | ||
commandParameter: checkParameterCommand, | ||
constructor: checkConstructor, | ||
type: checkTypeOf, | ||
@@ -602,0 +623,0 @@ commandType: checkCommandType, |
@@ -11,3 +11,3 @@ /* globals requestAnimationFrame, cancelAnimationFrame */ | ||
next: function (cb) { | ||
setTimeout(cb, 30) | ||
return setTimeout(cb, 16) | ||
}, | ||
@@ -14,0 +14,0 @@ cancel: clearTimeout |
194
lib/webgl.js
// Context and canvas creation helper functions | ||
/*globals HTMLElement,WebGLRenderingContext*/ | ||
var check = require('./util/check') | ||
var extend = require('./util/extend') | ||
function createCanvas (element, options) { | ||
function createCanvas (element, onDone, pixelRatio) { | ||
var canvas = document.createElement('canvas') | ||
var args = getContext(canvas, options) | ||
extend(canvas.style, { | ||
@@ -28,3 +24,2 @@ border: 0, | ||
var scale = +args.options.pixelRatio | ||
function resize () { | ||
@@ -38,4 +33,4 @@ var w = window.innerWidth | ||
} | ||
canvas.width = scale * w | ||
canvas.height = scale * h | ||
canvas.width = pixelRatio * w | ||
canvas.height = pixelRatio * h | ||
extend(canvas.style, { | ||
@@ -49,22 +44,19 @@ width: w + 'px', | ||
var prevDestroy = args.options.onDestroy | ||
args.options = extend(extend({}, args.options), { | ||
onDestroy: function () { | ||
window.removeEventListener('resize', resize) | ||
element.removeChild(canvas) | ||
prevDestroy && prevDestroy() | ||
} | ||
}) | ||
function onDestroy () { | ||
window.removeEventListener('resize', resize) | ||
element.removeChild(canvas) | ||
} | ||
resize() | ||
return args | ||
return { | ||
canvas: canvas, | ||
onDestroy: onDestroy | ||
} | ||
} | ||
function getContext (canvas, options) { | ||
var glOptions = options.glOptions || {} | ||
function createContext (canvas, contexAttributes) { | ||
function get (name) { | ||
try { | ||
return canvas.getContext(name, glOptions) | ||
return canvas.getContext(name, contexAttributes) | ||
} catch (e) { | ||
@@ -74,51 +66,143 @@ return null | ||
} | ||
return ( | ||
get('webgl') || | ||
get('experimental-webgl') || | ||
get('webgl-experimental') | ||
) | ||
} | ||
var gl = get('webgl') || | ||
get('experimental-webgl') || | ||
get('webgl-experimental') | ||
function isHTMLElement (obj) { | ||
return ( | ||
typeof obj.nodeName === 'string' && | ||
typeof obj.appendChild === 'function' && | ||
typeof obj.getBoundingClientRect === 'function' | ||
) | ||
} | ||
check(gl, 'webgl not supported') | ||
function isWebGLContext (obj) { | ||
return ( | ||
typeof obj.drawArrays === 'function' || | ||
typeof obj.drawElements === 'function' | ||
) | ||
} | ||
return { | ||
gl: gl, | ||
options: extend({ | ||
pixelRatio: window.devicePixelRatio | ||
}, options) | ||
function parseExtensions (input) { | ||
if (typeof input === 'string') { | ||
return input.split() | ||
} | ||
check(Array.isArray(input), 'invalid extension array') | ||
return input | ||
} | ||
module.exports = function parseArgs (args) { | ||
if (typeof document === 'undefined' || | ||
typeof HTMLElement === 'undefined') { | ||
return { | ||
gl: args[0], | ||
options: args[1] || {} | ||
function getElement (desc) { | ||
if (typeof desc === 'string') { | ||
check(typeof document !== 'undefined', 'not supported outside of DOM') | ||
return document.querySelector(desc) | ||
} | ||
return desc | ||
} | ||
module.exports = function parseArgs (args_) { | ||
var args = args_ || {} | ||
var element, container, canvas, gl | ||
var contextAttributes = {} | ||
var extensions = [] | ||
var optionalExtensions = [] | ||
var pixelRatio = (typeof window === 'undefined' ? 1 : window.devicePixelRatio) | ||
var profile = false | ||
var onDone = function (err) { | ||
if (err) { | ||
check.raise(err) | ||
} | ||
} | ||
var onDestroy = function () {} | ||
if (typeof args === 'string') { | ||
check( | ||
typeof document !== 'undefined', | ||
'selector queries only supported in DOM enviroments') | ||
element = document.querySelector(args) | ||
check(element, 'invalid query string for element') | ||
} else if (typeof args === 'object') { | ||
if (isHTMLElement(args)) { | ||
element = args | ||
} else if (isWebGLContext(args)) { | ||
gl = args | ||
canvas = gl.canvas | ||
} else { | ||
check.constructor(args) | ||
if ('gl' in args) { | ||
gl = args.gl | ||
} else if ('canvas' in args) { | ||
canvas = getElement(args.canvas) | ||
} else if ('container' in args) { | ||
container = getElement(args.container) | ||
} | ||
if ('attributes' in args) { | ||
contextAttributes = args.attributes | ||
check.type(contextAttributes, 'object', 'invalid context attributes') | ||
} | ||
if ('extensions' in args) { | ||
extensions = parseExtensions(args.extensions) | ||
} | ||
if ('optionalExtensions' in args) { | ||
optionalExtensions = parseExtensions(args.optionalExtensions) | ||
} | ||
if ('onDone' in args) { | ||
check.type( | ||
args.onDone, 'function', | ||
'invalid or missing onDone callback') | ||
onDone = args.onDone | ||
} | ||
if ('profile' in args) { | ||
profile = !!args.profile | ||
} | ||
if ('pixelRatio' in args) { | ||
pixelRatio = +args.pixelRatio | ||
check(pixelRatio > 0, 'invalid pixel ratio') | ||
} | ||
} | ||
} else { | ||
check.raise('invalid arguments to regl') | ||
} | ||
var element = document.body | ||
var options = args[1] || {} | ||
if (element) { | ||
if (element.nodeName.toLowerCase() === 'canvas') { | ||
canvas = element | ||
} else { | ||
container = element | ||
} | ||
} | ||
if (typeof args[0] === 'string') { | ||
element = document.querySelector(args[0]) || document.body | ||
} else if (typeof args[0] === 'object') { | ||
if (args[0] instanceof HTMLElement) { | ||
element = args[0] | ||
} else if (args[0] instanceof WebGLRenderingContext) { | ||
return { | ||
gl: args[0], | ||
options: extend({ | ||
pixelRatio: 1 | ||
}, options) | ||
if (!gl) { | ||
if (!canvas) { | ||
check( | ||
typeof document !== 'undefined', | ||
'must manually specify webgl context outside of DOM environments') | ||
var result = createCanvas(container || document.body, onDone, pixelRatio) | ||
if (!result) { | ||
return null | ||
} | ||
} else { | ||
options = args[0] | ||
canvas = result.canvas | ||
onDestroy = result.onDestroy | ||
} | ||
gl = createContext(canvas, contextAttributes) | ||
} | ||
if (element.nodeName && element.nodeName.toUpperCase() === 'CANVAS') { | ||
return getContext(element, options) | ||
} else { | ||
return createCanvas(element, options) | ||
if (!gl) { | ||
onDestroy() | ||
onDone('webgl not supported, try upgrading your browser or graphics drivers http://get.webgl.org') | ||
return null | ||
} | ||
return { | ||
gl: gl, | ||
canvas: canvas, | ||
container: container, | ||
extensions: extensions, | ||
optionalExtensions: optionalExtensions, | ||
pixelRatio: pixelRatio, | ||
profile: profile, | ||
onDone: onDone, | ||
onDestroy: onDestroy | ||
} | ||
} |
{ | ||
"name": "regl", | ||
"version": "0.9.0", | ||
"version": "0.10.0", | ||
"description": "Regl is a fast functional reactive abstraction for WebGL.", | ||
@@ -23,4 +23,7 @@ "main": "regl.js", | ||
"getusermedia": "^1.3.7", | ||
"git-commits": "^1.2.0", | ||
"git-parse-commit": "^1.0.0", | ||
"gl": "^4.0.1", | ||
"gl-mat4": "^1.1.4", | ||
"gl-vec2": "^1.0.0", | ||
"gl-vec3": "^1.0.3", | ||
@@ -37,2 +40,3 @@ "glob": "^7.0.3", | ||
"parse-dds": "^1.2.1", | ||
"present": "^1.0.0", | ||
"primitive-sphere": "^2.0.0", | ||
@@ -54,7 +58,10 @@ "regl-stats-widget": "0.0.1", | ||
"cover": "istanbul cover test/util/index.js", | ||
"bench": "budo bench/index.js --open", | ||
"bench-browser": "budo bench/bench.js --open", | ||
"bench-node": "node bench/bench.js", | ||
"bench-graph": "node bench/bench-graph.js", | ||
"bench-history": "node bench/bench-history", | ||
"build": "npm run build-script && npm run build-min && npm run build-bench && npm run build-gallery", | ||
"build-script": "browserify regl.js --standalone reglInit > dist/regl.js", | ||
"build-min": "node bin/build-min.js", | ||
"build-bench": "browserify bench/index.js | indexhtmlify > www/bench.html", | ||
"build-bench": "browserify bench/bench.js | indexhtmlify > www/bench.html", | ||
"build-gallery": "node bin/build-gallery.js" | ||
@@ -61,0 +68,0 @@ }, |
@@ -555,6 +555,6 @@ # regl | ||
* [Initialization](API.md#initialization) | ||
* [As a fullscreen canvas](API.md#as-a-fullscreen-canvas) | ||
* [From a container div](API.md#from-a-container-div) | ||
* [From a canvas](API.md#from-a-canvas) | ||
* [From a WebGL context](API.md#from-a-webgl-context) | ||
- [As a fullscreen canvas](API.md#as-a-fullscreen-canvas) | ||
- [From a container div](API.md#from-a-container-div) | ||
- [From a canvas](API.md#from-a-canvas) | ||
- [From a WebGL context](API.md#from-a-webgl-context) | ||
+ [Initialization options](API.md#initialization-options) | ||
@@ -569,3 +569,3 @@ * [Commands](API.md#commands) | ||
- [Props](API.md#props) | ||
- [`this`](API.md#-this-) | ||
- [`this`](API.md#this) | ||
+ [Parameters](API.md#parameters) | ||
@@ -577,2 +577,3 @@ - [Shaders](API.md#shaders) | ||
- [Render target](API.md#render-target) | ||
- [Profiling](API.md#profiling) | ||
- [Depth buffer](API.md#depth-buffer) | ||
@@ -611,3 +612,3 @@ - [Blending](API.md#blending) | ||
- [Destroy](API.md#destroy-4) | ||
+ [Frame buffers](API.md#frame-buffers) | ||
+ [Framebuffers](API.md#framebuffers) | ||
- [Constructor](API.md#constructor-5) | ||
@@ -630,3 +631,3 @@ - [Update](API.md#update-5) | ||
* [Tips](API.md#tips) | ||
+ [Reuse resources (buffers, elements, textures, etc.)](API.md#reuse-resources--buffers--elements--textures--etc-) | ||
+ [Reuse resources (API.mdbuffers, elements, textures, etc.)](API.md#reuse-resources--buffers--elements--textures--etc-) | ||
+ [Preallocate memory](API.md#preallocate-memory) | ||
@@ -633,0 +634,0 @@ + [Debug vs release](API.md#debug-vs-release) |
113
regl.js
@@ -35,11 +35,27 @@ var check = require('./lib/util/check') | ||
module.exports = function wrapREGL () { | ||
var args = initWebGL(Array.prototype.slice.call(arguments)) | ||
var gl = args.gl | ||
var options = args.options | ||
function find (haystack, needle) { | ||
for (var i = 0; i < haystack.length; ++i) { | ||
if (haystack[i] === needle) { | ||
return i | ||
} | ||
} | ||
return -1 | ||
} | ||
module.exports = function wrapREGL (args) { | ||
var config = initWebGL(args) | ||
if (!config) { | ||
return null | ||
} | ||
var gl = config.gl | ||
var glAttributes = gl.getContextAttributes() | ||
var extensionState = wrapExtensions(gl, config) | ||
if (!extensionState) { | ||
return null | ||
} | ||
var stringStore = createStringStore() | ||
var stats = createStats() | ||
var extensionState = wrapExtensions(gl) | ||
var extensions = extensionState.extensions | ||
@@ -61,3 +77,3 @@ var timer = createTimer(gl, extensions) | ||
drawingBufferHeight: HEIGHT, | ||
pixelRatio: options.pixelRatio | ||
pixelRatio: config.pixelRatio | ||
} | ||
@@ -87,3 +103,3 @@ var uniformState = {} | ||
limits, | ||
poll, | ||
function () { core.procs.poll() }, | ||
contextState, | ||
@@ -99,4 +115,2 @@ stats) | ||
stats) | ||
var readPixels = wrapRead(gl, poll, contextState) | ||
var core = createCore( | ||
@@ -116,3 +130,10 @@ gl, | ||
contextState, | ||
timer) | ||
timer, | ||
config) | ||
var readPixels = wrapRead( | ||
gl, | ||
framebufferState, | ||
core.procs.poll, | ||
contextState, | ||
glAttributes) | ||
@@ -123,13 +144,15 @@ var nextState = core.next | ||
var rafCallbacks = [] | ||
var activeRAF = 0 | ||
var activeRAF = null | ||
function handleRAF () { | ||
if (rafCallbacks.length === 0) { | ||
if (timer) { | ||
timer.update() | ||
} | ||
activeRAF = null | ||
return | ||
} | ||
// schedule next animation frame | ||
activeRAF = raf.next(handleRAF) | ||
// increment frame count | ||
contextState.tick += 1 | ||
// Update time | ||
contextState.time = (clock() - START_TIME) / 1000.0 | ||
// poll for changes | ||
@@ -139,5 +162,7 @@ poll() | ||
// fire a callback for all pending rafs | ||
for (var i = 0; i < rafCallbacks.length; ++i) { | ||
for (var i = rafCallbacks.length - 1; i >= 0; --i) { | ||
var cb = rafCallbacks[i] | ||
cb(contextState, null, 0) | ||
if (cb) { | ||
cb(contextState, null, 0) | ||
} | ||
} | ||
@@ -147,2 +172,4 @@ | ||
gl.flush() | ||
// poll GPU timers *after* gl.flush so we don't delay command dispatch | ||
if (timer) { | ||
@@ -155,3 +182,3 @@ timer.update() | ||
if (!activeRAF && rafCallbacks.length > 0) { | ||
handleRAF() | ||
activeRAF = raf.next(handleRAF) | ||
} | ||
@@ -163,3 +190,3 @@ } | ||
raf.cancel(handleRAF) | ||
activeRAF = 0 | ||
activeRAF = null | ||
} | ||
@@ -182,2 +209,3 @@ } | ||
function destroy () { | ||
rafCallbacks.length = 0 | ||
stopRAF() | ||
@@ -201,5 +229,3 @@ | ||
if (options.onDestroy) { | ||
options.onDestroy() | ||
} | ||
config.onDestroy() | ||
} | ||
@@ -314,4 +340,2 @@ | ||
}) | ||
// return REGLCommand | ||
} | ||
@@ -347,16 +371,19 @@ | ||
check.type(cb, 'function', 'regl.frame() callback must be a function') | ||
rafCallbacks.push(cb) | ||
function cancel () { | ||
var index = rafCallbacks.find(function (item) { | ||
return item === cb | ||
}) | ||
if (index < 0) { | ||
return | ||
// FIXME: should we check something other than equals cb here? | ||
// what if a user calls frame twice with the same callback... | ||
// | ||
var i = find(rafCallbacks, cb) | ||
check(i >= 0, 'cannot cancel a frame twice') | ||
function pendingCancel () { | ||
var index = find(rafCallbacks, pendingCancel) | ||
rafCallbacks[index] = rafCallbacks[rafCallbacks.length - 1] | ||
rafCallbacks.length -= 1 | ||
if (rafCallbacks.length <= 0) { | ||
stopRAF() | ||
} | ||
} | ||
rafCallbacks.splice(index, 1) | ||
if (rafCallbacks.length <= 0) { | ||
stopRAF() | ||
} | ||
rafCallbacks[i] = pendingCancel | ||
} | ||
@@ -389,2 +416,4 @@ | ||
function poll () { | ||
contextState.tick += 1 | ||
contextState.time = (clock() - START_TIME) / 1000.0 | ||
pollViewport() | ||
@@ -404,3 +433,3 @@ core.procs.poll() | ||
return extend(compileProcedure, { | ||
var regl = extend(compileProcedure, { | ||
// Clear current FBO | ||
@@ -431,3 +460,3 @@ clear: clear, | ||
// Expose context attributes | ||
attributes: gl.getContextAttributes(), | ||
attributes: glAttributes, | ||
@@ -454,3 +483,3 @@ // Frame rendering | ||
poll: function () { | ||
core.procs.poll() | ||
poll() | ||
if (timer) { | ||
@@ -464,2 +493,6 @@ timer.update() | ||
}) | ||
config.onDone(null, regl) | ||
return regl | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
2540363
102
15036
651
39