Comment puis-je nettoyer et décharger un contexte de lien WebGL à partir du GPU après utilisation?

Comment nettoyer un programme de contexte WebGL et décharger le programme, les tampons et tout, depuis le GPU et l'élément dom?

Je voudrais m'assurer que nous ne sommes pas lâches.

Aussi, il serait bon de réutiliser le canevas si possible (et je ne sais pas si ce serait 2d ou webgl contexte webgl ).

Vous pouvez simplement perdre toutes les références à votre contexte gl et tous les objets gl et la toile et enlever le canevas du DOM. Malheureusement, car JavaScript est collecté, il n'y a pas de savoir quand le navigateur va effectivement libérer la mémoire. Il existe des tests de conformité pour essayer de tester qu'ils le font correctement, mais si vous ne voulez pas simplement espérer et prier, alors …

Pour libérer toutes vos ressources en appelant gl.deleteXXX sur tout ce que vous avez créé et dévisser tous les points de liaison. Cela signifie que pour chaque unité de texture, appelez gl.bindTexture sur toutes les cibles avec null, la même chose avec les tableaux, les framebuffers et les renderbuffers.

 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); 

Parce que vous ne pouvez pas lier nulle à un attribut, vous pouvez définir la taille de tous vos tampons sur 1 (zéro n'est pas autorisé) avant de les supprimer. Soit, soit créez un nouveau tampon et attribuez-le à tous les attributs.

Exemple de la première

 // 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); 

Ou créez un nouveau tampon et attribuez-le à tous les attributs

 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); } 

Cela libérera les anciens tampons des attributs.

Enfin, définissez la taille de la toile à 1×1 pixel.

 gl.canvas.width = 1; gl.canvas.height = 1; 

Ce n'est pas une solution parfaite, mais il sera tout de suite immédiatement gratuit, mais quelques k de mémoire, sans attendre la collecte des ordures qui est hors de votre contrôle.

En ce qui concerne la réutilisation de la toile à partir de zéro, vous ne pouvez pas. La toile aura toujours le même contexte que vous l'avez demandé.

Voir aussi la réponse de @ Johan sur loseContext

Pour perdre le contexte, utilisez l'extension WEBGL_lose_context comme

 gl.getExtension('WEBGL_lose_context').loseContext(); 

Voir https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context/loseContext