使用后如何从 GPU 清理和卸载 WebGL 画布上下文?

2023-12-20

如何清理 WebGL 上下文程序并从 GPU 和 dom-element 卸载程序、缓冲区和所有内容?

我想确保我们没有乱扔垃圾。

另外,如果可能的话,重用画布会很好(而且我不知道是否会这样)2d or webgl语境)。


您可以丢失对 gl 上下文、所有 gl 对象和画布的所有引用,并从 DOM 中删除画布。不幸的是,因为 JavaScript 是垃圾收集的,所以不知道浏览器何时真正释放内存。有一些一致性测试来尝试测试它们是否正确执行此操作,但如果您不想只是希望和祈祷那么......

通过调用释放您的所有资源gl.deleteXXX在您创建的所有内容上并取消绑定所有绑定点。这意味着对于每个纹理单元调用gl.bindTexture在所有目标上null,与数组、帧缓冲区和渲染缓冲区相同。

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 内存之外的所有内存,无需等待超出您控制的垃圾收集。

至于从头开始重复使用画布,你不能。画布将始终具有您最初要求的相同上下文。

另请参阅@约翰的回答 https://stackoverflow.com/a/38027471/1480391 about loseContext

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用后如何从 GPU 清理和卸载 WebGL 画布上下文? 的相关文章

随机推荐

  • Krajee Bootstrap 文件输入,捕获 AJAX 成功响应

    我正在使用 Krajee Bootstrap 文件输入插件通过 AJAX 调用执行上传 以下是 Krajee 插件 AJAX 部分的链接 Krajee 插件 AJAX http plugins krajee com file input d
  • 使用 Hilt 将存储库注入 Android 中的服务

    我有一个带有 Hilt 依赖注入的 Android 项目 我已经定义了MyApplication and MyModule如下 HiltAndroidApp class MyApplication Application Module In
  • 使用 Javascript 打开 vCard

    使用二维码电子名片 用户用手机扫描该代码 然后手机上会弹出 添加到联系人 对话框 例如下面的代码 我怎样才能做到同样的事情 但我希望它通过单击按钮来完成相同的操作 而不是扫描二维码 我已经尝试过以下方法 var btn document g
  • 如何在 Alpine Docker 镜像上安装 gdbserver 包?

    我一直在尝试在 Alpine Docker 映像上安装 gdbserver 包 https hub docker com alpine https hub docker com alpine apk添加gdbserver 给了我这个 错误
  • Kotlin 如何创建动态对象

    在 javascript 中我们可以做这样的事情 function putritanjungsari data console log data name let data name putri div m4th putritanjungs
  • 选择不具有特定类的元素的最后一个子元素

    我尝试选择没有特定类别的子元素的最后一个元素 我已经设置了一个js fiddle http jsfiddle net VATaj 2
  • 在 Woocommerce 3 中通过 ajax 提交并创建结帐订单

    我在结账表单中添加了一个按钮
  • 为什么引入新的 JSLint 错误“使用空格,而不是制表符”和“不安全字符”?

    我使用 JSLint 验证 JavaScript 已经有大约 2 年了 偶尔会有一些规则发生变化 一般来说 当 JSLint 引入新规则时 会有一个复选框可以在解析时忽略此规则 或者如果您选择不忽略它 则使您的代码符合它 然而 当我今天运行
  • android LiveData 或协程通道

    让应用程序使用 LiveData 和 ViewModel for UI 来观察存储库中的数据更新 它运行良好 现在有人提出 LiveData还没有被很好地采用 也许应该改用协程的通道 首先不确定关于LiveData的说法是否准确 我确信使用
  • Python远程过程调用(不带远程部分)

    我有一个不以 root 身份运行的 Python 服务器 它面向我正在开发的应用程序 然而 有一些应用程序功能需要访问 RAW 套接字 这意味着 root 权限 显然 我不想以 root 身份运行主服务器 因此我的解决方案是创建一个守护进程
  • SQL Server + 实体框架基础知识

    我的任务是用 C 创建一个程序来管理公司的员工 仅简要概述 每个员工的所有信息都存储在 MS SQL 数据库中 作为表示层 我必须使用 WPF 并作为与数据库的通信 LINQ to Entities 问题是 我设法自学了 WPF 但 SQL
  • 制作一个 24/7 运行并从命名管道读取的 Perl 守护进程

    我正在尝试使用 perl 制作一个日志分析器 分析器将在 AIX 服务器上的后台全天候 24 7 运行 并从系统日志将日志定向到的管道 从整个网络 读取 基本上 logs from network gt named pipe A gt pe
  • TDD:您为单元测试公开了哪些方法?

    TDD 有一个方面我从未完全理解 假设有人要求您实现一个简单的 Stack 对象 如果您的设计正确 您将得到一个非常最小且干净的 API 认为 push pop and isEmpty 除此之外 任何事情都会过度抑制需求 并让用户有太多的空
  • 导出和导入 IndexedDB 数据

    我正在制作一个供我自己使用的工具 需要一个简单的数据库 这似乎是学习 HTML5 IndexedDB API 的好机会 但重要的是我在任何时候都不会丢失数据 我想备份浏览器的配置文件目录就可以进行备份 但我也希望可能使用不同的计算机 因此导
  • 从github导入ADT Eclipse中的android项目

    我正在尝试将 android 项目从 github 导入到 ADT Eclipse 中 但当我克隆它时 它在存储库中找不到任何项目 该仓库显然是一个android应用程序项目 从源代码来看 但没有找到可以导入的项目 我的步骤如下 在 包资源
  • 在函数重载中将右值引用实现为参数

    我已经询问过有关代码审查和软件工程的问题 但该主题不适合该网站 因此我在这里询问希望这不是基于意见的 我是一名 老派 C 开发人员 我已经停留在 C 2003 但现在我已经阅读了一些有关现代 C 11 17 的书籍 并且正在重写我的一些库
  • Python3.10源码venv已经改变

    我在个人仓库上做了一些 python leetcode 在我将 Kubuntu 升级到 22 04 后 我意识到当前的 venv 不起作用 我想我需要重新创建 venv 安装了 python3 10 venv 但我无法获取并激活它 事实上
  • Apache Spark:map、flatMap、mapPartitions、mapPartitionsWithIndex 的比较

    Apache Spark map flatMap mapPartitions mapPartitionsWithIndex 的比较 欢迎提出建议 以提高我们的知识 地图 函数 它有什么作用 通过提供的函数传递 RDD 的每个元素 即功能 平
  • 优化运行时间:改变igraph中边的权重需要很长时间。有没有办法优化它?

    我正在从 osmar 对象构建的 igraph 中搜索一组边 并希望更改这些边的权重 由于我的图表很大 因此这项任务需要很长时间 由于我在循环中运行此函数 因此运行时间变得更大 有什么办法可以优化这个吗 这是代码 library osmar
  • 使用后如何从 GPU 清理和卸载 WebGL 画布上下文?

    如何清理 WebGL 上下文程序并从 GPU 和 dom element 卸载程序 缓冲区和所有内容 我想确保我们没有乱扔垃圾 另外 如果可能的话 重用画布会很好 而且我不知道是否会这样 2d or webgl语境 您可以丢失对 gl 上下