Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Хотя Direct2D является аппаратным ускорением и предназначен для высокой производительности, необходимо правильно использовать функции для максимальной пропускной способности. Приведенные здесь методы являются производными от изучения распространенных сценариев и могут не применяться ко всем сценариям приложений. Поэтому тщательное понимание поведения приложения и целей производительности может помочь достичь нужных результатов.
- Использование ресурсов
- Ограничить использование сброса
- Растровые изображения
- Использование мозаичного битмапа вместо пунктирной линии
- Общие рекомендации по отрисовке сложного статического содержимого
- Кэширование для каждого примитива с использованием геометрических реализаций
- Визуализация геометрии
- Рисование текста с помощью Direct2D
- обрезание произвольной фигуры
- Взаимодействие DXGI: избегайте частых коммутаторов
- Знание формата пикселей
- Сложность сцены
- Повышение производительности приложений печати Direct2D
- Заключение
Использование ресурсов
Ресурс — это выделение какого-либо вида в видео или системной памяти. Растровые изображения и кисти являются примерами ресурсов.
В Direct2D ресурсы можно создавать как в программном обеспечении, так и в оборудовании. Создание и удаление ресурсов являются дорогостоящей операцией, так как они требуют больших затрат на взаимодействие с видеокартой. Давайте посмотрим, как Direct2D рендерит содержимое в целевой объект.
В Direct2D все команды отрисовки заключены между вызовом BeginDraw и вызовом EndDraw. Эти вызовы осуществляются на целевой объект отрисовки. Перед вызовом операций отрисовки необходимо вызвать метод BeginDraw . После вызова BeginDraw контекст обычно создает пакет команд отрисовки, но задерживает обработку этих команд до тех пор, пока одно из этих условий не станет истиной:
- Произошло EndDraw. При вызове EndDraw завершаются все пакетные операции рисования, и возвращается состояние операции.
- Вы делаете явный вызов Flush: метод Flush приводит к обработке пакета и выполнению всех ожидающих команд.
- Буфер, содержащий команды отрисовки, заполнен. Если этот буфер становится полным до выполнения предыдущих двух условий, команды отрисовки удаляются.
Пока примитивы не будут удалены, Direct2D сохраняет внутренние ссылки на соответствующие ресурсы, такие как растровые изображения и кисти.
Повторное использование ресурсов
Как уже упоминалось, создание и удаление ресурсов является дорогостоящим на оборудовании. Поэтому повторно используйте ресурсы, когда это возможно. Пример создания растрового изображения в разработке игр. Обычно растровые изображения, составляющие сцену в игре, создаются одновременно со всеми различными вариантами, необходимыми для последующей отрисовки кадров в кадр. Во время фактической отрисовки сцены и повторной отрисовки эти растровые изображения повторно используются вместо повторного создания.
Замечание
Вы не можете повторно использовать ресурсы для операции изменения размера окна. При изменении размера окна некоторые ресурсы, зависящие от масштабирования, такие как совместимые целевые объекты отрисовки, и, возможно, некоторые ресурсы слоя должны быть повторно созданы, так как содержимое окна должно быть перезаписано. Это может быть важно для поддержания общего качества отрисовки сцены.
Ограничение использования смыва
Так как метод Flush приводит к обработке пакетных команд отрисовки, рекомендуется не использовать его. Для большинства распространенных сценариев оставьте управление ресурсами в Direct2D.
Растровые изображения
Как упоминалось ранее, создание и удаление ресурсов являются очень дорогостоящими операциями в оборудовании. Растровое изображение — это тип ресурса, который часто используется. Создание растровых изображений на видеокарте является дорогостоящим. Повторное использование их может помочь ускорить выполнение приложения.
Создание больших растровых изображений
Видеокарты обычно имеют минимальный размер выделения памяти. Если требуется выделение, которое меньше этого, выделяется ресурс этого минимального размера, а излишняя память теряется и недоступна для других целей. Если вам нужно много небольших растровых изображений, лучше выделить одну большую растровую карту и сохранить все небольшое содержимое растрового изображения в этом большом растровом рисунке. Затем части более крупного растрового изображения можно считывать, если требуются небольшие растровые изображения. Часто следует включить заполнение (прозрачные черные пиксели) между небольшими растровыми изображениями, чтобы избежать взаимодействия между меньшими изображениями во время операций. Это также известно как атлас, и он имеет преимущество уменьшения накладных расходов на создание растровых изображений и потери памяти при небольших распределениях растровых изображений. Рекомендуется сохранить большинство растровых карт не менее 64 КБ и ограничить количество растровых карт, которые меньше 4 КБ.
Создание атласа растровых изображений
Существуют некоторые распространенные сценарии, для которых битовый атлас может служить очень хорошо. Небольшие растровые изображения можно хранить внутри большого растрового изображения. Эти небольшие растровые изображения можно извлечь из более крупного растрового изображения, если они нужны, указав прямоугольник назначения. Например, приложению нужно нарисовать несколько значков. Все растровые изображения, связанные с значками, можно загрузить заранее в большой растровый файл. И во время отрисовки их можно извлечь из большого растрового изображения.
Замечание
Растровое изображение Direct2D, созданное в памяти видео, ограничено максимальным размером растрового изображения, поддерживаемым адаптером, на котором он хранится. Создание растрового изображения большего размера может привести к ошибке.
Замечание
Начиная с Windows 8, Direct2D включает эффект Atlas , который может упростить этот процесс.
Создание общих растровых карт
Создание общих растровых карт позволяет расширенным вызывающим объектам создавать объекты растровых карт Direct2D, которые поддерживаются непосредственно существующим объектом, уже совместимым с целевым объектом отрисовки. Это позволяет избежать создания нескольких поверхностей и снижения затрат на производительность.
Замечание
Общие растровые карты обычно ограничены программными целями или целями взаимодействия с DXGI. Используйте методы CreateBitmapFromDxgiSurface, CreateBitmapFromWicBitmap и CreateSharedBitmap для создания общих битмапов.
Копирование растровых изображений
Создание поверхности DXGI является дорогостоящей операцией, чтобы повторно использовать существующие поверхности, когда вы можете. Даже в программном обеспечении, если растровое изображение в основном находится в нужной форме, за исключением небольшой части, лучше обновить эту часть, чем выбросить всю растровую карту и повторно создать все. Хотя вы можете использовать CreateCompatibleRenderTarget для достижения одинаковых результатов, отрисовка обычно является гораздо более дорогой операцией, чем копирование. Это связано с тем, что для улучшения локальности кэша оборудование фактически не сохраняет битмап в той же последовательности доступа в памяти, в которой он адресуется. Вместо этого растровое изображение может быть перекомпоновано. Переворачивается от ЦП либо драйвером (который медленно используется только в нижних частях), либо диспетчером памяти на GPU. Из-за ограничений на то, как данные записываются в целевой буфер отрисовки при рендеринге, целевые буферы отрисовки обычно либо не перемешаны, либо перемешаны таким образом, который менее оптимален, чем можно было бы достичь, если бы вы знали, что никогда не будете отрисовывать на эту поверхность. Поэтому методы CopyFrom* предоставляются для копирования прямоугольников из источника в растровое изображение Direct2D.
CopyFrom можно использовать в любой из трех форм:
Использовать текстурированное изображение вместо пунктирной линии
Отрисовка дефисной линии является очень дорогой операцией из-за высокого качества и точности базового алгоритма. В большинстве случаев, не связанных с прямоугольниками геометрии, один и тот же эффект можно создать быстрее с помощью плиток растровых изображений.
Общие рекомендации по отрисовке сложного статического содержимого
Кэшируйте содержимое, если вы отрисовываете тот же контент кадр за кадром, особенно если сцена сложна.
Существует три способа кэширования, которые можно использовать:
- Кэширование полной сцены с помощью цветного растрового изображения.
- Примитивное кэширование с помощью растрового изображения A8 и метода FillOpacityMask .
- Кэширование для каждого примитива с использованием геометрических реализаций.
Давайте рассмотрим каждый из них более подробно.
Кэширование полной сцены с использованием цветного растрового изображения
При отображении статического содержимого в таких сценариях, как анимация, создайте другой полноцветный растровый рисунок вместо записи непосредственно на растровое изображение экрана. Сохраните текущий целевой объект, установите целевой объект на промежуточное растровое изображение и отрисовка статического содержимого. Затем переключитесь на исходное растровое изображение экрана и нарисуйте на нем промежуточное растровое изображение.
Ниже приведен пример:
// Create a bitmap.
m_d2dContext->CreateBitmap(size, nullptr, 0,
D2D1::BitmapProperties(
D2D1_BITMAP_OPTIONS_TARGET,
D2D1::PixelFormat(
DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_PREMULTIPLIED),
dpiX, dpiY),
&sceneBitmap);
// Preserve the pre-existing target.
ComPtr<ID2D1Image> oldTarget;
m_d2dContext->GetTarget(&oldTarget);
// Render static content to the sceneBitmap.
m_d2dContext->SetTarget(sceneBitmap.Get());
m_d2dContext->BeginDraw();
…
m_d2dContext->EndDraw();
// Render sceneBitmap to oldTarget.
m_d2dContext->SetTarget(oldTarget.Get());
m_d2dContext->DrawBitmap(sceneBitmap.Get());
В этом примере используются промежуточные растровые изображения для кэширования, а также осуществляется переключение растрового изображения, на которое указывает контекст устройства при отрисовке. Это позволяет избежать необходимости создания совместимого целевого объекта отрисовки для той же цели.
Примитивное кэширование с помощью растрового изображения A8 и метода FillOpacityMask
Если полная сцена не является статической, но состоит из элементов, таких как геометрия или текст, которые являются статическими, можно использовать метод кэширования для каждого примитива. Этот метод сохраняет характеристики сглаживания кэшируемого примитива и работает с изменением типов кистей. В нем используется растровое изображение A8, где A8 представляет собой формат пикселя, представляющий альфа-канал с 8 битами. Растровые изображения A8 полезны для рисования геометрии и текста в виде маски. Когда необходимо управлять непрозрачностью статического содержимого, а не управлять самим содержимым, можно перевести, повернуть, сместить или масштабировать непрозрачность маски.
Ниже приведен пример:
// Create an opacity bitmap.
m_d2dContext->CreateBitmap(size, nullptr, 0,
D2D1::BitmapProperties(
D2D1_BITMAP_OPTIONS_TARGET,
D2D1::PixelFormat(
DXGI_FORMAT_A8_UNORM,
D2D1_ALPHA_MODE_PREMULTIPLIED),
dpiX, dpiY),
&opacityBitmap);
// Preserve the pre-existing target.
ComPtr<ID2D1Image> oldTarget;
m_d2dContext->GetTarget(&oldTarget);
// Render to the opacityBitmap.
m_d2dContext->SetTarget(opacityBitmap.Get());
m_d2dContext->BeginDraw();
…
m_d2dContext->EndDraw();
// Call the FillOpacityMask method
// Note: for this call to work correctly the anti alias mode must be D2D1_ANTIALIAS_MODE_ALIASED.
m_d2dContext->SetTarget(oldTarget.Get());
m_d2dContext->FillOpacityMask(
opacityBitmap.Get(),
m_contentBrush().Get(),
D2D1_OPACITY_MASK_CONTENT_GRAPHICS);
Кэширование отдельных примитивов с использованием геометрической реализации
Другой метод кэширования на основе примитивов, называемый реализациями геометрии, обеспечивает большую гибкость при работе с геометрией. Если вы хотите многократно нарисовать псевдонимы или анти-псевдонимы геометрий, их можно быстрее преобразовать в геометрическую реализацию и многократно рисовать реализации, чем многократно рисовать геометрии. Реализация геометрии также обычно потребляет меньше памяти, чем маски непрозрачности (особенно для больших геометрий), и они менее чувствительны к изменениям в масштабе. Дополнительные сведения см. в разделе "Общие сведения о реализации геометрии".
Ниже приведен пример:
// Compute a flattening tolerance based on the scales at which the realization will be used.
float flatteningTolerance = D2D1::ComputeFlatteningTolerance(...);
ComPtr<ID2D1GeometryRealization> geometryRealization;
// Create realization of the filled interior of the geometry.
m_d2dDeviceContext1->CreateFilledGeometryRealization(
geometry.Get(),
flatteningTolerance,
&geometryRealization
);
// In your app's rendering code, draw the geometry realization with a brush.
m_d2dDeviceContext1->BeginDraw();
m_d2dDeviceContext1->DrawGeometryRealization(
geometryRealization.Get(),
m_brush.Get()
);
m_d2dDeviceContext1->EndDraw();
Визуализация геометрии
Использование конкретных примитивов рисования по геометрии
Используйте более конкретныепримитивные вызовы рисования, такие как DrawRectangle для универсальных вызовов DrawGeometry . Это связано с тем, что при использовании DrawRectangle геометрия уже известна таким образом, что отрисовка выполняется быстрее.
Отрисовка статической геометрии
В сценариях, где геометрия является статической, используйте описанные выше методы кэширования для каждого примитива. Маски непрозрачности и реализации геометрии могут значительно повысить скорость отрисовки сцен, содержащих статическую геометрию.
Используйте контекст многопоточного устройства
Приложения, которые предполагают отрисовку значительных объемов сложного геометрического содержимого, должны указать флаг D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTI_THREADED_OPTIMIZATIONS при создании контекста устройства Direct2D. Если этот флаг указан, Direct2D распределяет отрисовку во всех логических ядрах, присутствующих в системе, что может значительно снизить общее время отрисовки.
Примечания:
- По состоянию на Windows 8.1 этот флаг влияет только на отрисовку геометрии пути. Это не влияет на сцены, содержащие только другие примитивные типы (например, текстовые, растровые изображения или реализации геометрии).
- Этот флаг также не влияет на отрисовку в программном обеспечении (т. е. при отрисовке с устройством WARP Direct3D). Чтобы управлять многопоточностью программного обеспечения, вызывающие устройства должны использовать флаг D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS при создании устройства WARP Direct3D.
- Указание этого флага может увеличить пиковый рабочий набор во время отрисовки, а также увеличить количество потоков в приложениях, которые уже используют многопотточную обработку.
Рисование текста с помощью Direct2D
Функции отрисовки текста Direct2D предлагаются в двух частях. Первая часть, которая предоставляется в качестве метода ID2D1RenderTarget::D rawText и ID2D1RenderTarget::D rawTextLayout , позволяет вызывающему объекту передавать параметры строки и форматирования или объект макета текста DWrite для нескольких форматов. Это должно быть подходит для большинства абонентов. Второй способ отрисовки текста, предоставляемый как метод ID2D1RenderTarget::D rawGlyphRun , обеспечивает растеризацию для клиентов, которые уже знают положение глифов, которые они хотят отрисовывать. Следующие два общих правила помогают повысить производительность текста при рисовании в Direct2D.
DrawTextLayout Vs. DrawText
Как DrawText, так и DrawTextLayout позволяют приложению легко отрисовывать текст, отформатированный API DirectWrite. DrawTextLayout рисует существующий объект DWriteTextLayout в объект RenderTarget, а DrawText создает макет DirectWrite для вызывающего объекта на основе параметров, передаваемых в. Если один и тот же текст должен отображаться несколько раз, используйте DrawTextLayout вместо DrawText, так как DrawText создает макет при каждом вызове.
Выбор правильного режима отрисовки текста
Задайте для режима защиты текста значение D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE явным образом. Качество отрисовки серого уровня текста сравнимо с ClearType, но гораздо быстрее.
Кэширование
Используйте полную сцену или кэширование примитивной растровой карты, как и при рисовании других примитивов.
Обрезка произвольной фигуры
На рисунке показан результат применения клипа к изображению.
Этот результат можно получить с помощью слоев с геометрической маской или методом FillGeometry, используя кисть для управления непрозрачностью.
Ниже приведен пример использования слоя:
// Call PushLayer() and pass in the clipping geometry.
m_d2dContext->PushLayer(
D2D1::LayerParameters(
boundsRect,
geometricMask));
Ниже приведен пример использования метода FillGeometry:
// Create an opacity bitmap and render content.
m_d2dContext->CreateBitmap(size, nullptr, 0,
D2D1::BitmapProperties(
D2D1_BITMAP_OPTIONS_TARGET,
D2D1::PixelFormat(
DXGI_FORMAT_A8_UNORM,
D2D1_ALPHA_MODE_PREMULTIPLIED),
dpiX, dpiY),
&opacityBitmap);
m_d2dContext->SetTarget(opacityBitmap.Get());
m_d2dContext->BeginDraw();
…
m_d2dContext->EndDraw();
// Create an opacity brush from the opacity bitmap.
m_d2dContext->CreateBitmapBrush(opacityBitmap.Get(),
D2D1::BitmapBrushProperties(),
D2D1::BrushProperties(),
&bitmapBrush);
// Call the FillGeometry method and pass in the clip geometry and the opacity brush
m_d2dContext->FillGeometry(
clipGeometry.Get(),
brush.Get(),
opacityBrush.Get());
В этом примере кода при вызове метода PushLayer вы не передаете слой, созданный приложением. Direct2D создает слой для вас. Direct2D может управлять выделением и уничтожением этого ресурса без какого-либо участия в приложении. Это позволяет Direct2D повторно использовать слои внутри системы и применять оптимизации управления ресурсами.
В Windows 8 многие оптимизации были сделаны для использования слоев, и мы рекомендуем использовать API слоев вместо FillGeometry по возможности.
PushLayer в Windows 8
Интерфейс ID2D1DeviceContext является производным от интерфейса ID2D1RenderTarget и играет ключевую роль в отображении содержимого Direct2D в Windows 8. Для получения дополнительных сведений об этом интерфейсе см. раздел Устройства и контексты устройств. С помощью интерфейса контекста устройства можно пропустить вызов метода CreateLayer, а затем передать NULL в метод ID2D1DeviceContext::PushLayer. Direct2D автоматически управляет ресурсом слоя и может совместно использовать ресурсы между слоями и графами эффектов.
Выровненные по оси клипы
Если область, подлежащая обрезке, выровнена по оси поверхности рисования, а не произвольной. Этот случай больше подходит для использования обрезающего прямоугольника вместо слоя. Увеличение производительности для геометрии с алиасингом больше, чем для геометрии с сглаживанием. Дополнительные сведения о клипах, выровненных по оси, см. PushAxisAlignedClip.
Взаимодействие DXGI: избегайте частых коммутаторов
Direct2D может легко взаимодействовать с поверхностями Direct3D. Это очень полезно для создания приложений, которые отображают смесь 2D-содержимого и трехмерного содержимого. Но каждый коммутатор между содержимым Direct2D и Direct3D влияет на производительность.
При отрисовке в поверхность DXGI Direct2D сохраняет состояние устройств Direct3D во время отрисовки и восстановления при завершении отрисовки. Каждый раз, когда выполняется пакет отрисовки Direct2D, стоимость этой экономии и восстановления и затраты на очистку всех операций 2D оплачиваются, а устройство Direct3D не очищается. Таким образом, чтобы повысить производительность, ограничивайте количество переключений отрисовки между Direct2D и Direct3D.
Знание формата пикселей
При создании целевого объекта отрисовки можно использовать структуру D2D1_PIXEL_FORMAT указать формат пикселей и альфа-режим, используемый целевым объектом отрисовки. Альфа-канал является частью формата пикселя, указывающего значение покрытия или сведения о непрозрачности. Если целевой объект отрисовки не использует альфа-канал, его следует создать с помощью альфа-режима D2D1_ALPHA_MODE_IGNORE. Это экономит время, затраченное на отрисовку альфа-канала, который не требуется.
Дополнительные сведения о форматах пикселей и альфа-режимах см. в разделе "Поддерживаемые форматы пикселей" и "Альфа-режимы".
Сложность сцены
При анализе горячих точек производительности в сцене, которая будет отображаться, полезно знать, ограничена ли сцена по скорости заполнения или по вершинам.
- Скорость заливки: скорость заливки относится к количеству пикселей, которые графические карты могут отображать и записывать в память видео в секунду.
- Вершинная привязка: сцена ограничена вершинами, когда в ней много сложной геометрии.
Понимание сложности сцены
Вы можете проанализировать сложность сцены, изменив размер целевого объекта отрисовки. Если видны улучшения производительности при пропорциональном уменьшении размера целевой поверхности отрисовки, то приложение ограничено скоростью заполнения. В противном случае сложность сцены станет узким местом в производительности.
Если сцена привязана к скорости заполнения, уменьшение размера целевого объекта отрисовки может повысить производительность. Это связано с тем, что число пикселей для отрисовки будет сокращено пропорционально с размером целевого объекта отрисовки.
Если сцена связана вершиной, уменьшите сложность геометрии. Но помните, что это делается за счет качества изображения. Поэтому необходимо принять тщательное решение о компромиссе между требуемым качеством и требуемой производительностью.
Повышение производительности приложений печати Direct2D
Direct2D обеспечивает совместимость с печатью. Вы можете отправлять те же команды рисования Direct2D (в виде списков команд Direct2D) в элемент управления печати Direct2D для печати, если вы не знаете, на каких устройствах вы выполняете отрисовку, или как отрисовка преобразуется для печати.
Вы можете дополнительно настроить их использование элемента управления печати Direct2D и команд рисования Direct2D , чтобы обеспечить результаты печати с более высокой производительностью.
Элемент управления печати Direct2D выводит отладочные сообщения, когда отображается шаблон кода Direct2D , который приводит к снижению качества печати или производительности (например, шаблонов кода, перечисленных далее в этом разделе), чтобы напомнить вам, где можно избежать проблем с производительностью. Чтобы просмотреть эти сообщения отладки, необходимо включить уровень отладки Direct2D в коде. В разделе "Сообщения отладки" см. инструкции по включению выходных данных сообщений отладки.
Задайте правильные значения свойств при создании элемента управления печати D2D
При создании элемента управления печати Direct2D можно задать три свойства. Два из этих свойств влияют на то, как элемент управления печати Direct2D обрабатывает определенные команды Direct2D и, в свою очередь, влияет на общую производительность.
- Режим подмножества шрифта: элемент управления печати Direct2D выделяет подмножества для шрифтовых ресурсов, которые используются на каждой странице перед отправкой страницы на печать. Этот режим уменьшает размер ресурсов страниц, необходимых для печати. В зависимости от использования шрифта на странице можно выбрать различные режимы подмножества шрифтов для оптимальной производительности.
- D2D1_PRINT_FONT_SUBSET_MODE_DEFAULT обеспечивает лучшую производительность печати в большинстве случаев. Когда активирован этот режим, элемент управления печатью Direct2D использует эвристическую стратегию, чтобы определить, когда выбирать шрифты подмножества.
- Для коротких заданий печати, содержащих 1 или 2 страницы, рекомендуется использовать D2D1_PRINT_FONT_SUBSET_MODE_EACHPAGE, при котором управление печатью Direct2D создает и внедряет подмножества шрифтовых ресурсов на каждой странице, а затем удаляет это подмножество после печати страницы. Этот параметр гарантирует, что каждая страница может быть напечатана сразу после создания, но немного увеличивает размер ресурсов страниц, необходимых для печати (обычно с большими подмножествами шрифтов).
- Для заданий печати с большим количеством страниц текста и небольших размеров шрифтов (например, 100 страниц текста, использующего один шрифт), рекомендуется D2D1_PRINT_FONT_SUBSET_MODE_NONE, где элемент управления печати Direct2D не подмножествует ресурсы шрифта вообще; Вместо этого он отправляет исходные ресурсы шрифта вместе со страницей, которая сначала использует шрифт, и повторно использует ресурсы шрифта для последующих страниц без повторной их отправки.
- DPI растрирования: Если элемент управления печати Direct2D должен растрировать команды Direct2D во время преобразования Direct2D-XPS, он использует этот DPI для растрирования. Другими словами, если на странице нет растрированного содержимого, настройка DPI не изменит производительность и качество. В зависимости от использования растеризации на странице можно выбрать различные dpis растеризации для оптимального баланса между точностью и производительностью.
- 150 — это значение по умолчанию, если вы не указываете значение при создании элемента управления печати Direct2D , что является лучшим балансом качества печати и производительности печати в большинстве случаев.
- Более высокие значения DPI обычно приводят к повышению качества печати (например, лучшее сохранение деталей), но снижению производительности из-за более крупных битмапов, которые он создает. Мы не рекомендуем никакое значение DPI больше 300, так как это не будет вводить дополнительную информацию визуально воспринимаемой человеческими глазами.
- Более низкий DPI может означать более высокую производительность, но также может привести к снижению качества.
Избегайте использования определенных шаблонов рисования Direct2D
Существуют различия между визуальным представлением Direct2D и тем, что подсистема печати может поддерживать и транспортировать по всему конвейеру печати. Управление печатью Direct2D мостит эти пробелы путем приближения или растеризации примитивов Direct2D, которые подсистема печати не поддерживает изначально. Такое приближение обычно приводит к снижению точности печати, снижению производительности печати или обоих. Таким образом, несмотря на то, что клиент может использовать одни и те же шаблоны рисования для отрисовки экрана и печати, это не идеально во всех случаях. Рекомендуется по возможности избегать использования таких примитивов и шаблонов Direct2D для печатного процесса, или выполнять собственную растеризацию, где у вас есть полный контроль над качеством и размером растрированных изображений.
Ниже приведен список случаев, когда производительность и качество печати не будут идеальными, и вы можете рассмотреть возможность изменения пути кода для оптимальной производительности печати.
- Избегайте использования режима примитивной смеси, отличного от D2D1_PRIMITIVE_BLEND_SOURCEOVER.
- Избегайте использования режимов композиции при рисовании изображения, отличного от D2D1_COMPOSITE_MODE_SOURCE_OVER и D2D1_COMPOSITE_MODE_DESTINATION_OVER.
- Избегайте рисования метафайла GDI.
- Избегайте отправлять ресурс слоя, который копирует исходный фон (вызов PushLayer с передачей D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND в структуру D2D1_LAYER_PARAMETERS1 ).
- Избегайте создания кисти для растровых изображений или кисти для изображений с помощью D2D1_EXTEND_MODE_CLAMP. Рекомендуем использовать D2D1_EXTEND_MODE_MIRROR, если вы не заботитесь о пикселях вне границы изображения (например, если известно, что изображение, присоединенное к кисти, больше, чем заполненная целевая область).
- Избегайте использования перспективных преобразований для растровых изображений.
Рисование текста прямым и простым способом
Direct2D имеет несколько оптимизаций при отображении текста для отображения более эффективной производительности и (или) лучшего визуального качества. Но не все оптимизации повышают производительность и качество печати, так как печать на бумаге обычно находится в гораздо более высоком DPI, и печать не требуется для размещения таких сценариев, как анимация. Поэтому рекомендуется напрямую нарисовать исходный текст или глифы и избежать любой из следующих оптимизаций при создании списка команд для печати.
- Избегайте рисования текста с помощью метода FillOpacityMask .
- Избегайте рисования текста в режиме без сглаживания.
Рисование исходных растровых изображений по возможности
Если целевое растровое изображение — JPEG, PNG, TIFF или JPEG-XR, вы можете создать растровое изображение WIC из файла на диске или из потока в памяти, затем создать растровое изображение Direct2D из этого растрового изображения WIC с помощью ID2D1DeviceContext::CreateBitmapFromWicBitmap, и, наконец, напрямую передать это растровое изображение Direct2D в элемент управления печати Direct2D без дополнительной обработки. Таким образом, элемент управления печати Direct2D может повторно использовать поток растровой карты, что обычно приводит к повышению производительности печати (пропуская избыточное кодирования растровых карт и декодирование), а также лучшее качество печати (если метаданные, такие как цветовые профили, в растровом рисунке будут сохранены).
Рисование исходного растрового изображения обеспечивает следующее преимущество для приложений.
- Как правило, печать Direct2D сохраняет исходную информацию (без потери или шума) до конца конвейера, особенно если приложения не знают (или не хотят знать) сведения о конвейере печати (например, на каком принтере он печатается, какой DPI является целевым принтером и т. д.).
- Во многих случаях задержка растрового изображения означает лучшую производительность (например, при печати фотографии 96dpi на принтер 600dpi).
- В некоторых случаях передача исходных изображений является единственным способом соблюдать высокую точность (например, внедренные цветовые профили).
Однако вы не можете отказаться от такой оптимизации, так как:
- Запрашивая сведения о принтере и осуществляя раннюю растеризацию, вы можете самостоятельно растеризировать содержимое, полностью контролируя его финальный вид на бумаге.
- В некоторых случаях преждевременная растеризация может действительно улучшить общую производительность приложения (например, печать фотографий размером с визитку).
- В некоторых случаях для использования исходных растровых изображений требуется значительное изменение существующей архитектуры кода (например, отложенная загрузка изображений и обновление ресурсов, что встречается в некоторых приложениях).
Заключение
Хотя Direct2D является аппаратным ускорением и предназначен для высокой производительности, необходимо правильно использовать функции для максимальной пропускной способности. Описанные здесь методы являются производными от изучения распространенных сценариев и могут не применяться ко всем сценариям приложений.