Skip to content

Commit be29160

Browse files
authored
Merge pull request #4136 from stalgiag/shaderUniformCache
Remove most redundant WebGL calls
2 parents 093d301 + f2f2178 commit be29160

File tree

9 files changed

+91
-123
lines changed

9 files changed

+91
-123
lines changed

src/webgl/material.js

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -782,14 +782,19 @@ p5.RendererGL.prototype._applyColorBlend = function(colors) {
782782
const gl = this.GL;
783783

784784
const isTexture = this.drawMode === constants.TEXTURE;
785-
if (isTexture || colors[colors.length - 1] < 1.0 || this._isErasing) {
786-
gl.depthMask(isTexture);
787-
gl.enable(gl.BLEND);
788-
this._applyBlendMode();
789-
} else {
790-
gl.depthMask(true);
791-
gl.disable(gl.BLEND);
785+
const doBlend =
786+
isTexture || colors[colors.length - 1] < 1.0 || this._isErasing;
787+
if (doBlend !== this._isBlending) {
788+
if (doBlend) {
789+
gl.depthMask(isTexture);
790+
gl.enable(gl.BLEND);
791+
} else {
792+
gl.depthMask(true);
793+
gl.disable(gl.BLEND);
794+
}
795+
this._isBlending = doBlend;
792796
}
797+
this._applyBlendMode();
793798
return colors;
794799
};
795800

@@ -799,6 +804,9 @@ p5.RendererGL.prototype._applyColorBlend = function(colors) {
799804
* @return {Number[]]} Normalized numbers array
800805
*/
801806
p5.RendererGL.prototype._applyBlendMode = function() {
807+
if (this._cachedBlendMode === this.curBlendMode) {
808+
return;
809+
}
802810
const gl = this.GL;
803811
switch (this.curBlendMode) {
804812
case constants.BLEND:
@@ -861,6 +869,7 @@ p5.RendererGL.prototype._applyBlendMode = function() {
861869
);
862870
break;
863871
}
872+
this._cachedBlendMode = this.curBlendMode;
864873
};
865874

866875
export default p5;

src/webgl/p5.RendererGL.Retained.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ p5.RendererGL.prototype._prepareBuffers = function(buffers, shader, defs) {
130130
gl.deleteBuffer(buffer);
131131
buffers[def.dst] = null;
132132
}
133-
// disable the vertex
134-
gl.disableVertexAttribArray(attr.index);
133+
// no need to disable
134+
// gl.disableVertexAttribArray(attr.index);
135135
}
136136
}
137137
};

src/webgl/p5.RendererGL.js

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ p5.RendererGL = function(elt, pInst, isMainCanvas, attr) {
6363
this._setAttributeDefaults(pInst);
6464
this._initContext();
6565
this.isP3D = true; //lets us know we're in 3d mode
66+
67+
// This redundant property is useful in reminding you that you are
68+
// interacting with WebGLRenderingContext, still worth considering future removal
6669
this.GL = this.drawingContext;
6770

6871
// erasing
@@ -94,8 +97,10 @@ p5.RendererGL = function(elt, pInst, isMainCanvas, attr) {
9497
this.curFillColor = this._cachedFillStyle = [1, 1, 1, 1];
9598
this.curStrokeColor = this._cachedStrokeStyle = [0, 0, 0, 1];
9699

97-
this.curBlendMode = this._cachedBlendMode = constants.BLEND;
100+
this.curBlendMode = constants.BLEND;
101+
this._cachedBlendMode = undefined;
98102
this.blendExt = this.GL.getExtension('EXT_blend_minmax');
103+
this._isBlending = false;
99104

100105
this._useSpecularMaterial = false;
101106
this._useEmissiveMaterial = false;
@@ -169,6 +174,9 @@ p5.RendererGL = function(elt, pInst, isMainCanvas, attr) {
169174

170175
this.fontInfos = {};
171176

177+
this._cachedBackground = undefined;
178+
this._curShader = undefined;
179+
172180
return this;
173181
};
174182

@@ -533,13 +541,19 @@ p5.RendererGL.prototype._update = function() {
533541
*/
534542
p5.RendererGL.prototype.background = function(...args) {
535543
const _col = this._pInst.color(...args);
536-
const _r = _col.levels[0] / 255;
537-
const _g = _col.levels[1] / 255;
538-
const _b = _col.levels[2] / 255;
539-
const _a = _col.levels[3] / 255;
540-
this.GL.clearColor(_r, _g, _b, _a);
541-
this.GL.depthMask(true);
542-
this.GL.clear(this.GL.COLOR_BUFFER_BIT | this.GL.DEPTH_BUFFER_BIT);
544+
const needsUpdate =
545+
this._cachedBackground === undefined ||
546+
!this._arraysEqual(_col._array, this._cachedBackground);
547+
if (needsUpdate) {
548+
const _r = _col.levels[0] / 255;
549+
const _g = _col.levels[1] / 255;
550+
const _b = _col.levels[2] / 255;
551+
const _a = _col.levels[3] / 255;
552+
this.GL.clearColor(_r, _g, _b, _a);
553+
this.GL.depthMask(true);
554+
this._cachedBackground = _col._array.slice(0);
555+
}
556+
this.GL.clear(this.GL.COLOR_BUFFER_BIT);
543557
};
544558

545559
//////////////////////////////////////////////
@@ -1293,6 +1307,24 @@ p5.RendererGL.prototype._bindBuffer = function(
12931307
///////////////////////////////
12941308
//// UTILITY FUNCTIONS
12951309
//////////////////////////////
1310+
p5.RendererGL.prototype._arraysEqual = function(a, b) {
1311+
const aLength = a.length;
1312+
if (aLength !== b.length) return false;
1313+
for (let i = 0; i < aLength; i++) {
1314+
if (a[i] !== b[i]) return false;
1315+
}
1316+
return true;
1317+
};
1318+
1319+
p5.RendererGL.prototype._isTypedArray = function(arr) {
1320+
let res = false;
1321+
res = arr instanceof Float32Array;
1322+
res = arr instanceof Float64Array;
1323+
res = arr instanceof Int16Array;
1324+
res = arr instanceof Uint16Array;
1325+
res = arr instanceof Uint32Array;
1326+
return res;
1327+
};
12961328
/**
12971329
* turn a two dimensional array into one dimensional array
12981330
* @private

src/webgl/p5.Shader.js

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,19 @@ p5.Shader.prototype._loadUniforms = function() {
171171
}
172172
uniform.name = uniformName;
173173
uniform.type = uniformInfo.type;
174+
uniform._cachedData = undefined;
174175
if (uniform.type === gl.SAMPLER_2D) {
175176
uniform.samplerIndex = samplerIndex;
176177
samplerIndex++;
177178
this.samplers.push(uniform);
178179
}
180+
uniform.isArray =
181+
uniform.type === gl.FLOAT_MAT3 ||
182+
uniform.type === gl.FLOAT_MAT4 ||
183+
uniform.type === gl.INT_VEC2 ||
184+
uniform.type === gl.INT_VEC3 ||
185+
uniform.type === gl.INT_VEC4;
186+
179187
this.uniforms[uniformName] = uniform;
180188
}
181189
this._loadedUniforms = true;
@@ -274,7 +282,10 @@ p5.Shader.prototype._setMatrixUniforms = function() {
274282
*/
275283
p5.Shader.prototype.useProgram = function() {
276284
const gl = this._renderer.GL;
277-
gl.useProgram(this._glProgram);
285+
if (this._renderer._curShader !== this) {
286+
gl.useProgram(this._glProgram);
287+
this._renderer._curShader = this;
288+
}
278289
return this;
279290
};
280291

@@ -341,16 +352,29 @@ p5.Shader.prototype.useProgram = function() {
341352
* canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.
342353
*/
343354
p5.Shader.prototype.setUniform = function(uniformName, data) {
344-
//@todo update all current gl.uniformXX calls
345-
346355
const uniform = this.uniforms[uniformName];
347356
if (!uniform) {
348357
return;
349358
}
359+
const gl = this._renderer.GL;
360+
361+
if (uniform.isArray) {
362+
if (
363+
uniform._cachedData &&
364+
this._renderer._arraysEqual(uniform._cachedData, data)
365+
) {
366+
return;
367+
} else {
368+
uniform._cachedData = data.slice(0);
369+
}
370+
} else if (uniform._cachedData && uniform._cachedData === data) {
371+
return;
372+
} else {
373+
uniform._cachedData = data;
374+
}
350375

351376
const location = uniform.location;
352377

353-
const gl = this._renderer.GL;
354378
this.useProgram();
355379

356380
switch (uniform.type) {
@@ -507,8 +531,11 @@ p5.Shader.prototype.enableAttrib = function(
507531
const loc = attr.location;
508532
if (loc !== -1) {
509533
const gl = this._renderer.GL;
510-
gl.enableVertexAttribArray(loc);
511-
gl.vertexAttribPointer(
534+
if (!attr.enabled) {
535+
gl.enableVertexAttribArray(loc);
536+
attr.enabled = true;
537+
}
538+
this._renderer.GL.vertexAttribPointer(
512539
loc,
513540
size,
514541
type || gl.FLOAT,

test/manual-test-examples/webgl/interaction/orbitControl/sketch.js

Lines changed: 0 additions & 33 deletions
This file was deleted.

test/manual-test-examples/webgl/lights/noLights/index.html

Lines changed: 0 additions & 17 deletions
This file was deleted.

test/manual-test-examples/webgl/lights/noLights/sketch.js

Lines changed: 0 additions & 18 deletions
This file was deleted.

test/manual-test-examples/webgl/lights/spotLight/index.html

Lines changed: 0 additions & 17 deletions
This file was deleted.

test/manual-test-examples/webgl/lights/spotLight/sketch.js

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)