11.17.2010

Архитектура wayland

Сей текст есть вольный перевод статьи


Хороший способ понять архитектуру wayland и то, как она отличается от архитектуры иксов - это следовать событиям.


Итак, иксы:




  1. Ядро получает откуда-ть события и отправляет их в X-сервер через evdev, выполняя всю тяжелую работу по трансляции специфичного протокола устройства в стандартный линуксячий evdev.

  2. X-сервер определяют, на какие окна влияет событие и отправляет событие X-клиентам, выбранных для данного события. X-сервер нихрена не знает как отрисовать правильно, так как пространство экрана контролирует композер, и это пространство может быть деформировано.

  3. X-клиент, рассмотрев событие, решает что делать. Часто событие просит чего-ть отрисовать, например проставить флажек в чекбоксе, или там подсветить кнопку при наведении мыша. Вобщем X-клиент решает чего ему надо и отправляет запрос рендеринга в X-сервер.

  4. X-сервер, получив запрос рендеринга, отпраляет его в драйвер, дабы не скучал и хардверно все отрисовал. Также X-сервер вычисляет границы региона отрисовки и отсылает это в композер как событие "дефекта".

  5. Событие "дефекта" объясняет композеру что чтото изменилось,и надо бы перекомпозировать ту часть сцены, где изменения видны. Так как композер отвечает за отрисовку всего содержимого экрана на основе дерева сцены и содержимого окна, то он подготавливает нужное и опять-таки трогает X-сервер, дабы отрендерить результат.

  6. X-сервер получает запросы композера и либо копирует back буффер композера в свой front буффер, либо делает pageflip. В общем случае, X-сервер должен сделать этот шаг, чтобы определить потребуются ли отсечения для перекрывающихся окон, а также определить возможен ли page flip. Однако для композера, который постоянно в фулскрин это еще одно ненужное переключение контекста.


Вобщем проблемы в этом подходе есть. X-сервер не имеет информации для выбора окон, которые должны получить события, и не может выполнять преобразования координат экрана в локальные координаты окна. И хотя X-сервер передает композеру ответственность за окончательную картинку на экране, X-сервер все еще контролирует front buffer и  modesetting.


Основная сложность в том, что X-сервер, используемый для обработки сейчас доступен в ядре или в библиотеках (KMS, evdev, mesa, fontconfig, freetype, cairo, Qt итд). Вобщем сейчас это просто посредник между приложениями и композером и между композером и железом.


В вэйланде композер это и есть сервер. Контроль над KMS и evdev опять-же у композера. Протокол вэйланда позволяет отправлять события ввода непосредственно клиентам и позволяет клиенту отослать событие дефекта непосредственно композеру.




  1. Ядро получает событие и отправляет его композеру. Это похоже на иксы, но круче, так как мы вдобавок получаем профит от использования одних и тех-же "входных" драйверов ядра.

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

  3. Как и в случае с иксами, клиент, получая событие - обновляет интерфейс в ответе. Но в случае с вайлендом отрисовка проходит прямо в клиенте, и клиент потом просто указывает композеру область, которая была обновлена.

  4. Композер собирает события "дефекта" от своих клиентов, а потом рекомпозирует сцену, а следовательно и экран. Более того, композер может напрямую потрогать ioctl для того чтобы запланировать pageflip в KMS.


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


Это оставляет приложению два способа рендеринга:




  1. Рендерим в новый буфер и просим композер использовать его вместо старого. Можно выделять каждый раз новый буфер, можно пустить по кругу два или более итд - это отдается под контроль приложения.

  2. Рендерим непосредственно в ранее отданный композеру буфер. Хотя так делать конечно можно, но есть шанс нарваться на гонку с композером.  Со всеми вкусностями типа с не до конца наложенными текстурами, с артефактами. Традиционный способ обойти это - рендеринг в back buffer, а потом копировать его на поверхность композера. Back buffer может быть выделен под новый контент заново или приложение может пользовать один и тотже - пофиг. Опятьже - отдано под контроль приложения.


В любом случае приложение обязано сообщить композеру о том, какой регион поверхности претерпел изменения. И в первом и во втором случае. Смысл в том, что измениться могла лишь малая часть экрана (курсор моргнул) - и значит отрисовать надо только её.


Вэйланд является полной оконной системой сам по себе, но всетаки умеет работать и с иксами. Иксы могут быть модифицированы для использования устройства ввода вэйланд для ввода и форвардить корневое окно или окно верхнего уровня как вэйланд поверхность. Сервер работает с тем-же 2D драйвером с той-же акселерацией как тогда, когда он работает сам по себе.




зы: тут можно посмотреть на скриншоты, тут - инструкции для сборки, тут порт Qt для вэйланда





Оригинал записи - в личном блоге. Комментировать можно тут, но желательно там.

Комментариев нет: