How to free and garbage collect a WebGL context?

后端 未结 1 1977
Happy的楠姐
Happy的楠姐 2021-01-11 17:25

I\'m developing a WebGL application for web and mobile. I often use hard-refreshs to test the results of my WebGL implementation. After a view tries, I get the error:

1条回答
  •  攒了一身酷
    2021-01-11 17:49

    I think maybe I misunderstood your question

    You say you're doing hard refreshes. Meaning you're pressing refresh in the browser? In that case first I'd disable all extensions and see if the issue is still there. If it is I'd file a bug with mozilla

    Otherwise if you are trying to free canvases and create knew ones and hoping for garbage collection well.. here's the answer I wrote before I re-read your question


    The short answer is you can't force garbage collection. You'd be better off re-using the same canvases.

    There's a solution here to freeing all the data and resetting the canvas

    How do I clean up and unload a WebGL canvas context from GPU after use?

    In your particular case though are you 100% sure you're not holding on to some reference to the WebGL context or canvas? For example if you do this

    canvas.addEventListener('click', function(..) {});
    

    You've just made a canvas that can NEVER be garbage collected. It has an event listener function attached. You have no way to remove that function since you didn't keep a reference to it. You need to remove all listeners as just one example of many ways you might be leaking references.

    There's tons of ways to accidentally keep references to HTML elements like the canvas as well as WebGL objects. Keep more than zero references and it will never be garbage collected.

    Here's some hints on finding the leaks

    On the other hand if it was me I'd try to re-use the canvases. To make sure I freed everything I might call my own creation/deletion functions that track all the resources. Example

    var textures = [];
    function createTexture(gl) {
      var tex = gl.createTexture();
      textures.push(txt);
    }
    
    function deleteTexture(gl, tex) {
      gl.deleteTexture(tex);
      textures.splice(textures.indexOf(tex), 1);
    }
    

    Now because I'm tracking all the textures I can easily delete all the remaining ones

    while (textures.length) {
      gl.deleteTexture(textures.pop());
    }
    

    0 讨论(0)
提交回复
热议问题