glBufferSubData очень медленно на многих устройствах Android

Это чистое решение для JavaScript без каких-либо библиотек или плагинов:

document.addEventListener('click', function (e) {
    if (hasClass(e.target, 'bu')) {
        // .bu clicked
        // Do your thing
    } else if (hasClass(e.target, 'test')) {
        // .test clicked
        // Do your other thing
    }
}, false);

, где hasClass -

function hasClass(elem, className) {
    return elem.className.split(' ').indexOf(className) > -1;
}

Live demo

Кредит относится к Dave и Sime Vidas

Использование более современных JS, hasClass может быть реализовано как:

function hasClass(elem, className) {
    return elem.classList.contains(className);
}

0
задан Nicol Bolas 28 March 2019 в 03:08
поделиться

1 ответ

Разница в производительности, которую вы видите, скорее всего, не просто разница между iOS / Android, но будет очень специфичной как для использования вами API, так и для реализации glBufferSubData в драйвере. Не видя больше кода или не зная, какие показатели производительности вы собираете, трудно комментировать дальше.

что означает «что рендеринг должен истечь из конвейера, прежде чем хранилище данных может быть обновлено», действительно означает?

Идея в том, что хотя API OpenGL дает иллюзию, что каждая команда выполняется до завершения перед продолжением, фактически рисование обычно разбивается на части и выполняется асинхронно в фоновом режиме. Проблема здесь заключается в том, что glBufferSubData потенциально добавляет точку синхронизации, что будет означать, что драйверу придется останавливаться, пока весь предыдущий рендеринг с использованием этого буфера не завершится, прежде чем продолжить.

Рассмотрим следующий пример. В хорошем случае у нас может быть что-то вроде этого:

  • glBufferSubData в буфер 1 с ABCDE
  • Вызов с использованием буфера 1
  • glBufferSubData в буфер 2 с FGHIJ
  • Отрисовка вызова с использованием буфера 2
  • Буферы подкачки < ----- Точка синхронизации, драйвер должен дождаться окончания рендеринга, прежде чем менять буферы

Однако, если вы перезаписываете тот же буфер, вы получите это вместо этого.

  • glBufferSubData в буфер 1 с ABCDE
  • Рисование вызова с использованием буфера 1
  • glBufferSubData в буфер 1 с перезаписью с помощью FGHIJ < ----- точки синхронизации в качестве драйвера должен убедиться, что буфер закончил использоваться первым вызовом отрисовки перед изменением данных
  • вызов отрисовки с использованием обновленного буфера 1
  • Обмен буферов < ----- Точка синхронизации, драйвер должен дождитесь окончания рендеринга, прежде чем менять буферы

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

0
ответ дан Laurie 28 March 2019 в 03:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: