Поделиться через


Основные понятия

Заметка

Для приложений в Windows 10 рекомендуется использовать API-интерфейсы Windows.UI.Composition вместо DirectComposition. Дополнительные сведения см. в Модернизацию классического приложения с помощьюВизуального слоя.

В этом разделе представлен обзор основных понятий Microsoft DirectComposition. Он содержит следующие разделы:

Состав

DirectComposition определяет композицию как коллекцию битмапов, объединённых и управляемых путём применения различных преобразований, эффектов и анимаций для создания визуального эффекта в пользовательском интерфейсе приложения. DirectComposition работает только с содержимым растрового изображения; он не поддерживает векторы или текст. DirectComposition не предоставляет содержимое растрового изображения. Вместо этого он предоставляет интерфейсы, в которых пользователи могут рисовать с использованием D2D, DXGI или загружать собственное содержание текстуры.

Приложение DirectComposition создает два набора объектов для создания сцены: растровых карт, состоящих вместе, и визуальных элементов, определяющих пространственные связи между растровыми изображениями. Дополнительные сведения о растровых объектах, поддерживаемых DirectComposition, см. в Растровые объекты.

Визуальные эффекты

Визуальные элементы (или визуальные объекты) являются основными элементами DirectComposition. Это основные стандартные блоки, которые используются для создания композиций и анимаций в пользовательском интерфейсе приложения.

В терминах программирования визуальный элемент — это объект, имеющий набор свойств, и предоставляет интерфейс, используемый для задания значения свойств. Свойство Содержимого визуального элемента связывает определенное растровое изображение с визуальным элементом, а другие свойства управляют положением DirectComposition и управляют визуальным элементом при отображении на экране.

Дополнительные сведения см. в разделе Свойства визуального.

Визуальное дерево

DirectComposition создает композицию из иерархической коллекции визуальных объектов, называемых визуального дерева. Визуальный элемент, находящийся в корне дерева, называется корневым элементом визуализации и может иметь один или несколько дочерних визуальных элементов, связанных с ним. Дочерний визуальный элемент может иметь один или несколько дочерних визуальных элементов. Любой визуальный элемент, связанный с дочерними визуальными элементами, называется родительским, а все дочерние визуальные элементы, имеющие одного и того же родителя, называются одноуровневыми визуальными элементами. Конкретный визуальный элемент вместе со всеми дочерними и всеми подчинёнными визуальными элементами называется визуальным поддеревом.

Расположение визуального элемента в дереве помогает определить его положение экрана и z-порядок относительно других визуальных элементов в композиции. Корневой визуальный элемент расположен относительно левого верхнего угла клиентской области целевого окна, в котором отрисовывается композиция. Все дочерние визуальные элементы расположены относительно левого верхнего угла родительского визуального элемента (или визуального элемента, указанного свойством TransformParent), и всегда отображаются перед их родительским элементом в порядке z.

На следующем рисунке показана композиция визуальных элементов и структура визуального дерева, используемого для создания композиции. Визуальный элемент 1 — это корневой визуальный элемент, который также является родительским элементом дочерних визуальных элементов 2 и 3. Visual 3 имеет два собственных дочерних визуальных элемента, Визуалы 4 и 5. Вместе визуальные элементы 3–5 составляют поддерев.

композиция визуальных элементов и соответствующего визуального дерева

Родительский визуальный объект ведет упорядоченный список дочерних визуальных объектов. Если визуальные элементы, являющиеся родными, расположены так, что они перекрываются друг с другом, DirectComposition определяет z-порядок сиблингов на основе порядка, в котором они появляются в списке дочерних элементов родительского визуального элемента. Одноуровневый элемент, который появляется позже в списке, ставится впереди всех одноуровневых элементов, отображаемых ранее в списке. На следующем рисунке показан z-порядок перекрывающихся дочерних визуальных элементов.

порядок перекрывающихся дочерних визуальных элементов

Свойства визуального объекта

Визуальный объект предоставляет набор свойств, которые позволяют задать растровое содержимое визуального элемента, а также управлять его положением и содержимым с помощью DirectComposition. В следующих разделах подробно описано каждое свойство.

Свойство контента

Свойство содержимого визуального элемента указывает содержимое растрового изображения, связанное с визуальным элементом. Это растровое изображение, которое DirectComposition использует при включении визуального элемента в композицию.

Чтобы задать свойство Content визуального элемента, вызовите метод IDCompositionVisual::SetContent.

Дополнительные сведения о типах содержимого растрового изображения, поддерживаемого DirectComposition, см. в объектах bitmap.

Свойство Clip

Свойство "Клип" визуального элемента задает прямоугольную область, называемую области обрезки (или прямоугольник клипа). При рендеринге визуального элемента отображается только часть, которая попадает в область отсечения, в то время как любое содержимое за пределами этой области отсечения обрезается (то есть не отображается). DirectComposition поддерживает области отсечения с округленными или квадратными углами.

Чтобы задать свойство Clip визуального элемента, вызовите метод IDCompositionVisual::SetClip.

Дополнительные сведения см. в обрезке.

Свойство BorderMode

Свойство BorderMode указывает, как составлять края растровых изображений и клипов, ассоциированных с этим визуальным элементом, или с визуальными элементами в поддереве, имеющем этот визуальный элемент в качестве корневого.

Режим границы влияет на то, как края растрового изображения создаются при преобразовании растрового изображения таким образом, чтобы края не были выровнены по оси с целыми координатами. Это также влияет на то, как содержимое обрезается в углах клипа с округленными углами, а также на краю клипа, преобразованного таким образом, что края не выровнены по оси с целыми координатами.

Дополнительные сведения см. в разделе IDCompositionVisual::SetBorderMode.

Свойство BitmapInterpolationMode

Свойство BitmapInterpolationMode указывает DirectComposition, как обрабатывать растровое изображение при его преобразовании таким образом, что отсутствует однозначное соответствие между пикселями в растровом изображении и пикселями на экране.

Свойство BitmapInterpolationMode визуального элемента устанавливается путем вызова метода IDCompositionVisual::SetBitmapInterpolationMode.

Свойство CompositeMode

Свойство CompositeMode сообщает DirectComposition, как смешать растровое содержимое визуального элемента с целевым объектом отрисовки. Описание поддерживаемых составных режимов см. в DCOMPOSITION_COMPOSITE_MODE.

Свойство CompositeMode визуального элемента устанавливается путем вызова метода IDCompositionVisual::SetCompositeMode.

Свойства OffsetX и OffsetY

Свойства OffsetX и OffsetY сообщают DirectComposition, где разместить визуальный элемент по горизонтали и вертикали. Они определяют двухмерное фиксированное положение, из которого вычисляются все преобразования и эффекты для визуального элемента.

Для корневого визуального элемента свойства OffsetX и OffsetY определяют координату x и координату y точки относительно левого верхнего угла окна, на котором размещен визуальный элемент. Для дочернего визуального элемента координаты определяются относительно левого верхнего угла родительского элемента или, если задано свойство TransformParent, левого верхнего угла указанного визуального элемента. При отображении визуального элемента он расположен таким образом, чтобы верхний левый угол визуального элемента совпадал с указанными координатами.

Свойства OffsetX и OffsetY визуального элемента задаются путем вызова методов IDCompositionVisual::SetOffsetX и SetOffsetY.

Свойство эффекта

Свойство Effect позволяет указать эффект или группу эффектов, которые изменят способ создания визуального элемента и его поддерев. Например, можно указать эффекты, управляющие непрозрачностью визуального элемента, смешивать визуальный элемент с другим растровым изображением различными способами и применять преобразования перспективы к визуальному элементу.

Свойство Effect визуального элемента можно задать путем вызова метода IDCompositionVisual::SetEffect.

Дополнительные сведения см. в разделе Эффекты.

Свойство трансформации

Свойство Transform задает двухмерное преобразование (2D) или группу двухмерных преобразований для выполнения DirectComposition на визуальном элементе. Преобразование (или преобразование) — это операция, которая изменяет систему координат визуального элемента относительно родительского элемента или относительно визуального элемента, указанного свойством TransformParent. Преобразования можно использовать для изменения положения, размера или характера визуального элемента, перемещая его в другое место (перемещение), увеличивая или уменьшая его (масштабирование), поворачивая (поворот), изменяя форму (наклон) и т. д.

Чтобы задать свойство Transform визуального элемента, вызовите метод IDCompositionVisual::SetTransform.

Дополнительные сведения см. в разделе Преобразования.

Свойство TransformParent

Система координат визуального элемента изменяется свойствами OffsetX, OffsetY и Transform. Как правило, эти свойства определяют систему координат визуального элемента относительно его непосредственного родительского элемента. Чтобы использовать некоторый визуальный элемент, отличный от родительского в качестве основы для системы координат дочернего визуального элемента, используйте свойство TransformParent, чтобы указать другой визуальный элемент в качестве родительского элемента для целей преобразования.

Вы задаете свойство TransformParent визуального элемента путем вызова метода IDCompositionVisual::SetTransformParent.

Объект устройства

Чтобы использовать DirectComposition, необходимо создать и управлять различными объектами объектной модели компонентов (COM). Первым объектом, который необходимо создать, является объект DirectComposition устройства, так как он служит фабрикой для создания всех остальных объектов, используемых в композиции.

Объект устройства создается путем вызова функции DCompositionCreateDevice, которая возвращает указатель интерфейса IDCompositionDevice. Этот интерфейс предоставляет набор методов, используемых для создания визуальных объектов, клиповых объектов, объектов анимации, преобразования объектов, объектов эффектов и т. д.

Объект устройства служит одной из других целей, помимо фабрики для создания других объектов. Он предоставляет метод с именем Commit, который передает визуальное дерево в DirectComposition для обработки. Дополнительные сведения см. в композиции транзакций.

Помните, что при создании нескольких экземпляров объекта устройства в приложении все объекты, используемые в определенной композиции, должны создаваться одним и тем же объектом устройства, за исключением одного исключения: можно объединить визуальные объекты из разных объектов устройств в одном визуальном дереве. При этом DirectComposition обрабатывает визуальное дерево как обычно, за исключением того, что изменения определенного визуального объекта в дереве вступили в силу только в том случае, если метод Commit вызывается на объекте устройства, который создал визуальный объект.

Возможность использовать визуальные элементы из разных устройств в одном визуальном дереве позволяет нескольким потокам создавать и управлять одним деревом визуальных элементов при сохранении двух независимых устройств, которые можно использовать для асинхронной фиксации изменений. Дополнительные сведения см. в Деревья визуальных элементов между устройствами.

Целевое окно компоновки

Визуальное дерево должно быть привязано к окну перед отображением любого из визуальных элементов дерева на экране. Окно, называемое целевым окном композиции , может быть окном верхнего уровня или дочерним окном. Кроме того, целевое окно композиции может быть многоуровневое окно; то есть он может иметь стиль окна WS_EX_LAYERED.

DirectComposition позволяет приложению привязать не более двух визуальных деревьев к каждому окну. Визуальные деревья включают одно, расположенное поверх самого окна, но за всеми его дочерними окнами, и другое — поверх окна и поверх дочерних окон. Другими словами, каждое окно имеет четыре концептуальных слоя, и все слои ограничены видимой областью целевого окна. На следующем рисунке показаны четыре концептуальных слоя окна.

концептуальные слои окна

Транзакционная композиция

DirectComposition использует транзакционную модель, в которой вы создаете пакетный набор изменений в визуальном элементе, а затем фиксируете этот набор в DirectComposition для одноразовой обработки. Вы можете изменить один и тот же визуальный объект DirectComposition и зафиксировать изменения в любое количество раз. Когда диспетчер окон рабочего стола (DWM) выбирает пакеты, он выбирает все ожидающие пакеты и применяет их к следующему кадру в том порядке, в который они были зафиксированы.

Все изменения в одном коммите гарантированно применяются к одному кадру. Так как DWM собирает пакеты один раз на кадр, можно изменять любой конкретный объект только один раз на кадр. Последующие коммиты, изменяющие различные объекты, также могут применяться к текущему кадру, но DirectComposition не гарантирует, что изменения произойдут в том же кадре.

Методы idCompositionSurface::BeginDraw и IDCompositionSurface::EndDraw позволяют синхронизировать обновления отрисовки с визуальными обновлениями. Например, можно вызвать IDCompositionSurface::BeginDraw, обновить свойства offsetX и Clip визуального элемента, вызвать IDCompositionDevice::Commit, нарисовать содержимое с помощью Microsoft DirectX, а затем вызвать IDCompositionSurface::EndDraw. В этом случае Microsoft DirectComposition гарантирует, что содержимое растрового изображения и визуальные свойства обновляются одновременно.

Пакетирование

Вы можете зафиксировать несколько изменений в одном визуальном элементе или несколько изменений в разных визуальных элементах в одном кадре. При внесении нескольких изменений в один визуальный элемент в одном кадре следует учитывать следующие моменты:

  • При внесении нескольких изменений в одно и то же свойство визуального элемента применяется только последнее изменение. Например, если задать для непрозрачности значение 0, то значение 0,5 и, наконец, значение 1.0, к визуальному элементу применяется только непрозрачность 1.0.

  • Если изменить несколько свойств одного визуального элемента, DirectComposition применяет изменения сначала к визуальному элементу, а затем к любым дочерним визуальным элементам. Свойства применяются в следующем порядке независимо от порядка, в котором они указаны:

    1. Смещение
    2. Преобразовать
    3. Клип
    4. Эффект

    На следующем рисунке показан результат применения всех четырех свойств к визуальному элементу.

    результат применения всех четырёх свойств к визуальному

    Помните, что все изменения применяются к визуальному элементу одновременно в контексте одного кадра. Это означает, что, с точки зрения пользователя, изменения визуального элемента происходят мгновенно.

  • Для свойства Transform можно использовать IDCompositionDevice::CreateTransformGroup для создания группы преобразований для применения к визуальному элементу одновременно. DirectComposition применяет преобразования в указанном порядке.

  • Для свойства Effect можно использовать IDCompositionEffectGroup для применения группы эффектов. DirectComposition применяет эффекты в указанном порядке. Кроме того, преобразования трехмерной перспективы приводят к выравниванию визуального дерева после применения всех трехмерных преобразований в текущем визуальном элементе. Это помогает убедиться, что результирующее изображение выглядит как можно ближе к трехмерному.

Синхронизация

Приложение может вызывать DirectComposition из нескольких потоков одновременно. Порядок выполнения гарантируется для последовательных вызовов, но не для одновременных вызовов. Например, если поток A изменяет визуальный элемент и поток B фиксирует пакет одновременно, не определено, включается ли это изменение в зафиксированный пакет или начинается новый пакет. С другой стороны, если приложение использует другие механизмы синхронизации, чтобы убедиться, что один метод вызывается перед другим, DirectComposition учитывает порядок вызовов и обрабатывает их, как если бы оба вызова были выданы в этом порядке из одного потока.

Визуальные деревья между устройствами

Объекты DirectComposition не привязаны к потоку; для изменения одного набора объектов можно использовать несколько потоков. Однако помните о следующих проблемах при совместном использовании одного объекта устройства.

  • Оба потока должны иметь возможность вызывать IDCompositionDevice::Commit. Если только один из потоков вызывает IDCompositionDevice::Commit, другой поток не может зафиксировать какие-либо изменения в DirectComposition.
  • Поведение транзакций может быть потеряно, если один поток вызывает IDCompositionDevice::Commit, а другой поток по-прежнему вносит изменения, которые должны быть частью одной транзакции.

Если необходимо зафиксировать несколько одновременных транзакций в DirectComposition, необходимо использовать несколько объектов устройства, возможно, из нескольких потоков. В этом сценарии одно и то же визуальное дерево используется обоими объектами устройства, и каждый объект выполняет свои собственные транзакции.

На следующем рисунке показано визуальное дерево, совместно используемое двумя объектами устройства. Визуальные элементы 1, 2, 4 и 5 принадлежат одному из устройств, а визуальный элемент 3 используется обоими устройствами и может использоваться для объединения двух вложенных деревьев в одно большее визуальное дерево. Совместное использование визуального дерева позволяет управлять двумя устройствами из разных потоков асинхронно.

визуальное дерево, совместно используемое двумя устройствами

Чтобы проиллюстрировать полезность совместного использования визуального дерева между двумя устройствами, рассмотрим архитектуру, которая обеспечивает низкую задержку ввода сенсорного ввода. Архитектура может использовать два потока, один из них обрабатывает большинство задач пользовательского интерфейса и второй поток, выделенный для обработки событий сенсорного ввода. Сенсорный поток обновляет преобразование определенного визуального элемента на основе жеста ввода пользователя. Обновив преобразование, поток касания может сделать так, чтобы всё поддерево под этим визуальным элементом следовало за пальцем пользователя, увеличивалось или уменьшалось по мере того, как пользователь выполняет мультитач-жест. Поток пользовательского интерфейса сохраняет владение большинством дерева композиции, при этом поток обработки касаний владеет только несколькими визуальными элементами, отмеченными для асинхронного ответа на касания. На следующем рисунке показана упрощенная версия такого дерева композиции:

визуальное дерево, совместно используемое между потоком пользовательского интерфейса и сенсорным потоком

Как правило, поток пользовательского интерфейса изменяет только визуальные элементы, принадлежащие только ему, и сенсорный поток изменяет только общий визуальный элемент. Единственное исключение возникает при создании или уничтожении поддерев с поддержкой сенсорного ввода.

IDCompositionSurface::BeginDraw

IDCompositionSurface::EndDraw

IDCompositonDevice::Commit

Основные понятия DirectComposition