From 87c456cd78cba6ffc7cdbaa5de0e90d7a05f98dd Mon Sep 17 00:00:00 2001 From: Danilo Neves Cruz Date: Sat, 2 Sep 2017 03:59:59 -0300 Subject: [PATCH 1/3] fix cc.GLProgramState.apply --- cocos2d/shaders/CCGLProgramState.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/cocos2d/shaders/CCGLProgramState.js b/cocos2d/shaders/CCGLProgramState.js index 0a9cef01cb..80e25b3ade 100644 --- a/cocos2d/shaders/CCGLProgramState.js +++ b/cocos2d/shaders/CCGLProgramState.js @@ -43,7 +43,6 @@ cc.UniformValue = function (uniform, glprogram) { this._glprogram = glprogram; this._value = null; - this._currentBoundValue = null; this._type = -1; }; @@ -105,12 +104,6 @@ cc.UniformValue.prototype = { }, apply: function apply() { - if (this._currentBoundValue === this._value - && this._type !== types.GL_CALLBACK) { - return; - } - - this._currentBoundValue = this._value; switch (this._type) { case types.GL_INT: this._glprogram.setUniformLocationWith1i(this._uniform.location, this._value); @@ -180,10 +173,7 @@ cc.GLProgramState.prototype = { } for (var i = 0; i < this._uniforms.length; ++i) { - var uniform = this._uniforms[i]; - if (uniform._currentBoundValue !== uniform._value) { - uniform.apply(); - } + this._uniforms[i].apply(); } }, From 444c237e145fba57785f9128bce53afb3fa9cb29 Mon Sep 17 00:00:00 2001 From: Danilo Neves Cruz Date: Sat, 2 Sep 2017 21:35:32 -0300 Subject: [PATCH 2/3] fix cc.GLProgram uniform cache --- cocos2d/shaders/CCGLProgram.js | 327 +++++++++++++++++----------- cocos2d/shaders/CCGLProgramState.js | 69 +++--- 2 files changed, 222 insertions(+), 174 deletions(-) diff --git a/cocos2d/shaders/CCGLProgram.js b/cocos2d/shaders/CCGLProgram.js index 8708db54f5..67e23db2d7 100644 --- a/cocos2d/shaders/CCGLProgram.js +++ b/cocos2d/shaders/CCGLProgram.js @@ -42,28 +42,22 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ _projectionUpdated: -1, // Uniform cache - _updateUniformLocation: function (location) { - if (!location) + _updateUniform: function (name) { + if (!name) return false; - var updated; - var element = this._hashForUniforms[location]; - - if (!element) { - element = [ - arguments[1], - arguments[2], - arguments[3], - arguments[4] - ]; - this._hashForUniforms[location] = element; + var updated = false; + var element = this._hashForUniforms[name]; + var args = Array.isArray(arguments[1]) ? arguments[1] : + Array.prototype.slice.call(arguments, 1); + + if (!element || element.length !== args.length) { + this._hashForUniforms[name] = args.slice(); updated = true; } else { - updated = false; - var count = arguments.length - 1; - for (var i = 0; i < count; ++i) { - if (arguments[i + 1] !== element[i]) { - element[i] = arguments[i + 1]; + for (var i = 0; i < args.length; i += 1) { + if (args[i] !== element[i]) { + element[i] = args[i]; updated = true; } } @@ -169,9 +163,7 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ if (this._fragShader) locGL.attachShader(this._programObj, this._fragShader); - for (var key in this._hashForUniforms) { - delete this._hashForUniforms[key]; - } + if (Object.keys(this._hashForUniforms).length > 0) this._hashForUniforms = {}; cc.checkGLErrorDebug(); return true; @@ -231,7 +223,7 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ } this._glContext.linkProgram(this._programObj); - + if (this._vertShader) this._glContext.deleteShader(this._vertShader); if (this._fragShader) @@ -268,18 +260,13 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * cc.UNIFORM_SAMPLER */ updateUniforms: function () { - this._uniforms[cc.UNIFORM_PMATRIX_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_PMATRIX_S); - this._uniforms[cc.UNIFORM_MVMATRIX_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_MVMATRIX_S); - this._uniforms[cc.UNIFORM_MVPMATRIX_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_MVPMATRIX_S); - this._uniforms[cc.UNIFORM_TIME_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_TIME_S); - this._uniforms[cc.UNIFORM_SINTIME_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_SINTIME_S); - this._uniforms[cc.UNIFORM_COSTIME_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_COSTIME_S); - + [cc.UNIFORM_PMATRIX_S, cc.UNIFORM_MVMATRIX_S, cc.UNIFORM_MVPMATRIX_S, + cc.UNIFORM_TIME_S, cc.UNIFORM_SINTIME_S, cc.UNIFORM_COSTIME_S, + cc.UNIFORM_RANDOM01_S, cc.UNIFORM_SAMPLER_S].forEach(function(name) { + this._addUniformLocation(name); + }.bind(this)); this._usesTime = (this._uniforms[cc.UNIFORM_TIME_S] != null || this._uniforms[cc.UNIFORM_SINTIME_S] != null || this._uniforms[cc.UNIFORM_COSTIME_S] != null); - this._uniforms[cc.UNIFORM_RANDOM01_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_RANDOM01_S); - this._uniforms[cc.UNIFORM_SAMPLER_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_SAMPLER_S); - this.use(); // Since sample most probably won't change, set it to 0 now. this.setUniformLocationWith1i(this._uniforms[cc.UNIFORM_SAMPLER_S], 0); @@ -287,7 +274,9 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ _addUniformLocation: function (name) { var location = this._glContext.getUniformLocation(this._programObj, name); + if (location) location._name = name; this._uniforms[name] = location; + return location; }, /** @@ -301,7 +290,7 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ if (!this._programObj) throw new Error("cc.GLProgram.getUniformLocationForName(): Invalid operation. Cannot get uniform location when program is not initialized"); - var location = this._uniforms[name] || this._glContext.getUniformLocation(this._programObj, name); + var location = this._uniforms[name] || this._addUniformLocation(name); return location; }, @@ -327,16 +316,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} i1 */ setUniformLocationWith1i: function (location, i1) { - var gl = this._glContext; - if (typeof location === 'string') { - var updated = this._updateUniformLocation(location, i1); - if (updated) { - var locObj = this.getUniformLocationForName(location); - gl.uniform1i(locObj, i1); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, i1)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform1i(location, i1); } - } - else { - gl.uniform1i(location, i1); + } else { + this._glContext.uniform1i(location, i1); } }, @@ -347,16 +335,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} i2 */ setUniformLocationWith2i: function (location, i1, i2) { - var gl = this._glContext; - if (typeof location === 'string') { - var updated = this._updateUniformLocation(location, i1, i2); - if (updated) { - var locObj = this.getUniformLocationForName(location); - gl.uniform2i(locObj, i1, i2); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, i1, i2)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform2i(location, i1, i2); } - } - else { - gl.uniform2i(location, i1, i2); + } else { + this._glContext.uniform2i(location, i1, i2); } }, @@ -368,16 +355,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} i3 */ setUniformLocationWith3i: function (location, i1, i2, i3) { - var gl = this._glContext; - if (typeof location === 'string') { - var updated = this._updateUniformLocation(location, i1, i2, i3); - if (updated) { - var locObj = this.getUniformLocationForName(location); - gl.uniform3i(locObj, i1, i2, i3); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, i1, i2, i3)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform3i(location, i1, i2, i3); } - } - else { - gl.uniform3i(location, i1, i2, i3); + } else { + this._glContext.uniform3i(location, i1, i2, i3); } }, @@ -390,16 +376,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} i4 */ setUniformLocationWith4i: function (location, i1, i2, i3, i4) { - var gl = this._glContext; - if (typeof location === 'string') { - var updated = this._updateUniformLocation(location, i1, i2, i3, i4); - if (updated) { - var locObj = this.getUniformLocationForName(location); - gl.uniform4i(locObj, i1, i2, i3, i4); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, i1, i2, i3, i4)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform4i(location, i1, i2, i3, i4); } - } - else { - gl.uniform4i(location, i1, i2, i3, i4); + } else { + this._glContext.uniform4i(location, i1, i2, i3, i4); } }, @@ -410,8 +395,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} numberOfArrays */ setUniformLocationWith2iv: function (location, intArray) { - var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location; - this._glContext.uniform2iv(locObj, intArray); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, intArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform2iv(location, intArray); + } + } else { + this._glContext.uniform2iv(location, intArray); + } }, /** @@ -420,8 +413,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Int32Array} intArray */ setUniformLocationWith3iv: function (location, intArray) { - var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location; - this._glContext.uniform3iv(locObj, intArray); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, intArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform3iv(location, intArray); + } + } else { + this._glContext.uniform3iv(location, intArray); + } }, /** @@ -430,8 +431,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Int32Array} intArray */ setUniformLocationWith4iv: function (location, intArray) { - var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location; - this._glContext.uniform4iv(locObj, intArray); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, intArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform4iv(location, intArray); + } + } else { + this._glContext.uniform4iv(location, intArray); + } }, /** @@ -449,16 +458,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} f1 */ setUniformLocationWith1f: function (location, f1) { - var gl = this._glContext; - if (typeof location === 'string') { - var updated = this._updateUniformLocation(location, f1); - if (updated) { - var locObj = this.getUniformLocationForName(location); - gl.uniform1f(locObj, f1); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, f1)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform1f(location, f1); } - } - else { - gl.uniform1f(location, f1); + } else { + this._glContext.uniform1f(location, f1); } }, @@ -469,16 +477,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} f2 */ setUniformLocationWith2f: function (location, f1, f2) { - var gl = this._glContext; - if (typeof location === 'string') { - var updated = this._updateUniformLocation(location, f1, f2); - if (updated) { - var locObj = this.getUniformLocationForName(location); - gl.uniform2f(locObj, f1, f2); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, f1, f2)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform2f(location, f1, f2); } - } - else { - gl.uniform2f(location, f1, f2); + } else { + this._glContext.uniform2f(location, f1, f2); } }, @@ -490,16 +497,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} f3 */ setUniformLocationWith3f: function (location, f1, f2, f3) { - var gl = this._glContext; - if (typeof location === 'string') { - var updated = this._updateUniformLocation(location, f1, f2, f3); - if (updated) { - var locObj = this.getUniformLocationForName(location); - gl.uniform3f(locObj, f1, f2, f3); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, f1, f2, f3)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform3f(location, f1, f2, f3); } - } - else { - gl.uniform3f(location, f1, f2, f3); + } else { + this._glContext.uniform3f(location, f1, f2, f3); } }, @@ -512,16 +518,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} f4 */ setUniformLocationWith4f: function (location, f1, f2, f3, f4) { - var gl = this._glContext; - if (typeof location === 'string') { - var updated = this._updateUniformLocation(location, f1, f2, f3, f4); - if (updated) { - var locObj = this.getUniformLocationForName(location); - gl.uniform4f(locObj, f1, f2, f3, f4); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, f1, f2, f3, f4)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform4f(location, f1, f2, f3, f4); } - } - else { - gl.uniform4f(location, f1, f2, f3, f4); + } else { + this._glContext.uniform4f(location, f1, f2, f3, f4); + cc.log('uniform4f', f1, f2, f3, f4); } }, @@ -531,8 +537,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Float32Array} floatArray */ setUniformLocationWith2fv: function (location, floatArray) { - var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location; - this._glContext.uniform2fv(locObj, floatArray); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, floatArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform2fv(location, floatArray); + } + } else { + this._glContext.uniform2fv(location, floatArray); + } }, /** @@ -541,8 +555,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Float32Array} floatArray */ setUniformLocationWith3fv: function (location, floatArray) { - var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location; - this._glContext.uniform3fv(locObj, floatArray); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, floatArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform3fv(location, floatArray); + } + } else { + this._glContext.uniform3fv(location, floatArray); + } }, /** @@ -551,17 +573,53 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Float32Array} floatArray */ setUniformLocationWith4fv: function (location, floatArray) { - var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location; - this._glContext.uniform4fv(locObj, floatArray); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, floatArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform4fv(location, floatArray); + } + } else { + this._glContext.uniform4fv(location, floatArray); + cc.log('uniform4fv', floatArray); + } }, + + /** + * calls glUniformMatrix2fv + * @param {WebGLUniformLocation|String} location + * @param {Float32Array} matrixArray + */ + setUniformLocationWithMatrix2fv: function (location, matrixArray) { + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, matrixArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniformMatrix2fv(location, false, matrixArray); + } + } else { + this._glContext.uniformMatrix2fv(location, false, matrixArray); + } + }, + /** * calls glUniformMatrix3fv * @param {WebGLUniformLocation|String} location * @param {Float32Array} matrixArray */ setUniformLocationWithMatrix3fv: function (location, matrixArray) { - var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location; - this._glContext.uniformMatrix3fv(locObj, false, matrixArray); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, matrixArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniformMatrix3fv(location, false, matrixArray); + } + } else { + this._glContext.uniformMatrix3fv(location, false, matrixArray); + } }, /** @@ -570,8 +628,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Float32Array} matrixArray */ setUniformLocationWithMatrix4fv: function (location, matrixArray) { - var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location; - this._glContext.uniformMatrix4fv(locObj, false, matrixArray); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, matrixArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniformMatrix4fv(location, false, matrixArray); + } + } else { + this._glContext.uniformMatrix4fv(location, false, matrixArray); + } }, setUniformLocationF32: function () { @@ -664,25 +730,25 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * will update the MVP matrix on the MVP uniform if it is different than the previous call for this same shader program. */ setUniformForModelViewProjectionMatrix: function () { - this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_MVPMATRIX_S], false, + this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVPMATRIX_S], cc.getMat4MultiplyValue(cc.projection_matrix_stack.top, cc.modelview_matrix_stack.top)); }, setUniformForModelViewProjectionMatrixWithMat4: function (swapMat4) { cc.kmMat4Multiply(swapMat4, cc.projection_matrix_stack.top, cc.modelview_matrix_stack.top); - this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_MVPMATRIX_S], false, swapMat4.mat); + this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVPMATRIX_S], swapMat4.mat); }, setUniformForModelViewAndProjectionMatrixWithMat4: function () { - this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_MVMATRIX_S], false, cc.modelview_matrix_stack.top.mat); - this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], false, cc.projection_matrix_stack.top.mat); + this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVMATRIX_S], cc.modelview_matrix_stack.top.mat); + this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], cc.projection_matrix_stack.top.mat); }, _setUniformForMVPMatrixWithMat4: function (modelViewMatrix) { if (!modelViewMatrix) throw new Error("modelView matrix is undefined."); - this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_MVMATRIX_S], false, modelViewMatrix.mat); - this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], false, cc.projection_matrix_stack.top.mat); + this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVMATRIX_S], modelViewMatrix.mat); + this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], cc.projection_matrix_stack.top.mat); }, _updateProjectionUniform: function () { @@ -748,7 +814,7 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ reset: function () { this._vertShader = null; this._fragShader = null; - this._uniforms.length = 0; + if (Object.keys(this._uniforms).length > 0) this._uniforms = {}; // it is already deallocated by android //ccGLDeleteProgram(m_uProgram); @@ -756,10 +822,7 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ this._programObj = null; // Purge uniform hash - for (var key in this._hashForUniforms) { - this._hashForUniforms[key].length = 0; - delete this._hashForUniforms[key]; - } + if (Object.keys(this._hashForUniforms).length > 0) this._hashForUniforms = {}; }, /** diff --git a/cocos2d/shaders/CCGLProgramState.js b/cocos2d/shaders/CCGLProgramState.js index 80e25b3ade..2e9ec348ee 100644 --- a/cocos2d/shaders/CCGLProgramState.js +++ b/cocos2d/shaders/CCGLProgramState.js @@ -24,7 +24,7 @@ THE SOFTWARE. ****************************************************************************/ -var types = +var types = { GL_FLOAT: 0, GL_INT: 1, @@ -50,7 +50,7 @@ cc.UniformValue.prototype = { setFloat: function setFloat(value) { this._value = value; this._type = types.GL_FLOAT; - }, + }, setInt: function setInt(value) { this._value = value; @@ -106,30 +106,28 @@ cc.UniformValue.prototype = { apply: function apply() { switch (this._type) { case types.GL_INT: - this._glprogram.setUniformLocationWith1i(this._uniform.location, this._value); + this._glprogram.setUniformLocationWith1i(this._uniform._location, this._value); break; case types.GL_FLOAT: - this._glprogram.setUniformLocationWith1f(this._uniform.location, this._value); + this._glprogram.setUniformLocationWith1f(this._uniform._location, this._value); break; case types.GL_FLOAT_VEC2: - this._glprogram.setUniformLocationWith2f(this._uniform.location, this._value[0], this._value[1]); + this._glprogram.setUniformLocationWith2fv(this._uniform._location, this._value); break; case types.GL_FLOAT_VEC3: - this._glprogram.setUniformLocationWith3f(this._uniform.location, this._value[0], - this._value[1], this._value[2]); + this._glprogram.setUniformLocationWith3fv(this._uniform._location, this._value); break; case types.GL_FLOAT_VEC4: - this._glprogram.setUniformLocationWith4f(this._uniform.location, this._value[0], - this._value[1], this._value[2], this._value[3]); + this._glprogram.setUniformLocationWith4fv(this._uniform._location, this._value); break; case types.GL_FLOAT_MAT4: - this._glprogram.setUniformLocationWithMatrix4fv(this._uniform.location, this._value); + this._glprogram.setUniformLocationWithMatrix4fv(this._uniform._location, this._value); break; case types.GL_CALLBACK: this._value(this._glprogram, this._uniform); break; case types.GL_TEXTURE: - this._glprogram.setUniformLocationWith1i(this._uniform.location, this._value); + this._glprogram.setUniformLocationWith1i(this._uniform._location, this._value); cc.glBindTexture2DN(this._value, this._textureId); break; default: @@ -140,27 +138,20 @@ cc.UniformValue.prototype = { cc.GLProgramState = function (glprogram) { this._glprogram = glprogram; - this._uniforms = []; - this._uniformsByName = {}; - this._uniformsByLocation = {}; + this._uniforms = {}; this._boundTextureUnits = {}; this._textureUnitIndex = 1; // Start at 1, as CC_Texture0 is bound to 0 var activeUniforms = glprogram._glContext.getProgramParameter(glprogram._programObj, glprogram._glContext.ACTIVE_UNIFORMS); - var count = 0; - for (var i = 0; i < activeUniforms; ++i) { - var uniform = glprogram._glContext.getActiveUniform(glprogram._programObj, i); + for (var i = 0; i < activeUniforms; i += 1) { + var uniform = glprogram._glContext.getActiveUniform(glprogram._programObj, i); if (uniform.name.indexOf("CC_") !== 0) { - uniform.location = glprogram._glContext.getUniformLocation(glprogram._programObj, - uniform.name); - uniform.name = uniform.name.replace("[]", ""); + uniform._location = glprogram._glContext.getUniformLocation(glprogram._programObj, uniform.name); + uniform._location._name = uniform.name; var uniformValue = new cc.UniformValue(uniform, glprogram); - this._uniforms.push(uniformValue); - this._uniformsByName[uniform.name] = count; - this._uniformsByLocation[uniform.location] = count; - count++; + this._uniforms[uniform.name] = uniformValue; } } }; @@ -171,10 +162,10 @@ cc.GLProgramState.prototype = { if (modelView) { this._glprogram._setUniformForMVPMatrixWithMat4(modelView); } - - for (var i = 0; i < this._uniforms.length; ++i) { - this._uniforms[i].apply(); - } + + Object.values(this._uniforms).forEach(function(uniform) { + uniform.apply(); + }); }, setGLProgram: function setGLProgram(glprogram) { @@ -189,16 +180,10 @@ cc.GLProgramState.prototype = { return this._uniforms.length; }, - getUniformValue: function getUniformValue(uniform) - { - if (typeof uniform === 'string') { - return this._uniforms[this._uniformsByName[uniform]]; - } else { - return this._uniforms[this._uniformsByLocation[uniform]]; - } + getUniformValue: function getUniformValue(uniform) { + return this._uniforms[uniform]; }, - // Accepts either string or uniform location setUniformInt: function setUniformInt(uniform, value) { var v = this.getUniformValue(uniform); if (v) { @@ -225,7 +210,7 @@ cc.GLProgramState.prototype = { cc.log("cocos2d: warning: Uniform not found: " + uniform); } }, - + setUniformVec2v: function setUniformVec2v(uniform, value) { var v = this.getUniformValue(uniform); if (v) { @@ -234,7 +219,7 @@ cc.GLProgramState.prototype = { cc.log("cocos2d: warning: Uniform not found: " + uniform); } }, - + setUniformVec3: function setUniformVec3(uniform, v1, v2, v3) { var v = this.getUniformValue(uniform); if (v) { @@ -252,7 +237,7 @@ cc.GLProgramState.prototype = { cc.log("cocos2d: warning: Uniform not found: " + uniform); } }, - + setUniformVec4: function setUniformVec4(uniform, v1, v2, v3, v4) { var v = this.getUniformValue(uniform); if (v) { @@ -271,7 +256,7 @@ cc.GLProgramState.prototype = { } }, - + setUniformMat4: function setUniformMat4(uniform, value) { var v = this.getUniformValue(uniform); if (v) { @@ -291,7 +276,7 @@ cc.GLProgramState.prototype = { } }, - + setUniformTexture: function setUniformTexture(uniform, texture) { var uniformValue = this.getUniformValue(uniform); if (uniformValue) { @@ -300,7 +285,7 @@ cc.GLProgramState.prototype = { uniformValue.setTexture(texture, textureUnit); } else { uniformValue.setTexture(texture, this._textureUnitIndex); - this._boundTextureUnits[uniform] = this._textureUnitIndex++; + this._boundTextureUnits[uniform] = this._textureUnitIndex++; } } } From d67a8b3a8e34e02be91c9cfd2171961a57b889e4 Mon Sep 17 00:00:00 2001 From: danilo neves cruz Date: Wed, 13 Sep 2017 02:32:22 -0300 Subject: [PATCH 3/3] optimize uniform cache performance --- cocos2d/shaders/CCGLProgram.js | 26 ++++++++++++++++++-------- cocos2d/shaders/CCGLProgramState.js | 6 +++--- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/cocos2d/shaders/CCGLProgram.js b/cocos2d/shaders/CCGLProgram.js index 67e23db2d7..4e8301d50b 100644 --- a/cocos2d/shaders/CCGLProgram.js +++ b/cocos2d/shaders/CCGLProgram.js @@ -48,11 +48,18 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ var updated = false; var element = this._hashForUniforms[name]; - var args = Array.isArray(arguments[1]) ? arguments[1] : - Array.prototype.slice.call(arguments, 1); + var args; + if (Array.isArray(arguments[1])) { + args = arguments[1]; + } else { + args = new Array(arguments.length - 1); + for (var i = 1; i < arguments.length; i += 1) { + args[i - 1] = arguments[i]; + } + } if (!element || element.length !== args.length) { - this._hashForUniforms[name] = args.slice(); + this._hashForUniforms[name] = [].concat(args); updated = true; } else { for (var i = 0; i < args.length; i += 1) { @@ -260,11 +267,14 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * cc.UNIFORM_SAMPLER */ updateUniforms: function () { - [cc.UNIFORM_PMATRIX_S, cc.UNIFORM_MVMATRIX_S, cc.UNIFORM_MVPMATRIX_S, - cc.UNIFORM_TIME_S, cc.UNIFORM_SINTIME_S, cc.UNIFORM_COSTIME_S, - cc.UNIFORM_RANDOM01_S, cc.UNIFORM_SAMPLER_S].forEach(function(name) { - this._addUniformLocation(name); - }.bind(this)); + this._addUniformLocation(cc.UNIFORM_PMATRIX_S); + this._addUniformLocation(cc.UNIFORM_MVMATRIX_S); + this._addUniformLocation(cc.UNIFORM_MVPMATRIX_S); + this._addUniformLocation(cc.UNIFORM_TIME_S); + this._addUniformLocation(cc.UNIFORM_SINTIME_S); + this._addUniformLocation(cc.UNIFORM_COSTIME_S); + this._addUniformLocation(cc.UNIFORM_RANDOM01_S); + this._addUniformLocation(cc.UNIFORM_SAMPLER_S); this._usesTime = (this._uniforms[cc.UNIFORM_TIME_S] != null || this._uniforms[cc.UNIFORM_SINTIME_S] != null || this._uniforms[cc.UNIFORM_COSTIME_S] != null); this.use(); diff --git a/cocos2d/shaders/CCGLProgramState.js b/cocos2d/shaders/CCGLProgramState.js index 2e9ec348ee..c5bc2fd428 100644 --- a/cocos2d/shaders/CCGLProgramState.js +++ b/cocos2d/shaders/CCGLProgramState.js @@ -163,9 +163,9 @@ cc.GLProgramState.prototype = { this._glprogram._setUniformForMVPMatrixWithMat4(modelView); } - Object.values(this._uniforms).forEach(function(uniform) { - uniform.apply(); - }); + for (var name in this._uniforms) { + this._uniforms[name].apply(); + }; }, setGLProgram: function setGLProgram(glprogram) {