为什么 webgl canvas 上下文比 2d canvas 使用更多的内存?
why webgl canvas context use much more memory than 2d canvas?
1024x1024 2d canvas 可能使用大约 1024 * 1024 * 4 = 4M 内存,但 webGL 上下文使用至少 5-10 倍的内存。
<!DOCTYPE html>
<html>
<body>
<div style="display:inline-block ;overflow: hidden;width: 512px;height: 512px;">
<canvas id="canvas" width="1024" height="1024" style="border: red 1px solid;transform: scale(0.5); transform-origin: 0 0;">old version need update</canvas>
</div>
</body>
<script>
var ctx = window.document.getElementById("canvas").getContext("webgl")
var gl = canvas.getContext("experimental-webgl");
</script>
</html>
可能有多种原因
默认情况下,webgl canvas 是 anti-aliased。
浏览器选择金额但检查
const gl = document.createElement('canvas').getContext('webgl');
const samples = gl.getParameter(gl.SAMPLES) || 1;
console.log(`samples is ${samples} so this canvas is actually ${gl.canvas.width * samples} x ${gl.canvas.height * samples} pixels big internally`);
在我的机器上 300x150 canvas 实际上是 1200x600 因为那是 how a GPU's built in antialiasing works
您可以通过在创建上下文时传入antialias: false
来关闭anti-aliasing
const gl = document.createElement('canvas').getContext('webgl', {
antialias: false,
});
const samples = gl.getParameter(gl.SAMPLES) || 1;
console.log(`samples is ${samples} so this canvas is actually ${gl.canvas.width * samples} x ${gl.canvas.height * samples} pixels big internally`);
WebGL 是双缓冲的
所以总会分配至少 2 个缓冲区,绘图缓冲区(您渲染到的缓冲区)和一个用于渲染页面的副本。因此,即使关闭抗锯齿功能,也会有 2 个缓冲区,其中 2D canvas 可能只有 1 个(这取决于浏览器对 canvas 2D 的作用)
WebGL 需要 GL 上下文和相关支持
WebGL 在浏览器内部创建某种上下文来跟踪所有状态。该状态是每个 WebGL 上下文。换句话说,如果您创建 2 个 WebGL 上下文,浏览器需要跟踪 2 组 WebGL 状态。在 Chrome 中,包括命令缓冲区和其他缓冲区,用于将命令和数据从进程 运行 网页传输到与 GPU 对话的进程。这本身可以是 2-4 兆。 Canvas 另一方面,2D 最有可能分配该信息一次并在所有 canvases 之间共享。在查看内存使用情况时甚至可能不会考虑它。
1024x1024 2d canvas 可能使用大约 1024 * 1024 * 4 = 4M 内存,但 webGL 上下文使用至少 5-10 倍的内存。
<!DOCTYPE html>
<html>
<body>
<div style="display:inline-block ;overflow: hidden;width: 512px;height: 512px;">
<canvas id="canvas" width="1024" height="1024" style="border: red 1px solid;transform: scale(0.5); transform-origin: 0 0;">old version need update</canvas>
</div>
</body>
<script>
var ctx = window.document.getElementById("canvas").getContext("webgl")
var gl = canvas.getContext("experimental-webgl");
</script>
</html>
可能有多种原因
默认情况下,webgl canvas 是 anti-aliased。
浏览器选择金额但检查
const gl = document.createElement('canvas').getContext('webgl');
const samples = gl.getParameter(gl.SAMPLES) || 1;
console.log(`samples is ${samples} so this canvas is actually ${gl.canvas.width * samples} x ${gl.canvas.height * samples} pixels big internally`);
在我的机器上 300x150 canvas 实际上是 1200x600 因为那是 how a GPU's built in antialiasing works
您可以通过在创建上下文时传入antialias: false
来关闭anti-aliasing
const gl = document.createElement('canvas').getContext('webgl', {
antialias: false,
});
const samples = gl.getParameter(gl.SAMPLES) || 1;
console.log(`samples is ${samples} so this canvas is actually ${gl.canvas.width * samples} x ${gl.canvas.height * samples} pixels big internally`);
WebGL 是双缓冲的
所以总会分配至少 2 个缓冲区,绘图缓冲区(您渲染到的缓冲区)和一个用于渲染页面的副本。因此,即使关闭抗锯齿功能,也会有 2 个缓冲区,其中 2D canvas 可能只有 1 个(这取决于浏览器对 canvas 2D 的作用)
WebGL 需要 GL 上下文和相关支持
WebGL 在浏览器内部创建某种上下文来跟踪所有状态。该状态是每个 WebGL 上下文。换句话说,如果您创建 2 个 WebGL 上下文,浏览器需要跟踪 2 组 WebGL 状态。在 Chrome 中,包括命令缓冲区和其他缓冲区,用于将命令和数据从进程 运行 网页传输到与 GPU 对话的进程。这本身可以是 2-4 兆。 Canvas 另一方面,2D 最有可能分配该信息一次并在所有 canvases 之间共享。在查看内存使用情况时甚至可能不会考虑它。