¿Por qué drawImage es lento cuando se usa un gran lienzo WebGL como fuente?
Esta pregunta surge de la siguiente observación. Si pega esta función en la consola de su navegador:
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); }Y luego llámalo con diferentes tamaños de lienzo:
test(1024, 1024, 'webgl', 10) 942 loops (94.2 per seconds) test(4096, 4096, 'webgl', 10) 182 loops (18.2 per seconds) Puede ver que el rendimiento se reduce significativamente cuando se utiliza un lienzo de origen grande (Firefox 98 Linux). Cabe señalar que si usa un contexto 2d como fuente, no hay caída:
test(1024, 1024, '2d', 10) 1868 loops (186.8 per seconds) test(4096, 4096, '2d', 10) 1825 loops (182.5 per seconds) Lo que hace la función de prueba es comparar una configuración de lienzo. Tengo un lienzo de origen en el que puedo configurar el tamaño, el tipo de contexto ('2d', 'webgl', 'webgl2') y un retraso. Luego, dibujaré repetidamente el lienzo de origen en el lienzo de destino, que siempre tendrá el mismo tamaño (1024x1024). Tenga en cuenta que drawImage siempre dibuja una zona de 1024x1024. El tamaño del lienzo de origen no cambia nada en los parámetros de drawImage .
La caída depende del navegador. En Chromium (98 Linux) no es tan significativo. Pero sube la resolución a 8192x8192 y lo verás. Es por eso que no podemos descartarlo como un error de Firefox porque ocurre en ambos navegadores pero en diferente grado.
Considerándolo todo, no veo ninguna justificación de esta caída específicamente para el lienzo WebGL. En particular, parece que el navegador tendrá su lienzo en la memoria de la GPU por encima de cierto tamaño de todos modos. Si alguien pudiera iluminarme.