Spec-Zone.ru › Qt 5.6

Класс QOpenGLDebugLogger

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

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

Публичные типы

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

Свойства

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

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

QOpenGLDebugLogger(QObject *parent = Q_NULLPTR)
~QOpenGLDebugLogger()
void disableMessages(QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource, QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType, QOpenGLDebugMessage::Severities severities = QOpenGLDebugMessage::AnySeverity)
void disableMessages(const QVector<GLuint> &ids, QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource, QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType)
void enableMessages(QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource, QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType, QOpenGLDebugMessage::Severities severities = QOpenGLDebugMessage::AnySeverity)
void enableMessages(const QVector<GLuint> &ids, QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource, QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType)
bool initialize()
bool isLogging() const
QList<QOpenGLDebugMessage> loggedMessages() const
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(LoggingMode loggingMode = AsynchronousLogging)
void stopLogging()
  • 1 публичный слот унаследован от QObject

Сигналы

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

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

  • 11 статических публичных членов унаследованы от 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);

Также есть много другой информации, которая нас интересует (как разработчиков приложений), например, проблемы с производительностью или предупреждения об использовании устаревших 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 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():

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

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

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

Журналирование сообщений в реальном времени

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

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

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

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

END_OF_DOCUMENT_MARKER

С другой стороны, вход в синхронном режиме имеет большой overhead, но реализация 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(). По умолчанию все сообщения регистрируются.

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

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

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

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

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

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

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

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

См. также QOpenGLDebugMessage.

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

enum 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().

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

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

LoggingMode loggingMode() const

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

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

QOpenGLDebugLogger::QOpenGLDebugLogger(QObject *parent = Q_NULLPTR)

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

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

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

QOpenGLDebugLogger::~QOpenGLDebugLogger()

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

void QOpenGLDebugLogger::disableMessages(QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource, QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType, QOpenGLDebugMessage::Severities severities = QOpenGLDebugMessage::AnySeverity)

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

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

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

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

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

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

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

void QOpenGLDebugLogger::enableMessages(QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource, QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType, QOpenGLDebugMessage::Severities severities = QOpenGLDebugMessage::AnySeverity)

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

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

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

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

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

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

См. также 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().

LoggingMode QOpenGLDebugLogger::loggingMode() const

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

Примечание: Метод-геттер для свойства loggingMode.

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

qint64 QOpenGLDebugLogger::maximumMessageLength() const

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

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

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

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

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

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

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

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

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

void QOpenGLDebugLogger::popGroup()

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

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

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

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

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

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

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

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

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

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

[slot] void QOpenGLDebugLogger::startLogging(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/archives/qt-5.6/qopengldebuglogger.html

Spec-Zone.ru

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