'CanvasRenderingContext2D.drawImage() slow when using a large WebGL canvas as source
Why is drawImage slow when using a large WebGL canvas as a source ?
This question stems from the following observation. If you paste this function to your browser's console:
function test(sourceCanvasWidth, sourceCanvasHeight, sourceContextType, delay) {
const srcCanvas = document.createElement('canvas');
const srcCtx = srcCanvas.getContext(sourceContextType);
srcCanvas.width = sourceCanvasWidth;
srcCanvas.height = sourceCanvasHeight;
const dstCanvas = document.createElement('canvas');
const dstCtx = dstCanvas.getContext('2d');
dstCanvas.width = 1024;
dstCanvas.height = 1024;
let start;
let count = 0;
function loop(timestamp) {
count++;
if (start === undefined) {
start = timestamp;
}
dstCtx.drawImage(srcCanvas, 0, 0, 1024, 1024, 0, 0, 1024, 1024);
// Stop after delay seconds
if (timestamp - start < delay * 1000) {
setTimeout(() => loop(Date.now()), 0);
} else {
console.log(`${count} loops (${count / 10} per seconds)`);
}
}
setTimeout(() => loop(Date.now()), 0);
}
And then call it with different canvas sizes:
test(1024, 1024, 'webgl', 10)
942 loops (94.2 per seconds)
test(4096, 4096, 'webgl', 10)
182 loops (18.2 per seconds)
You can see that performances significantly drop when using a large source canvas (Firefox 98 Linux). It is to be noted that if you use a 2d context as a source, there is no drop:
test(1024, 1024, '2d', 10)
1868 loops (186.8 per seconds)
test(4096, 4096, '2d', 10)
1825 loops (182.5 per seconds)
What the test function does is benchmark a configuration of canvas. I have a source canvas on which I can configure the size, the context type ('2d', 'webgl', 'webgl2') and a delay. I will then repeatedly draw the source canvas on the destination canvas which always have the same size (1024x1024). Note that drawImage always draws a 1024x1024 zone. The source canvas size does not change anything to drawImage parameters.
The drop is dependent on the browser. On Chromium (98 Linux) it is not so significant. But raise the resolution to 8192x8192 and you will see it. That's why we can't dismiss it as a Firefox bug because it happens in both browsers but at a different degree.
All in all, I see no justification of this drop specifically for WebGL canvas. In particular, it seems that browser will have their canvas in GPU memory above a certain size anyway. If someone could enlighten me.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
