Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/456.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将阵列缓冲器的一部分绘制到画布上的最佳方法是什么?_Javascript_Html_Canvas_Asm.js - Fatal编程技术网

Javascript 将阵列缓冲器的一部分绘制到画布上的最佳方法是什么?

Javascript 将阵列缓冲器的一部分绘制到画布上的最佳方法是什么?,javascript,html,canvas,asm.js,Javascript,Html,Canvas,Asm.js,我有一个ArrayBuffer,还有一个名为module.repaint的函数,它与ArrayBuffer一起工作。在每次重画调用中,我都希望将颜色从ArrayBuffer放到画布上 我是这样做的: imgData.data.set(new Uint8ClampedArray(MEM, 0, siz)); 但是,有可能将ArrayBuffer的一部分复制到另一个更快的位置吗? 代码: 如果可能,重构您的模块。repaint()以使用屏幕外画布而不是像素阵列。 这样,您就可以将图像从屏幕外的画布

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

我是这样做的:

imgData.data.set(new Uint8ClampedArray(MEM, 0, siz));
但是,有可能将ArrayBuffer的一部分复制到另一个更快的位置吗? 代码:


如果可能,重构您的模块。repaint()以使用屏幕外画布而不是像素阵列。

这样,您就可以将图像从屏幕外的画布绘制到屏幕上的画布上——这很有效,因为GPU可以执行blitting,而不是加重CPU的负担


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

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

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

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

使用该代码,
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();
};

该模块是一个asmjs模块。堆对象的byteLength必须是4096的倍数,堆对象的byteLength必须是2的幂。马克:没错,drawImage与putImageData的速度提升是巨大的,很可能远远超过使用asmjs所能提供的@迭代器:阅读markE的答案怎么样?但是如果我想使用
drawImage
方法,那么我必须在每个循环中将实际的图像数据转换为图像。我不知道如何从ArrayBuffer读取字节,并将像素快速写入画布。
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();
};