aboutsummaryrefslogtreecommitdiff
path: root/src/experimental
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-08-05 09:54:24 -0700
committerAlon Zakai <alonzakai@gmail.com>2012-08-05 21:56:54 -0700
commit82291eb9c6d3fa9cbb1125e0cbf2af392266916b (patch)
tree77c788e5cfc20f6921707bdc08d356059b268830 /src/experimental
parent390e155e6092cf2b198ddaa129448c95d38dee48 (diff)
experimental renderer cache hash diff
Diffstat (limited to 'src/experimental')
-rw-r--r--src/experimental/renderer_cache_hash.diff99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/experimental/renderer_cache_hash.diff b/src/experimental/renderer_cache_hash.diff
new file mode 100644
index 00000000..469e3446
--- /dev/null
+++ b/src/experimental/renderer_cache_hash.diff
@@ -0,0 +1,99 @@
+diff --git a/src/library_gl.js b/src/library_gl.js
+index 4bce0ef..094a961 100644
+--- a/src/library_gl.js
++++ b/src/library_gl.js
+@@ -1386,6 +1386,7 @@ var LibraryGL = {
+ mode: 0,
+
+ rendererCache: {},
++ rendererCacheTemp: [], // temporary item for renderer cache lookups
+ rendererComponents: {}, // small cache for calls inside glBegin/end. counts how many times the element was seen
+ rendererComponentPointer: 0, // next place to start a glBegin/end component
+ lastRenderer: null, // used to avoid cleaning up and re-preparing the same renderer
+@@ -1520,9 +1521,71 @@ var LibraryGL = {
+ },
+
+ getRenderer: function() {
+- // return a renderer object given the liveClientAttributes
+- // we maintain a cache of renderers, optimized to not generate garbage
++ // return a renderer object given the liveClientAttributes and other relevant information about rendering state
+ var attributes = GL.immediate.liveClientAttributes;
++
++
++
++
++
++ var temp = GL.immediate.rendererCacheTemp;
++ temp.length = 0;
++ var hash = 1000;
++ var salt = 0x0149F37A;
++ function add(value) {
++ temp.push(value);
++ hash = (hash*(value+3))^salt;
++ }
++ for (var i = 0; i < attributes.length; i++) {
++ var attribute = attributes[i];
++ add(attribute.name);
++ add(attribute.size);
++ add(attribute.type);
++ }
++ add(GLEmulation.fogEnabled ? GLEmulation.fogMode : 0);
++ if (GL.currProgram) { // Note the order here; this one is last, and optional
++ add(GL.currProgram);
++ }
++ var cache = GL.immediate.rendererCache;
++ function isCorrect(item) {
++ if (item.hash != hash) return false;
++ if (item.id.length != temp.length) return false;
++ var length = temp.length;
++ var existing = item.id;
++ for (var i = 0; i < length; i++) {
++ if (existing[i] != temp[i]) {
++ return false;
++ }
++ }
++ return true;
++ }
++ var seek = hash;
++ var item;
++ while ((item = cache[seek]) && !isCorrect(item)) {
++ Module.printErr('cache collision!');
++ seek++;
++ }
++ if (item) return item.renderer;
++#if GL_DEBUG
++ Module.printErr('generating renderer for ' + JSON.stringify(attributes));
++#endif
++ var renderer = this.createRenderer();
++ cache[seek] = {
++ id: temp.slice(0),
++ hash: hash,
++ renderer: renderer
++ };
++ return renderer;
++
++
++
++
++
++
++
++
++
++ // we maintain a cache of renderers, optimized to not generate garbage
+ var cacheItem = GL.immediate.rendererCache;
+ for (var i = 0; i < attributes.length; i++) {
+ var attribute = attributes[i];
+@@ -1544,6 +1607,12 @@ var LibraryGL = {
+ if (!cacheItem[GL.currProgram]) cacheItem[GL.currProgram] = {};
+ cacheItem = cacheItem[GL.currProgram];
+ }
++
++
++
++
++
++
+ if (!cacheItem.renderer) {
+ #if GL_DEBUG
+ Module.printErr('generating renderer for ' + JSON.stringify(attributes));