如何清理WebGL上下文程序并从GPU和dom-element卸载程序,缓冲区和所有内容?
我想确保我们不乱扔垃圾。
如果可能的话,重复使用画布也是很好的(我不知道它是2d
还是webgl
上下文。)
答案 0 :(得分:19)
您可以丢失对gl上下文和所有gl对象和画布的每个引用,并从DOM中删除画布。不幸的是,因为JavaScript被垃圾收集,所以不知道浏览器何时会实际释放内存。有一些一致性测试试图测试他们是否正确地做了这个,但如果你不想只是希望并祈祷......
通过在您创建的所有内容上调用gl.deleteXXX
来释放所有资源,并取消绑定所有绑定点。这意味着对于每个纹理单元,在所有具有null的目标上调用gl.bindTexture,与数组,帧缓冲区和渲染缓冲区相同。
var numTextureUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
for (var unit = 0; unit < numTextureUnits; ++unit) {
gl.activeTexture(gl.TEXTURE0 + unit);
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
}
gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
// Delete all your resources
// Note!!!: You'd have to change this code to delete the resources YOU created.
gl.deleteTexture(someTexture);
gl.deleteTexture(someOtherTexture);
gl.deleteBuffer(someBuffer);
gl.deleteBuffer(someOtherBuffer);
gl.deleteRenderbuffer(someRenderbuffer);
gl.deleteFramebuffer(someFramebuffer);
因为您无法将null绑定到属性,所以您可以在删除它们之前将所有缓冲区的大小设置为1(不允许为零)。或者创建一个新缓冲区并将其分配给所有属性。
第一个
的例子// set a buffer to 1 byte before deleting
// NOTE: You'd need to do this for ALL BUFFERS you created.
gl.bindBuffer(gl.ARRAY_BUFFER, someArrayBuffer);
gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW);
gl.deleteBuffer(someArrayBuffer);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, someElementArrayBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, 1, gl.STATIC_DRAW);
gl.deleteBuffer(someElementArrayBuffer);
或制作新缓冲区并将其分配给所有属性
var buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
var numAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
for (var attrib = 0; attrib < numAttributes; ++attrib) {
gl.vertexAttribPointer(attrib, 1, gl.FLOAT, false, 0, 0);
}
这将从属性中解除旧缓冲区的绑定。
最后将画布大小设置为1x1像素。
gl.canvas.width = 1;
gl.canvas.height = 1;
它不是一个完美的解决方案,但它会立即释放除了几k内存之外的所有内存,而不是等待你无法控制的垃圾收集。
至于从头开始重新使用画布,你不能。画布将始终具有您首次要求的相同上下文。
另见@ Johan关于loseContext
答案 1 :(得分:7)
要丢失上下文,请使用扩展名WEBGL_lose_context作为
gl.getExtension('WEBGL_lose_context').loseContext();
请参阅https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context/loseContext