javascript 使用后如何从 GPU 清理和卸载 WebGL 画布上下文?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23598471/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I clean up and unload a WebGL canvas context from GPU after use?
提问by Bartvds
How do you clean up a WebGL context program and unload the program, buffers and everything from the GPU and dom-element?
如何清理 WebGL 上下文程序并从 GPU 和 dom 元素中卸载程序、缓冲区和所有内容?
I'd like to make sure we're not littering.
我想确保我们没有乱扔垃圾。
Also it'd be nice to reuse the canvas if possible (and I don't know if it'd be 2d
or webgl
context).
如果可能的话,重用画布也很好(我不知道它是否会是2d
或webgl
上下文)。
回答by gman
You can just lose every reference to your gl context and all gl objects and the canvas and remove the canvas from the DOM. Unfortunately, because JavaScript is garbage collected there's no knowing when the browser will actually free the memory. There are some conformance tests to try to test they do this correctly but if you don't want to just hope and pray then ....
您可以丢失对 gl 上下文、所有 gl 对象和画布的所有引用,并从 DOM 中删除画布。不幸的是,因为 JavaScript 是垃圾收集的,所以不知道浏览器何时会真正释放内存。有一些一致性测试可以尝试测试它们是否正确执行此操作,但是如果您不想只是希望和祈祷,那么......
To free all your resources by calling gl.deleteXXX
on everything you created and unbind all bind points. That means for every texture unit call gl.bindTexture on all targets with null, the same with arrays, framebuffers and renderbuffers.
通过调用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);
Because you can't bind null to an attribute you could set the size of all your buffers to 1 (zero is not allowed) before you delete them. Either that or make a new buffer and assign it to all attributes.
因为您不能将 null 绑定到属性,所以您可以在删除它们之前将所有缓冲区的大小设置为 1(不允许为零)。要么创建一个新缓冲区并将其分配给所有属性。
Example of the first
第一个例子
// 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);
Or make a new buffer and assign it to all attributes
或者创建一个新的缓冲区并将其分配给所有属性
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);
}
This will unbind the old buffers from the attributes.
这将从属性中解除旧缓冲区的绑定。
Finally set the canvas size to 1x1 pixel.
最后将画布大小设置为 1x1 像素。
gl.canvas.width = 1;
gl.canvas.height = 1;
It's not a perfect solution but it will immediately free all but a few k of memory immediately, no waiting for garbage collection which is out of your control.
这不是一个完美的解决方案,但它会立即释放除几 k 内存之外的所有内存,无需等待您无法控制的垃圾收集。
As for reusing the canvas from scratch you can't. The canvas will always have the same context you first asked it for.
至于从头开始重用画布,你不能。画布将始终具有您最初要求它的相同上下文。
Also see @Johan's answer about loseContext
另请参阅@Johan's answer about loseContext
回答by Johan van Breda
To lose the context, use the extension WEBGL_lose_context as
要丢失上下文,请使用扩展 WEBGL_lose_context 作为
gl.getExtension('WEBGL_lose_context').loseContext();
See https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context/loseContext
见https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context/loseContext