Spec-Zone.ru › Qt 5.12

Класс QOpenGLDebugLogger

Класс QOpenGLDebugLogger позволяет регистрировать сообщения об отладке OpenGL. Подробнее...

Заголовок: #include <QOpenGLDebugLogger>
qmake: QT += gui
С момента: Qt 5.1
Наследует: QObject
  • Список всех членов, включая наследуемые
  • Устаревшие члены

Типы публичного доступа

перечисление LoggingMode { AsynchronousLogging, SynchronousLogging }

Свойства

  • loggingMode : const LoggingMode
  • 1 свойство унаследовано от QObject

Публичные функции

QOpenGLDebugLogger(QObject *parent = nullptr)
virtual ~QOpenGLDebugLogger()
void disableMessages(QOpenGLDebugMessage::Sources sources, QOpenGLDebugMessage::Types types, QOpenGLDebugMessage::Severities severities)
void disableMessages(const QVector<GLuint> &ids, QOpenGLDebugMessage::Sources sources, QOpenGLDebugMessage::Types types)
void enableMessages(QOpenGLDebugMessage::Sources sources, QOpenGLDebugMessage::Types types, QOpenGLDebugMessage::Severities severities)
void enableMessages(const QVector<GLuint> &ids, QOpenGLDebugMessage::Sources sources, QOpenGLDebugMessage::Types types)
bool initialize()
bool isLogging() const
QList<QOpenGLDebugMessage> loggedMessages() const
QOpenGLDebugLogger::LoggingMode loggingMode() const
qint64 maximumMessageLength() const
void popGroup()
void pushGroup(const QString &name, GLuint id = 0, QOpenGLDebugMessage::Source source = QOpenGLDebugMessage::ApplicationSource)
  • 31 публичная функция унаследована от QObject

Свойства публичного доступа

void logMessage(const QOpenGLDebugMessage &debugMessage)
void startLogging(QOpenGLDebugLogger::LoggingMode loggingMode = AsynchronousLogging)
void stopLogging()
  • 1 свойство публичного доступа унаследовано от QObject

Сигналы

void messageLogged(const QOpenGLDebugMessage &debugMessage)
  • 2 сигнала унаследовано от QObject

Статические публичные члены

const QMetaObject staticMetaObject
  • 9 статических публичных членов унаследовано от QObject

Дополнительные унаследованные члены

  • 9 защищенных функций унаследовано от QObject

Подробное описание

Класс QOpenGLDebugLogger позволяет регистрировать сообщения об отладке OpenGL.

Вступление

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

Единственный способ убедиться, что из реализации OpenGL не возвращаются ошибки, заключается в проверке с glGetError после каждого и каждого API-вызова. Кроме того, ошибки OpenGL накапливаются, поэтому glGetError всегда следует использовать в цикле таким образом:

    GLenum error = GL_NO_ERROR;
    do {
        error = glGetError();
        if (error != GL_NO_ERROR)
            // handle the error
    } while (error != GL_NO_ERROR);

Если вы пытаетесь очистить стек ошибок, убедитесь, что вы не просто продолжаете, пока не вернётся GL_NO_ERROR, а также прерываете цикл на GL_CONTEXT_LOST, так как это значение ошибки будет повторяться.

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

QOpenGLDebugLogger призван решить эти проблемы, предоставив доступ к журналу отладки OpenGL. Если ваша реализация OpenGL его поддерживает (путем экспонирования GL_KHR_debug расширения), сообщения от сервера OpenGL будут либо записаны во внутренний журнал OpenGL, либо переданы в «реальном времени» слушателям по мере их генерации OpenGL.

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

Создание контекста отладки OpenGL

По причинам эффективности реализации OpenGL разрешается не создавать никакого отладочного вывода вообще, если контекст OpenGL не является контекстом отладки. Для создания контекста отладки из Qt необходимо установить параметр формата QSurfaceFormat::DebugContext в формате QSurfaceFormat, используемом для создания объекта QOpenGLContext:

    QSurfaceFormat format;
    // asks for a OpenGL 3.2 debug context using the Core profile
    format.setMajorVersion(3);
    format.setMinorVersion(2);
    format.setProfile(QSurfaceFormat::CoreProfile);
    format.setOption(QSurfaceFormat::DebugContext);

    QOpenGLContext *context = new QOpenGLContext;
    context->setFormat(format);
    context->create();

Обратите внимание, что запрос OpenGL Core Profile 3.2 предназначен только для целей примера; этот класс не привязан к какой-либо конкретной версии OpenGL или OpenGL ES, так как он полагается на наличие GL_KHR_debug расширения (см. ниже).

Создание и инициализация QOpenGLDebugLogger

QOpenGLDebugLogger — это простой класс, производный от QObject. Как и все подклассы QObject, вы создаёте экземпляр (и необязательно указываете родительский объект), и, как и другие функции OpenGL в Qt, вы обязаны его инициализировать перед использованием, вызвав initialize() в то время, когда есть текущий контекст OpenGL:

    QOpenGLContext *ctx = QOpenGLContext::currentContext();
    QOpenGLDebugLogger *logger = new QOpenGLDebugLogger(this);

    logger->initialize(); // initializes in the current context, i.e. ctx

Обратите внимание, что GL_KHR_debug расширение обязательно должно быть доступно в контексте для доступа к сообщениям, записанным в OpenGL. Вы можете проверить наличие этого расширения, вызвав:

    ctx->hasExtension(QByteArrayLiteral("GL_KHR_debug"))

где ctx — допустимый QOpenGLContext. Если расширение недоступно, initialize() вернёт false.

Чтение внутреннего журнала отладки OpenGL

Реализации OpenGL сохраняют внутренний журнал сообщений об отладке. Сообщения, хранящиеся в этом журнале, можно получить, используя функцию loggedMessages():

    const QList<QOpenGLDebugMessage> messages = logger->loggedMessages();
    for (const QOpenGLDebugMessage &message : messages)
        qDebug() << message;

Внутренний журнал имеет ограниченный размер; когда он заполняется, более старые сообщения будут удалены, чтобы освободить место для новых входящих сообщений. Когда вы вызываете loggedMessages(), внутренний журнал также будет очищен.

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

Реальное время регистрации сообщений

Также можно получать поток сообщений об отладке с сервера OpenGL по мере их генерации реализацией. Для этого вам нужно подключить соответствующий слот к сигналу messageLogged() и начать регистрацию, вызвав startLogging():

    connect(logger, &QOpenGLDebugLogger::messageLogged, receiver, &LogHandler::handleLoggedMessage);
    logger->startLogging();

Аналогично, регистрацию можно отключить в любое время, вызвав функцию stopLogging().

END_OF_DOCUMENT_MARKER ```

Логирование в реальном времени может быть асинхронным или синхронным, в зависимости от параметра, переданного в startLogging(). При логировании в асинхронном режиме (по умолчанию, так как он имеет очень низкую нагрузку), реализация OpenGL может генерировать сообщения в любое время и/или в порядке, отличном от порядка команд OpenGL, которые вызвали эти сообщения. Сообщения также могут быть сгенерированы из потока, отличного от потока, к которому в данный момент привязан контекст. Это связано с тем, что реализации OpenGL обычно являются высокопоточными и асинхронными, и поэтому никаких гарантий относительно относительного порядка и времени появления сообщений отладки не дается.

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

Это означает, что при логировании в синхронном режиме вы сможете запустить свою OpenGL-приложение в отладчике, установить точку останова на слоте, подключенном к сигналу messageLogged(), и увидеть в стеке вызовов точное обращение, вызвавшее зарегистрированное сообщение. Это может быть чрезвычайно полезно для отладки проблемы OpenGL. Обратите внимание, что если рендеринг OpenGL происходит в другом потоке, вам необходимо принудительно установить тип подключения сигнал/слот на Qt::DirectConnection, чтобы иметь возможность увидеть фактический стек вызовов.

Дополнительную информацию о режимах логирования см. в документации перечисления LoggingMode.

Примечание: При включенном логировании в реальном времени сообщения отладки не будут вставлены в внутренний журнал отладки OpenGL. Сообщения, уже присутствующие во внутреннем журнале, не будут удалены, ни они не будут выпущены через сигнал messageLogged(). Поскольку некоторые сообщения могут быть сгенерированы до запуска логирования в реальном времени (и, следовательно, будут сохранены во внутреннем журнале OpenGL), важно всегда проверять, содержит ли он какие-либо сообщения после вызова startLogging().

Вставка сообщений в журнал отладки

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

Для этого можно создать объект QOpenGLDebugMessage, вызвав createApplicationMessage() или createThirdPartyMessage(), а затем вставить его в журнал, вызвав logMessage():

    QOpenGLDebugMessage message =
        QOpenGLDebugMessage::createApplicationMessage(QStringLiteral("Custom message"));

    logger->logMessage(message);

Обратите внимание, что реализации OpenGL имеют зависящую от поставщика ограничение на длину сообщений, которые могут быть вставлены в журнал отладки. Вы можете получить эту длину, вызвав метод maximumMessageLength(); сообщения, длиннее ограничения, будут автоматически усечены.

Управление выводом отладки

QOpenGLDebugMessage также может применять фильтры к сообщениям отладки и, следовательно, ограничивать количество регистрируемых сообщений. Вы можете включить или отключить логирование сообщений, вызвав enableMessages() и disableMessages() соответственно. По умолчанию все сообщения регистрируются.

Можно включить или отключить сообщения, выбрав их по:

  • источнику, типу и степени важности (и включая все идентификаторы в выборке);
  • идентификатору, источнику и типу (и включая все степени важности в выборке).

Обратите внимание, что состояние «включено» для данного сообщения является свойством кортежа (id, источник, тип, степень важности); атрибуты сообщения не образуют иерархии любого рода. Вы должны быть внимательны к порядку вызовов enableMessages() и disableMessages(), так как это изменит, какие сообщения будут включены/отключены.

Фильтр по самому тексту сообщения невозможен; приложения должны делать это самостоятельно (в слотах, подключенных к сигналу messageLogged() или после извлечения сообщений во внутреннем журнале отладки через loggedMessages()).

Для упрощения управления состояниями включения/выключения QOpenGLDebugMessage также поддерживает понятие debug groups. Группа отладки содержит группу настроек включения/выключения сообщений отладки. Кроме того, группы отладки организованы в стеке: можно поместить и извлечь группы, вызвав pushGroup() и popGroup() соответственно. (При создании контекста OpenGL в стеке уже есть группа).

Функции enableMessages() и disableMessages() будут изменять конфигурацию в текущей группе отладки, то есть в группе, находящейся вверху стека групп отладки.

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

Добавление (соответственно, извлечение) групп отладки также автоматически сгенерирует сообщение отладки типа QOpenGLDebugMessage::GroupPushType (соответственно, GroupPopType).

См. также QOpenGLDebugMessage.

Документация типов членов

перечисление QOpenGLDebugLogger::LoggingMode

Перечисление LoggingMode определяет режим логирования объекта логгера.

Константа Значение Описание
QOpenGLDebugLogger::AsynchronousLogging 0 Сообщения от сервера OpenGL регистрируются асинхронно. Это означает, что сообщения могут быть зарегистрированы некоторое время после соответствующих действий OpenGL, которые их вызвали, и даже быть получены в неправильном порядке, в зависимости от реализации OpenGL. Этот режим имеет очень низкую нагрузку на производительность, так как реализации OpenGL по своей природе сильно многопоточны и асинхронны.
QOpenGLDebugLogger::SynchronousLogging 1 Сообщения от сервера OpenGL регистрируются синхронно и последовательно. Это сильно снижает производительность, так как реализации OpenGL по своей природе очень асинхронны; но это очень полезно для отладки проблем OpenGL, так как OpenGL гарантирует, что сообщения, сгенерированные командой OpenGL, будут зарегистрированы до возвращения выполнения соответствующей команды. Поэтому вы можете установить точку останова на сигнале messageLogged() и увидеть в стеке вызовов, какая команда OpenGL его вызвала; единственное замечание состоит в том, что если вы используете OpenGL из нескольких потоков, вам может потребоваться принудительно установить прямое подключение при подключении к сигналу messageLogged().

Документация свойств

loggingMode : const LoggingMode

Это свойство хранит режим логирования, переданный в startLogging().

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

Функции доступа:

QOpenGLDebugLogger::LoggingMode loggingMode() const

См. также startLogging() и isLogging().

Документация функций-членов

QOpenGLDebugLogger::QOpenGLDebugLogger(QObject *parent = nullptr)

Конструирует новый объект логгера с заданным parent.

Примечание: Объект необходимо инициализировать перед началом логирования.

См. также initialize().

[virtual] QOpenGLDebugLogger::~QOpenGLDebugLogger()

Удаляет объект логгера.

void QOpenGLDebugLogger::disableMessages(QOpenGLDebugMessage::Sources sources, QOpenGLDebugMessage::Types types, QOpenGLDebugMessage::Severities severities)

Отключает логирование сообщений с заданными sources, types и severities и любым идентификатором сообщения.

Логирование будет отключено в текущей группе управления.

См. также enableMessages(), pushGroup() и popGroup().

void QOpenGLDebugLogger::disableMessages(const QVector<GLuint> &ids, QOpenGLDebugMessage::Sources sources, QOpenGLDebugMessage::Types types)

Отключает логирование сообщений с заданными ids, sources и types и любой степенью важности.

Логирование будет отключено в текущей группе управления.

См. также enableMessages(), pushGroup() и popGroup().

void QOpenGLDebugLogger::enableMessages(QOpenGLDebugMessage::Sources sources, QOpenGLDebugMessage::Types types, QOpenGLDebugMessage::Severities severities)

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

Протоколирование будет включено в текущей группе управления.

См. также disableMessages(), pushGroup() и popGroup().

void QOpenGLDebugLogger::enableMessages(const QVector<GLuint> &ids, QOpenGLDebugMessage::Sources sources, QOpenGLDebugMessage::Types types)

Включает протоколирование сообщений с заданными ids, из заданных источников и заданных типов и любой степенью серьезности.

Протоколирование будет включено в текущей группе управления.

См. также disableMessages(), pushGroup() и popGroup().

bool QOpenGLDebugLogger::initialize()

Инициализирует объект в текущем контексте OpenGL. Контекст должен поддерживать расширение GL_KHR_debug для успешной инициализации. Объект должен быть инициализирован перед любым протоколированием.

Безопасно вызывать эту функцию несколько раз из одного и того же контекста.

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

Возвращает true если логгер успешно инициализирован; в противном случае возвращает false.

См. также QOpenGLContext.

bool QOpenGLDebugLogger::isLogging() const

Возвращает true если этот объект в данный момент выполняет протоколирование; в противном случае возвращает false.

См. также startLogging().

[slot] void QOpenGLDebugLogger::logMessage(const QOpenGLDebugMessage &debugMessage)

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

Примечание: debugMessage должна иметь QOpenGLDebugMessage::ApplicationSource или QOpenGLDebugMessage::ThirdPartySource в качестве источника и допустимый тип и степень серьезности, иначе она не будет вставлена в журнал.

Примечание: Объект должен быть инициализирован перед протоколированием.

См. также initialize().

QList<QOpenGLDebugMessage> QOpenGLDebugLogger::loggedMessages() const

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

См. также startLogging().

QOpenGLDebugLogger::LoggingMode QOpenGLDebugLogger::loggingMode() const

Возвращает режим протоколирования объекта.

Примечание: Функция-получатель для свойства loggingMode.

См. также startLogging().

qint64 QOpenGLDebugLogger::maximumMessageLength() const

Возвращает максимальную поддерживаемую длину, в байтах, для текста сообщений, передаваемых в logMessage(). Это также максимальная длина имени группы отладки, так как добавление или удаление групп автоматически записывает сообщение с именем группы отладки в качестве текста сообщения.

Если текст сообщения слишком длинный, он автоматически усекается QOpenGLDebugLogger.

Примечание: Тексты сообщений кодируются в UTF-8 при передаче в OpenGL, поэтому их размер в байтах обычно не совпадает с количеством единиц UTF-16, возвращаемых, например, QString::length(). (Это так, если сообщение содержит только данные ASCII 7 бит, что типично для сообщений отладки.)

[signal] void QOpenGLDebugLogger::messageLogged(const QOpenGLDebugMessage &debugMessage)

Этот сигнал испускается, когда сообщение отладки (завернутое в аргумент debugMessage) записывается из сервера OpenGL.

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

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

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

См. также startLogging().

void QOpenGLDebugLogger::popGroup()

Удаляет верхнюю группу отладки из стека групп отладки. Если группа успешно удалена, OpenGL автоматически запишет сообщение с id и источником, соответствующими удаленной группе, типом QOpenGLDebugMessage::GroupPopType и степенью серьезности QOpenGLDebugMessage::NotificationSeverity.

Удаление группы отладки восстановит настройки фильтрации сообщений группы, которая становится верхней в стеке групп отладки.

Примечание: Объект должен быть инициализирован перед управлением группами отладки.

См. также pushGroup().

void QOpenGLDebugLogger::pushGroup(const QString &name, GLuint id = 0, QOpenGLDebugMessage::Source source = QOpenGLDebugMessage::ApplicationSource)

Добавляет группу отладки с именем name, id id и источником source в стек групп отладки. Если группа успешно добавлена, OpenGL автоматически запишет сообщение с именем name, id id, источником source, типом QOpenGLDebugMessage::GroupPushType и степенью серьезности QOpenGLDebugMessage::NotificationSeverity.

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

Примечание: source должен быть либо QOpenGLDebugMessage::ApplicationSource, либо QOpenGLDebugMessage::ThirdPartySource, иначе группа не будет добавлена.

Примечание: Объект должен быть инициализирован перед управлением группами отладки.

См. также popGroup(), enableMessages() и disableMessages().

[slot] void QOpenGLDebugLogger::startLogging(QOpenGLDebugLogger::LoggingMode loggingMode = AsynchronousLogging)

Начинает протоколирование сообщений, поступающих от сервера OpenGL. Когда поступает новое сообщение, испускается сигнал messageLogged(), содержащий записанное сообщение в качестве аргумента.

loggingMode определяет, должно ли протоколирование быть асинхронным (по умолчанию) или синхронным.

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

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

Примечание: Объект должен быть инициализирован перед протоколированием.

См. также stopLogging() и initialize().

[slot] void QOpenGLDebugLogger::stopLogging()

Останавливает протоколирование сообщений от сервера OpenGL.

См. также startLogging().

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.12/qopengldebuglogger.html

Spec-Zone.ru

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