Я просто решил оставить тут несколько фактов о принципах работы wayland и их применимости на android.
И прежде всего я обращаю внимание на тот факт, что ровно две конторы решили сделать мобильные ОС поверх драйверов android: Canonical и Mozilla. Обе перед этим разрабатывали софт под андроид, ubuntu for android и firefox for android соответственно. В ходе разработки они столкнулись с одними и теми же проблемами и интересными решениями от команды разработчиков из Google. Разумность этих решений и побудила их к тому, что они делают.
Часть I, или wayland — не дисплейный сервер
Wayland — название протокола, описанного в XML файле. Из файла генерируется документация к протоколу и код на C, позволяющий общаться посредством этого протокола (libwayland). Если кто-то из разработчиков вейланда говорит вам, что «в вейланде явно не специфицируется то-то и то-то», его слова следует просто игнорировать: протокол-то не специфицирует, но реализация у него была и есть одна — weston — а он как раз специфицирует многие вещи; кроме того, попробуйте-ка заставить авторов тулкитов и mesa вот так взять и добавить поддержку особенностей альтернативной реализации протокола wayland (а таковой в будущем мог бы стать даже mir). С вас шкуру спустят, за то что опять фрагментируете бедное комьюнити своими забагованными альтернативными реализациями.
Часть II, pixmap <-> texture
На многих устройствах с android стоит относительно слабый процессор, и даже его мощность следует максимально беречь из-за батарейки (например, один из смартфонов самсунга имеет два ядра на 1,3 и 1,9 ГГц, но в нормальном режиме работает только слабое ядро), ОЗУ надо беречь из-за батарейки. Также на устройствах есть интеграшка вместо видеокарты и большой экран (у Samsung S3 он больше, чем у iPad без ретины). Увеличение размера экрана в n раз увеличивает число пикселей в n² раз. Как мы все уже знаем, современные тулкиты рисуют готовую картинку и отправляют её серверу, но делать это можно четырьмя способами
- Выделять места в памяти, рисовать там картинки, отправлять серверу. Это всегда даёт оверхед на ОЗУ, даёт оверхед на передачу данных по шине для дискретных видеокарт и оверхед на копирование памяти для интеграшек. OpenGL использовать нельзя, аппаратного ускорения нет. В начале своего пути Wayland умел только так.
- Выделять OpenGL framebuffer, рисовать туда командами OpenGL, забирать оттуда пиксели с помощью glReadPixels, а потом способ №1; про его оверхед уже сказано. Хотите я вас обрадую? У драйверов android есть баги, например, на видеокартах Qualcomm иногда пиксели из фреймбуфера читаются некорректно, потому что они оптимизировали вывод графики и потребление ресурсов с помощью тайлинга (разбиения фреймбуфера на квадраты 16x16, которые обрабатываются отдельно) и теперь не гарантируют, что весь фреймбуфер целиком может быть нормально разобран на пиксели. Отдельные баги, может быть, исправлены в android 4.2, но кто исправит их в android 4.1, на котором и основан cyanogen mode? Конкретные проблемы и сопутствующий оверхед можно пофиксить путём использования способа №4.
- Выделять OpenGL framebuffer, рисовать туда командами OpenGL, отдавать дисплейному серверу. Используется в weston и mir. Кстати, в обоих случаях используется библиотека EGL, которая выступает связующим звеном между объектами OpenGL/OpenGLES/OpenVG и знакомыми всем программистам понятиями из мира программной отрисовки, такими как pixmap, surface, и так далее. В обоих случаях надо попросить weston или mir создать окно, потом попросить libEGL о создании EGLSurface из полученного окна, а дальше уже средствами чистого EGL создать контекст OpenGL и другие ништяки. Недостаток — невозможность использовать частично программную отрисовку, всё только через GPU.
- В реальных устройствах на андроиде все карты — интеграшки, и выделенной памяти у них нет. Просим у драйвера видеокарты область оперативной памяти в виде EGLImage (у EGL для android есть такое нестандартное расширение), связываем его с текстурой либо фреймбуфером, рисуем в картинку софтварно и/или через OpenGL и используем дальше как текстуру. Это — идеал, именно он используется внутри андроида, но недоступен прямо через NDK или java: [1], [2], [3]. Нулевой оверхед на копирование, нулевой оверхед на ОЗУ. Поддерживают ли этот способ тулкиты на вейланде? Поддерживает ли его Weston? Зато есть заявления о работоспособности Weston под android и непонимание, зачем нужен Mir.
Впрочем, замечу, что Jolla пытается накостылить поддержку способа №4 в Weston [4].
Часть III, server allocated buffers
Wayland нам абсолютно неинтересен. Смотреть надо на Weston, и он действует так: клиент просит у видеодрайвера буфер, рисует в него что-то, а затем передаёт этот буфер и время, когда он был отрисован, для Weston через протокол Wayland с просьбой нарисовать. В Mir сделано иначе: клиент просит у Mir буфер, затем пишет в него что-то, затем просит другой буфер и одновременно передаёт имеющийся буфер для отображения на экране. Клиент работает через библиотеку mir-toolkit и не зависит от того, какие именно данные идут от него по сокету.
Преимущество подхода mir в том, что mir может воровать буферы у неактивных приложений и тем самым давать огромную экономию памяти [5]. Именно так сейчас поступает android, и, насколько известно, ios [6] [7].
Часть IV, ввод
Акселерометры, множественные касания, виртуальная клавиатура и аппаратная клавиатура, геймпады, датчики роботов — всё это уже сейчас работает в android. Mir просто взял эту часть гугловского surface flinger и перенёс к себе, отделив его от остального кода и подключив boost, добавил трансляцию в API Mir. Трансляция прямая, например, тип события мыши или касания напрямую кастуется в соответствующий enum из библиотеки mir-toolkit, и дальше передаётся клиенту (и тут же поправлюсь: 4 июля 2013 года кастования типа убрали для ещё большей совместимости с android, потому что иногда приходящее от Surface Flinger значение не укладывается в enum). Как результат, Mir поддерживает абсолютно все фичи ввода, доступные андроиду.
Тем временем в Weston всё ещё продумывают каждую мелкую деталь событий ввода в протоколе wayland. Это прекрасная работа и отличный задел на будущее, но полноценной обработки ввода на weston под android не будет в ближайшие 5-10 лет. Но тут есть выход: если в дисплейный сервер Mir будет добавлена поддержка протокола wayland, то он сможет транслировать события ввода андроида в протокол wayland и потребует для этого гораздо меньше отладки, чем Weston, потому что код mir уже покрыт тестами и может хостить Qt-шные приложения для андроида неотличимо от Surface Flinger.
Часть V, client-side decorations
Каждый тулкит рисует client-side decorations по-своему. Ниже будет список нюансов CSD, для которых должна быть поддержка со стороны каждого из тулкитов — и это очень грустная ситуация, потому что число тулкитов, способных написать и отладить весь этот код со всеми нюансами, резко сокращается. Уже сейчас только Qt5, gtk3 и EFL более-менее поддерживают последние решения вейланда. Итак, нюансы:
- Wayland не заставляет использовать клиент-серверные декорации, но мы уже знаем, что надо смотреть на Weston. Weston в общем и в целом заставляет, если не считать инициативу мейнтейнера kwin.
- Для тайлинга, полноэкранных окон и окон на пол-экрана CSD надо частично отключить. Wayland в лице его основателя предлагает [8] давать окнам подсказки, какие именно стороны окна должны быть без декораций. Кстати, именно так kwin может добиться серверных декораций — просто отключив CSD для всех четырёх сторон окна. На андроиде CSD не нужны, как и на любых устройствах с маленьким физическим размером экрана.
- Заголовок окна не рисуется для развёрнутых на весь экран окон в Unity, KDE Plasma Netbook [9] и, насколько я знаю, в GNOME. Wayland никак об этом не сообщает, но можно использовать тот же механизм, что для глобального меню.
- Порт Qt на wayland получает оверхед из-за CSD, и поэтому в Qt оставлен флаг для отключения CSD. Скорее всего, у других тулкитов будут те же трудности. Тем более CSD создают очевидный оверхед по оперативной памяти из-за того, что каждое приложение само собирает и хранит в памяти копию всей графики (растровой или векторной), необходимой для декораций.
Напоследок процитирую слова Мартина Грэсслина:
Is this fear valid? Well during said presentation Weston was running with two windows. They had different decorations. One was the terminal with minimize, maximize and close button on the right. One was a pdf viewer with a standard GNOME Shell decoration: minimize button missing. And during FOSDEM I had also a look on the decorations for Qt Wayland: again different decorations.
GNOME уже не раз убирал из своих приложений и из GTK фичи, непосредственно нужные другим DE. Например, автора Transmission попросили выкинуть что-то из уведомлений [10], причём багу присвоен тип «Улучшение» ☺. Дальше диалог развивался так:
Removing it altogether, as you suggest, will hurt XFCE users. I wish GNOME, Canonical, and everyone else involved would settle on one consistent API for this and stop fucking the app developers over.
Ответ:
I guess you have to decide if you are a GNOME app, an Ubuntu app, or an XFCE app unfortunately. I'm sorry that this is the case but it wasn't GNOME's fault that Ubuntu has started this fork. And I have no idea what XFCE is or does sorry.
Никогда у вас не будет нормальных клиентских декораций в официальном GTK 3. Забудьте об этом. Могут помочь те, кто патчит GTK в своём дистрибутиве — но пока конкретно этот тулкит более-менее патчит только Canonical.