Я думаю, что довольно ясно, что браузеры, которые реализуют объект Canvas, используют DIBS (независимые от устройства растровые изображения). Тот факт, что у вас есть доступ к пиксельному буферу без предварительной блокировки дескриптора, является доказательством этого. И Direct2D не имеет ничего общего с JS в браузере, это точно. GDI отличается тем, что использует DDB (зависящие от устройства растровые изображения, то есть выделяемые из видеопамяти, а не обычного ОЗУ). Однако все это не имеет ничего общего с оптимальной скоростью рендеринга JS. Я думаю, что написание значений RGBA, как вы делаете, вероятно, лучший способ.
Важным фактором в приведенном выше коде является вызов метода putImageData (). Это где браузеры могут отличаться по своей реализации. Вы на самом деле пишете напрямую в DIB, а putImageData - это просто оболочка для InvalidateRect? Или вы на самом деле пишете дубликат в памяти, который, в свою очередь, копируется в контекст устройства canvas? Если вы используете Linux или Mac, то это все еще актуальный вопрос. Хотя контексты устройств и т. Д. Обычно являются терминами «окон», большинство ОС работают с дескрипторами или структурами практически одинаково. Но еще раз, мы в зависимости от поставщика браузера.
Я думаю, что можно сказать следующее:
Если вы рисуете много пикселей за один раз, то, вероятно, лучше всего писать прямо в пиксельный буфер, как вы делаете. Это быстрее "bitblt" (копировать) pixelbuffer за один раз после X количество операций. Причина этого заключается в том, что встроенные графические функции, такие как FillRect, также вызывают «недействительный прямоугольник», который сообщает системе, что часть экрана нуждается в повторном рисовании (обновлении). Поэтому, если вы вызовете 100 команд строки, будет выпущено 100 обновлений, что замедляет процесс. Если (и это не подвох) вы используете методы beginPath / EndPath так, как они должны использоваться. Тогда это совершенно другая игра в мяч.
Именно здесь вступает в игру «система» пути начала / конца, а также команды обводки / контура. Они позволяют вам выполнить X операций рисования за одно обновление. Но многие люди понимают это неправильно и перерисовывают каждый вызов линии / fillrect и т. Д.
Кроме того, пытались ли вы создать невидимый объект холста, нарисовать его и затем скопировать на видимый холст? Это может быть быстрее (правильная двойная буферизация).