Сей текст есть вольный перевод статьи
Хороший способ понять архитектуру wayland и то, как она отличается от архитектуры иксов - это следовать событиям.
- Ядро получает откуда-ть события и отправляет их в X-сервер через evdev, выполняя всю тяжелую работу по трансляции специфичного протокола устройства в стандартный линуксячий evdev.
- X-сервер определяют, на какие окна влияет событие и отправляет событие X-клиентам, выбранных для данного события. X-сервер нихрена не знает как отрисовать правильно, так как пространство экрана контролирует композер, и это пространство может быть деформировано.
- X-клиент, рассмотрев событие, решает что делать. Часто событие просит чего-ть отрисовать, например проставить флажек в чекбоксе, или там подсветить кнопку при наведении мыша. Вобщем X-клиент решает чего ему надо и отправляет запрос рендеринга в X-сервер.
- X-сервер, получив запрос рендеринга, отпраляет его в драйвер, дабы не скучал и хардверно все отрисовал. Также X-сервер вычисляет границы региона отрисовки и отсылает это в композер как событие "дефекта".
- Событие "дефекта" объясняет композеру что чтото изменилось,и надо бы перекомпозировать ту часть сцены, где изменения видны. Так как композер отвечает за отрисовку всего содержимого экрана на основе дерева сцены и содержимого окна, то он подготавливает нужное и опять-таки трогает X-сервер, дабы отрендерить результат.
- X-сервер получает запросы композера и либо копирует back буффер композера в свой front буффер, либо делает pageflip. В общем случае, X-сервер должен сделать этот шаг, чтобы определить потребуются ли отсечения для перекрывающихся окон, а также определить возможен ли page flip. Однако для композера, который постоянно в фулскрин это еще одно ненужное переключение контекста.
Вобщем проблемы в этом подходе есть. X-сервер не имеет информации для выбора окон, которые должны получить события, и не может выполнять преобразования координат экрана в локальные координаты окна. И хотя X-сервер передает композеру ответственность за окончательную картинку на экране, X-сервер все еще контролирует front buffer и modesetting.
Основная сложность в том, что X-сервер, используемый для обработки сейчас доступен в ядре или в библиотеках (KMS, evdev, mesa, fontconfig, freetype, cairo, Qt итд). Вобщем сейчас это просто посредник между приложениями и композером и между композером и железом.
В вэйланде композер это и есть сервер. Контроль над KMS и evdev опять-же у композера. Протокол вэйланда позволяет отправлять события ввода непосредственно клиентам и позволяет клиенту отослать событие дефекта непосредственно композеру.
- Ядро получает событие и отправляет его композеру. Это похоже на иксы, но круче, так как мы вдобавок получаем профит от использования одних и тех-же "входных" драйверов ядра.
- Композер просматривает дерево сцены для определения окна, которое должно получить сигнал. Так как дерево сцены соответствует тому, что на экране, то композер сразу же может применять преобразования координат, трансформацию и тд. Типы трансформации могут быть применены к окну только те, которые может сделать композер и до того момента, пока возможны обратные преобразования для входящих событий.
- Как и в случае с иксами, клиент, получая событие - обновляет интерфейс в ответе. Но в случае с вайлендом отрисовка проходит прямо в клиенте, и клиент потом просто указывает композеру область, которая была обновлена.
- Композер собирает события "дефекта" от своих клиентов, а потом рекомпозирует сцену, а следовательно и экран. Более того, композер может напрямую потрогать ioctl для того чтобы запланировать pageflip в KMS.
Одна из деталей, которая пропущена выше это то, как клиенты на самом деле рендерят под вайлендом. Удаляя X-сервер мы удаляем и механизм, посредством которго обычно делается рендеринг. Но есть и другой механизм: прямой рендеринг. С прямым рендерингом клиент и сервер используют один и тот-же буффер видеопамяти. Клиент линкует для рендеринга ту-же OpenGL, которая знает как общаться с железом. Композер, в свою очередь, может пользовать буфер как текстуру. Вобщем клиент, после начальной настройки, должен сообщить композеру - какой буфер пользовать, когда и где в нем рисовать.
Это оставляет приложению два способа рендеринга:
- Рендерим в новый буфер и просим композер использовать его вместо старого. Можно выделять каждый раз новый буфер, можно пустить по кругу два или более итд - это отдается под контроль приложения.
- Рендерим непосредственно в ранее отданный композеру буфер. Хотя так делать конечно можно, но есть шанс нарваться на гонку с композером. Со всеми вкусностями типа с не до конца наложенными текстурами, с артефактами. Традиционный способ обойти это - рендеринг в back buffer, а потом копировать его на поверхность композера. Back buffer может быть выделен под новый контент заново или приложение может пользовать один и тотже - пофиг. Опятьже - отдано под контроль приложения.
В любом случае приложение обязано сообщить композеру о том, какой регион поверхности претерпел изменения. И в первом и во втором случае. Смысл в том, что измениться могла лишь малая часть экрана (курсор моргнул) - и значит отрисовать надо только её.
Вэйланд является полной оконной системой сам по себе, но всетаки умеет работать и с иксами. Иксы могут быть модифицированы для использования устройства ввода вэйланд для ввода и форвардить корневое окно или окно верхнего уровня как вэйланд поверхность. Сервер работает с тем-же 2D драйвером с той-же акселерацией как тогда, когда он работает сам по себе.
зы: тут можно посмотреть на скриншоты, тут - инструкции для сборки, тут порт Qt для вэйланда
Комментариев нет:
Отправить комментарий