Оптимальная скорость рисования пикселей? - PullRequest
2 голосов
/ 22 января 2010

Я использую объект Canvas с JavaScript. Просто сделаю несколько тестов, чтобы увидеть, как быстро я могу установить пиксели в цикле рисования.

На Mac это прекрасно работает в FF, Safari, Chrome. На окнах я получаю мерцающий эффект на FF и Chrome. Похоже, как-то реализация canvas в Windows отличается от Mac для разных браузеров? (не уверен, что это правда).

Это основной код, который я использую для рисования (взято из статьи ниже - я оптимизировал нижеприведенное, чтобы затянуть цикл рисования, теперь он работает довольно плавно):

var canvas = document.getElementById('myCanvasElt');
var ctx = canvas.getContext('2d');
var canvasData = ctx.getImageData(0, 0, canvas.width, canvas.height);
for (var x = 0; x < canvasData.width; x++) {
    for (var y = 0; y < canvasData.height; y++) {
        // Index of the pixel in the array
        var idx = (x + y * canvas.width) * 4;
        canvasData.data[idx + 0] = 0;
        canvasData.data[idx + 1] = 255;
        canvasData.data[idx + 2] = 0;
        canvasData.data[idx + 3] = 255;
    }
}
ctx.putImageData(canvasData, 0, 0);

снова, браузеры на окнах будут немного мерцать. Похоже, что реализация canvas пытается очистить холст до белого цвета перед следующей операцией рисования (это не происходит в Mac). Мне интересно, есть ли параметр, который я могу изменить в объекте Canvas, чтобы изменить это значение (двойная буферизация, очистка перед рисованием и т. Д.)?

Это статья, которую я использую для справки: http://hacks.mozilla.org/2009/06/pushing-pixels-with-canvas/

Спасибо

Ответы [ 2 ]

1 голос
/ 06 июня 2011

Я думаю, что довольно ясно, что браузеры, которые реализуют объект 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 и т. Д.

Кроме того, пытались ли вы создать невидимый объект холста, нарисовать его и затем скопировать на видимый холст? Это может быть быстрее (правильная двойная буферизация).

0 голосов
/ 22 января 2010

Проблема заключается в том, как браузеры используют собственные графические API-интерфейсы в разных ОС. И даже в одной и той же ОС использование разных API (например, GDI или Direct2D в Windows) также приведет к разным результатам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...