Skip to content
This repository was archived by the owner on Nov 7, 2023. It is now read-only.

Commit b011dce

Browse files
committed
Merge pull request #83 from OpenGeoscience/cache-shaders
Cache shaders.
2 parents a021f15 + 27c4327 commit b011dce

2 files changed

Lines changed: 70 additions & 70 deletions

File tree

src/shader.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,45 @@ vgl.shader = function (type) {
115115
};
116116

117117
inherit(vgl.shader, vgl.object);
118+
119+
120+
/* We can use the same shader multiple times if it is identical. This caches
121+
* the last N shaders and will reuse them when possible. The cache keeps the
122+
* most recently requested shader at the front. If you are doing anything more
123+
* to a shader then creating it and setting its source once, do not use this
124+
* cache.
125+
*/
126+
(function () {
127+
'use strict';
128+
var m_shaderCache = [],
129+
m_shaderCacheMaxSize = 10;
130+
131+
/////////////////////////////////////////////////////////////////////////////
132+
/**
133+
* Get a shader from the cache. Create a new shader if necessary using a
134+
* specific source.
135+
*
136+
* @param type One of vgl.GL.*_SHADER
137+
* @param {string} source the source code of the shader.
138+
*/
139+
/////////////////////////////////////////////////////////////////////////////
140+
vgl.getCachedShader = function (type, source) {
141+
for (var i = 0; i < m_shaderCache.length; i += 1) {
142+
if (m_shaderCache[i].type === type &&
143+
m_shaderCache[i].source === source) {
144+
if (i) {
145+
m_shaderCache.splice(0, 0, m_shaderCache.splice(i, 1)[0]);
146+
}
147+
return m_shaderCache[0].shader;
148+
}
149+
}
150+
var shader = new vgl.shader(type);
151+
shader.setShaderSource(source);
152+
m_shaderCache.unshift({type: type, source: source, shader: shader});
153+
if (m_shaderCache.length >= m_shaderCacheMaxSize) {
154+
m_shaderCache.splice(m_shaderCacheMaxSize,
155+
m_shaderCache.length - m_shaderCacheMaxSize);
156+
}
157+
return shader;
158+
};
159+
})();

src/utils.js

Lines changed: 28 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,8 @@ vgl.utils.createTextureVertexShader = function (context) {
7272
'{',
7373
'gl_PointSize = pointSize;',
7474
'gl_Position = projectionMatrix * modelViewMatrix * vec4(vertexPosition, 1.0);',
75-
' iTextureCoord = textureCoord;', '}'].join('\n'),
76-
shader = new vgl.shader(vgl.GL.VERTEX_SHADER);
77-
shader.setShaderSource(vertexShaderSource);
78-
return shader;
75+
' iTextureCoord = textureCoord;', '}'].join('\n');
76+
return vgl.getCachedShader(vgl.GL.VERTEX_SHADER, vertexShaderSource);
7977
};
8078

8179
//////////////////////////////////////////////////////////////////////////////
@@ -98,11 +96,8 @@ vgl.utils.createTextureFragmentShader = function (context) {
9896
'void main(void) {',
9997
'gl_FragColor = vec4(texture2D(sampler2d, vec2(iTextureCoord.s, ' +
10098
'iTextureCoord.t)).xyz, opacity);',
101-
'}'].join('\n'),
102-
shader = new vgl.shader(vgl.GL.FRAGMENT_SHADER);
103-
104-
shader.setShaderSource(fragmentShaderSource);
105-
return shader;
99+
'}'].join('\n');
100+
return vgl.getCachedShader(vgl.GL.FRAGMENT_SHADER, fragmentShaderSource);
106101
};
107102

108103
//////////////////////////////////////////////////////////////////////////////
@@ -128,11 +123,8 @@ vgl.utils.createRgbaTextureFragmentShader = function (context) {
128123
' color.w *= opacity;',
129124
' gl_FragColor = color;',
130125
'}'
131-
].join('\n'),
132-
shader = new vgl.shader(vgl.GL.FRAGMENT_SHADER);
133-
134-
shader.setShaderSource(fragmentShaderSource);
135-
return shader;
126+
].join('\n');
127+
return vgl.getCachedShader(vgl.GL.FRAGMENT_SHADER, fragmentShaderSource);
136128
};
137129

138130
//////////////////////////////////////////////////////////////////////////////
@@ -160,11 +152,8 @@ vgl.utils.createVertexShader = function (context) {
160152
'{',
161153
'gl_PointSize = pointSize;',
162154
'gl_Position = projectionMatrix * modelViewMatrix * vec4(vertexPosition, 1.0);',
163-
' iVertexColor = vertexColor;', '}'].join('\n'),
164-
shader = new vgl.shader(vgl.GL.VERTEX_SHADER);
165-
166-
shader.setShaderSource(vertexShaderSource);
167-
return shader;
155+
' iVertexColor = vertexColor;', '}'].join('\n');
156+
return vgl.getCachedShader(vgl.GL.VERTEX_SHADER, vertexShaderSource);
168157
};
169158

170159
//////////////////////////////////////////////////////////////////////////////
@@ -192,11 +181,8 @@ vgl.utils.createPointVertexShader = function (context) {
192181
'{',
193182
'gl_PointSize = vertexSize;',
194183
'gl_Position = projectionMatrix * modelViewMatrix * vec4(vertexPosition, 1.0);',
195-
' iVertexColor = vertexColor;', '}'].join('\n'),
196-
shader = new vgl.shader(vgl.GL.VERTEX_SHADER);
197-
198-
shader.setShaderSource(vertexShaderSource);
199-
return shader;
184+
' iVertexColor = vertexColor;', '}'].join('\n');
185+
return vgl.getCachedShader(vgl.GL.VERTEX_SHADER, vertexShaderSource);
200186
};
201187

202188
//////////////////////////////////////////////////////////////////////////////
@@ -221,11 +207,8 @@ vgl.utils.createVertexShaderSolidColor = function (context) {
221207
'{',
222208
'gl_PointSize = pointSize;',
223209
'gl_Position = projectionMatrix * modelViewMatrix * vec4(vertexPosition, 1.0);',
224-
'}'].join('\n'),
225-
shader = new vgl.shader(vgl.GL.VERTEX_SHADER);
226-
227-
shader.setShaderSource(vertexShaderSource);
228-
return shader;
210+
'}'].join('\n');
211+
return vgl.getCachedShader(vgl.GL.VERTEX_SHADER, vertexShaderSource);
229212
};
230213

231214
//////////////////////////////////////////////////////////////////////////////
@@ -258,11 +241,8 @@ vgl.utils.createVertexShaderColorMap = function (context, min, max) {
258241
'gl_PointSize = pointSize;',
259242
'gl_Position = projectionMatrix * modelViewMatrix * vec4(vertexPosition, 1.0);',
260243
'iVertexScalar = (vertexScalar-lutMin)/(lutMax-lutMin);',
261-
'}'].join('\n'),
262-
shader = new vgl.shader(vgl.GL.VERTEX_SHADER);
263-
264-
shader.setShaderSource(vertexShaderSource);
265-
return shader;
244+
'}'].join('\n');
245+
return vgl.getCachedShader(vgl.GL.VERTEX_SHADER, vertexShaderSource);
266246
};
267247

268248
//////////////////////////////////////////////////////////////////////////////
@@ -282,11 +262,8 @@ vgl.utils.createFragmentShader = function (context) {
282262
'uniform mediump float opacity;',
283263
'void main(void) {',
284264
'gl_FragColor = vec4(iVertexColor, opacity);',
285-
'}'].join('\n'),
286-
shader = new vgl.shader(vgl.GL.FRAGMENT_SHADER);
287-
288-
shader.setShaderSource(fragmentShaderSource);
289-
return shader;
265+
'}'].join('\n');
266+
return vgl.getCachedShader(vgl.GL.FRAGMENT_SHADER, fragmentShaderSource);
290267
};
291268

292269
//////////////////////////////////////////////////////////////////////////////
@@ -322,13 +299,8 @@ vgl.utils.createPhongVertexShader = function (context) {
322299
'gl_Position = projectionMatrix * varPosition;',
323300
'varNormal = vec3(normalMatrix * vec4(vertexNormal, 0.0));',
324301
'varVertexColor = vertexColor;',
325-
'}'].join('\n'),
326-
327-
shader = new vgl.shader(vgl.GL.VERTEX_SHADER);
328-
329-
shader.setShaderSource(vertexShaderSource);
330-
331-
return shader;
302+
'}'].join('\n');
303+
return vgl.getCachedShader(vgl.GL.VERTEX_SHADER, vertexShaderSource);
332304
};
333305

334306
//////////////////////////////////////////////////////////////////////////////
@@ -368,11 +340,8 @@ vgl.utils.createPhongFragmentShader = function (context) {
368340
' color = lambertian * varVertexColor;',
369341
'}',
370342
'gl_FragColor = vec4(color * opacity, 1.0 - opacity);',
371-
'}'].join('\n'),
372-
shader = new vgl.shader(vgl.GL.FRAGMENT_SHADER);
373-
374-
shader.setShaderSource(fragmentShaderSource);
375-
return shader;
343+
'}'].join('\n');
344+
return vgl.getCachedShader(vgl.GL.FRAGMENT_SHADER, fragmentShaderSource);
376345
};
377346

378347

@@ -392,11 +361,8 @@ vgl.utils.createFragmentShaderSolidColor = function (context, color) {
392361
'uniform mediump float opacity;',
393362
'void main(void) {',
394363
'gl_FragColor = vec4(' + color[0] + ',' + color[1] + ',' + color[2] + ', opacity);',
395-
'}'].join('\n'),
396-
shader = new vgl.shader(vgl.GL.FRAGMENT_SHADER);
397-
398-
shader.setShaderSource(fragmentShaderSource);
399-
return shader;
364+
'}'].join('\n');
365+
return vgl.getCachedShader(vgl.GL.FRAGMENT_SHADER, fragmentShaderSource);
400366
};
401367

402368
//////////////////////////////////////////////////////////////////////////////
@@ -419,11 +385,8 @@ vgl.utils.createFragmentShaderColorMap = function (context) {
419385
'void main(void) {',
420386
'gl_FragColor = vec4(texture2D(sampler2d, vec2(iVertexScalar, ' +
421387
'0.0)).xyz, opacity);',
422-
'}'].join('\n'),
423-
shader = new vgl.shader(vgl.GL.FRAGMENT_SHADER);
424-
425-
shader.setShaderSource(fragmentShaderSource);
426-
return shader;
388+
'}'].join('\n');
389+
return vgl.getCachedShader(vgl.GL.FRAGMENT_SHADER, fragmentShaderSource);
427390
};
428391

429392
//////////////////////////////////////////////////////////////////////////////
@@ -457,10 +420,8 @@ vgl.utils.createPointSpritesVertexShader = function (context) {
457420
'iVertexScalar = vertexPosition.z;',
458421
'gl_Position = projectionMatrix * modelViewMatrix * ' +
459422
'vec4(vertexPosition.xy, height, 1.0);',
460-
' iVertexColor = vertexColor;', '}'].join('\n'),
461-
shader = new vgl.shader(vgl.GL.VERTEX_SHADER);
462-
shader.setShaderSource(vertexShaderSource);
463-
return shader;
423+
' iVertexColor = vertexColor;', '}'].join('\n');
424+
return vgl.getCachedShader(vgl.GL.VERTEX_SHADER, vertexShaderSource);
464425
};
465426

466427
//////////////////////////////////////////////////////////////////////////////
@@ -504,11 +465,8 @@ vgl.utils.createPointSpritesFragmentShader = function (context) {
504465
'} else {',
505466
' gl_FragColor = vec4(texture2D(opacityLookup, realTexCoord).xyz, texOpacity);',
506467
'}}'
507-
].join('\n'),
508-
shader = new vgl.shader(vgl.GL.FRAGMENT_SHADER);
509-
510-
shader.setShaderSource(fragmentShaderSource);
511-
return shader;
468+
].join('\n');
469+
return vgl.getCachedShader(vgl.GL.FRAGMENT_SHADER, fragmentShaderSource);
512470
};
513471

514472
//////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)