Arquitectura y componentes
Nota:
En el caso de las aplicaciones de Windows 10, se recomienda usar las API de Windows.UI.Composition en lugar de DirectComposition. Para obtener más información, consulta Modernize your desktop app using the Visual layer (Modernización de la aplicación de escritorio mediante la capa visual).
En este tema se describen los componentes que componen Microsoft DirectComposition. Consta de las secciones siguientes.
Componentes de software
DirectComposition consta de los siguientes componentes de software principales.
- Una biblioteca de aplicaciones en modo de usuario (dcomp.dll) que implementa la API pública basada en el modelo de objetos componentes (COM).
- Un motor de composición en modo de usuario (dwmcore.dll) hospedado en el proceso administrador de ventanas de escritorio (DWM) (dwm.exe) y realiza la composición real del escritorio.
- Base de datos de objetos en modo kernel (parte de win32k.sys) que serializa los comandos de la aplicación al motor de composición.
Una única instancia del motor de composición controla los árboles de composición DirectComposition para todas las aplicaciones y el árbol de composición DWM, que representa todo el escritorio. Tanto la base de datos de objetos en modo kernel como el motor de composición en modo de usuario se crean instancias una vez por sesión, por lo que un equipo de Terminal Server con varios usuarios tiene varias instancias de ambos componentes.
En el diagrama siguiente se muestran los componentes principales de DirectComposition y cómo se relacionan entre sí.
Biblioteca de aplicaciones
La biblioteca de aplicaciones DirectComposition es una API pública basada en COM con un único punto de entrada plano que se exporta desde dcomp.dll y devuelve un puntero de interfaz a un objeto de dispositivo. El objeto de dispositivo, a su vez, tiene métodos para crear todos los demás objetos, cada uno de los cuales se representa mediante un puntero de interfaz. Todas las interfaces DirectComposition heredan de e implementan completamente la interfaz IUnknown . Todos los métodos que aceptan interfaces DirectComposition comprueban si la interfaz se implementa dentro de dcomp.dll o si está implementada por otro componente. Dado que DirectComposition no es extensible, los métodos que toman interfaces como parámetros devuelven E_INVALIDARG si las interfaces no se implementan en dcomp.dll. La API no requiere privilegios especiales; se puede llamar mediante procesos que se ejecutan en el nivel más bajo de acceso. Sin embargo, dado que la API no funciona en la sesión 0, no es adecuada para los servicios. En estos aspectos, directComposition API es similar a otras API de Microsoft DirectX, especialmente Direct2D, Microsoft Direct3D y Microsoft DirectWrite.
Dado que el motor de composición está diseñado exclusivamente para la ejecución asincrónica, las propiedades de objeto de directComposition API son de solo escritura. Todas las propiedades tienen métodos establecedores, pero no métodos captadores. La lectura de propiedades no solo consume muchos recursos, sino que también puede ser inexacta porque cualquier valor que devuelve el motor de composición puede dejar de ser válido de inmediato. Esto puede ocurrir si, por ejemplo, una animación independiente está enlazada a la propiedad que se está leyendo.
La API es segura para subprocesos. Una aplicación puede llamar a cualquier método desde cualquier subproceso en cualquier momento. Sin embargo, dado que se debe llamar a muchos métodos de API en una secuencia determinada, sin ninguna sincronización, una aplicación puede experimentar un comportamiento imprevisible en función de cómo intercalen los subprocesos. Por ejemplo, si dos subprocesos cambian la misma propiedad del mismo objeto a valores diferentes al mismo tiempo, la aplicación no puede predecir cuál de los dos valores será el valor final de la propiedad. Del mismo modo, si dos subprocesos llaman a Commit en el mismo dispositivo, ninguno obtiene un comportamiento realmente transaccional porque una llamada a Commit en un subproceso enviará el lote de todos los comandos emitidos por ambos subprocesos, no solo el que llamó a Commit.
El sistema mantiene todo el estado interno por objeto de dispositivo. Si una aplicación crea dos o más objetos de dispositivo DirectComposition, la aplicación puede mantener lotes independientes y otro estado entre los dos.
Todos los objetos DirectComposition tienen afinidad de objeto de dispositivo; Los objetos creados por un objeto de dispositivo determinado solo se pueden usar con ese objeto de dispositivo y solo se pueden asociar a otros objetos creados por el mismo objeto de dispositivo. En otras palabras, cada objeto de dispositivo es una isla separada de funcionalidad separada. La única excepción es la clase visual, que permite la creación de árboles visuales donde un objeto visual puede pertenecer a un objeto de dispositivo diferente al de su elemento primario. Esto permite escenarios en los que una aplicación y un control pueden administrar un único árbol de composición sin necesidad de compartir un solo objeto de dispositivo DirectComposition.
Motor de composición
El motor de composición DirectComposition se ejecuta en un proceso dedicado, independiente de cualquier proceso de aplicación. Un único proceso de composición, dwm.exe, admite todas las aplicaciones de una sesión. Cada aplicación puede crear dos árboles visuales para cada ventana que posee. Todos los árboles se implementan realmente como subárboles de un árbol visual más grande que también abarca las estructuras de composición de DWM. DwM construye un árbol visual grande para cada escritorio de una sesión. Estas son las principales ventajas de esta arquitectura:
- El motor de composición tiene acceso a todos los mapas de bits de la aplicación y a los árboles visuales, lo que permite la interoperabilidad y la composición de ventanas entre procesos.
- El motor de composición se ejecuta en un proceso de sistema de confianza que es independiente de cualquier proceso de aplicación, lo que permite a las aplicaciones que tienen derechos de acceso bajos para crear contenido protegido de forma segura.
- El motor de composición puede detectar cuándo una ventana determinada está totalmente ocluida y evitar el desaprovisionamiento de recursos de la unidad de procesamiento de cpu y gráficos (GPU) para la ventana.
- El motor de composición puede componer directamente en el búfer de reserva de pantalla, evitando la necesidad de una copia adicional necesaria para los motores de composición por proceso.
- Todas las aplicaciones comparten un único dispositivo Direct3D para la composición, lo que ofrece un ahorro considerable de memoria.
El árbol visual es una estructura conservada. La API DirectComposition expone métodos para editar la estructura en lotes de cambios que se procesan de forma atómica. El objeto raíz de directComposition API es el objeto de dispositivo, que actúa como generador de todos los demás objetos DirectComposition y contiene un método denominado Commit. El motor de composición no refleja ningún cambio que la aplicación realice en el árbol visual hasta que la aplicación llame a Commit, momento en el que todos los cambios desde la última confirmación se procesan como una única transacción.
El requisito de llamar a Commit es similar al concepto de un "marco", salvo que, dado que el motor de composición se ejecuta de forma asincrónica, puede presentar varios marcos diferentes entre las llamadas a Commit. En DirectComposition, un marco es una sola iteración del motor de composición y el intervalo invertido por una aplicación entre dos llamadas a Commit se denomina lote.
DirectComposition agrupa por lotes todas las llamadas de aplicación a directComposition API. La base de datos de objetos de kernel, que se implementa en el controlador de sesión de win32k.sys, almacena toda la información de estado asociada a las llamadas API.
El motor de composición genera un marco para cada vertical en blanco en la pantalla. El marco se inicia en un espacio en blanco vertical y tiene como destino el espacio en blanco vertical posterior. Cuando se inicia el marco, el motor de composición recoge todos los lotes pendientes e incluye sus comandos en ese fotograma. Los lotes se colocan en una cola pendiente cuando la aplicación llama a Commit y la cola pendiente se vacía atómicamente al principio del marco. Por lo tanto, hay un único punto en el tiempo que marca el principio de un marco. Todos los lotes enviados antes de este punto se incluyen en el marco, mientras que los lotes enviados después deben esperar hasta que se procese el siguiente fotograma. El bucle de composición completa es el siguiente:
- Calcule el tiempo del siguiente espacio en blanco vertical.
- Recupere todos los lotes pendientes.
- Procese los lotes recuperados.
- Actualice todas las animaciones con el tiempo estimado en el paso 1.
- Determine las regiones de la pantalla que deben volver a redactarse.
- Vuelva a redactar las regiones desfasadas.
- Presente el marco al voltear los búferes delanteros y traseros para cada pantalla.
- Si no se compuso nada y se presentó en los pasos 6 y 7, espere a que se confirme un lote.
- Espere al siguiente espacio en blanco vertical.
Si hay varios monitores conectados a un único adaptador de vídeo, el motor de composición usa el espacio en blanco vertical del monitor principal para controlar el bucle de composición y establecer los tiempos de muestreo de animación. Cada monitor se representa mediante una cadena de volteo de pantalla completa independiente; El motor de composición repite los pasos 6 y 7 para cada monitor, de forma round robin, con un solo dispositivo Direct3D. Si también hay varios adaptadores de vídeo, el motor de composición usa un dispositivo Direct3D independiente para cada adaptador de vídeo en los pasos 6 y 7.
Los marcos de composición están programados para empezar siempre en blanco vertical, como se muestra en la ilustración siguiente.
Si el motor de composición no tiene ningún trabajo que hacer porque el árbol de composición no ha cambiado, el subproceso de composición se suspende mientras espera un nuevo lote. Cuando se envía un nuevo lote, el subproceso de composición se reactiva pero vuelve inmediatamente a suspensión hasta el siguiente espacio en blanco vertical. Este comportamiento garantiza tiempos de inicio y finalización predecibles de fotogramas para las aplicaciones y para el motor de composición.
El motor de composición publica los tiempos de presentación de fotogramas y la velocidad de fotogramas actual. La publicación de esta información permite a las aplicaciones calcular el tiempo de presentación de sus propios lotes, lo que a su vez permite sincronizar las animaciones. En concreto, una aplicación puede usar una combinación de estadísticas de fotogramas del motor de composición y un modelo histórico de cuánto tiempo tarda su subproceso de interfaz de usuario en generar un lote, para determinar el tiempo de muestreo de sus propias animaciones.
Por ejemplo, al principio del lote de aplicación que se muestra en la ilustración anterior, la aplicación puede consultar el motor de composición para determinar el tiempo de presentación exacto del siguiente fotograma. Después, la aplicación puede usar la hora actual, junto con información sobre los lotes anteriores que ha generado, para determinar si la aplicación puede completar el lote actual antes del siguiente espacio en blanco vertical. Por lo tanto, la aplicación usa el tiempo de presentación de fotogramas como tiempo de muestreo para sus propias animaciones. Si la aplicación determina que es poco probable que complete su trabajo en el espacio en blanco vertical actual, la aplicación puede usar el tiempo de fotograma posterior como tiempo de muestreo en su lugar, mediante la información de velocidad de fotogramas devuelta por el motor de composición para calcular ese tiempo.
Temas relacionados