Spec-Zone.ru › Qt

Qt Quick Scene Graph По умолчанию Рендерер сцены

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

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

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

Элементы 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. На видеокартах, которые внутренне выполняют раннюю проверку глубины, это означает, что фрагментный шейдер не нужен для пикселей или блоков пикселей, которые закрыты. Имейте в виду, что рендерер по-прежнему должен учитывать эти узлы, и вершинный шейдер по-прежнему выполняется для каждой вершины в этих примитивах, поэтому, если приложение знает, что что-то полностью закрыто, лучше всего явно скрыть его с помощью Item::visible или Item::opacity.

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

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

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

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

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

С точки зрения 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]. Переопределение этих флагов будет в основном полезно для поставщиков платформ.

END_OF_DOCUMENT_MARKER ```

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

Обрезка

При установке Item::clip в значение true, создается QSGClipNode с прямоугольником в его геометрии. По умолчанию рендерер применяет эту обрезку, используя функцию scissoring в 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() вместо использования элемента Rectangle верхнего уровня. 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

Rendering via the Qt Rendering Hardware Interface

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

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

Переменная среды Возможные значения Описание
QSG_RHI_BACKEND vulkan, metal, opengl, d3d11 Запрашивает конкретный бэкэнд RHI. По умолчанию целевой графический API выбирается на основе платформы, если это не переопределено этой переменной или эквивалентными API C++. По умолчанию в настоящее время это Direct3D 11 для Windows, Metal для macOS, OpenGL в других случаях.
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::setGraphicsApi(QSGRendererInterface::Vulkan);

См. QSGRendererInterface::GraphicsApi. Значения перечисления OpenGL, Vulkan, Metal, Direct3D11 эквивалентны запуску с 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-6.2/qtquick-visualcanvas-scenegraph-renderer.html

Spec-Zone.ru

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