Skip to content

Commit b8533a2

Browse files
committed
Renderer: Fixed WebGLPrograms factorization.
1 parent 0ffd772 commit b8533a2

File tree

3 files changed

+64
-65
lines changed

3 files changed

+64
-65
lines changed

src/renderers/WebGLRenderer.js

Lines changed: 34 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,6 @@ THREE.WebGLRenderer = function ( parameters ) {
8282

8383
var _this = this,
8484

85-
_programs = [],
86-
8785
// internal state cache
8886

8987
_currentProgram = null,
@@ -131,7 +129,6 @@ THREE.WebGLRenderer = function ( parameters ) {
131129

132130
_infoMemory = {
133131

134-
programs: 0,
135132
geometries: 0,
136133
textures: 0
137134

@@ -150,10 +147,16 @@ THREE.WebGLRenderer = function ( parameters ) {
150147

151148
render: _infoRender,
152149
memory: _infoMemory,
153-
programs: _programs
150+
programs: []
154151

155152
};
156153

154+
Object.defineProperty( _infoMemory, 'programs', { get: function() {
155+
156+
return _this.info.programs.length;
157+
158+
} } );
159+
157160
// initialize
158161

159162
var _gl;
@@ -589,41 +592,13 @@ THREE.WebGLRenderer = function ( parameters ) {
589592

590593
function releaseMaterialProgramReference( material ) {
591594

592-
var program = properties.get( material ).program.program;
593-
594-
if ( program === undefined ) return;
595+
var programInfo = properties.get( material ).program;
595596

596597
material.program = undefined;
597598

598-
for ( var i = 0, n = _programs.length; i !== n; ++ i ) {
599-
600-
var programInfo = _programs[ i ];
601-
602-
if ( programInfo.program === program ) {
603-
604-
var newReferenceCount = -- programInfo.usedTimes;
605-
606-
if ( newReferenceCount === 0 ) {
607-
608-
// the last material that has been using the program let
609-
// go of it, so remove it from the (unordered) _programs
610-
// set and deallocate the GL resource
611-
612-
var newLength = n - 1;
613-
614-
_programs[ i ] = _programs[ newLength ];
615-
_programs.pop();
616-
617-
_gl.deleteProgram( program );
618-
619-
_infoMemory.programs = newLength;
620-
621-
}
622-
623-
break;
624-
625-
}
599+
if ( programInfo !== undefined ) {
626600

601+
programCache.releaseProgram( programInfo );
627602
}
628603

629604
}
@@ -1442,15 +1417,15 @@ THREE.WebGLRenderer = function ( parameters ) {
14421417
var parameters = programCache.getParameters( material, lights, fog, object );
14431418
var code = programCache.getProgramCode( material, parameters );
14441419

1445-
1420+
var program = materialProperties.program;
14461421
var programChange = true;
14471422

1448-
if ( ! materialProperties.program ) {
1423+
if ( program === undefined ) {
14491424

14501425
// new material
14511426
material.addEventListener( 'dispose', onMaterialDispose );
14521427

1453-
} else if ( materialProperties.program.code !== code ) {
1428+
} else if ( program.code !== code ) {
14541429

14551430
// changed glsl or parameters
14561431
releaseMaterialProgramReference( material );
@@ -1467,41 +1442,39 @@ THREE.WebGLRenderer = function ( parameters ) {
14671442

14681443
}
14691444

1470-
if ( parameters.shaderID ) {
1445+
if ( programChange ) {
14711446

1472-
var shader = THREE.ShaderLib[ parameters.shaderID ];
1447+
if ( parameters.shaderID ) {
14731448

1474-
materialProperties.__webglShader = {
1475-
name: material.type,
1476-
uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
1477-
vertexShader: shader.vertexShader,
1478-
fragmentShader: shader.fragmentShader
1479-
};
1449+
var shader = THREE.ShaderLib[ parameters.shaderID ];
14801450

1481-
} else {
1451+
materialProperties.__webglShader = {
1452+
name: material.type,
1453+
uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
1454+
vertexShader: shader.vertexShader,
1455+
fragmentShader: shader.fragmentShader
1456+
};
14821457

1483-
materialProperties.__webglShader = {
1484-
name: material.type,
1485-
uniforms: material.uniforms,
1486-
vertexShader: material.vertexShader,
1487-
fragmentShader: material.fragmentShader
1488-
};
1458+
} else {
14891459

1490-
}
1460+
materialProperties.__webglShader = {
1461+
name: material.type,
1462+
uniforms: material.uniforms,
1463+
vertexShader: material.vertexShader,
1464+
fragmentShader: material.fragmentShader
1465+
};
14911466

1492-
material.__webglShader = materialProperties.__webglShader;
1467+
}
14931468

1494-
var program = programCache.getProgram( material, parameters, code );
1469+
material.__webglShader = materialProperties.__webglShader;
14951470

1496-
if ( programChange ) {
1471+
program = programCache.acquireProgram( material, parameters, code );
14971472

1498-
program.usedTimes ++;
1473+
materialProperties.program = program;
1474+
material.program = program;
14991475

15001476
}
15011477

1502-
materialProperties.program = program;
1503-
material.program = program;
1504-
15051478
var attributes = program.getAttributes();
15061479

15071480
if ( material.morphTargets ) {

src/renderers/webgl/WebGLProgram.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,15 @@ THREE.WebGLProgram = ( function () {
454454

455455
};
456456

457+
// free resource
458+
459+
this.destroy = function() {
460+
461+
gl.deleteProgram( program );
462+
this.program = undefined;
463+
464+
};
465+
457466
// DEPRECATED
458467

459468
Object.defineProperties( this, {

src/renderers/webgl/WebGLPrograms.js

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
THREE.WebGLPrograms = function ( renderer, capabilities ) {
22

3-
var programs = [];
3+
var programs = renderer.info.programs;
44

55
var shaderIDs = {
66
MeshDepthMaterial: 'depth',
@@ -230,7 +230,7 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
230230

231231
};
232232

233-
this.getProgram = function ( material, parameters, code ) {
233+
this.acquireProgram = function ( material, parameters, code ) {
234234

235235
var program;
236236

@@ -242,6 +242,7 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
242242
if ( programInfo.code === code ) {
243243

244244
program = programInfo;
245+
++ program.usedTimes;
245246

246247
break;
247248

@@ -256,8 +257,24 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
256257

257258
}
258259

259-
return program ;
260+
return program;
260261

261-
}
262+
};
263+
264+
this.releaseProgram = function( program ) {
265+
266+
if ( -- program.usedTimes === 0 ) {
267+
268+
// Remove from unordered set
269+
var i = programs.indexOf( program );
270+
programs[ i ] = programs[ programs.length - 1 ];
271+
programs.pop();
272+
273+
// Free WebGL resources
274+
program.destroy();
275+
276+
}
277+
278+
};
262279

263280
};

0 commit comments

Comments
 (0)