I have an ArrayBuffer
, and I have a function called module.repaint, which works with the ArrayBuffer. In every redraw call, I would like to put the colors from the ArrayBuffer to the canvas.
I do it like this:
imgData.data.set(new Uint8ClampedArray(MEM, 0, siz));
But is it possible, to copy a part of the ArrayBuffer to an other faster? Code:
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();
};
If possible, refactor your module.repaint() to use an offscreen canvas instead of a pixel array.
That way you can just drawImage the offscreen canvas to the onscreen canvas--efficient because the GPU can do the blitting instead of burdening the CPU.
putImageData
is slower because it involves the CPU fetching data from the pixel array, setting that data in your temp array and transferring the temp array to the onscreen imageData. These are all activities that burden the CPU and reduce performance.
Note that I didn't check if the gain is important, but I can see some useful optimizations here.
First, Uint8ClampedArray
is a view to the buffer, not a buffer itself, so you don't need to create it everytime. (You can also have multiple views on a single buffer)
You should also avoid using the set
method of imgData.data
because it copies all the data from one array to another (which is useless). Instead, you can set your Uint8ClampedArray
on the constructor.
With that code, each change on MEM
will automatically affect imgData
because imgData.data
directly points to 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();
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.