簡體   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