Compartir a través de


Creación de una aplicación de compositor personalizada para monitores especializados y montados en la cabeza

La API Windows.Devices.Display.Core es una API de Windows Runtime (WinRT) de bajo nivel para compositores de terceros y componentes internos de Windows que se encuentran debajo de todas las demás API públicas para enumerar, configurar y conducir adaptadores de pantalla y destinos de visualización en Windows. La idea es tratar el controlador de pantalla como un motor independiente, análogo al motor 3D y al motor multimedia en la GPU. Esta API es responsable de:

  • Responder a consultas sobre el hardware de visualización (como funcionalidades y posibles modos de visualización)
  • Respuesta a consultas sobre la configuración actual
  • Establecer propiedades en el hardware de presentación (como los modos de visualización)
  • Configuración del hardware de visualización (la resolución de los monitores conectados, su formato de conexión, etc.)
  • Asignar y examinar superficies especiales de GPU conocidas como principales
  • Permitir la interoperabilidad entre Direct3D y las API Windows.Devices.Display.Core (por ejemplo, compartir superficies, vallas)

Merece la pena llamar lo que Windows.Devices.Display.Core no es:

  • No es una API usada por juegos o aplicaciones para mostrar contenido en una ventana. Las aplicaciones siguen usando DXGI, XAML, API de composición, GDI, etc.
  • No es una API usada por juegos o aplicaciones para mostrar contenido en pantalla completa. Las aplicaciones siguen usando DXGI, las aplicaciones Win32 siguen usando HWND y las aplicaciones para UWP siempre muestran contenido en CoreWindow.

Esta API es solo para aplicaciones compositoras que impulsan hardware especializado.

Diagrama que muestra las capas de arquitectura de API para pantallas especializadas.

Escenarios para crear compositores personalizados

Las API Windows.Devices.Display.Core son adecuadas para su uso en los escenarios siguientes:

  • Pantallas de realidad virtual y aumentada que requieren un compositor propietario para controlar directamente el controlador de pantalla y recibir un control específico sobre la configuración de tiempo y modo independiente del escritorio de Windows.
  • Escenarios de hardware de visualización especializados que requieren un control dedicado sobre una pantalla en una configuración comercial. Por ejemplo, en los casos en los que el escritorio de Windows no se puede representar correctamente en esta pantalla debido a la guerra de hardware, las pantallas de escala de grises, etc.
  • Escenarios especializados de "dispositivo" en los que un monitor puede estar totalmente dedicado a una aplicación sin interferencias de la experiencia de escritorio de Windows durante un largo período de tiempo (por ejemplo, un monitor de vídeo dedicado).

La API lo logra:

  • Proporcionar un control específico sobre la información del modo de visualización completa, incluido el formato de cable, HDR, etc.
  • El uso de barreras para sincronizar la presentación permite a un compositor encadenar la presentación entre procesos o sub-componentes con casi cero sobrecarga de rendimiento.
  • Mejora de la capacidad de consultar y configurar la red de vídeo presente subyacente (VidPN) para permitir que los componentes del sistema y los componentes de composición de bajo nivel realicen operaciones más complejas de una manera menos propensa a errores y más extensible.

Tenga en cuenta que esta API solo es para un conjunto muy específico de casos de uso de terceros con hardware especializado. Su uso está muy restringido al hardware que se declara que necesita la funcionalidad de esta API. Por lo tanto, se espera un cierto grado de familiaridad con los conceptos de hardware de los desarrolladores y los asociados deben ponerse en contacto con Microsoft directamente para ayudar con problemas.

Requisitos de hardware y software

Los compositores personalizados de terceros solo pueden adquirir pantallas designadas previamente como pantallas montadas en la cabeza (HMD) o "especializadas". Esta designación debe proporcionarse de una de estas dos maneras:

  • Extensión EDID: los dispositivos de visualización personalizados diseñados para su uso permanente como HMD, monitores de rayos X, paredes de vídeo u otros escenarios especializados deben implementar la extensión EDID de Microsoft para pantallas montadas y especializadas.
  • Invalidación de usuario: en el caso de las instalaciones de hardware personalizadas mediante monitores fuera del estante, Windows proporciona un botón de alternancia de interfaz de usuario para designar monitores como "especializados".

Es posible que las pantallas no se designan como HMD o pantallas especializadas invalidando el EDID en el software.

Nota:

Las pantallas especializadas solo están disponibles a partir de Windows 10, versión 2004 y requieren Windows 10 Enterprise, Windows 10 Pro para estaciones de trabajo o Windows 10 IoT Enterprise.

Hoja de ruta para implementar un compositor personalizado

La implementación de un compositor personalizado se puede dividir en varias fases:

  • Enumerar y detectar HMD asociados o pantallas especializadas
  • Adquirir la propiedad de las pantallas seleccionadas
  • Configurar modos para todas las pantallas seleccionadas
  • Crear recursos para presentar fotogramas a las pantallas
  • Representación de contenido y presentación de fotogramas de programación
API Audiencia objetivo y propósito
DisplayInformation Se usa para recuperar las propiedades de representación y diseño de coreWindow.
HdmiDisplayInformation API solo de Xbox para enumerar y establecer un conjunto restringido de modos. Altamente especializado para escenarios de aplicaciones multimedia de Xbox.
DisplayMonitor Se usa para consultar las propiedades de un dispositivo de supervisión física. No expone ninguna información en tiempo de ejecución sobre cómo el sistema operativo configura o usa actualmente un monitor.
EnumDisplayDevices, EnumDisplayMonitors, EnumDisplaySettingsEx API de Win32 heredadas para consultar HMONITOR, dispositivos GDI y asignaciones de monitores físicos. La información devuelta aquí está altamente virtualizada y mantenida para la compatibilidad de aplicaciones.
Direct3D Se usa para representar contenido de píxeles en superficies de GPU y realizar cálculos en una GPU.
Cadenas de intercambio DXGI Se usa para la presentación en pantalla completa con ventanas y sin bordes. El contenido de la cadena de intercambio de aplicaciones fluye a través del compositor del sistema, DWM.
Enumeración de salida DXGI Proporciona contenedores DXGI alrededor de HMONITOR.
QueryDisplayConfig, SetDisplayConfig, DisplayConfigGetDeviceInfo, DisplayConfigSetDeviceInfo API de Win32 para configurar la topología para mostrar. No proporciona ningún mecanismo para enumerar varios modos, pero tiene un amplio conjunto de información sobre la configuración y las opciones actuales. Sin embargo, estas API no exponen todas las propiedades más recientes de un modo.
Windows.Devices.Display.Core (este documento) Se usa para enumerar destinos, enumerar modos, configurar modos, asignar superficies de GPU para presentación y presentar contenido a pantallas.

Información general sobre la configuración de visualización

Enumeración de hardware físico

La API Windows.Devices.Display.Core tiene varios objetos para representar objetos de hardware físicos. Un DisplayAdapter suele ser (pero no siempre) un dispositivo de hardware físico, como una GPU conectada a PCI Express o una GPU integrada en una CPU. Los objetos DisplayTarget representan los conectores físicos (por ejemplo, HDMI, VGA, DisplayPort, etc.) a los que se puede conectar desde la GPU. Esto puede incluir conexiones internas no visibles para usuarios para dispositivos con monitores internos (portátiles, tabletas, etc.). Puede haber más objetos DisplayTarget representados en software que los usuarios pueden conectarse físicamente a la vez. Por ejemplo, dado que el estándar de conexión DisplayPort permite el encadenamiento de margaritas, los controladores de GPU suelen enumerar varios destinos de DisplayPort por puerto físico para tener en cuenta los monitores encadenados.

Ilustración de la topología de hardware para adaptadores de pantalla y destinos de visualización.

Objetos para los modos de configuración

Para enumerar objetos DisplayTarget , establecer y consultar modos, etc. las conexiones a objetos DisplayTarget se representan con objetos DisplayPath . Los grupos de rutas de acceso que muestran el mismo contenido (grupos clonados) se representan mediante DisplayView y se agregan a displayState. Por lo tanto, un objeto DisplayState puede representar un conjunto completo de estados de modo que se puede enviar a controladores para varios monitores.

Ilustración de la topología de modo con la ruta de acceso para mostrar, la vista de visualización y los objetos de estado de visualización.

Estado atómico para la configuración y enumeración del modo

La API Windows.Devices.Display.Core está diseñada para garantizar que los compositores puedan adquirir acceso a varios estados de visualización del sistema de forma atómica y con comportamientos de obsolescencia bien definidos. Esto es importante porque las GPU son recursos compartidos, con restricciones de ancho de banda y energía muy estrechas. En los sistemas modernos, los dispositivos pueden llegar o salir en cualquier momento y otras cosas pueden afectar a la lista de modos de visualización disponibles (por ejemplo, acoplamiento o desacoplación, estados de suspensión, otros modos de cambio de componente en otra ruta de acceso). Por lo tanto, es importante que los compositores sean resistentes a los cambios en la configuración del sistema mediante la API Windows.Devices.Display.Core y los siguientes patrones recomendados para configurar el estado.

Por lo tanto, la API Windows.Devices.Display.Core proporciona un modelo de lectura y confirmación transaccional simple, similar a una base de datos. Los clientes pueden leer de forma atómica un objeto DisplayState para dispositivos de visualización en el sistema. Todos los objetos son inmutables o proporcionan API bien definidas para actualizar o confirmar el estado en el sistema. Los cambios no se realizan hasta que se llama a DisplayState.TryApply , que "confirma" los cambios en el sistema. Confirmar o aplicar cambios a displayState produce un error sin ningún impacto o se realiza correctamente con los cambios completos aplicados.

Para aprovechar las características de atomicidad de la API:

  • Escriba cualquier lógica de configuración de modo en un bucle de reintento.
  • Cree un displayState al principio de la configuración del modo, dentro de cada bucle.
  • Use la marca FailIfStateChanged al llamar a DisplayState.TryApply para detectar que el estado del sistema ya no es el mismo que cuando se creó displayState. Esto le permite volver a intentar la operación. Si se produce un error en la operación con SystemStateChanged, vuelva a intentar el bucle completo.
  • No combine otras API (DXGI, GDI, etc.) que lean o cambien el estado con el uso de las API Windows.Devices.Display.Core, ya que es posible que no tengan las mismas garantías de atomicidad.
#include <winrt\Windows.Devices.Display.Core.h>
using namespace winrt::Windows::Devices::Display::Core;
...

// Create a DisplayManager
DisplayManager manager = DisplayManager::Create(DisplayManagerOptions::EnforceSourceOwnership);

// Loop around trying to acquire a target and set a mode
bool shouldRetry;
do
{
    shouldRetry = false;

    // ... Find the target that you want to use
    auto targets = manager.GetCurrentTargets();
    DisplayTarget selectedTarget = ...;

    auto stateCreationResult = manager.TryAcquireTargetsAndCreateEmptyState(
        winrt::single_threaded_vector<DisplayTarget>({ selectedTarget }));

    if (stateCreationResult.ErrorCode() != DisplayManagerResult::Success)
    {
        winrt::check_hresult(stateCreationResult.ExtendedErrorCode());
    }

    auto state = stateCreationResult.State();
    DisplayPath newPath = state.ConnectTarget(selectedTarget);

    // ... Configure the path

    auto applyResult = state.TryApply(DisplayStateApplyOptions::FailIfStateChanged);

    if (applyResult.Status() == DisplayStateOperationStatus::SystemStateChanged)
    {
        shouldRetry = true;
    }
    else if (applyResult.Status() != DisplayStateOperationStatus::Success)
    {
        winrt::check_hresult(applyResult.ExtendedErrorCode());
    }

} while (shouldRetry);

Las SIGUIENTES API leen el estado de forma atómica desde el sistema:

Las SIGUIENTES API confirman el estado en el sistema:

  • DisplayManager
  • DisplayState
    • TryApply Actualiza el estado de visualización actual del sistema estableciendo o desactivando modos en todos los destinos propiedad del sistema, a través de los controladores de pantalla.

Restricciones conocidas

La API Windows.Devices.Display.Core tiene varias limitaciones conocidas (a partir de Windows 10, versión 2004):

  • Los controladores de pantalla indirectos (por ejemplo, Miracast, adaptadores de pantalla USB, controladores de software) no se pueden solucionar actualmente. DisplayManager.CreateDisplayDevice producirá un error cuando se pase un adaptador de pantalla indirecto.

Código de ejemplo

Para obtener una aplicación de ejemplo, consulte Ejemplo de compositor personalizado Windows.Devices.Display.Core.