diff --git a/Source/Renderer/ShaderCache.js b/Source/Renderer/ShaderCache.js index a2a9e86d7358..22428426d04a 100644 --- a/Source/Renderer/ShaderCache.js +++ b/Source/Renderer/ShaderCache.js @@ -138,6 +138,21 @@ define([ return cachedShader.shaderProgram; }; + ShaderCache.prototype.replaceDerivedShaderProgram = function(shaderProgram, keyword, options) { + var cachedShader = shaderProgram._cachedShader; + var derivedKeyword = keyword + cachedShader.keyword; + var cachedDerivedShader = this._shaders[derivedKeyword]; + if (defined(cachedDerivedShader)) { + destroyShader(this, cachedDerivedShader); + var index = cachedShader.derivedKeywords.indexOf(keyword); + if (index > -1) { + cachedShader.derivedKeywords.splice(index, 1); + } + } + + return this.createDerivedShaderProgram(shaderProgram, keyword, options); + }; + ShaderCache.prototype.getDerivedShaderProgram = function(shaderProgram, keyword) { var cachedShader = shaderProgram._cachedShader; var derivedKeyword = keyword + cachedShader.keyword; diff --git a/Specs/Renderer/ShaderCacheSpec.js b/Specs/Renderer/ShaderCacheSpec.js index 39e05c765e36..0384eb53f257 100644 --- a/Specs/Renderer/ShaderCacheSpec.js +++ b/Specs/Renderer/ShaderCacheSpec.js @@ -193,6 +193,49 @@ defineSuite([ cache.destroy(); }); + it('replaces derived shader program', function() { + var vs = 'attribute vec4 position; void main() { gl_Position = position; }'; + var fs = 'void main() { gl_FragColor = vec4(1.0); }'; + + var cache = new ShaderCache(context); + var sp = cache.getShaderProgram({ + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : { + position : 0 + } + }); + var derivedKeywords = sp._cachedShader.derivedKeywords; + + var keyword = 'derived'; + var fsDerived = 'void main() { gl_FragColor = vec4(vec3(1.0), 0.5); }'; + var spDerived = cache.replaceDerivedShaderProgram(sp, keyword, { + vertexShaderSource : vs, + fragmentShaderSource : fsDerived, + attributeLocations : { + position : 0 + } + }); + + expect(spDerived).toBeDefined(); + expect(derivedKeywords.length).toBe(1); + + var fsDerived2 = 'void main() { gl_FragColor = vec4(vec3(0.5), 0.5); }'; + var spDerived2 = cache.replaceDerivedShaderProgram(sp, keyword, { + vertexShaderSource : vs, + fragmentShaderSource : fsDerived2, + attributeLocations : { + position : 0 + } + }); + + expect(spDerived.isDestroyed()).toBe(true); + expect(spDerived2.isDestroyed()).toBe(false); + expect(derivedKeywords.length).toBe(1); + + cache.destroy(); + }); + it('destroying a shader program destroys its derived shaders', function() { var vs = 'attribute vec4 position; void main() { gl_Position = position; }'; var fs = 'void main() { gl_FragColor = vec4(1.0); }';