Руководство по программированию цепочки буферов компоновки
API подкачки композиции является духовным преемником цепочки буферов DXGI, что позволяет приложениям отображать и представлять содержимое на экране. Существует несколько преимуществ использования этого API по сравнению с цепочкой буферов DXGI. Более точное управление предоставляется вашему приложению относительно состояния цепочки переключения, и больше свободы предоставляется, когда речь идет о том, как используется цепочка буферов. Кроме того, API обеспечивает лучшую историю для точного текущего времени.
Что такое презентация?
Презентация — это концепция отображения результатов операций рисования на экране. Представление представляет собой один экземпляр презентации — запрос на отображение результатов операции рисования на одном буфере на экране. Представление может содержать дополнительные атрибуты, описывающие отображение на экране. В этом API может также иметь целевое время, которое является меткой времени относительной системы (прерывание), описывающей идеальное время, которое должно отображаться. Приложение может использовать это для более точного управления скоростью отображения содержимого на экране, а также для синхронизации с другими событиями в системе, такими как звуковая дорожка.
В основе презентации лежит синхронизация. То есть операции рисования обычно выполняются GPU, а не ЦП и, например, выполняются на асинхронной временной шкале от ЦП, выдавшего операции первоначально. Презентация — это операция, отправленная на GPU, которая гарантирует, что операции рисования, выданные ранее, будут завершены до отображения буфера на экране.
Приложение обычно выдает множество представлений с течением времени и имеет несколько текстур, чтобы выбрать их при выдаче подарков. Приложение должно использовать механизмы синхронизации, предоставляемые этим API, чтобы убедиться, что после рисования буфера и представления буфера вы не нарисуйте этот буфер еще раз до тех пор, пока это представление не будет отображено и впоследствии заменено новым буфером из последующего текущего. В противном случае содержимое буфера, которое приложение предназначено для первоначального представления, может быть перезаписано, как это отображается на экране.
Режимы презентации — композиция, многоплановая наложение и независимый перевернутый
Буферы, представленные приложением, могут отображаться системой несколькими способами.
Самый простой способ, используемый по умолчанию, заключается в том, что представление будет отправлено в DWM, а DWM отрисовывает кадр на основе представленного буфера. То есть существует копия (или более точно, трехмерная отрисовка) буфера презентации в серверную часть, которую DWM отправляет на экран. Этот метод отображения текущего объекта называется Composition.
Более производительный режим отображения присутствующих — это сканирование буфера презентации непосредственно на оборудование и устранение копии, которая выполняется. Этот метод отображения текущего объекта называется прямым сканированием. При обработке представлений DWM может решить программировать оборудование для непосредственного сканирования из буфера презентации, назначив буфер многоплановой плоскости наложения (или плоскости MPO), или напрямую перевернуть буфер на оборудование (известное как прямой перевернутый).
Еще более производительный способ отображения подарка будет отображаться непосредственно графическим ядром и полностью обойти DWM. Этот метод представления называется независимым перевернутием (iflip). Многоплановые наложения и iflip описаны в разделе "Для оптимальной производительности", используйте модель переверки DXGI.
Композиция является наиболее легко поддерживаемой, но и наименее эффективной. Поверхность должна быть специально выделена, чтобы иметь право на прямое сканирование или если скольжение, и этот тип специального выделения имеет более строгие требования к системе, чем цепочка буферов композиции. Она доступна только на оборудовании WDDM 3.0 и более поздней версии. В результате приложение может запрашивать поддержку API для презентации только для композиции, а также презентацию, которая квалифизируется для прямого сканирования или iflip.
Примечание.
Чтобы ваши поверхности могли воспользоваться преимуществами этих более оптимизированных режимов презентации автоматически, поверхности должны быть выделены как непосредственно отображаемые gpu. Для поверхностей Direct3D 11 необходимо выделить свои поверхности в качестве отображаемых. Поверхности, которые не выделены как отображаемые, по-прежнему могут быть составны системным компостатором на экране, но никогда не получат преимущества независимого режима переворачивания.
Фабрика презентаций, проверка возможностей и диспетчер презентаций
Первый объект, который приложение будет использовать из API буферной цепочки композиции, — фабрика презентаций. Фабрика презентаций создается приложением и привязана к устройству Direct3D, которое приложение передает в вызов для создания, и таким образом имеет сходство с видеоадаптером, связанным с этим устройством.
Фабрика презентаций предоставляет методы для проверки того, может ли текущее устройство системы и графического устройства использовать API буферной цепочки композиции. Для проверки поддержки системы можно использовать такие методы возможностей, как IPresentationFactory::IsPresentationSupported. Если методы возможностей указывают системную поддержку API, можно использовать фабрику презентаций для создания диспетчера презентаций. Этот диспетчер презентаций — это объект, используемый для выполнения функций презентации, и привязан к тому же устройству Direct3D и видеоадаптере, что и в фабрике презентаций, которая использовалась для ее создания.
В настоящее время требования к системе для использования API буфера композиции являются драйверами GPU, поддерживающими WDDM (модель драйвера устройств Windows) 2.0, и Windows 11 (сборка 10.0.22000.194) или более поздней версии. Чтобы использовать API цепочки переключения композиции в наиболее эффективном способе (прямой сканирования и независимой переверки или при слипе), системам потребуется драйверы GPU, поддерживающие WDDM 3.0.
Если система не может использовать API цепочки буферов композиции, приложению потребуется отдельный кодовой путь для обработки презентации с помощью старых методов, таких как буферная цепочка DXGI.
Регистрация буферов презентации для представления
Диспетчер презентаций отслеживает буферы, которые он может представить. Чтобы представить текстуру Direct3D, приложение должно сначала создать текстуру с помощью Direct3D, а затем зарегистрировать ее в диспетчере презентаций. Когда текстура зарегистрирована в диспетчере презентаций, она называется буфером презентации и может отображаться на экране этим менеджером презентаций. Приложение может добавлять и удалять буферы презентаций по мере необходимости, хотя в одном диспетчере презентаций можно добавить максимальное количество буферов презентаций (в настоящее время 31). Эти буферы презентации также могут иметь различные размеры и форматы, которые вступают в силу в качестве отдельного буфера презентации.
Текстуру можно зарегистрировать с любым количеством менеджеров презентаций; Однако в большинстве случаев это не считается нормальным и будет приводить к сложным сценариям синхронизации, которые ваше приложение будет отвечать за управление.
Определение содержимого для представления
Как правило, буферы, которые мы представляем, должны быть связаны с содержимым в визуальном дереве. Таким образом, необходимо определить тип привязки, чтобы при появлении проблем с приложением было ясно, где в визуальном дереве представлены буферы, которые должны идти. Мы называем эту привязку содержимым презентации.
Представленное содержимое может принимать множество форм. Ваше приложение может представить один буфер, который будет отображаться, или может потребоваться представить стереоконтент с буферами для левого и правого глаз и т. д. Начальная версия этого API обеспечивает поддержку представления одного буфера на экране.
Мы определяем область презентации как форму содержимого презентации, в которую одновременно представлен один буфер. Область презентации может быть задана как содержимое в визуальном дереве и может отображать один буфер презентации на экране одновременно. Диспетчер презентаций обновит буфер, отображаемый одним или несколькими поверхностями презентации атомарно.
Диспетчер презентаций можно использовать для создания одной или нескольких поверхностей презентации для заданного дескриптора поверхности композиции. Каждый дескриптор поверхности композиции можно привязать к одному или нескольким визуальным элементам в визуальном дереве (по стратегиям, описанным в документации по API Windows.UI.Composition и DirectComposition), чтобы определить связь между связанной поверхностью презентации и местом ее отображения в визуальном дереве. Приложение может обновить одну или несколько поверхностей презентации, которые отправляются в систему и выполняются в следующей текущей операции.
Обратите внимание, что диспетчер презентаций может представить любой буфер презентации любому количеству поверхностей презентации, которые он хочет. Ограничения отсутствуют. Тем не менее, это связано с приложением, чтобы отслеживать, какие буферы вы выдали, и где, чтобы убедиться, что вы не пытаетесь выдавать новый рисунок в этот буфер, пока он по-прежнему отображается поверхностью презентации.
Применение свойств к поверхности презентации
Помимо указания буферов, отображаемых в поверхности презентации, может также указывать различные другие свойства для этой области презентации. К ним относятся свойства, определяющие способ выборки исходной текстуры, включая альфа-режим и цветовое пространство, способ преобразования и размещения исходной текстуры, а также любые отображаемые или ограничения обратного чтения для защищенного содержимого. Все они предоставляются как методы задания свойств на поверхности презентации, которые могут быть изменены приложением, и, как и обновления буфера, вступают в силу при наличии приложения.
Презентация на поверхности презентации
После создания поверхностей презентации приложение регистрирует буферы презентаций и задает обновления для проблем во время настоящего времени, эти свойства можно применить, предоставив эти свойства. Ваше приложение выдает представление через диспетчер презентаций. При обработке системой все обновления применяются атомарно. Кроме того, приложение также может указать другие свойства текущего, например идеальное время ( текущее целевое время ) и другие редкие свойства, такие как предполагаемая скорость содержимого, которая может использоваться для включения пользовательских режимов обновления в системе. Так как представление может быть запланировано в определенное время, приложение может выдавать несколько подарков заранее. Эти подарки будут обрабатываться по одному по мере достижения запланированного времени.
Синхронизация презентации
Приложение должно быть уверенным в том, что при отображении в буферах и проблемах он выбирает буфер для отрисовки, на который в настоящее время не ссылается любой другой выдающийся предыдущий текущий момент, так как это может перезаписать содержимое буфера, которое они предназначены. Кроме того, если приложение выдает проблемы с отрисовкой в буфер, отображаемый областью презентации в оборудовании сканирования, то ее отрисовка может быть остановлена на неопределенный срок, так как Direct3D запрещает отрисовку переднего буфера.
API буферной цепочки композиции предоставляет несколько различных механизмов, позволяющих приложению выполнять правильную синхронизацию буферов, которые он представил.
Как сообщается, буфер доступен, если нет выдающихся представлений, которые ссылаются на него, и в настоящее время он не отображается системой. В противном случае он недоступен. API предоставляет событие для каждого буфера презентации, указывающего, доступен ли буфер. Это самый простой метод синхронизации для используемого приложения. Перед рисованием в буфер и его презентацией приложение может убедиться, что его доступное событие сигнализирует. Доступное событие для определенного буфера становится незаписанным моментом, когда он был привязан к поверхности презентации в API, и остается без знака до тех пор, пока настоящее не станет устаревшим.
Во-вторых, менеджер презентаций отслеживает один представленный забор выхода на пенсию для обмена данными с приложением, которое было завершено. Значение забора соответствует настоящему идентификатору последнего присутствующих, который начал этап выхода на пенсию жизненного цикла, как описано в разделе жизненного цикла ниже. После того как данный этап входит в этот этап, можно предположить, что все буферы, которые были заменены последующими презентациями, можно повторно использовать.
Этот метод синхронизации более сложный, но позволяет повысить контроль над регулированием рабочего процесса и более информативно о состоянии системы в отношении глубины текущей текущей очереди. Общие сведения о жизненном цикле настоящего см. в разделе ниже.
Жизненный цикл представления
В рамках текущей очереди диспетчер презентаций помещаются в систему. Системные процессы представлены в порядке очереди. Кроме того, каждый из них имеет уникальный (для диспетчера презентаций) связанный идентификатор, который является добавочным значением, назначенным настоящему, начиная с 1 для первого представления, и увеличивается на 1 для каждого последующего представления. Этот идентификатор используется в различных частях API, таких как примитивы синхронизации и статистика презентации, чтобы ссылаться на это конкретное представление.
Каждое представление о проблемах с приложением следует определенному жизненному циклу, как описано здесь.
После того как приложение настроит изменения, внесенные в рамках представления, он будет использовать диспетчер презентаций для фактической выдачи настоящего. На этом этапе, как говорят, настоящее ожидается.
После ожидания презентация будет находиться в текущей очереди руководителя презентации, где она останется до тех пор, пока не произойдет одно из двух вещей.
- Данный момент становится отмененным. Диспетчер презентаций позволяет приложению отменить ранее выданные подарки. Если это произойдет, то настоящее, как говорят, отменено, а затем сразу же становится отставным. На этом переходе будут обновлены связанные события буфера , доступные для отмененного представления, однако текущее отставленное ограждение не будет сигнализировать, так как ранее отображаемый (до отмененных представлений) останется отображаемым. По этой причине ваше приложение не может использовать забор выхода на пенсию, чтобы определить, какие подарки были отменены. Вместо этого необходимо узнать это из текущей статистики состояния, которая возвращается для каждого отмененного представления. Мы рекомендуем, чтобы приложение использовало доступные события буфера для поиска доступного буфера после отмены. После отображения этого представления предыдущее представление начнет процесс выхода на пенсию и обновит нынешний забор выхода на пенсию.
- Если это не отменено, то текущее состояние в конечном итоге становится готовым к обработке. Чтобы быть готовым, необходимо выполнить два основных условия.
- Все действия рисования, выданные контексту Direct3D перед вызовом настоящего объекта, должны быть завершены. Это гарантирует, что буфер не отображается до завершения рисования приложения.
- Если задано текущее целевое время, то текущее системное относительное время, которое мы ожидаем, будет иметь возможность отобразить текущее время, соответствующее запрошенное целевое время, примененное к настоящему приложению.
Когда система решит найти подарок для отображения на экране, он выберет последнее представление, которое стало готовым к отображению. Если есть несколько готовых представлений, все, но последние (т. е. настоящее с наибольшим идентификатором) будут пропущены, и сразу же введите состояние отставленного состояния, в то время как его буфер доступные события будут сигнализировать, но нынешний забор выхода на пенсию не будет сигнален, так как пропущенное представление не переходит от отображаемого состояния.
Когда будет выбрано готовое представление, система начинает работу, чтобы отобразить ее на экране. Это может означать отрисовку буфера в составе кадра DWM, а затем запрос оборудования показать, что кадр на экране, или это может означать отправку буфера непосредственно на оборудование сканирования в случае с лилипом. После этого, как говорят, настоящее находится в очереди. На высоком уровне это означает, что он находится на пути к отображению.
Когда оборудование приближается к отображению текущего, это, как сообщается, отображается. Там он останется, видимый на экране, пока последующий подарок не появится и заменит его.
Когда последующий подарок становится в очереди, мы знаем, что оборудование в конечном итоге перестанет отображать текущее текущее представление. На этом этапе, как говорят , настоящее уходит в отставку.
Когда после этого последующего представления отображается, то текущий подарок, как сообщается , отставлен.
Диспетчер презентаций предоставляет настоящий забор выхода на пенсию, который сигнализирует настоящему идентификатору каждого присутствующих при входе в состояние выхода на пенсию . Этот сигнал указывает приложению, что он стал безопасным для выдачи работы отрисовки буферам, связанным с этим, без повреждения предыдущего текущего. Если в приложении возникают проблемы с отрисовкой во время выхода текущего состояния, работа отрисовки будет помещена в очередь до тех пор, пока он не войдет в состояние отставленного состояния, в какой момент он будет выполнен. Если работа отрисовки будет выдана после выхода из эксплуатации, она будет выполнена немедленно.
Ниже приведена схема изменения состояния.
Схема буферов, поверхностей и представлений
Ниже приведена схема, связанная с диспетчером презентаций, буферами презентаций, поверхностями презентации, презентациями и обновлениями.
На этой схеме показан диспетчер презентаций с двумя поверхностями презентации и тремя буферами презентации, которые были выпущены двумя выпущенными презентациями— первый представленный буфер 1 в поверхности 1 и буфер 2 в поверхности 2. Второй представленный обновленный surface 2 для отображения буфера презентации 3 и не изменил привязку surface 1. После отображения текущего 2 surface 1 будет отображать буфер 1, а поверхность 2 будет отображать буфер 3, который можно увидеть в текущем состоянии объектов в диспетчере презентаций. Каждая из присутствующих в очереди вступают в силу при обработке в системе.
Примечание.
Так как В настоящее время 2 не изменило буфер для поверхности 1, поверхность 1 была оставлена привязанной к буферу 1 из предыдущего текущего. В этом смысле существует неявная ссылка на буфер 1 в настоящее время 2, так как поверхность 1 останется привязанной к буферу 1 после отображения 2.
Добавление поверхностей презентации в визуальное дерево
Поверхности презентации — это содержимое, которое существует в составе визуального дерева композиции. Каждая поверхность презентации привязана к дескриптору поверхности композиции. В Windows.UI.Composition можно создать кисть поверхности для предварительно существующего дескриптора поверхности композиции и привязать к визуальному элементу спрайта. В DirectComposition поверхность композиции можно создать из существующего дескриптора поверхности композиции и связать как содержимое с визуальным элементом. Дополнительные сведения см. в соответствующей документации по каждому API.
API, такие как Windows Media Foundation, созданные для использования этого API, предоставляют маркеры поверхности композиции, которые будут предварительно привязаны к поверхности презентации. Приложение также может создать собственный дескриптор поверхности композиции для последующей привязки к поверхности презентации и добавления в визуальное дерево путем вызова DCompositionCreateSurfaceHandle.
Чтение статистики презентации
API подкачки композиции предоставляет статистику презентации, которая описывает различные сведения о том, как был обработан конкретный подарок. Как правило, информация может описать, как поверхность презентации использовалась в кадре DWM, момент времени, в течение которого он отображался, отображался ли он вообще, и т. д.
Существуют различные типы статистики презентаций, и они предназначены для расширения в будущих версиях API. Приложение использует диспетчер презентаций для регистрации для получения нужных типов статистики. Затем эти статистические данные отправляются в очередь статистики диспетчера презентаций. Диспетчер презентаций предоставляет доступное для приложений событие статистики, которое представляет собой дескриптор событий, указывающий, когда в очереди статистики есть элементы статистики, доступные для чтения. Когда это делает, приложение может выключить первый элемент статистики из очереди, прочитать его и обработать его. Диспетчер презентаций сбрасывает доступное событие статистики, когда приложение считывает всю статистику в очереди. Приложение обычно считывает и обрабатывает статистику в цикле, пока не будет сброшено доступное событие статистики. Приложение будет распространено для обработки этой очереди статистики в том же рабочем цикле, который вы используете для выдачи. Рекомендуемый шаблон использования заключается в приоритете статистики обработки при выдаче новых представлений, чтобы убедиться, что очередь не переполнена.
Очередь имеет максимальное количество статистики, которую она будет отслеживать, которая будет находиться в порядке 512-1024 статистики. Максимальная глубина очереди должна быть достаточной, чтобы сохранить около 5 секунд статистики в обычных случаях. Если очередь статистики становится полной, и больше статистики сообщается, политика заключается в том, что самая старая статистика будет прекращена, чтобы сделать место.