diff --git a/src/core/const.js b/src/core/const.js index 37a9741..c0a7efb 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -1,4 +1,5 @@ import maxRecommendedTextures from './utils/maxRecommendedTextures'; +import canUploadSameBuffer from './utils/canUploadSameBuffer'; /** * String of the current PIXI version. @@ -417,3 +418,13 @@ * @type {number} */ export const SPRITE_MAX_TEXTURES = maxRecommendedTextures(32); + +/** + * Can we upload the same buffer in a single frame? + * + * @static + * @constant + * @memberof PIXI + * @type {boolean} + */ +export const CAN_UPLOAD_SAME_BUFFER = canUploadSameBuffer(); diff --git a/src/core/const.js b/src/core/const.js index 37a9741..c0a7efb 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -1,4 +1,5 @@ import maxRecommendedTextures from './utils/maxRecommendedTextures'; +import canUploadSameBuffer from './utils/canUploadSameBuffer'; /** * String of the current PIXI version. @@ -417,3 +418,13 @@ * @type {number} */ export const SPRITE_MAX_TEXTURES = maxRecommendedTextures(32); + +/** + * Can we upload the same buffer in a single frame? + * + * @static + * @constant + * @memberof PIXI + * @type {boolean} + */ +export const CAN_UPLOAD_SAME_BUFFER = canUploadSameBuffer(); diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index fcb5005..e67680f 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -101,9 +101,8 @@ shaderTemp.uniforms.tint = hex2rgb(graphics.tint); shaderTemp.uniforms.alpha = graphics.worldAlpha; - webGLData.vao.bind() - .draw(gl.TRIANGLE_STRIP, webGLData.indices.length) - .unbind(); + renderer.bindVao(webGLData.vao); + webGLData.vao.draw(gl.TRIANGLE_STRIP, webGLData.indices.length); } } @@ -177,6 +176,8 @@ webGL.lastIndex++; } + this.renderer.bindVao(null); + // upload all the dirty data... for (let i = 0; i < webGL.data.length; i++) { diff --git a/src/core/const.js b/src/core/const.js index 37a9741..c0a7efb 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -1,4 +1,5 @@ import maxRecommendedTextures from './utils/maxRecommendedTextures'; +import canUploadSameBuffer from './utils/canUploadSameBuffer'; /** * String of the current PIXI version. @@ -417,3 +418,13 @@ * @type {number} */ export const SPRITE_MAX_TEXTURES = maxRecommendedTextures(32); + +/** + * Can we upload the same buffer in a single frame? + * + * @static + * @constant + * @memberof PIXI + * @type {boolean} + */ +export const CAN_UPLOAD_SAME_BUFFER = canUploadSameBuffer(); diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index fcb5005..e67680f 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -101,9 +101,8 @@ shaderTemp.uniforms.tint = hex2rgb(graphics.tint); shaderTemp.uniforms.alpha = graphics.worldAlpha; - webGLData.vao.bind() - .draw(gl.TRIANGLE_STRIP, webGLData.indices.length) - .unbind(); + renderer.bindVao(webGLData.vao); + webGLData.vao.draw(gl.TRIANGLE_STRIP, webGLData.indices.length); } } @@ -177,6 +176,8 @@ webGL.lastIndex++; } + this.renderer.bindVao(null); + // upload all the dirty data... for (let i = 0; i < webGL.data.length; i++) { diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 20ccfee..6bef874 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -162,6 +162,8 @@ */ this._activeShader = null; + this._activeVao = null; + /** * Holds the current render target * @@ -550,6 +552,34 @@ } /** + * Changes the current Vao to the one given in parameter + * + * @param {PIXI.VertexArrayObject} vao - the new Vao + * @return {PIXI.WebGLRenderer} Returns itself. + */ + bindVao(vao) + { + if (this._activeVao === vao) + { + return this; + } + + if (vao) + { + vao.bind(); + } + else if (this._activeVao) + { + // TODO this should always be true i think? + this._activeVao.unbind(); + } + + this._activeVao = vao; + + return this; + } + + /** * Resets the WebGL state so you can render things however you fancy! * * @return {PIXI.WebGLRenderer} Returns itself. diff --git a/src/core/const.js b/src/core/const.js index 37a9741..c0a7efb 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -1,4 +1,5 @@ import maxRecommendedTextures from './utils/maxRecommendedTextures'; +import canUploadSameBuffer from './utils/canUploadSameBuffer'; /** * String of the current PIXI version. @@ -417,3 +418,13 @@ * @type {number} */ export const SPRITE_MAX_TEXTURES = maxRecommendedTextures(32); + +/** + * Can we upload the same buffer in a single frame? + * + * @static + * @constant + * @memberof PIXI + * @type {boolean} + */ +export const CAN_UPLOAD_SAME_BUFFER = canUploadSameBuffer(); diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index fcb5005..e67680f 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -101,9 +101,8 @@ shaderTemp.uniforms.tint = hex2rgb(graphics.tint); shaderTemp.uniforms.alpha = graphics.worldAlpha; - webGLData.vao.bind() - .draw(gl.TRIANGLE_STRIP, webGLData.indices.length) - .unbind(); + renderer.bindVao(webGLData.vao); + webGLData.vao.draw(gl.TRIANGLE_STRIP, webGLData.indices.length); } } @@ -177,6 +176,8 @@ webGL.lastIndex++; } + this.renderer.bindVao(null); + // upload all the dirty data... for (let i = 0; i < webGL.data.length; i++) { diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 20ccfee..6bef874 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -162,6 +162,8 @@ */ this._activeShader = null; + this._activeVao = null; + /** * Holds the current render target * @@ -550,6 +552,34 @@ } /** + * Changes the current Vao to the one given in parameter + * + * @param {PIXI.VertexArrayObject} vao - the new Vao + * @return {PIXI.WebGLRenderer} Returns itself. + */ + bindVao(vao) + { + if (this._activeVao === vao) + { + return this; + } + + if (vao) + { + vao.bind(); + } + else if (this._activeVao) + { + // TODO this should always be true i think? + this._activeVao.unbind(); + } + + this._activeVao = vao; + + return this; + } + + /** * Resets the WebGL state so you can render things however you fancy! * * @return {PIXI.WebGLRenderer} Returns itself. diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 802ceb2..1d1409e 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -231,9 +231,13 @@ } // TODO - this only needs to be done once? + renderer.bindVao(null); + this.quad.initVao(shader); } + renderer.bindVao(this.quad.vao); + renderer.bindRenderTarget(output); if (clear) @@ -262,7 +266,7 @@ gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, input.texture.texture); - this.quad.draw(); + this.quad.vao.draw(this.renderer.gl.TRIANGLES, 6, 0); // restore cache. gl.bindTexture(gl.TEXTURE_2D, tex._glTextures[this.renderer.CONTEXT_UID].texture); diff --git a/src/core/const.js b/src/core/const.js index 37a9741..c0a7efb 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -1,4 +1,5 @@ import maxRecommendedTextures from './utils/maxRecommendedTextures'; +import canUploadSameBuffer from './utils/canUploadSameBuffer'; /** * String of the current PIXI version. @@ -417,3 +418,13 @@ * @type {number} */ export const SPRITE_MAX_TEXTURES = maxRecommendedTextures(32); + +/** + * Can we upload the same buffer in a single frame? + * + * @static + * @constant + * @memberof PIXI + * @type {boolean} + */ +export const CAN_UPLOAD_SAME_BUFFER = canUploadSameBuffer(); diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index fcb5005..e67680f 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -101,9 +101,8 @@ shaderTemp.uniforms.tint = hex2rgb(graphics.tint); shaderTemp.uniforms.alpha = graphics.worldAlpha; - webGLData.vao.bind() - .draw(gl.TRIANGLE_STRIP, webGLData.indices.length) - .unbind(); + renderer.bindVao(webGLData.vao); + webGLData.vao.draw(gl.TRIANGLE_STRIP, webGLData.indices.length); } } @@ -177,6 +176,8 @@ webGL.lastIndex++; } + this.renderer.bindVao(null); + // upload all the dirty data... for (let i = 0; i < webGL.data.length; i++) { diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 20ccfee..6bef874 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -162,6 +162,8 @@ */ this._activeShader = null; + this._activeVao = null; + /** * Holds the current render target * @@ -550,6 +552,34 @@ } /** + * Changes the current Vao to the one given in parameter + * + * @param {PIXI.VertexArrayObject} vao - the new Vao + * @return {PIXI.WebGLRenderer} Returns itself. + */ + bindVao(vao) + { + if (this._activeVao === vao) + { + return this; + } + + if (vao) + { + vao.bind(); + } + else if (this._activeVao) + { + // TODO this should always be true i think? + this._activeVao.unbind(); + } + + this._activeVao = vao; + + return this; + } + + /** * Resets the WebGL state so you can render things however you fancy! * * @return {PIXI.WebGLRenderer} Returns itself. diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 802ceb2..1d1409e 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -231,9 +231,13 @@ } // TODO - this only needs to be done once? + renderer.bindVao(null); + this.quad.initVao(shader); } + renderer.bindVao(this.quad.vao); + renderer.bindRenderTarget(output); if (clear) @@ -262,7 +266,7 @@ gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, input.texture.texture); - this.quad.draw(); + this.quad.vao.draw(this.renderer.gl.TRIANGLES, 6, 0); // restore cache. gl.bindTexture(gl.TEXTURE_2D, tex._glTextures[this.renderer.CONTEXT_UID].texture); diff --git a/src/core/renderers/webgl/utils/Quad.js b/src/core/renderers/webgl/utils/Quad.js index 58271da..218fca5 100644 --- a/src/core/renderers/webgl/utils/Quad.js +++ b/src/core/renderers/webgl/utils/Quad.js @@ -133,20 +133,6 @@ } /** - * Draws the quad - * - * @return {PIXI.Quad} Returns itself. - */ - draw() - { - this.vao.bind() - .draw(this.gl.TRIANGLES, 6, 0) - .unbind(); - - return this; - } - - /** * Binds the buffer and uploads the data * * @return {PIXI.Quad} Returns itself. diff --git a/src/core/const.js b/src/core/const.js index 37a9741..c0a7efb 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -1,4 +1,5 @@ import maxRecommendedTextures from './utils/maxRecommendedTextures'; +import canUploadSameBuffer from './utils/canUploadSameBuffer'; /** * String of the current PIXI version. @@ -417,3 +418,13 @@ * @type {number} */ export const SPRITE_MAX_TEXTURES = maxRecommendedTextures(32); + +/** + * Can we upload the same buffer in a single frame? + * + * @static + * @constant + * @memberof PIXI + * @type {boolean} + */ +export const CAN_UPLOAD_SAME_BUFFER = canUploadSameBuffer(); diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index fcb5005..e67680f 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -101,9 +101,8 @@ shaderTemp.uniforms.tint = hex2rgb(graphics.tint); shaderTemp.uniforms.alpha = graphics.worldAlpha; - webGLData.vao.bind() - .draw(gl.TRIANGLE_STRIP, webGLData.indices.length) - .unbind(); + renderer.bindVao(webGLData.vao); + webGLData.vao.draw(gl.TRIANGLE_STRIP, webGLData.indices.length); } } @@ -177,6 +176,8 @@ webGL.lastIndex++; } + this.renderer.bindVao(null); + // upload all the dirty data... for (let i = 0; i < webGL.data.length; i++) { diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 20ccfee..6bef874 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -162,6 +162,8 @@ */ this._activeShader = null; + this._activeVao = null; + /** * Holds the current render target * @@ -550,6 +552,34 @@ } /** + * Changes the current Vao to the one given in parameter + * + * @param {PIXI.VertexArrayObject} vao - the new Vao + * @return {PIXI.WebGLRenderer} Returns itself. + */ + bindVao(vao) + { + if (this._activeVao === vao) + { + return this; + } + + if (vao) + { + vao.bind(); + } + else if (this._activeVao) + { + // TODO this should always be true i think? + this._activeVao.unbind(); + } + + this._activeVao = vao; + + return this; + } + + /** * Resets the WebGL state so you can render things however you fancy! * * @return {PIXI.WebGLRenderer} Returns itself. diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 802ceb2..1d1409e 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -231,9 +231,13 @@ } // TODO - this only needs to be done once? + renderer.bindVao(null); + this.quad.initVao(shader); } + renderer.bindVao(this.quad.vao); + renderer.bindRenderTarget(output); if (clear) @@ -262,7 +266,7 @@ gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, input.texture.texture); - this.quad.draw(); + this.quad.vao.draw(this.renderer.gl.TRIANGLES, 6, 0); // restore cache. gl.bindTexture(gl.TEXTURE_2D, tex._glTextures[this.renderer.CONTEXT_UID].texture); diff --git a/src/core/renderers/webgl/utils/Quad.js b/src/core/renderers/webgl/utils/Quad.js index 58271da..218fca5 100644 --- a/src/core/renderers/webgl/utils/Quad.js +++ b/src/core/renderers/webgl/utils/Quad.js @@ -133,20 +133,6 @@ } /** - * Draws the quad - * - * @return {PIXI.Quad} Returns itself. - */ - draw() - { - this.vao.bind() - .draw(this.gl.TRIANGLES, 6, 0) - .unbind(); - - return this; - } - - /** * Binds the buffer and uploads the data * * @return {PIXI.Quad} Returns itself. diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index d052a80..8a9a1d6 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -4,7 +4,7 @@ import generateMultiTextureShader from './generateMultiTextureShader'; import checkMaxIfStatmentsInShader from '../../renderers/webgl/utils/checkMaxIfStatmentsInShader'; import Buffer from './BatchBuffer'; -import { SPRITE_BATCH_SIZE, SPRITE_MAX_TEXTURES } from '../../const'; +import { SPRITE_BATCH_SIZE, SPRITE_MAX_TEXTURES, CAN_UPLOAD_SAME_BUFFER } from '../../const'; import glCore from 'pixi-gl-core'; import bitTwiddle from 'bit-twiddle'; @@ -114,6 +114,11 @@ // create a couple of buffers this.indexBuffer = glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); + // we use the second shader as the first one depending on your browser may omit aTextureId + // as it is not used by the shader so is optimized out. + + this.renderer.bindVao(null); + for (let i = 0; i < this.vaoMax; i++) { this.vertexBuffers[i] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); @@ -199,7 +204,6 @@ const boundTextures = this.boundTextures; const rendererBoundTextures = this.renderer.boundTextures; - const touch = this.renderer.textureGC.count; let index = 0; @@ -356,24 +360,33 @@ currentGroup.size = i - currentGroup.start; - // this is still needed for IOS performance.. - // it realy doe not like uploading to the same bufffer in a single frame! - if (this.vaoMax <= this.vertexCount) + if (!CAN_UPLOAD_SAME_BUFFER) { - this.vaoMax++; - this.vertexBuffers[this.vertexCount] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); + // this is still needed for IOS performance.. + // it realy doe not like uploading to the same bufffer in a single frame! + if (this.vaoMax <= this.vertexCount) + { + this.vaoMax++; + this.vertexBuffers[this.vertexCount] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); - // build the vao object that will render.. - this.vaos[this.vertexCount] = this.renderer.createVao() - .addIndex(this.indexBuffer) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); + // build the vao object that will render.. + this.vaos[this.vertexCount] = this.renderer.createVao() + .addIndex(this.indexBuffer) + .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) + .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) + .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4) + .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); + } + + this.renderer.bindVao(this.vaos[this.vertexCount]); + + this.vertexBuffers[this.vertexCount].upload(buffer.vertices, 0, false); } - - this.vaos[this.vertexCount].bind(); - this.vertexBuffers[this.vertexCount].upload(buffer.vertices, 0, false); + else + { + // lets use the faster option.. + this.vertexBuffers[this.vertexCount].upload(buffer.vertices, 0, true); + } this.vertexCount++; @@ -418,10 +431,8 @@ */ start() { - // this.renderer.bindShader(this.shader); - // TICK %= 1000; - this.vao = this.vaos[0].bind(); this.renderer.bindShader(this.shader); + this.renderer.bindVao(this.vaos[this.vertexCount]); } /** @@ -431,7 +442,6 @@ stop() { this.flush(); - this.vao.unbind(); } /** diff --git a/src/core/const.js b/src/core/const.js index 37a9741..c0a7efb 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -1,4 +1,5 @@ import maxRecommendedTextures from './utils/maxRecommendedTextures'; +import canUploadSameBuffer from './utils/canUploadSameBuffer'; /** * String of the current PIXI version. @@ -417,3 +418,13 @@ * @type {number} */ export const SPRITE_MAX_TEXTURES = maxRecommendedTextures(32); + +/** + * Can we upload the same buffer in a single frame? + * + * @static + * @constant + * @memberof PIXI + * @type {boolean} + */ +export const CAN_UPLOAD_SAME_BUFFER = canUploadSameBuffer(); diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index fcb5005..e67680f 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -101,9 +101,8 @@ shaderTemp.uniforms.tint = hex2rgb(graphics.tint); shaderTemp.uniforms.alpha = graphics.worldAlpha; - webGLData.vao.bind() - .draw(gl.TRIANGLE_STRIP, webGLData.indices.length) - .unbind(); + renderer.bindVao(webGLData.vao); + webGLData.vao.draw(gl.TRIANGLE_STRIP, webGLData.indices.length); } } @@ -177,6 +176,8 @@ webGL.lastIndex++; } + this.renderer.bindVao(null); + // upload all the dirty data... for (let i = 0; i < webGL.data.length; i++) { diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 20ccfee..6bef874 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -162,6 +162,8 @@ */ this._activeShader = null; + this._activeVao = null; + /** * Holds the current render target * @@ -550,6 +552,34 @@ } /** + * Changes the current Vao to the one given in parameter + * + * @param {PIXI.VertexArrayObject} vao - the new Vao + * @return {PIXI.WebGLRenderer} Returns itself. + */ + bindVao(vao) + { + if (this._activeVao === vao) + { + return this; + } + + if (vao) + { + vao.bind(); + } + else if (this._activeVao) + { + // TODO this should always be true i think? + this._activeVao.unbind(); + } + + this._activeVao = vao; + + return this; + } + + /** * Resets the WebGL state so you can render things however you fancy! * * @return {PIXI.WebGLRenderer} Returns itself. diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 802ceb2..1d1409e 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -231,9 +231,13 @@ } // TODO - this only needs to be done once? + renderer.bindVao(null); + this.quad.initVao(shader); } + renderer.bindVao(this.quad.vao); + renderer.bindRenderTarget(output); if (clear) @@ -262,7 +266,7 @@ gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, input.texture.texture); - this.quad.draw(); + this.quad.vao.draw(this.renderer.gl.TRIANGLES, 6, 0); // restore cache. gl.bindTexture(gl.TEXTURE_2D, tex._glTextures[this.renderer.CONTEXT_UID].texture); diff --git a/src/core/renderers/webgl/utils/Quad.js b/src/core/renderers/webgl/utils/Quad.js index 58271da..218fca5 100644 --- a/src/core/renderers/webgl/utils/Quad.js +++ b/src/core/renderers/webgl/utils/Quad.js @@ -133,20 +133,6 @@ } /** - * Draws the quad - * - * @return {PIXI.Quad} Returns itself. - */ - draw() - { - this.vao.bind() - .draw(this.gl.TRIANGLES, 6, 0) - .unbind(); - - return this; - } - - /** * Binds the buffer and uploads the data * * @return {PIXI.Quad} Returns itself. diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index d052a80..8a9a1d6 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -4,7 +4,7 @@ import generateMultiTextureShader from './generateMultiTextureShader'; import checkMaxIfStatmentsInShader from '../../renderers/webgl/utils/checkMaxIfStatmentsInShader'; import Buffer from './BatchBuffer'; -import { SPRITE_BATCH_SIZE, SPRITE_MAX_TEXTURES } from '../../const'; +import { SPRITE_BATCH_SIZE, SPRITE_MAX_TEXTURES, CAN_UPLOAD_SAME_BUFFER } from '../../const'; import glCore from 'pixi-gl-core'; import bitTwiddle from 'bit-twiddle'; @@ -114,6 +114,11 @@ // create a couple of buffers this.indexBuffer = glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); + // we use the second shader as the first one depending on your browser may omit aTextureId + // as it is not used by the shader so is optimized out. + + this.renderer.bindVao(null); + for (let i = 0; i < this.vaoMax; i++) { this.vertexBuffers[i] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); @@ -199,7 +204,6 @@ const boundTextures = this.boundTextures; const rendererBoundTextures = this.renderer.boundTextures; - const touch = this.renderer.textureGC.count; let index = 0; @@ -356,24 +360,33 @@ currentGroup.size = i - currentGroup.start; - // this is still needed for IOS performance.. - // it realy doe not like uploading to the same bufffer in a single frame! - if (this.vaoMax <= this.vertexCount) + if (!CAN_UPLOAD_SAME_BUFFER) { - this.vaoMax++; - this.vertexBuffers[this.vertexCount] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); + // this is still needed for IOS performance.. + // it realy doe not like uploading to the same bufffer in a single frame! + if (this.vaoMax <= this.vertexCount) + { + this.vaoMax++; + this.vertexBuffers[this.vertexCount] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); - // build the vao object that will render.. - this.vaos[this.vertexCount] = this.renderer.createVao() - .addIndex(this.indexBuffer) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); + // build the vao object that will render.. + this.vaos[this.vertexCount] = this.renderer.createVao() + .addIndex(this.indexBuffer) + .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) + .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) + .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4) + .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); + } + + this.renderer.bindVao(this.vaos[this.vertexCount]); + + this.vertexBuffers[this.vertexCount].upload(buffer.vertices, 0, false); } - - this.vaos[this.vertexCount].bind(); - this.vertexBuffers[this.vertexCount].upload(buffer.vertices, 0, false); + else + { + // lets use the faster option.. + this.vertexBuffers[this.vertexCount].upload(buffer.vertices, 0, true); + } this.vertexCount++; @@ -418,10 +431,8 @@ */ start() { - // this.renderer.bindShader(this.shader); - // TICK %= 1000; - this.vao = this.vaos[0].bind(); this.renderer.bindShader(this.shader); + this.renderer.bindVao(this.vaos[this.vertexCount]); } /** @@ -431,7 +442,6 @@ stop() { this.flush(); - this.vao.unbind(); } /** diff --git a/src/core/utils/canUploadSameBuffer.js b/src/core/utils/canUploadSameBuffer.js new file mode 100644 index 0000000..eb4ae5c --- /dev/null +++ b/src/core/utils/canUploadSameBuffer.js @@ -0,0 +1,9 @@ +export default function canUploadSameBuffer() +{ + // Uploading the same buffer multiple times in a single frame can cause perf issues. + // Apparent on IOS so only check for that at the moment + // this check may become more complex if this issue pops up elsewhere. + const ios = !!navigator.platform && (/iPad|iPhone|iPod/).test(navigator.platform); + + return !ios; +} diff --git a/src/core/const.js b/src/core/const.js index 37a9741..c0a7efb 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -1,4 +1,5 @@ import maxRecommendedTextures from './utils/maxRecommendedTextures'; +import canUploadSameBuffer from './utils/canUploadSameBuffer'; /** * String of the current PIXI version. @@ -417,3 +418,13 @@ * @type {number} */ export const SPRITE_MAX_TEXTURES = maxRecommendedTextures(32); + +/** + * Can we upload the same buffer in a single frame? + * + * @static + * @constant + * @memberof PIXI + * @type {boolean} + */ +export const CAN_UPLOAD_SAME_BUFFER = canUploadSameBuffer(); diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index fcb5005..e67680f 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -101,9 +101,8 @@ shaderTemp.uniforms.tint = hex2rgb(graphics.tint); shaderTemp.uniforms.alpha = graphics.worldAlpha; - webGLData.vao.bind() - .draw(gl.TRIANGLE_STRIP, webGLData.indices.length) - .unbind(); + renderer.bindVao(webGLData.vao); + webGLData.vao.draw(gl.TRIANGLE_STRIP, webGLData.indices.length); } } @@ -177,6 +176,8 @@ webGL.lastIndex++; } + this.renderer.bindVao(null); + // upload all the dirty data... for (let i = 0; i < webGL.data.length; i++) { diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 20ccfee..6bef874 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -162,6 +162,8 @@ */ this._activeShader = null; + this._activeVao = null; + /** * Holds the current render target * @@ -550,6 +552,34 @@ } /** + * Changes the current Vao to the one given in parameter + * + * @param {PIXI.VertexArrayObject} vao - the new Vao + * @return {PIXI.WebGLRenderer} Returns itself. + */ + bindVao(vao) + { + if (this._activeVao === vao) + { + return this; + } + + if (vao) + { + vao.bind(); + } + else if (this._activeVao) + { + // TODO this should always be true i think? + this._activeVao.unbind(); + } + + this._activeVao = vao; + + return this; + } + + /** * Resets the WebGL state so you can render things however you fancy! * * @return {PIXI.WebGLRenderer} Returns itself. diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 802ceb2..1d1409e 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -231,9 +231,13 @@ } // TODO - this only needs to be done once? + renderer.bindVao(null); + this.quad.initVao(shader); } + renderer.bindVao(this.quad.vao); + renderer.bindRenderTarget(output); if (clear) @@ -262,7 +266,7 @@ gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, input.texture.texture); - this.quad.draw(); + this.quad.vao.draw(this.renderer.gl.TRIANGLES, 6, 0); // restore cache. gl.bindTexture(gl.TEXTURE_2D, tex._glTextures[this.renderer.CONTEXT_UID].texture); diff --git a/src/core/renderers/webgl/utils/Quad.js b/src/core/renderers/webgl/utils/Quad.js index 58271da..218fca5 100644 --- a/src/core/renderers/webgl/utils/Quad.js +++ b/src/core/renderers/webgl/utils/Quad.js @@ -133,20 +133,6 @@ } /** - * Draws the quad - * - * @return {PIXI.Quad} Returns itself. - */ - draw() - { - this.vao.bind() - .draw(this.gl.TRIANGLES, 6, 0) - .unbind(); - - return this; - } - - /** * Binds the buffer and uploads the data * * @return {PIXI.Quad} Returns itself. diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index d052a80..8a9a1d6 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -4,7 +4,7 @@ import generateMultiTextureShader from './generateMultiTextureShader'; import checkMaxIfStatmentsInShader from '../../renderers/webgl/utils/checkMaxIfStatmentsInShader'; import Buffer from './BatchBuffer'; -import { SPRITE_BATCH_SIZE, SPRITE_MAX_TEXTURES } from '../../const'; +import { SPRITE_BATCH_SIZE, SPRITE_MAX_TEXTURES, CAN_UPLOAD_SAME_BUFFER } from '../../const'; import glCore from 'pixi-gl-core'; import bitTwiddle from 'bit-twiddle'; @@ -114,6 +114,11 @@ // create a couple of buffers this.indexBuffer = glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); + // we use the second shader as the first one depending on your browser may omit aTextureId + // as it is not used by the shader so is optimized out. + + this.renderer.bindVao(null); + for (let i = 0; i < this.vaoMax; i++) { this.vertexBuffers[i] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); @@ -199,7 +204,6 @@ const boundTextures = this.boundTextures; const rendererBoundTextures = this.renderer.boundTextures; - const touch = this.renderer.textureGC.count; let index = 0; @@ -356,24 +360,33 @@ currentGroup.size = i - currentGroup.start; - // this is still needed for IOS performance.. - // it realy doe not like uploading to the same bufffer in a single frame! - if (this.vaoMax <= this.vertexCount) + if (!CAN_UPLOAD_SAME_BUFFER) { - this.vaoMax++; - this.vertexBuffers[this.vertexCount] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); + // this is still needed for IOS performance.. + // it realy doe not like uploading to the same bufffer in a single frame! + if (this.vaoMax <= this.vertexCount) + { + this.vaoMax++; + this.vertexBuffers[this.vertexCount] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); - // build the vao object that will render.. - this.vaos[this.vertexCount] = this.renderer.createVao() - .addIndex(this.indexBuffer) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); + // build the vao object that will render.. + this.vaos[this.vertexCount] = this.renderer.createVao() + .addIndex(this.indexBuffer) + .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) + .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) + .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4) + .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); + } + + this.renderer.bindVao(this.vaos[this.vertexCount]); + + this.vertexBuffers[this.vertexCount].upload(buffer.vertices, 0, false); } - - this.vaos[this.vertexCount].bind(); - this.vertexBuffers[this.vertexCount].upload(buffer.vertices, 0, false); + else + { + // lets use the faster option.. + this.vertexBuffers[this.vertexCount].upload(buffer.vertices, 0, true); + } this.vertexCount++; @@ -418,10 +431,8 @@ */ start() { - // this.renderer.bindShader(this.shader); - // TICK %= 1000; - this.vao = this.vaos[0].bind(); this.renderer.bindShader(this.shader); + this.renderer.bindVao(this.vaos[this.vertexCount]); } /** @@ -431,7 +442,6 @@ stop() { this.flush(); - this.vao.unbind(); } /** diff --git a/src/core/utils/canUploadSameBuffer.js b/src/core/utils/canUploadSameBuffer.js new file mode 100644 index 0000000..eb4ae5c --- /dev/null +++ b/src/core/utils/canUploadSameBuffer.js @@ -0,0 +1,9 @@ +export default function canUploadSameBuffer() +{ + // Uploading the same buffer multiple times in a single frame can cause perf issues. + // Apparent on IOS so only check for that at the moment + // this check may become more complex if this issue pops up elsewhere. + const ios = !!navigator.platform && (/iPad|iPhone|iPod/).test(navigator.platform); + + return !ios; +} diff --git a/src/extras/webgl/TilingSpriteRenderer.js b/src/extras/webgl/TilingSpriteRenderer.js index cc97c2d..60bb185 100644 --- a/src/extras/webgl/TilingSpriteRenderer.js +++ b/src/extras/webgl/TilingSpriteRenderer.js @@ -41,6 +41,7 @@ glslify('./tilingSprite.vert'), glslify('./tilingSprite_simple.frag')); + this.renderer.bindVao(null); this.quad = new core.Quad(gl, this.renderer.state.attribState); this.quad.initVao(this.shader); } @@ -51,7 +52,11 @@ */ render(ts) { + const renderer = this.renderer; const quad = this.quad; + + renderer.bindVao(quad.vao); + let vertices = quad.vertices; vertices[0] = vertices[6] = (ts._width) * -ts.anchor.x; @@ -70,7 +75,6 @@ quad.upload(); - const renderer = this.renderer; const tex = ts._texture; const baseTex = tex.baseTexture; const lt = ts.tileTransform.localTransform; @@ -141,7 +145,7 @@ renderer.setBlendMode(ts.blendMode); - quad.draw(); + quad.vao.draw(this.renderer.gl.TRIANGLES, 6, 0); } } diff --git a/src/core/const.js b/src/core/const.js index 37a9741..c0a7efb 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -1,4 +1,5 @@ import maxRecommendedTextures from './utils/maxRecommendedTextures'; +import canUploadSameBuffer from './utils/canUploadSameBuffer'; /** * String of the current PIXI version. @@ -417,3 +418,13 @@ * @type {number} */ export const SPRITE_MAX_TEXTURES = maxRecommendedTextures(32); + +/** + * Can we upload the same buffer in a single frame? + * + * @static + * @constant + * @memberof PIXI + * @type {boolean} + */ +export const CAN_UPLOAD_SAME_BUFFER = canUploadSameBuffer(); diff --git a/src/core/graphics/webgl/GraphicsRenderer.js b/src/core/graphics/webgl/GraphicsRenderer.js index fcb5005..e67680f 100644 --- a/src/core/graphics/webgl/GraphicsRenderer.js +++ b/src/core/graphics/webgl/GraphicsRenderer.js @@ -101,9 +101,8 @@ shaderTemp.uniforms.tint = hex2rgb(graphics.tint); shaderTemp.uniforms.alpha = graphics.worldAlpha; - webGLData.vao.bind() - .draw(gl.TRIANGLE_STRIP, webGLData.indices.length) - .unbind(); + renderer.bindVao(webGLData.vao); + webGLData.vao.draw(gl.TRIANGLE_STRIP, webGLData.indices.length); } } @@ -177,6 +176,8 @@ webGL.lastIndex++; } + this.renderer.bindVao(null); + // upload all the dirty data... for (let i = 0; i < webGL.data.length; i++) { diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 20ccfee..6bef874 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -162,6 +162,8 @@ */ this._activeShader = null; + this._activeVao = null; + /** * Holds the current render target * @@ -550,6 +552,34 @@ } /** + * Changes the current Vao to the one given in parameter + * + * @param {PIXI.VertexArrayObject} vao - the new Vao + * @return {PIXI.WebGLRenderer} Returns itself. + */ + bindVao(vao) + { + if (this._activeVao === vao) + { + return this; + } + + if (vao) + { + vao.bind(); + } + else if (this._activeVao) + { + // TODO this should always be true i think? + this._activeVao.unbind(); + } + + this._activeVao = vao; + + return this; + } + + /** * Resets the WebGL state so you can render things however you fancy! * * @return {PIXI.WebGLRenderer} Returns itself. diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 802ceb2..1d1409e 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -231,9 +231,13 @@ } // TODO - this only needs to be done once? + renderer.bindVao(null); + this.quad.initVao(shader); } + renderer.bindVao(this.quad.vao); + renderer.bindRenderTarget(output); if (clear) @@ -262,7 +266,7 @@ gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, input.texture.texture); - this.quad.draw(); + this.quad.vao.draw(this.renderer.gl.TRIANGLES, 6, 0); // restore cache. gl.bindTexture(gl.TEXTURE_2D, tex._glTextures[this.renderer.CONTEXT_UID].texture); diff --git a/src/core/renderers/webgl/utils/Quad.js b/src/core/renderers/webgl/utils/Quad.js index 58271da..218fca5 100644 --- a/src/core/renderers/webgl/utils/Quad.js +++ b/src/core/renderers/webgl/utils/Quad.js @@ -133,20 +133,6 @@ } /** - * Draws the quad - * - * @return {PIXI.Quad} Returns itself. - */ - draw() - { - this.vao.bind() - .draw(this.gl.TRIANGLES, 6, 0) - .unbind(); - - return this; - } - - /** * Binds the buffer and uploads the data * * @return {PIXI.Quad} Returns itself. diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index d052a80..8a9a1d6 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -4,7 +4,7 @@ import generateMultiTextureShader from './generateMultiTextureShader'; import checkMaxIfStatmentsInShader from '../../renderers/webgl/utils/checkMaxIfStatmentsInShader'; import Buffer from './BatchBuffer'; -import { SPRITE_BATCH_SIZE, SPRITE_MAX_TEXTURES } from '../../const'; +import { SPRITE_BATCH_SIZE, SPRITE_MAX_TEXTURES, CAN_UPLOAD_SAME_BUFFER } from '../../const'; import glCore from 'pixi-gl-core'; import bitTwiddle from 'bit-twiddle'; @@ -114,6 +114,11 @@ // create a couple of buffers this.indexBuffer = glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); + // we use the second shader as the first one depending on your browser may omit aTextureId + // as it is not used by the shader so is optimized out. + + this.renderer.bindVao(null); + for (let i = 0; i < this.vaoMax; i++) { this.vertexBuffers[i] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); @@ -199,7 +204,6 @@ const boundTextures = this.boundTextures; const rendererBoundTextures = this.renderer.boundTextures; - const touch = this.renderer.textureGC.count; let index = 0; @@ -356,24 +360,33 @@ currentGroup.size = i - currentGroup.start; - // this is still needed for IOS performance.. - // it realy doe not like uploading to the same bufffer in a single frame! - if (this.vaoMax <= this.vertexCount) + if (!CAN_UPLOAD_SAME_BUFFER) { - this.vaoMax++; - this.vertexBuffers[this.vertexCount] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); + // this is still needed for IOS performance.. + // it realy doe not like uploading to the same bufffer in a single frame! + if (this.vaoMax <= this.vertexCount) + { + this.vaoMax++; + this.vertexBuffers[this.vertexCount] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); - // build the vao object that will render.. - this.vaos[this.vertexCount] = this.renderer.createVao() - .addIndex(this.indexBuffer) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); + // build the vao object that will render.. + this.vaos[this.vertexCount] = this.renderer.createVao() + .addIndex(this.indexBuffer) + .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) + .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) + .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4) + .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); + } + + this.renderer.bindVao(this.vaos[this.vertexCount]); + + this.vertexBuffers[this.vertexCount].upload(buffer.vertices, 0, false); } - - this.vaos[this.vertexCount].bind(); - this.vertexBuffers[this.vertexCount].upload(buffer.vertices, 0, false); + else + { + // lets use the faster option.. + this.vertexBuffers[this.vertexCount].upload(buffer.vertices, 0, true); + } this.vertexCount++; @@ -418,10 +431,8 @@ */ start() { - // this.renderer.bindShader(this.shader); - // TICK %= 1000; - this.vao = this.vaos[0].bind(); this.renderer.bindShader(this.shader); + this.renderer.bindVao(this.vaos[this.vertexCount]); } /** @@ -431,7 +442,6 @@ stop() { this.flush(); - this.vao.unbind(); } /** diff --git a/src/core/utils/canUploadSameBuffer.js b/src/core/utils/canUploadSameBuffer.js new file mode 100644 index 0000000..eb4ae5c --- /dev/null +++ b/src/core/utils/canUploadSameBuffer.js @@ -0,0 +1,9 @@ +export default function canUploadSameBuffer() +{ + // Uploading the same buffer multiple times in a single frame can cause perf issues. + // Apparent on IOS so only check for that at the moment + // this check may become more complex if this issue pops up elsewhere. + const ios = !!navigator.platform && (/iPad|iPhone|iPod/).test(navigator.platform); + + return !ios; +} diff --git a/src/extras/webgl/TilingSpriteRenderer.js b/src/extras/webgl/TilingSpriteRenderer.js index cc97c2d..60bb185 100644 --- a/src/extras/webgl/TilingSpriteRenderer.js +++ b/src/extras/webgl/TilingSpriteRenderer.js @@ -41,6 +41,7 @@ glslify('./tilingSprite.vert'), glslify('./tilingSprite_simple.frag')); + this.renderer.bindVao(null); this.quad = new core.Quad(gl, this.renderer.state.attribState); this.quad.initVao(this.shader); } @@ -51,7 +52,11 @@ */ render(ts) { + const renderer = this.renderer; const quad = this.quad; + + renderer.bindVao(quad.vao); + let vertices = quad.vertices; vertices[0] = vertices[6] = (ts._width) * -ts.anchor.x; @@ -70,7 +75,6 @@ quad.upload(); - const renderer = this.renderer; const tex = ts._texture; const baseTex = tex.baseTexture; const lt = ts.tileTransform.localTransform; @@ -141,7 +145,7 @@ renderer.setBlendMode(ts.blendMode); - quad.draw(); + quad.vao.draw(this.renderer.gl.TRIANGLES, 6, 0); } } diff --git a/src/mesh/webgl/MeshRenderer.js b/src/mesh/webgl/MeshRenderer.js index 148737e..94fafdc 100644 --- a/src/mesh/webgl/MeshRenderer.js +++ b/src/mesh/webgl/MeshRenderer.js @@ -55,6 +55,8 @@ if (!glData) { + renderer.bindVao(null); + glData = { shader: this.shader, vertexBuffer: glCore.GLBuffer.createVertexBuffer(gl, mesh.vertices, gl.STREAM_DRAW), @@ -92,6 +94,7 @@ renderer.bindShader(glData.shader); glData.shader.uniforms.uSampler = renderer.bindTexture(texture); + renderer.state.setBlendMode(mesh.blendMode); glData.shader.uniforms.translationMatrix = mesh.worldTransform.toArray(true); @@ -100,9 +103,8 @@ const drawMode = mesh.drawMode === Mesh.DRAW_MODES.TRIANGLE_MESH ? gl.TRIANGLE_STRIP : gl.TRIANGLES; - glData.vao.bind() - .draw(drawMode, mesh.indices.length) - .unbind(); + renderer.bindVao(glData.vao); + glData.vao.draw(drawMode, mesh.indices.length, 0); } }