繁体   English   中英

将一个数组缓冲区绘制到画布上的最佳方法是什么?

[英]What is the best way, to draw a part of an arraybuffer to the canvas?

我有一个ArrayBuffer ,我有一个名为module.repaint的函数,它与ArrayBuffer一起使用。 在每次重绘调用中,我都希望将ArrayBuffer中的颜色放到画布上。

我是这样做的:

imgData.data.set(new Uint8ClampedArray(MEM, 0, siz));

但是有可能将ArrayBuffer的一部分更快地复制到另一个吗? 码:

var MEM = new ArrayBuffer(2*1024*1024);
var canvas, ctx, imgData, siz;

var repaint = function() {
    // module.repaint works on the arraybuffer
    module.repaint();

    imgData.data.set(new Uint8ClampedArray(MEM, 0, siz));
    ctx.putImageData(imgData, 0, 0);

    requestAnimationFrame(repaint);
};

var init = function() {
    canvas = document.getElementById('canvas');
    ctx = canvas.getContext('2d');

    siz = canvas.width*canvas.height*4;

    imgData=ctx.createImageData(canvas.width,canvas.height);

    repaint();
};

如果可能,重构module.repaint()以使用屏幕外画布而不是像素数组。

这样你就可以将屏幕外画布绘制到屏幕画布上 - 效率很高,因为GPU可以进行blitting而不是增加CPU的负担。

putImageData较慢,因为它涉及CPU从像素数组中获取数据,在temp数组中设置该数据并将temp数组传输到屏幕上的imageData。 这些都是负担CPU并降低性能的活动。

请注意,我没有检查增益是否重要,但我可以在这里看到一些有用的优化。

首先, Uint8ClampedArray是缓冲区的视图,而不是缓冲区本身,因此您不需要每次都创建它。 (您还可以在单​​个缓冲区上拥有多个视图)

您还应该避免使用imgData.dataset方法,因为它将所有数据从一个数组复制到另一个数组(这是无用的)。 相反,您可以在构造函数上设置Uint8ClampedArray

使用该代码, MEM上的每个更改都将自动影响imgData因为imgData.data直接指向MEM

var MEM = new ArrayBuffer(2*1024*1024);
var canvas, ctx, imgData, siz;

var repaint = function() {
    // module.repaint works on the arraybuffer
    module.repaint();

    ctx.putImageData(imgData, 0, 0);

    requestAnimationFrame(repaint);
};

var init = function() {
    canvas = document.getElementById('canvas');
    ctx = canvas.getContext('2d');

    siz = canvas.width*canvas.height*4;

    imgData = ctx.createImageData(new Uint8ClampedArray(MEM, 0, siz), canvas.width, canvas.height);

    repaint();
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM