更新:整个问题最终是与系统图形驱动有关,而不是(似乎)浏览器/API问题。撕裂的帧是由于实际显示更新引起的。再次感谢那些参与讨论和尝试帮助的人。
我有一个页面,使用画布和2D上下文以720p显示预渲染的画面。我单独渲染每一帧并将新的ImageData更新到变量中。然后,在requestAnimationFrame中,我只需执行context.putImageData(cached_image_data);
即可。尽管事先完全渲染了帧并且具有有效的双缓冲区,但仍然经常出现撕裂现象。我在SO上找到了几个类似的问题,但它们都以“使用RAF”结束。代码如下:
var canvas = document.getElementById("canvas");
var cached_frame = new ImageData(new Uint8ClampedArray(canvas.width * canvas.height * 4), canvas.width, canvas.height);
var context = canvas.getContext("2d");
var framerate = 30;
function draw() {
if (cached_frame)
context.putImageData(cached_frame, 0, 0);
requestAnimationFrame(draw);
}
setInterval(function() {
var frame = context.getImageData(0, 0, canvas.width, canvas.height);
// Do things to manipulate frame.data.
// Save the resultant pixel data for the cached_frame.
cached_frame.data = frame.data;
}, 1000 / framerate);
draw();
有没有其他方法可以不使用webgl来完成更多的任务?
欢迎提出任何建议。谢谢大家 :D
setInterval(function() { cached_frame = new ImageData(new Uint8ClampedArray(pixel_data)
会消耗大量内存。垃圾回收器会一直运行,因为每次间隔触发时都会创建新的Image和Uint8ClampedArray。请至少将它们保存为变量并重复使用。 - ericjbastigetImageData
/putImageData
。rAF 将有助于您的剪切。在同一个 rAF 中执行 getImageData 和 putImageData 操作。使用自动提供给draw(timestamp)
的时间戳参数来执行定时活动。将requestAnimationFrame(draw)
放在 draw() 的底部(而不是顶部)。Canvas 本身是双缓冲的,但如果您正在呈现视频,则可能需要缓冲额外的帧。 - markE