Показать сообщение отдельно
Старый 02.02.2012, 12:40
maxkar вне форума Посмотреть профиль Отправить личное сообщение для maxkar Найти все сообщения от maxkar
  № 31  
Ответить с цитированием
maxkar

Регистрация: Nov 2010
Сообщений: 497
Цитата:
Сообщение от Black Soviet Посмотреть сообщение
В параметрах публикации Flash, выставил "Аппаратное ускорение - direct (прямое ускорение)" как советовали на буржуйских форумах. Тоже не помогло.
А покажите код, которым вы флешку на страницу вставляете. Там должно быть wmode="direct". И только direct! Если он не стоит, результат рендеринга кадра отдается бразуеру, а браузерам обычно не интересно заниматься вертикальной синхронизацией.

Цитата:
Спасибо, сегодня в свободное время постараюсь реализовать и выложить резултат.
Не поможет. Потому что проблемы происходят не на этапе рендеринга, а на этапе передачи картинки монитору .

Цитата:
То есть как я понимаю проблема в том Flash начинает рисовать объект на новом месте, до конца не удалив его с предыдущего, в результате на объекте видны мерцающие горизонтальные полосы.
Нет!

Придется, правда, рассказать, как работают мониторы и видеотракт.
Так получилось, что первые мониторы были на электронно-лучевых трубках. В них "луч" бегал по экрану сверху вниз и слева направо, зажигая нужные люминофоры. В сигнале передавалась служебная информация (информация о начале/конце строки/кадра) и уровни сигналов для каждой точки, проходимой лучом.
Проще всего реализовывать такой обмен так - выделяется непрерывный блок памяти, и при обмене на выход видеокарты просто передаются "перекодированные в сигнал" значения байтов этой памяти. После окончания прохода буфер начинает передаваться заново. Занимается этим специальный чип (или часть общего чипа), который подключен к видеовыходам.
Сейчас схема передачи изображения на монитор принципиально не поменялась. Да, сигнал стал цифровым, но значения пикселей все равно передаются по-очереди и видеокарты также используют непрерывный буфер.

Теперь рассмотрим способы формирования изображения.
Как проще всего формировать изображение? Да просто изменяя значения байтов в той самой выделенной области. А что будет, если область одновременно читается и записывается? Правильно, на монитор уйдет часть "старых" данных и часть "новых". Где будет старая часть, а где новая - зависит от скоростей "читателя" (передающего картинку на монитор) и писателя. Если скорость писателя выше, новая часть будет "снизу". Если выше скорость "читателя" - сверху. Вот так и образуется "tearing" на экране. (Кстати, двойной "tearing" как у вас на картинке - все же ситуация нетипичная и редкая)
Для избавления от tearing'а тоже было придумано решение. И достаточно простое. Не нужно писать в "выводимый" кадр, нужно писать в отдельную область и после выдачи экрана выводить только полностью сформированную область. Это называется double buffering. Отрисовка производится в один буфер, а в это время второй буфер передается на монитор. После полной передачи буфера они меняются местами. Теперь на монитор передается тот буфер, который рисовался, а отрисовка производится в буфер, который только что выводился на экран. Этот механизм реализуется видеокартой. Но есть одна проблема - приложение, выполняющее отрисовку, тоже должно знать об этой схеме и правильно переключать буфера. "Просто автоматически" переключать не получится - приложение может не успеть обновить буфер и продолжит писать в "выводимый на экран" буфер. Если я не ошибаюсь, переключение буферов делается явно приложением (командой видеокарте).

Теперь вернемся к браузерам и флешу. При большинстве значений wmode флеш генерирует картинку и передает ее браузеру со словами "отрисуй-ка ты мне ее". Даже wmode="gpu" работает по этой схеме, правда само изображение формируется с использованием видеокарты. Дальше за вывод картинки отвечает браузер. Сейчас браузеры не используют вертикальную синхронизацию (им это особо и не нужно), поэтому он работает по "первой" схеме (прямая запись в видеобуфер). Ну а это и приводит к артефактам. Заметьте, что ошибка происходит на этапе вывода изображения и передачи на монитор! Никакие программные ухищрения во флеш не могут повлиять на этот эффект. А сам эффект зависит от стечения множества обстоятельств (например, от того, попал ли обмен с кадром "посередине" передачи кадра или нет).
Теперь разберем wmode="direct". Он позволяет флешке установить контроль над выводимой частью экрана. Для этого используется технология "overlay", которая позволяет составлять образ экрана из нескольких различных буферов. В основном буфере требуемая область заливается определенным цветом (одним и сплошным, цвет может быть разный). Само изображение формируется в другом буффере. При выводе проверяется цвет выводимого пикселя и при необходимости пиксель заменяется другим из буфера (с необходимой трансляцией координат). Сейчас вывод overlay-поверхностей поддерживается аппаратно видеокартой. overlay'и часто используются при выводе видео. Для буферов в этом случае тоже доступны почти все имеющиеся возможности, в том числе двойная буферизация. wmode="direct" как раз и включает эту технологию. В этом случае на странице рисуется прямоугольник определенного цвета, а flash-player формирует буфер кадра в памяти видеокарты минуя браузер. И только в этом случае флеш может переключать выдаваемый кадр "целиком", что и избавляет от проблемы tearing'а.

Выводы.
1. Никакие программные пляски с бубном вокруг двойной и тройной буферизации на стороне flash-player'а не помогут без включенного wmode="direct". С другой стороны, со включенным wmode="direct" (и при правильной реализации флеша, сейчас она правильная) данная проблема не возникает вообще. И никакие пляски с бубном вокруг программной двойной буферизации не нужны.
2. Проявление эффекта зависит от массы различных факторов и может нестабильно проявляться даже на одном и том же компьютере (например, в разных частях изображения или не во всех случаях).