Spec-Zone.ru › Qt 5.14

Класс QOpenGLDebugLogger

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

Заголовок: #include <QOpenGLDebugLogger>
qmake: QT += gui
С тех пор: Qt 5.1
Наследует: QObject

Этот класс был представлен в Qt 5.1.

  • Список всех членов, включая унаследованные

Типы

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

Свойства

  • loggingMode : const LoggingMode

Открытые функции

QOpenGLDebugLogger(QObject *parent = nullptr)
virtual ~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
QOpenGLDebugLogger::LoggingMode loggingMode() const
qint64 maximumMessageLength() const
void popGroup()
void pushGroup(const QString &name, GLuint id = 0, QOpenGLDebugMessage::Source source = QOpenGLDebugMessage::ApplicationSource)

Открытые слоты

void logMessage(const QOpenGLDebugMessage &debugMessage)
void startLogging(QOpenGLDebugLogger::LoggingMode loggingMode = AsynchronousLogging)
void stopLogging()

Сигналы

void messageLogged(const QOpenGLDebugMessage &debugMessage)

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

Введение

Программирование 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 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().

Протоколирование в реальном времени может быть асинхронным или синхронным, в зависимости от параметра, передаваемого в 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.

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

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

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

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

QOpenGLDebugLogger::LoggingMode loggingMode() const

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

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

QOpenGLDebugLogger::QOpenGLDebugLogger(QObject *parent = nullptr)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[virtual] 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)

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

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

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

bool QOpenGLDebugLogger::initialize()

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

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

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

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

См. также QOpenGLContext.

bool QOpenGLDebugLogger::isLogging() const

Возвращает true если этот объект в настоящее время регистрирует, в противном случае — false.

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

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(). (Это так, если сообщение содержит только данные 7-битного ASCII, что типично для отладочных сообщений.)

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

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

Spec-Zone.ru

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