Эта статья изначально была размещена в 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.

Цель

  1. Обеспечьте единый интерфейс управления и настройки дисплеев для клиентов ozone-gbm.
  2. Разрешить клиентам 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

Ошибки

Список изменений

Ссылка