Compartilhar via


Arquitetura e componentes

Nota

Para aplicativos no Windows 10, recomendamos o uso de APIs Windows.UI.Composition em vez de DirectComposition. Para obter mais informações, consulte Modernizar seu aplicativo da área de trabalho usando a camada visual.

Este tópico descreve os componentes que compõem o Microsoft DirectComposition. Ele consiste nas seções a seguir.

Componentes de software

O DirectComposition consiste nos seguintes componentes de software principais.

  • Uma biblioteca de aplicativos no modo de usuário (dcomp.dll) que implementa a API pública baseada em COM (Component Object Model).
  • Um mecanismo de composição do modo de usuário (dwmcore.dll) hospedado no processo dwm (dwm.exe) do Gerenciador de Janelas da Área de Trabalho e executa a composição da área de trabalho real.
  • Um banco de dados de objeto do modo kernel (parte do win32k.sys) que faz marshaling de comandos do aplicativo para o mecanismo de composição.

Uma única instância do mecanismo de composição manipula as árvores de composição do DirectComposition para todos os aplicativos e a árvore de composição DWM, que representa toda a área de trabalho. O banco de dados de objeto do modo kernel e o mecanismo de composição do modo de usuário são instanciados uma vez por sessão, portanto, um computador do Terminal Server com vários usuários tem várias instâncias desses dois componentes.

O diagrama a seguir mostra os principais componentes do DirectComposition e como eles se relacionam entre si.

arquitetura de nível superior de directcomposition

Biblioteca de aplicativos

A biblioteca de aplicativos DirectComposition é uma API pública baseada em COM com um único ponto de entrada simples que é exportado de dcomp.dll e retorna um ponteiro de interface para um objeto de dispositivo. O objeto do dispositivo, por sua vez, tem métodos para criar todos os outros objetos, cada um deles representado por um ponteiro de interface. Todas as interfaces DirectComposition herdam e implementam totalmente a interfaceIUnknown. Todos os métodos que aceitam interfaces DirectComposition verificam se a interface é implementada dentro de dcomp.dll ou se ela é implementada por outro componente. Como o DirectComposition não é extensível, os métodos que tomam interfaces como parâmetros retornam E_INVALIDARG se as interfaces não forem implementadas no dcomp.dll. A API não requer privilégios especiais; ele pode ser chamado por processos em execução no nível mais baixo de acesso. No entanto, como a API não opera na sessão 0, ela não é adequada para serviços. Nesses aspectos, a API DirectComposition é semelhante a outras APIs do Microsoft DirectX, principalmente Direct2D, Microsoft Direct3D e Microsoft DirectWrite.

Como o mecanismo de composição foi projetado exclusivamente para execução assíncrona, as propriedades de objeto na API DirectComposition são somente gravação. Todas as propriedades têm métodos setter, mas não métodos getter. As propriedades de leitura não só são intensivas em recursos, mas também podem ser imprecisas porque qualquer valor retornado pelo mecanismo de composição pode se tornar imediatamente inválido. Isso pode acontecer se, por exemplo, uma animação independente estiver associada à propriedade que está sendo lida.

A API é thread-safe. Um aplicativo pode chamar qualquer método de qualquer thread a qualquer momento. No entanto, como muitos métodos de API devem ser chamados em uma sequência específica, sem qualquer sincronização, um aplicativo pode experimentar um comportamento imprevisível dependendo de como os threads se intercalam. Por exemplo, se dois threads alterarem a mesma propriedade do mesmo objeto para valores diferentes ao mesmo tempo, o aplicativo não poderá prever qual dos dois valores será o valor final da propriedade. Da mesma forma, se dois threads chamarem Commit no mesmo dispositivo, nenhum thread obterá um comportamento verdadeiramente transacional porque uma chamada para Commit em um thread enviará o lote de todos os comandos emitidos por ambos os threads, não apenas aquele que chamou Commit.

O sistema mantém todo o estado interno por objeto de dispositivo. Se um aplicativo criar dois ou mais objetos de dispositivo DirectComposition, o aplicativo poderá manter lotes independentes e outro estado entre os dois.

Todos os objetos DirectComposition têm afinidade de objeto de dispositivo; os objetos criados por um objeto de dispositivo específico só podem ser usados com esse objeto de dispositivo e podem ser associados apenas a outros objetos criados pelo mesmo objeto de dispositivo. Em outras palavras, cada objeto de dispositivo é uma ilha de funcionalidade separada. A única exceção é a classe visual, que permite a construção de árvores visuais em que um visual pode pertencer a um objeto de dispositivo diferente do pai. Isso permite cenários em que um aplicativo e um controle podem gerenciar uma única árvore de composição sem também precisar compartilhar um único objeto de dispositivo DirectComposition.

Mecanismo de composição

O mecanismo de composição do DirectComposition é executado em um processo dedicado, separado de qualquer processo de aplicativo. Um único processo de composição, dwm.exe, dá suporte a cada aplicativo em uma sessão. Cada aplicativo pode criar duas árvores visuais para cada janela que possui. Todas as árvores são realmente implementadas como subárvores de uma árvore visual maior que também abrange as estruturas de composição do DWM. O DWM constrói uma árvore visual grande para cada área de trabalho em uma sessão. Aqui estão as principais vantagens dessa arquitetura:

  • O mecanismo de composição tem acesso a todos os bitmaps do aplicativo e árvores visuais, o que permite interoperabilidade e composição entre janelas de processo.
  • O mecanismo de composição é executado em um processo de sistema confiável separado de qualquer processo de aplicativo, permitindo que aplicativos com direitos de acesso baixos componham conteúdo protegido com segurança.
  • O mecanismo de composição pode detectar quando uma janela específica é totalmente ocluída e evitar o perda de recursos de GPU (unidade de processamento gráfico) e CPU compondo para a janela.
  • O mecanismo de composição pode compor diretamente para o buffer de fundo da tela, evitando a necessidade de uma cópia extra necessária para mecanismos de composição por processo.
  • Todos os aplicativos compartilham um único dispositivo Direct3D para composição, o que oferece uma economia de memória considerável

A árvore visual é uma estrutura retida. A API do DirectComposition expõe métodos para editar a estrutura em lotes de alterações que são processadas atomicamente. O objeto raiz na API DirectComposition é o objeto do dispositivo, que serve como a fábrica para todos os outros objetos DirectComposition e contém um método chamado Commit. O mecanismo de composição não reflete nenhuma alteração feita pelo aplicativo na árvore visual até que o aplicativo chame Commit, momento em que todas as alterações desde o último commit são processadas como uma única transação.

O requisito para chamar Commit é semelhante ao conceito de um "quadro", exceto que, como o mecanismo de composição é executado de forma assíncrona, ele pode apresentar vários quadros diferentes entre chamadas para Commit. No DirectComposition, um quadro é uma única iteração do mecanismo de composição e o intervalo gasto por um aplicativo entre duas chamadas para Commit é chamado de de lote.

O DirectComposition agrupa todas as chamadas de aplicativo para a API DirectComposition. O banco de dados de objeto kernel, que é implementado no driver de sessão win32k.sys, armazena todas as informações de estado associadas às chamadas à API.

O mecanismo de composição produz um quadro para cada espaço em branco vertical na exibição. O quadro é iniciado em um espaço em branco vertical e tem como destino o espaço em branco vertical subsequente. Quando o quadro é iniciado, o mecanismo de composição pega todos os lotes pendentes e inclui seus comandos nesse quadro. Os lotes são colocados em uma fila pendente quando o aplicativo chama Commite a fila pendente é liberada atomicamente no início do quadro. Portanto, há um único ponto no tempo que marca o início de um quadro. Todos os lotes enviados antes desse ponto são incluídos no quadro, enquanto os lotes enviados depois devem aguardar até que o próximo quadro seja processado. O loop de composição completo é o seguinte:

  1. Estimar a hora do próximo espaço em branco vertical.
  2. Recupere todos os lotes pendentes.
  3. Processe os lotes recuperados.
  4. Atualize todas as animações usando o tempo estimado na etapa 1.
  5. Determine as regiões da tela que precisam ser redigidas.
  6. Redigir as regiões sujas.
  7. Apresente o quadro invertendo os buffers traseiro e frontal para cada tela.
  8. Se nada tiver sido composto e apresentado nas etapas 6 e 7, aguarde até que um lote seja confirmado.
  9. Aguarde o próximo espaço em branco vertical.

Se houver vários monitores anexados a um único adaptador de vídeo, o mecanismo de composição usará o espaço em branco vertical do monitor primário para conduzir o loop de composição e definir os tempos de amostragem de animação. Cada monitor é representado por uma cadeia de inversão de tela inteira separada; o mecanismo de composição repete as etapas 6 e 7 para cada monitor, de forma round robin, usando um único dispositivo Direct3D. Se também houver vários adaptadores de vídeo, o mecanismo de composição usará um dispositivo Direct3D separado para cada adaptador de vídeo nas etapas 6 e 7.

Os quadros de composição são agendados para sempre iniciar em um espaço em branco vertical, como mostra a ilustração a seguir.

de agendamento de quadro de composição

Se o mecanismo de composição não tiver trabalho a fazer porque a árvore de composição não foi alterada, o thread de composição dormirá enquanto aguarda um novo lote. Quando um novo lote é enviado, o thread de composição é ativado, mas imediatamente volta a dormir até o próximo espaço em branco vertical. Esse comportamento garante tempos previsíveis de início e término do quadro para aplicativos e para o mecanismo de composição.

O mecanismo de composição publica os tempos de apresentação do quadro e a taxa de quadros atual. A publicação dessas informações permite que os aplicativos estimam o tempo de apresentação para seus próprios lotes, o que, por sua vez, permite que as animações sejam sincronizadas. Em particular, um aplicativo pode usar uma combinação de estatísticas de quadro do mecanismo de composição e um modelo histórico de quanto tempo seu thread de interface do usuário leva para produzir um lote, para determinar o tempo de amostragem para suas próprias animações.

Por exemplo, no início do lote do aplicativo mostrado na ilustração anterior, o aplicativo pode consultar o mecanismo de composição para determinar a hora exata da apresentação do próximo quadro. Em seguida, o aplicativo pode usar a hora atual, juntamente com informações sobre os lotes anteriores que ele produziu, para determinar se o aplicativo pode concluir o lote atual antes do próximo espaço em branco vertical. Portanto, o aplicativo usa o tempo de apresentação do quadro como o tempo de amostragem para suas próprias animações. Se o aplicativo determinar que é improvável concluir seu trabalho no espaço em branco vertical atual, o aplicativo poderá usar o tempo de quadro subsequente como o tempo de amostragem, usando as informações de taxa de quadros retornadas pelo mecanismo de composição para calcular esse tempo.

conceitos do DirectComposition