Эта статья изначально была размещена в Google Docs.
Введение
Теоретически приложения с Ozone в Chromium могут выбирать свои серверные части, такие как X11, DRM/GBM, Wayland или безголовые, во время выполнения. Однако, если мы создадим content_shell с бэкэндом ozone-gbm(DRM/GBM), он ничего не отобразит на дисплее, потому что не реализует конфигуратор дисплея для настройки дисплея, который является частью Ash(Aura+shell). Следовательно, если мы хотим визуализировать пользовательский интерфейс клиентов ozone-gbm, каждый клиент ozone-gbm должен реализовать свой собственный конфигуратор отображения, как это делает ozone_demo. Однако каждый клиент должен реализовать одни и те же обработчики конфигурации отображения, что неэффективно. Кроме того, в CrOS уже реализованы функции управления отображением, такие как поддержка нескольких дисплеев, HDCP и менеджер компоновки дисплея, поэтому нам нужно найти способ поделиться этими функциями с приложениями, отличными от CrOS, такими как цифровые вывески, киоски, IVI, телевизионные приставки. коробка, цифровое телевидение, системы IoT и т. д.
В этом документе описывается, как реализовать единый интерфейс для клиентов ozone-gbm для настройки дисплея с помощью CrOS DisplayManager и DisplayConfigurator и как его можно использовать в клиентах ozone-gbm.
Цель
- Обеспечьте единый интерфейс управления и настройки дисплеев для клиентов ozone-gbm.
- Разрешить клиентам ozone-gbm, таким как CrOS, ozone_demo и т. д., использовать интерфейс.
Текущая архитектура CrOS для управления дисплеями
ash::Shell владеет DisplayManager и DisplayConfigurator. Это также зависит от ui::DisplayChangeObserver, который используется для создания сведений об отображении для передачи их в DisplayManager из ui::DisplayConfigurator путем отслеживания обратных вызовов конфигурации отображения.
Однако нам нужен единый интерфейс для настройки дисплеев, чтобы любые клиенты ozone-gbm могли более легко использовать функцию настройки дисплея.
Предлагаемая архитектура
Разрешить DisplayManager владеть DisplayConfigurator (Готово)
bool DisplayManager::SetDisplayMode(int64_t display_id, const ManagedDisplayMode& display_mode) { ... #if defined(OS_CHROMEOS) else if (resolution_changed && configure_displays_) delegate_->display_configurator()->OnConfigurationChanged(); #endif ... }
В настоящее время ui::DisplayManager взаимодействует с ui::DisplayConfigurator через ash::WindowTreeHostManager, но он может напрямую обращаться к ui::DisplayConfigurator, позволяя DisplayManager владеть DisplayConfigurator. Таким образом, мы могли бы избежать цепочки вызовов функций в приведенном выше коде.
Единый интерфейс для настройки дисплея и управления им
ui::DisplayManager может быть единым интерфейсом для клиентов ozone-gbm путем перемещения DisplayConfigurator и DisplayChangeObserver в DisplayManager, что может упростить связь между оболочкой CrOS и ui/Display/Manager. Клиенты Ozone-gbm могут легко использовать функции настройки/управления дисплеем, используя только DisplayManager.
Установите обратный вызов вместо создания NativeDisplayObserver
В этой архитектуре клиенты ozone-gbm не будут иметь NativeDisplayObserver, поэтому нет возможности наблюдать за изменением конфигурации дисплея. Вместо этого мы можем установить функцию обратного вызова в DisplayManager, чтобы функция обратного вызова могла запускаться при настройке дисплея.
Выполнение
1-й этап: отделить код конфигурации дисплея от CrOS (готово)
Во-первых, нам нужно отделить код конфигурации дисплея от CrOS, введя флаг сборки build_display_configuration, чтобы его можно было легко включить для любых клиентов ozone-gbm, которые уже были зафиксированы в транке:
https://chromium.googlesource.com/chromium/src/+/d3ae8737f7186154d2fdc3ccc5fe43bf290f91b5
Этот CL переместил все файлы в ui/display/manager/chromeos в ui/display/manager и добавил build_display_configuration GN arg.
2-й этап: добавьте макрос DISPLAY_CONFIGURATION
Однако, если мы попытаемся собрать content_shell с build_display_configuration без OS_CHROMEOS, все еще будут разрывы сборки, потому что часть кода конфигурации дисплея принадлежит сборке CrOS, поэтому нам нужно отделить этот код от сборки CrOS, введя макрос DISPLAY_CONFIGURATION.
if (build_display_configuration) { defines += [ “DISPLAY_CONFIGURATION” ] }
Кроме того, специальный код CrOS в коде конфигурации дисплея должен быть защищен макросом OS_CHROMEOS следующим образом:
#if defined(OS_CHROMEOS) if (!chromeos::IsRunningAsSystemCompositor()) return cached_displays; #endif
[WIP] https://chromium-review.googlesource.com/c/chromium/src/+/1399472
3-й этап: заставить ozone_demo работать с DisplayManager и DisplayConfigurator без собственного конфигуратора дисплея.
Вот пример кода для ozone_demo:
WindowManager::WindowManager(std::unique_ptr<RendererFactory> renderer_factory, base::OnceClosure quit_closure) : quit_closure_(std::move(quit_closure)), renderer_factory_(std::move(renderer_factory)) { if (!renderer_factory_->Initialize()) LOG(FATAL) << “Failed to initialize renderer factory”; std::unique_ptr<display::NativeDisplayDelegate> delegate( ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate()); if (delegate) { std::unique_ptr<display::Screen> screen(aura::TestScreen::Create(gfx::ScaleToCeiledSize( gfx::Size(800, 600), 2.0))); display::Screen::SetScreenInstance(screen.get()); display_configurator_ = std::make_unique<display::DisplayConfigurator>(); display_configurator_->Init(std::move(delegate), false); display_manager_ = std::make_unique<display::DisplayManager>(std::move(screen)); if (!display_manager_->InitFromCommandLine()) { display_change_observer_ = std::make_unique<display::DisplayChangeObserver>( display_configurator_.get(), display_manager_.get()); display_configurator_->AddObserver( display_change_observer_.get()); display_configurator_->set_state_controller( display_change_observer_.get()); display_configurator_->ForceInitialConfigure( base::BindRepeating( &WindowManager::OnConfigured, base::Unretained(this))); } else display_manager_->InitDefaultDisplay(); } else { LOG(WARNING) << “No display delegate; falling back to test window”; int width = kTestWindowWidth; int height = kTestWindowHeight; sscanf(base::CommandLine::ForCurrentProcess() ->GetSwitchValueASCII(kWindowSize).c_str(), “%dx%d”, &width, &height); DemoWindow* window = new DemoWindow(this, renderer_factory_.get(), gfx::Rect(gfx::Size(width, height))); window->Start(); } }
4-й этап: позволить DisplayManager владеть DisplayConfigurator
ui::DisplayManager будет владеть DisplayConfigurator и DisplayChangeObserver, поэтому клиенты ozone-gbm будут получать доступ к информации ui::Display путем настройки дисплеев только через ui::DisplayManager.
[Выполнено] https://chromium-review.googlesource.com/c/chromium/src/+/1418315
5-й этап: включить ускорение текстур и видео с нулевым копированием для gbm-клиентов.
Мы можем включить загрузку текстур с нулевым копированием и ускорение видео для любых клиентов ozone-gbm, таких как CrOS.
6-й этап: применить новый интерфейс конфигурации отображения к content_shell с поддержкой Layout Test
Мы можем протестировать функции аппаратного ускорения в реальной среде просмотра, что лучше, чем модульные тесты.
Другой подход заключается в том, что вместо применения функции настройки/управления отображением к content_shell мы можем создать бестелесную оболочку с новым озоновым бэкэндом (без тела).
План на будущее: внедрить бестелесный озон
ozone-bodiless — это новая платформа ozone, разработанная для приложений, которые хотят включить функции аппаратного ускорения, такие как ускорение видео, аппаратное наложение и загрузка текстур с нулевым копированием в системах Linux. Он обеспечивает поддержку полноэкранного просмотра с помощью Chromeless, что позволяет создавать новый пользовательский интерфейс с использованием веб-технологий. Вот некоторые функции, которые будет реализовывать ozone_bodliess:
- Всегда один WTH с размером окна, равным размеру дисплея для каждого дисплея.
- Поддержка нескольких дисплеев
- Ввод (клавиатура, мышь и сенсорный ввод) и поддержка курсора
- Поддержка всплывающих окон
- Ускорение видео и поддержка аппаратного наложения
- Поддержка HDCP
[Ошибка] https://bugs.chromium.org/p/chromium/issues/detail?id=936704
Ошибки
- Ozone-GBM не настраивает отображение на content_shell
- Разрешить запуск ozone-gbm на рабочем столе Linux/Intel
- Запустите content_shell с помощью ozone-gbm на рабочем столе Linux
- Реализовать единый интерфейс для клиентов ozone-gbm для настройки дисплеев
Список изменений
- https://chromium.googlesource.com/chromium/src/+/d3ae8737f7186154d2fdc3ccc5fe43bf290f91b5 (Готово)
- https://chromium-review.googlesource.com/c/chromium/src/+/1220719 (WIP)
- Разрешить DisplayManager владеть DisplayConfigurator (Готово)