2010-01-22 3 views
2

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

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

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

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/

Благодаря

ответ

0

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

+1

Да, я думаю, что с этим ничего не поделаешь - нет способа сказать Canvas изменить способ, которым браузер реализует перерисовку, не так ли? Как символ canvas.pleaseDoubleBuffer = "true"? – user246114

+0

Или я имею в виду - кажется, что полотно на некоторых реализациях стирается до белого после каждой ничьей - если это можно отключить, все будет идеально. Не думайте, что есть что-то подобное. – user246114

+0

К сожалению, я не знаю, как управлять тем, как canvas использует базовые API OS. –

1

Я думаю, что довольно ясно, что браузеры, реализующие объект Canvas, используют DIBS (независимые от устройства растровые изображения). Доказательством этого является тот факт, что у вас есть доступ к пиксельному буферизу без необходимости блокировки дескриптора. И Direct2D не имеет ничего общего с JS в браузере, это точно. GDI отличается тем, что использует DDB (зависимые от устройства растровые изображения, то есть выделенные из видеопамяти, а не обычные). Все это, однако, не имеет никакого отношения к оптимальной скорости рендеринга JS. Я думаю, что писать значения RGBA, как вы, вероятно, лучший способ.

Решающим фактором в коде выше является вызов putImageData(). Здесь браузеры могут различаться в своей реализации. Вы на самом деле пишете непосредственно в DIB, а putImageData - это просто оболочка InvalidateRect? Или вы на самом деле записываете дубликат в память, который, в свою очередь, копируется в контекст canvas? Если вы используете linux или mac, это все равно правильный вопрос. Хотя контексты устройств и т. Д. Обычно являются терминами «окон», большинство ОС имеют дело с ручками или структурами почти так же. Но еще раз мы находимся во власти поставщика браузера.

Я думаю, можно сказать следующее:

Если вы рисуете много пикселей на одном дыхании, а затем писать прямо на pixelbuffer, как и вы, вероятно, лучше всего. Быстрее «битрейт» (копировать) pixelbuffer за один проход после X числа операций. Причина этого в том, что встроенные функции графики, такие как FillRect, также называют «invalidate rectangle», который сообщает системе, что часть, если на экране требуется повторная ничья (обновление). Поэтому, если вы вызываете 100 линейных команд, тогда будет выпущено 100 обновлений - замедление процесса. Если (и это не улов), вы используете методы beginPath/EndPath, поскольку они должны использоваться. Тогда это совершенно другой мяч.

Здесь вступает в действие «система» начала и конца пути, а также команды «Обводка/контур». Они позволяют выполнять X число операций рисования в рамках одного обновления. Но многие люди ошибаются и вызывают перерисовку для каждого звонка в строку/заполнение и т. Д.

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

Смежные вопросы