Spec-Zone.ru › Qt 5.15

По умолчанию рендерер графа сцен Qt Quick

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

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

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

Элементы Qt Quick в сцене QML заполняют дерево экземпляров QSGNode. После создания это дерево представляет собой полное описание того, как должен быть отрисован определенный кадр. Оно не содержит никаких ссылок обратно на элементы Qt Quick и на большинстве платформ будет обрабатываться и отрисовываться в отдельном потоке. Рендерер — это автономная часть графа сцен, которая обходит дерево QSGNode и использует геометрию, определенную в QSGGeometryNode, и состояние шейдера, определенное в QSGMaterial, для обновления состояния графики и генерации вызовов отрисовки.

При необходимости рендерер можно полностью заменить с помощью внутреннего API-интерфейса заднего плана графа сцен. Это в основном интересно для поставщиков платформ, которые хотят воспользоваться нестандартными аппаратными функциями. Для большинства случаев использования рендерер по умолчанию будет достаточным.

По умолчанию рендерер фокусируется на двух основных стратегиях оптимизации отрисовки: группировании вызовов отрисовки и сохранении геометрии на графическом процессоре.

Группирование

В то время как традиционный 2D-API, такой как QPainter, Cairo или Context2D, написан для обработки тысяч отдельных вызовов отрисовки за кадр, OpenGL и другие API с аппаратным ускорением работают лучше всего, когда количество вызовов отрисовки очень низкое, а изменения состояния минимальны.

Примечание: Хотя OpenGL используется в качестве примера в следующих разделах, те же концепции применимы и к другим API графики.

Рассмотрим следующий пример использования:

Самый простой способ отображения этого списка — по ячейкам. Сначала рисуется фон. Это прямоугольник определенного цвета. В терминах OpenGL это означает выбор программы шейдера для заливки однородным цветом, настройку цвета заливки, настройку матрицы преобразования, содержащей смещения по x и y, а затем, например, glDrawArrays для отрисовки двух треугольников, образующих прямоугольник. Затем рисуется значок. В терминах OpenGL это означает выбор программы шейдера для отрисовки текстур, выбор активной текстуры для использования, настройку матрицы преобразования, включение альфа-смешивания и затем, например, glDrawArrays для отрисовки двух треугольников, образующих границу значка. Текст и разделительная линия между ячейками следуют аналогичному шаблону. И этот процесс повторяется для каждой ячейки в списке, поэтому для более длинного списка накладные расходы, связанные с изменениями состояния OpenGL и вызовами отрисовки, полностью перевешивают преимущества использования API с аппаратным ускорением.

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

Рендерер сцен по умолчанию работает в рамках этих ограничений и будет пытаться объединить отдельные примитивы в группы, сохраняя при этом точный визуальный результат. Результатом является меньшее количество изменений состояния OpenGL и минимальное количество вызовов отрисовки, что приводит к оптимальной производительности.

Непрозрачные примитивы

Рендерер разделяет непрозрачные примитивы и примитивы, которые требуют альфа-смешивания. Используя буфер глубины OpenGL и присваивая каждому примитиву уникальное значение z, рендерер может свободно переупорядочивать непрозрачные примитивы без учета их расположения на экране и перекрытия других элементов. Рассматривая состояние материала каждого примитива, рендерер создаст непрозрачные группы. Из набора элементов Qt Quick core это включает в себя элементы Rectangle с непрозрачными цветами и полностью непрозрачными изображениями, такими как JPEG или BMP.

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

Непрозрачные примитивы отрисовываются спереди назад с включенными glDepthMask и GL_DEPTH_TEST. На графических процессорах, которые внутренне выполняют предварительные проверки z, это означает, что фрагментный шейдер не нужно запускать для пикселей или блоков пикселей, которые скрыты. Обратите внимание, что рендерер все равно должен учитывать эти узлы, и вершинный шейдер по-прежнему выполняется для каждой вершины в этих примитивах, поэтому, если приложение знает, что что-то полностью скрыто, лучше всего явно скрыть его с помощью Item::visible или Item::opacity.

Примечание: Item::z используется для управления порядком расположения элементов относительно их собратьев. Он не имеет прямой связи с рендерером и буфером глубины OpenGL.

Примитивы с альфа-смешиванием

После отрисовки непрозрачных примитивов рендерер отключит glDepthMask, включит GL_BLEND и отрисует все примитивы с альфа-смешиванием сзади вперед.

Группирование примитивов с альфа-смешиванием требует от рендерера немного больше усилий, так как элементы, которые перекрываются, должны быть отрисованы в правильном порядке для корректного альфа-смешивания. Только на буфере глубины нельзя положиться. Рендерер выполняет проход по всем примитивам с альфа-смешиванием и проверяет их ограничивающие прямоугольники, а также состояние их материала, чтобы определить, какие элементы можно сгруппировать, а какие нет.

В случае слева синие фоны могут быть отрисованы одним вызовом, а два элемента текста — другим вызовом, поскольку тексты перекрывают только фон, впереди которого они расположены. В случае справа фон «Элемента 4» перекрывает текст «Элемента 3», поэтому в этом случае каждый из фонов и текстов должен быть отрисован с использованием отдельных вызовов.

С точки зрения z, альфа-примитивы чередуются с непрозрачными узлами и могут вызывать предварительные проверки z при их наличии, но еще раз, установка Item::visible в false всегда быстрее.

Смешение с 3D-примитивами

Граф сцен может поддерживать псевдо 3D и собственные 3D-примитивы. Например, можно реализовать эффект «скручивания страницы» с помощью ShaderEffect или реализовать тор с объемным отображением с помощью QSGGeometry и настраиваемого материала. При этом необходимо учитывать, что рендерер по умолчанию уже использует буфер глубины.

Рендерер изменяет вершинный шейдер, возвращаемый из QSGMaterialShader::vertexShader(), и сжимает значения z вершин после применения матриц модели-представления и проекции, а затем добавляет небольшое смещение по z для размещения в нужном положении z.

Сжатие предполагает, что значения z находятся в диапазоне от 0 до 1.

Атлас текстур

Активная текстура — это уникальное состояние OpenGL, что означает, что несколько примитивов, использующих разные текстуры OpenGL, не могут быть сгруппированы. Поэтому график сцен Qt Quick позволяет создавать несколько экземпляров QSGTexture в виде более мелких подзон большой текстуры; атлас текстур.

Главное преимущество атласов текстур состоит в том, что несколько экземпляров QSGTexture теперь ссылаются на один и тот же экземпляр текстуры OpenGL. Это позволяет группировать вызовы отрисовки с текстурами, такие как элементы Image, элементы BorderImage, элементы ShaderEffect, а также типы C++, такие как QSGSimpleTextureNode и настраиваемые QSGGeometryNodes, использующие текстуры.

Примечание: Крупные текстуры не попадают в атлас текстур.

Текстуры, основанные на атласе, создаются путем передачи QQuickWindow::TextureCanUseAtlas в QQuickWindow::createTextureFromImage().

Примечание: Текстуры, основанные на атласе, не имеют текстурных координат в диапазоне от 0 до 1. Используйте QSGTexture::normalizedTextureSubRect() для получения координат текстуры атласа.

Граф сцен использует эвристические методы для определения размера атласа и порогового значения размера для включения в атлас. Если необходимы другие значения, можно переопределить их с помощью переменных среды QSG_ATLAS_WIDTH=[width], QSG_ATLAS_HEIGHT=[height] и QSG_ATLAS_SIZE_LIMIT=[size]. Изменение этих значений будет в основном интересно для поставщиков платформ.

Корни групп

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

Узлы преобразования

Каждый элемент Qt Quick вставляет QSGTransformNode в дерево графа сцен для управления его x, y, масштабом или поворотом. Дочерние элементы будут размещены под этим узлом преобразования. По умолчанию рендерер отслеживает состояние узлов преобразования между кадрами и будет анализировать поддеревья, чтобы определить, является ли узел преобразования хорошим кандидатом для того, чтобы стать корнем набора групп. Узел преобразования, который изменяется между кадрами и у которого довольно сложное поддерево, может стать корнем группы.

QSGGeometryNodes в поддереве корня группы предварительно преобразуются относительно корня на центральном процессоре. Затем они загружаются и сохраняются на графическом процессоре. При изменении преобразования рендереру нужно только обновить матрицу корня, а не каждый отдельный элемент, что делает прокрутку списка и сетки очень быстрой. Для последующих кадров, пока узлы не добавляются и не удаляются, отрисовка списка фактически бесплатна. При вводе нового содержимого в поддерево группа, которая его получает, перестраивается, но это все равно относительно быстро. Обычно есть несколько неизменных кадров для каждого кадра с добавленными или удаленными узлами при прокрутке сетки или списка.

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

Порог узла и вершин для того, чтобы узел преобразования стал корнем группы, можно переопределить с помощью переменных среды QSG_RENDERER_BATCH_NODE_THRESHOLD=[count] и QSG_RENDERER_BATCH_VERTEX_THRESHOLD=[count]. Переопределение этих флагов будет в основном полезно поставщикам платформ.

Примечание: Под корнем группы создается по одной группе для каждого уникального набора состояния материала и типа геометрии.

Обрезка

При установке Item::clip в значение true, будет создан QSGClipNode с прямоугольником в его геометрии. По умолчанию рендерер будет применять этот обрезку, используя цизирование в OpenGL. Если элемент повернут на угол, не равный 90 градусам, используется буфер трафарета OpenGL. Элемент Qt Quick Item поддерживает установку только прямоугольника в качестве обрезки через QML, но API графа сцены и рендерер по умолчанию могут использовать любую форму для обрезки.

При применении обрезки к поддереву, это поддерево должно быть отрисовано с уникальным состоянием OpenGL. Это означает, что при Item::clip = true, кэширование этого элемента ограничено его дочерними элементами. При большом количестве дочерних элементов, таких как ListView или GridView, или сложных дочерних элементов, таких как TextArea, это нормально. Однако следует осторожно использовать обрезку для небольших элементов, так как это препятствует кэшированию. Это включает метки кнопок, текстовые поля или делегаты списков и ячейки таблицы.

Буферы вершин

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

По умолчанию рендерер загрузит данные в VBO, используя GL_STATIC_DRAW. Можно выбрать другую стратегию загрузки, установив переменную среды QSG_RENDERER_BUFFER_STRATEGY=[strategy]. Допустимые значения: stream и dynamic. Изменение этого значения в основном полезно для поставщиков платформ.

Антиалиасинг

Граф сцены поддерживает два типа антиалиасинга. По умолчанию примитивы, такие как прямоугольники и изображения, будут антиалиасированы путем добавления дополнительных вершин по краю примитивов, так что края плавно переходят в прозрачность. Мы называем этот метод антиалиасингом вершин. Если пользователь запросит контекст OpenGL с многократной выборкой, установив QSurfaceFormat с количеством выборок, большим чем 0 с помощью QQuickWindow::setFormat(), граф сцены отдаст предпочтение антиалиасингу на основе многократной выборки (MSAA). Эти два метода повлияют на то, как происходит отрисовка внутри, и имеют разные ограничения.

Также можно переопределить метод антиалиасинга, установив переменную среды QSG_ANTIALIASING_METHOD в значение vertex или msaa.

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

Антиалиасинг вершин

Антиалиасинг вершин можно включить и выключить для каждого элемента, используя свойство Item::antialiasing. Он будет работать независимо от того, поддерживает ли это подлежащее оборудование, и обеспечивает более качественный антиалиасинг, как для обычных отрисовываемых примитивов, так и для примитивов, захваченных в буферы кадров, например, с помощью типа ShaderEffectSource.

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

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

Антиалиасинг с многократной выборкой

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

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

При использовании антиалиасинга с многократной выборкой для содержимого, отрисовываемого в буферы кадров, требуются дополнительные расширения для поддержки многократной выборки буферов кадров. Обычно GL_EXT_framebuffer_multisample и GL_EXT_framebuffer_blit. Большинство настольных процессоров имеют эти расширения, но они менее распространены в встраиваемых процессорах. Если многократная выборка буфера кадров недоступна в оборудовании, содержимое, отрисованное в буферы кадров, не будет антиалиасировано, включая содержимое ShaderEffectSource.

Производительность

Как было сказано в начале, для достижения хорошей производительности не нужно понимать тонкие детали рендерера. Он разработан для оптимизации типовых случаев использования и будет работать довольно хорошо практически во всех ситуациях.

  • Хорошая производительность достигается за счет эффективного кэширования с минимальным количеством геометрии, загружаемой снова и снова. Установив переменную среды QSG_RENDERER_DEBUG=render, рендерер выведет статистику о том, насколько хорошо происходит кэширование, сколько используется пакетов, какие пакеты сохраняются, а какие непрозрачны и нет. При стремлении к оптимальной производительности загрузки должны выполняться только тогда, когда это действительно необходимо, пакетов должно быть меньше 10, и по крайней мере 3-4 из них должны быть непрозрачными.
  • По умолчанию рендерер не выполняет обрезку области просмотра и обнаружение непрозрачности на стороне процессора. Если что-то не должно быть видно, оно не должно отображаться. Используйте Item::visible: false для элементов, которые не должны быть нарисованы. Основная причина, по которой такая логика не добавляется, заключается в том, что это добавляет дополнительные затраты, которые также повредят приложениям, позаботившимся о хорошем поведении.
  • Убедитесь, что используется атлас текстур. Элементы Image и BorderImage будут использовать его, если изображение не слишком большое. Для текстур, созданных в C++, передайте QQuickWindow::TextureCanUseAtlas при вызове QQuickWindow::createTexture(). Установив переменную среды QSG_ATLAS_OVERLAY, все текстуры атласа будут раскрашены, чтобы их было легко идентифицировать в приложении.
  • В тех случаях, где это возможно, используйте непрозрачные примитивы. Непрозрачные примитивы быстрее обрабатываются рендерером и быстрее рисуются на графическом процессоре. Например, файлы PNG часто имеют альфа-канал, даже если каждый пиксель полностью непрозрачен. Файлы JPG всегда непрозрачны. При предоставлении изображений в QQuickImageProvider или создании изображений с помощью QQuickWindow::createTextureFromImage(), сделайте формат изображения QImage::Format_RGB32, если это возможно.
  • Следите за тем, что перекрывающиеся составные элементы, как на иллюстрации выше, не могут быть кэшированы.
  • Обрезка нарушает кэширование. Никогда не используйте её на уровне элемента, внутри ячеек таблицы, делегатов элементов или аналогичных. Вместо обрезки текста используйте обрезание. Вместо обрезки изображения создайте QQuickImageProvider, возвращающий обрезанное изображение.
  • Кэширование работает только для 16-битных индексов. Все встроенные элементы используют 16-битные индексы, но пользовательская геометрия также может использовать 32-битные индексы.
  • Некоторые флаги материалов препятствуют кэшированию, наиболее ограничивающим из которых является QSGMaterial::RequiresFullMatrix, который предотвращает все кэширование.
  • Приложения с однотонным фоном должны устанавливать его с помощью QQuickWindow::setColor(), а не используя верхний прямоугольник. QQuickWindow::setColor() будет использоваться в вызове glClear(), что потенциально быстрее.
  • Элементы изображения с mipmapping не размещаются в глобальном атласе и не будут кэшироваться.
  • Ошибка в драйвере OpenGL, связанная с чтением из буфера кадров (FBO), может привести к повреждению отрисованных глифов. Если вы установите переменную среды QML_USE_GLYPHCACHE_WORKAROUND, Qt сохранит дополнительную копию глифа в оперативной памяти. Это означает, что производительность немного ниже при отрисовке глифов, которые не были нарисованы ранее, поскольку Qt обращается к дополнительной копии через процессор. Это также означает, что кэш глифов будет использовать в два раза больше памяти. Качество при этом не страдает.

Если приложение работает плохо, убедитесь, что рендеринг является узким местом. Используйте профайлер! Переменная среды QSG_RENDER_TIMING=1 выведет ряд полезных временных параметров, которые могут быть полезны для определения места проблемы.

Визуализация

Для визуализации различных аспектов рендерера графа сцены по умолчанию можно установить переменную среды QSG_VISUALIZE в одно из значений, описанных в каждом разделе ниже. Мы предоставляем примеры вывода некоторых переменных, используя следующий код QML:

import QtQuick 2.2

Rectangle {
    width: 200
    height: 140

    ListView {
        id: clippedList
        x: 20
        y: 20
        width: 70
        height: 100
        clip: true
        model: ["Item A", "Item B", "Item C", "Item D"]

        delegate: Rectangle {
            color: "lightblue"
            width: parent.width
            height: 25

            Text {
                text: modelData
                anchors.fill: parent
                horizontalAlignment: Text.AlignHCenter
                verticalAlignment: Text.AlignVCenter
            }
        }
    }

    ListView {
        id: clippedDelegateList
        x: clippedList.x + clippedList.width + 20
        y: 20
        width: 70
        height: 100
        clip: true
        model: ["Item A", "Item B", "Item C", "Item D"]

        delegate: Rectangle {
            color: "lightblue"
            width: parent.width
            height: 25
            clip: true

            Text {
                text: modelData
                anchors.fill: parent
                horizontalAlignment: Text.AlignHCenter
                verticalAlignment: Text.AlignVCenter
            }
        }
    }
}

Для ListView слева мы устанавливаем свойство clip в true. Для ListView справа мы также устанавливаем свойство clip каждого делегата в true для иллюстрации эффектов обрезки на кэширование.

"Original"

Оригинал

Примечание: Визуализируемые элементы не учитывают обрезку, и порядок отрисовки произвольный.

Визуализация пакетов

Установка QSG_VISUALIZE в значение batches визуализирует пакеты в рендерере. Объединенные пакеты отрисовываются сплошным цветом, а не объединенные пакеты — диагональным узором. Малое количество уникальных цветов означает хорошее кэширование. Необъединенные пакеты плохие, если они содержат много отдельных узлов.

"batches"

QSG_VISUALIZE=batches

Визуализация обрезки

Установка QSG_VISUALIZE в значение clip отрисовывает красные области поверх сцены, чтобы указать обрезку. Поскольку элементы Qt Quick по умолчанию не обрезаются, обычно обрезка не визуализируется.

QSG_VISUALIZE=clip

Визуализация изменений

Установка QSG_VISUALIZE в значение changes визуализирует изменения в рендерере. Изменения в графе сцены визуализируются вспыхивающим наложением случайного цвета. Изменения в примитиве визуализируются сплошным цветом, а изменения в предке, такие как изменения матрицы или непрозрачности, визуализируются узором.

Визуализация избыточного отображения

Установка QSG_VISUALIZE в значение overdraw визуализирует избыточное отображение в рендерере. Визуализируйте все элементы в 3D, чтобы выделить избыточное отображение. Этот режим также может быть использован для обнаружения геометрии за пределами области просмотра до некоторой степени. Непрозрачные элементы отображаются с зелёным оттенком, а полупрозрачные — с красным. Границы области просмотра отрисовываются синим цветом. Непрозрачное содержимое легче обрабатывается графом сцены и обычно быстрее отрисовывается.

Обратите внимание, что корневой прямоугольник в коде выше излишен, так как окно также белое, поэтому отрисовка прямоугольника — пустая трата ресурсов в данном случае. Изменение его на элемент может немного улучшить производительность.

"overdraw-1"

"overdraw-2"

QSG_VISUALIZE=overdraw

Рендеринг с помощью интерфейса аппаратного рендеринга Qt

Начиная с Qt 5.14, по умолчанию используется возможность рендеринга через абстракцию графического слоя, интерфейс аппаратного рендеринга Qt (RHI), предоставляемый модулем QtGui. При включении прямые вызовы OpenGL не выполняются. Вместо этого, граф сцены выполняет рендеринг, используя API, предоставляемые абстракцией, которые затем переводятся в вызовы OpenGL, Vulkan, Metal или Direct 3D. Обработка шейдеров также унифицирована путем написания кода шейдеров один раз, компиляции в SPIR-V, а затем перевода в язык, соответствующий различным графическим API.

Для включения этого вместо прямого использования OpenGL можно использовать следующие переменные среды:

Переменная среды Возможные значения Описание
QSG_RHI 1 Включает рендеринг через RHI. Целевой графический API выбирается на основе платформы, если не переопределен переменной QSG_RHI_BACKEND. По умолчанию используются Direct3D 11 для Windows, Metal для macOS и OpenGL для других платформ.
QSG_RHI_BACKEND vulkan, metal, opengl, d3d11 Запрашивает конкретный бэкэнд RHI.
QSG_INFO 1 Как и при использовании пути рендеринга на основе OpenGL, установка этой переменной включает отображение системной информации при инициализации графа сцены Qt Quick. Это может быть очень полезно для устранения неполадок.
QSG_RHI_DEBUG_LAYER 1 Где это применимо (Vulkan, Direct3D), включает отладочные и/или валидационные слои реализации графического API, если они доступны.
QSG_RHI_PREFER_SOFTWARE_RENDERER 1 Запрашивает выбор адаптера или физического устройства, использующего растрирование на основе программного обеспечения. Применимо только в том случае, если основной API поддерживает перечисление адаптеров (например, Direct3D или Vulkan), и в противном случае игнорируется.

Приложения, желающие всегда работать с одним заданным графическим API, могут запросить это через C++ также. Например, следующий вызов, сделанный на ранней стадии main(), до построения любого QQuickWindow, принудительно использует Vulkan (и в противном случае завершится ошибкой);

QQuickWindow::setSceneGraphBackend(QSGRendererInterface::VulkanRhi);

См. QSGRendererInterface::GraphicsApi. Значения перечисления, заканчивающиеся на Rhi, эквивалентны по эффекту запуску с заданными одновременно QSG_RHI и QSG_RHI_BACKEND.

Все бэкэнды QRhi выберут системный адаптер GPU или физическое устройство по умолчанию, если не переопределены переменными QSG_RHI_PREFER_SOFTWARE_RENDERER или специфичными для бэкэнда переменными, такими как QT_D3D_ADAPTER_INDEX или QT_VK_PHYSICAL_DEVICE_INDEX. В настоящее время дополнительная настройка адаптеров не предоставляется.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.15/qtquick-visualcanvas-scenegraph-renderer.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API