Архитектура и компоненты
Примечание
Для приложений на Windows 10 рекомендуется использовать API Windows.UI.Composition вместо DirectComposition. Дополнительные сведения см. в статье Модернизация классического приложения с помощью визуального слоя.
В этом разделе описываются компоненты, составляющие Microsoft DirectComposition. Он состоит из следующих разделов.
Компоненты программного обеспечения
DirectComposition состоит из следующих main программных компонентов.
- Библиотека приложений пользовательского режима (dcomp.dll), реализующая общедоступный API на основе com.
- Обработчик композиции в пользовательском режиме (dwmcore.dll), размещенный в процессе Диспетчера окон на рабочем столе (DWM) (dwm.exe) и выполняющий фактическую композицию рабочего стола.
- Объектная база данных в режиме ядра (часть win32k.sys), которая маршалирует команды из приложения в обработчик композиции.
Один экземпляр обработчика композиции обрабатывает деревья композиции DirectComposition для всех приложений и дерево композиции DWM, которое представляет весь рабочий стол. Как объектная база данных в режиме ядра, так и обработчик композиции в пользовательском режиме создаются один раз за сеанс, поэтому компьютер сервера терминалов с несколькими пользователями имеет несколько экземпляров обоих этих компонентов.
На следующей схеме показаны main компонентов DirectComposition и их связь друг с другом.
Библиотека приложений
Библиотека приложений DirectComposition — это общедоступный API на основе COM с одной плоской точкой входа, которая экспортируется из dcomp.dll и возвращает указатель интерфейса на объект устройства. Объект устройства, в свою очередь, имеет методы для создания всех других объектов, каждый из которых представлен указателем интерфейса. Все интерфейсы DirectComposition наследуют от интерфейса IUnknown и полностью реализуют его. Все методы, принимаюющие интерфейсы DirectComposition, проверка, реализован ли интерфейс внутри dcomp.dll или другим компонентом. Так как DirectComposition не является расширяемым, методы, которые принимают интерфейсы в качестве параметров, возвращают E_INVALIDARG, если интерфейсы не реализованы в dcomp.dll. ДЛЯ API не требуются специальные привилегии; Он может вызываться процессами, работающими на самом низком уровне доступа. Однако, поскольку API не работает в сеансе 0, он не подходит для служб. В этом отношении API DirectComposition аналогичен другим API Microsoft DirectX, в первую очередь Direct2D, Microsoft Direct3D и Microsoft DirectWrite.
Так как обработчик композиции предназначен исключительно для асинхронного выполнения, свойства объектов в API DirectComposition доступны только для записи. Все свойства имеют методы задания, но не методы получения. Чтение свойств не только ресурсоемко, но и может быть неточным, так как любое значение, возвращаемое обработчиком композиции, может сразу же стать недопустимым. Это может произойти, например, если независимая анимация привязана к считываемом свойству.
API является потокобезопасным. Приложение может в любое время вызывать любой метод из любого потока. Однако, поскольку многие методы API должны вызываться в определенной последовательности, без синхронизации приложение может столкнуться с непредсказуемым поведением в зависимости от того, как чередуется потоки. Например, если два потока одновременно изменяют одно и то же свойство одного и того же объекта на разные значения, приложение не может предсказать, какое из двух значений будет окончательным значением свойства. Аналогичным образом, если два потока вызывают Commit на одном устройстве, ни один поток не получает действительно транзакционного поведения, так как вызов Commit в одном потоке отправляет пакет всех команд, выданных обоими потоками, а не только тем, который называется Commit.
Система поддерживает все внутреннее состояние для каждого объекта устройства. Если приложение создает два или более объектов устройства DirectComposition, оно может поддерживать независимые пакеты и другое состояние между ними.
Все объекты DirectComposition имеют сходство объектов устройства; Объекты, созданные определенным объектом устройства, могут использоваться только с этим объектом устройства и могут быть связаны только с другими объектами, созданными тем же объектом устройства. Иными словами, каждый объект устройства представляет собой отдельный несвязанный остров функциональных возможностей. Исключением является класс visual, который позволяет создавать визуальные деревья, в которых визуальный элемент может принадлежать объекту устройства, отличному от его родительского. Это позволяет реализовать сценарии, в которых приложение и элемент управления могут управлять одним деревом композиции без необходимости совместно использовать один объект устройства DirectComposition.
Подсистема композиции
Подсистема композиции DirectComposition выполняется в выделенном процессе, отдельном от любого процесса приложения. Один процесс композиции, dwm.exe, поддерживает каждое приложение в сеансе. Каждое приложение может создать два визуальных дерева для каждого окна, которым оно владеет. Все деревья фактически реализуются как поддерево большего визуального дерева, которое также охватывает структуры композиции DWM. DWM создает одно большое визуальное дерево для каждого рабочего стола в сеансе. Ниже приведены основные преимущества этой архитектуры.
- Подсистема композиции имеет доступ ко всем точечным изображениям приложения и визуальным деревьям, что обеспечивает взаимодействие и композицию окон между процессами.
- Подсистема композиции выполняется в доверенном системном процессе, отдельном от любого процесса приложения, что позволяет приложениям с низким уровнем прав доступа безопасно составлять защищенное содержимое.
- Подсистема композиции может определить, когда конкретное окно полностью заблокировано, и избежать потребления ресурсов ЦП и графического процессора (GPU), составляющих окно.
- Подсистема композиции может создавать данные непосредственно в буфер обратной части экрана, избегая необходимости в дополнительной копии, необходимой для обработчиков композиции для каждого процесса.
- Все приложения совместно используют одно устройство Direct3D для композиции, что обеспечивает значительную экономию памяти
Визуальное дерево является сохраненной структурой. API DirectComposition предоставляет методы для изменения структуры в пакетах изменений, обрабатываемых атомарно. Корневой объект в API DirectComposition — это объект устройства, который служит фабрикой для всех остальных объектов DirectComposition и содержит метод Commit. Обработчик композиции не отражает никаких изменений, внесенных приложением в визуальное дерево, пока приложение не вызовет Commit, после чего все изменения, внесенные с момента последней фиксации , обрабатываются как одна транзакция.
Требование вызова commit похоже на концепцию "фрейма", за исключением того, что, поскольку обработчик композиции выполняется асинхронно, он может представлять несколько разных кадров между вызовами commit. В DirectComposition кадр — это одна итерация обработчика композиции, а интервал, затрачиваемый приложением между двумя вызовами Commit , называется пакетом.
DirectComposition пакетирует все вызовы приложений к API DirectComposition. База данных объектов ядра, реализованная в драйвере сеанса win32k.sys, хранит все сведения о состоянии, связанные с вызовами API.
Подсистема композиции создает по одному кадру для каждого вертикального пустого элемента на экране. Кадр запускается на вертикальном пустом месте и нацелен на последующее вертикальное пустое. При запуске кадра обработчик композиции берет все ожидающие пакеты и включает их команды в этот кадр. Пакеты помещаются в очередь ожидания, когда приложение вызывает Commit, а ожидающая очередь атомарно очищается в начале кадра. Таким образом, существует одна точка во времени, которая знаменует собой начало кадра. Все пакеты, отправленные до этой точки, включаются в кадр, а все пакеты, отправленные после, должны ждать обработки следующего кадра. Полный цикл композиции выглядит следующим образом:
- Оцените время следующего вертикального пробела.
- Получение всех ожидающих пакетов.
- Обработайте полученные пакеты.
- Обновите все анимации, используя время, предполагаемое на шаге 1.
- Определите области экрана, которые необходимо создать заново.
- Повторно создайте грязное регионы.
- Представить кадр, отвердив задний и передний буферы для каждого экрана.
- Если в шагах 6 и 7 ничего не было создано, дождитесь фиксации пакета.
- Дождитесь следующего вертикального пробела.
Если к одному видеоадаптелю подключено несколько мониторов, обработчик композиции использует вертикальное пустое место основного монитора для управления циклом композиции и задания времени выборки анимации. Каждый монитор представлен отдельной полноэкранной цепочкой перелистывания; обработчик композиции повторяет шаги 6 и 7 для каждого монитора с циклическим перебором, используя одно устройство Direct3D. При наличии нескольких видеоадаптеров обработчик композиции использует отдельное устройство Direct3D для каждого видеоадаптера на шагах 6 и 7.
Кадры композиции всегда должны начинаться с вертикального пустого поля, как показано на следующем рисунке.
Если подсистеме композиции не нужно выполнять никаких действий, так как дерево композиции не изменилось, поток композиции переходит в спящий режим во время ожидания нового пакета. При отправке нового пакета поток композиции просыпается, но сразу же возвращается в спящий режим до следующего вертикального пустого. Такое поведение обеспечивает предсказуемое время начала и окончания фрейма для приложений и подсистемы композиции.
Обработчик композиции публикует время представления кадров и текущую частоту кадров. Публикация этих сведений позволяет приложениям оценивать время презентации для собственных пакетов, что, в свою время, позволяет синхронизировать анимации. В частности, приложение может использовать сочетание статистики кадров из обработчика композиции и историческую модель того, сколько времени занимает поток пользовательского интерфейса для создания пакета, чтобы определить время выборки для собственных анимаций.
Например, в начале пакета приложения, показанного на предыдущем рисунке, приложение может запросить обработчик композиции, чтобы определить точное время представления следующего кадра. Затем приложение может использовать текущее время вместе со сведениями о предыдущих пакетах, которые оно создало, чтобы определить, может ли приложение завершить текущий пакет до следующего вертикального пробела. Таким образом, приложение использует время представления кадра в качестве времени выборки для собственных анимаций. Если приложение определяет, что оно вряд ли завершит свою работу в текущем вертикальном пустом месте, приложение может использовать последующее время кадра в качестве времени выборки, используя сведения о частоте кадров, возвращаемые обработчиком композиции для вычисления этого времени.
Связанные темы