Skip to content

Commit 8c77ba4

Browse files
committed
Merge pull request mrdoob#7159 from tschw/FixPrograms
Renderer: Fixed WebGLPrograms factorization.
2 parents bd8c360 + 99e185f commit 8c77ba4

File tree

3 files changed

+72
-65
lines changed

3 files changed

+72
-65
lines changed

src/renderers/WebGLRenderer.js

Lines changed: 40 additions & 62 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,9 +129,9 @@ THREE.WebGLRenderer = function ( parameters ) {
131129

132130
_infoMemory = {
133131

134-
programs: 0,
135132
geometries: 0,
136-
textures: 0
133+
textures: 0,
134+
programs: 0
137135

138136
},
139137

@@ -150,10 +148,18 @@ THREE.WebGLRenderer = function ( parameters ) {
150148

151149
render: _infoRender,
152150
memory: _infoMemory,
153-
programs: _programs
151+
programs: null
154152

155153
};
156154

155+
Object.defineProperty( _infoMemory, 'programs', { get: function() {
156+
157+
var programs = _this.info.programs;
158+
return programs !== null ? programs.length : 0;
159+
160+
} } );
161+
162+
157163
// initialize
158164

159165
var _gl;
@@ -215,6 +221,8 @@ THREE.WebGLRenderer = function ( parameters ) {
215221
var objects = new THREE.WebGLObjects( _gl, properties, this.info );
216222
var programCache = new THREE.WebGLPrograms( this, capabilities );
217223

224+
this.info.programs = programCache.programs;
225+
218226
var bufferRenderer = new THREE.WebGLBufferRenderer( _gl, extensions, _infoRender );
219227
var indexedBufferRenderer = new THREE.WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
220228

@@ -589,41 +597,13 @@ THREE.WebGLRenderer = function ( parameters ) {
589597

590598
function releaseMaterialProgramReference( material ) {
591599

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

596602
material.program = undefined;
597603

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-
}
604+
if ( programInfo !== undefined ) {
626605

606+
programCache.releaseProgram( programInfo );
627607
}
628608

629609
}
@@ -1442,15 +1422,15 @@ THREE.WebGLRenderer = function ( parameters ) {
14421422
var parameters = programCache.getParameters( material, lights, fog, object );
14431423
var code = programCache.getProgramCode( material, parameters );
14441424

1445-
1425+
var program = materialProperties.program;
14461426
var programChange = true;
14471427

1448-
if ( ! materialProperties.program ) {
1428+
if ( program === undefined ) {
14491429

14501430
// new material
14511431
material.addEventListener( 'dispose', onMaterialDispose );
14521432

1453-
} else if ( materialProperties.program.code !== code ) {
1433+
} else if ( program.code !== code ) {
14541434

14551435
// changed glsl or parameters
14561436
releaseMaterialProgramReference( material );
@@ -1467,41 +1447,39 @@ THREE.WebGLRenderer = function ( parameters ) {
14671447

14681448
}
14691449

1470-
if ( parameters.shaderID ) {
1450+
if ( programChange ) {
14711451

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

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

1481-
} else {
1456+
materialProperties.__webglShader = {
1457+
name: material.type,
1458+
uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
1459+
vertexShader: shader.vertexShader,
1460+
fragmentShader: shader.fragmentShader
1461+
};
14821462

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

1490-
}
1465+
materialProperties.__webglShader = {
1466+
name: material.type,
1467+
uniforms: material.uniforms,
1468+
vertexShader: material.vertexShader,
1469+
fragmentShader: material.fragmentShader
1470+
};
14911471

1492-
material.__webglShader = materialProperties.__webglShader;
1472+
}
14931473

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

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

1498-
program.usedTimes ++;
1478+
materialProperties.program = program;
1479+
material.program = program;
14991480

15001481
}
15011482

1502-
materialProperties.program = program;
1503-
material.program = program;
1504-
15051483
var attributes = program.getAttributes();
15061484

15071485
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: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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,27 @@ 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+
};
279+
280+
// Exposed for resource monitoring & error feedback via renderer.info:
281+
this.programs = programs;
262282

263283
};

0 commit comments

Comments
 (0)