QOpenGLDebugLogger Class
Le QOpenGLDebugLogger permet l'enregistrement des messages de débogage OpenGL. Plus d'informations...
| En-tête : | #include <QOpenGLDebugLogger> |
| CMake : | find_package(Qt6 REQUIRED COMPONENTS OpenGL)target_link_libraries(mytarget PRIVATE Qt6::OpenGL) |
| qmake : | QT += opengl |
| Héritages : | QObject |
- Liste de tous les membres, y compris les membres hérités
- QOpenGLDebugLogger fait partie de Rendering in 3D.
Types publics
| enum | LoggingMode { AsynchronousLogging, SynchronousLogging } |
Propriétés
- loggingMode : LoggingMode
Fonctions publiques
| 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 QList<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 QList<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) |
Emplacements publics
| void | logMessage(const QOpenGLDebugMessage &debugMessage) |
| void | startLogging(QOpenGLDebugLogger::LoggingMode loggingMode = AsynchronousLogging) |
| void | stopLogging() |
Signaux
| void | messageLogged(const QOpenGLDebugMessage &debugMessage) |
Description détaillée
Introduction
La programmation OpenGL peut être très sujette aux erreurs. La plupart du temps, un seul appel défaillant à OpenGL peut entraîner l'arrêt de toute une partie de l'application, sans que rien ne soit dessiné à l'écran.
Le seul moyen d'être sûr qu'aucune erreur n'est renvoyée par l'implémentation OpenGL est de vérifier avec glGetError après chaque appel à l'API. De plus, les erreurs OpenGL s'empilent, c'est pourquoi glGetError devrait toujours être utilisé dans une boucle comme celle-ci :
GLenum error = GL_NO_ERROR; do { error = glGetError(); if (error != GL_NO_ERROR) { // handle the error } } while (error != GL_NO_ERROR);
Si vous essayez d'effacer la pile d'erreurs, assurez-vous de ne pas continuer jusqu'à ce que GL_NO_ERROR soit retourné, mais aussi de vous arrêter sur GL_CONTEXT_LOST car cette valeur d'erreur continuera à se répéter.
Il existe également de nombreuses autres informations qui nous intéressent (en tant que développeurs d'applications), par exemple les problèmes de performance ou les avertissements concernant l'utilisation d'API obsolètes. Ces types de messages ne sont pas rapportés par les mécanismes ordinaires de rapport d'erreur d'OpenGL.
QOpenGLDebugLogger vise à résoudre ces problèmes en fournissant un accès au journal de débogage d'OpenGL. Si votre implémentation OpenGL le supporte (en exposant l'extension GL_KHR_debug ), les messages du serveur OpenGL seront soit enregistrés dans un journal interne OpenGL, soit transmis en "temps réel" aux auditeurs lorsqu'ils sont générés par OpenGL.
QOpenGLDebugLogger supporte ces deux modes de fonctionnement. Référez-vous aux sections suivantes pour connaître les différences entre les deux.
Créer un contexte de débogage OpenGL
Pour des raisons d'efficacité, les implémentations OpenGL sont autorisées à ne pas créer de sortie de débogage, à moins que le contexte OpenGL ne soit un contexte de débogage. Afin de créer un contexte de débogage à partir de Qt XML, vous devez définir l'option de format QSurfaceFormat::DebugContext sur l'objet QSurfaceFormat utilisé pour créer l'objet 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();
Cette classe n'est pas liée à une version spécifique d'OpenGL ou d'OpenGL ES, car elle repose sur la disponibilité de l'extension GL_KHR_debug (voir ci-dessous).
Création et initialisation d'un QOpenGLDebugLogger
QOpenGLDebugLogger est une simple classe dérivée de QObject. Comme toutes les sous-classes de QObject, vous créez une instance (et optionnellement vous spécifiez un objet parent), et comme les autres fonctions OpenGL dans QtGL vous devez l'initialiser avant de l'utiliser en appelant initialize() tant qu'il y a un contexte OpenGL en cours :
QOpenGLContext *ctx = QOpenGLContext::currentContext(); QOpenGLDebugLogger *logger = new QOpenGLDebugLogger(this); logger->initialize(); // initializes in the current context, i.e. ctx
Notez que l'extension GL_KHR_debug doit être disponible dans le contexte afin d'accéder aux messages enregistrés par OpenGL. Vous pouvez vérifier la présence de cette extension en appelant :
ctx->hasExtension(QByteArrayLiteral("GL_KHR_debug"));
où ctx est un QOpenGLContext valide. Si l'extension n'est pas disponible, initialize() renverra false.
Lire le journal de débogage interne d'OpenGL
Les implémentations OpenGL conservent un journal interne des messages de débogage. Les messages stockés dans ce journal peuvent être récupérés en utilisant la fonction loggedMessages() :
const QList<QOpenGLDebugMessage> messages = logger->loggedMessages() ;for(const QOpenGLDebugMessage &message: messages) qDebug() << message;
Le journal interne a une taille limitée ; lorsqu'il se remplit, les anciens messages sont supprimés pour faire de la place aux nouveaux messages entrants. Lorsque vous appelez loggedMessages(), le journal interne est également vidé.
Si vous voulez être sûr de ne perdre aucun message de débogage, vous devez utiliser la journalisation en temps réel au lieu d'appeler cette fonction. Toutefois, des messages de débogage peuvent encore être générés entre la création du contexte et l'activation de la journalisation en temps réel (ou, en général, lorsque la journalisation en temps réel est désactivée).
Enregistrement en temps réel des messages
Il est également possible de recevoir un flux de messages de débogage du serveur OpenGL au fur et à mesure qu'ils sont générés par l'implémentation. Pour ce faire, vous devez connecter un slot approprié au signal messageLogged(), et démarrer l'enregistrement en appelant startLogging() :
connect(logger, &QOpenGLDebugLogger::messageLogged, receiver, &LogHandler::handleLoggedMessage); logger->startLogging();
De même, la journalisation peut être désactivée à tout moment en appelant la fonction stopLogging().
L'enregistrement en temps réel peut être asynchrone ou synchrone, en fonction du paramètre transmis à startLogging(). Lorsque l'enregistrement se fait en mode asynchrone (le mode par défaut, car il a un très faible surcoût), l'implémentation OpenGL peut générer des messages à tout moment, et/ou dans un ordre différent de l'ordre des commandes OpenGL qui ont causé l'enregistrement de ces messages. Les messages peuvent également être générés à partir d'un thread différent de celui auquel le contexte est actuellement lié. Ceci est dû au fait que les implémentations d'OpenGL sont généralement hautement threadées et asynchrones, et donc aucune garantie n'est donnée quant à l'ordre relatif et à la chronologie des messages de débogage.
D'un autre côté, l'enregistrement en mode synchrone a un coût élevé, mais l'implémentation OpenGL garantit que tous les messages provoqués par une certaine commande sont reçus dans l'ordre, avant que la commande ne revienne, et depuis le même thread auquel le contexte OpenGL est lié.
Cela signifie que lorsque vous enregistrez en mode synchrone, vous pourrez exécuter votre application OpenGL dans un débogueur, placer un point d'arrêt sur un slot connecté au signal messageLogged(), et voir dans le backtrace l'appel exact qui a causé le message enregistré. Cela peut être extrêmement utile pour déboguer un problème OpenGL. Notez que si le rendu OpenGL se produit dans un autre thread, vous devez forcer le type de connexion signal/emplacement à Qt::DirectConnection afin de pouvoir voir la trace arrière réelle.
Reportez-vous à la documentation de l'enum LoggingMode pour plus d'informations sur les modes de journalisation.
Note : Lorsque la journalisation en temps réel est activée, les messages de débogage ne seront plus insérés dans le journal de débogage interne d'OpenGL ; les messages déjà présents dans le journal interne ne seront pas supprimés, et ils ne seront pas non plus émis par le signal messageLogged(). Puisque certains messages peuvent être générés avant que la journalisation en temps réel ne soit lancée (et donc être conservés dans le journal interne d'OpenGL), il est important de toujours vérifier s'il contient un message après avoir appelé startLogging().
Insérer des messages dans le journal de débogage
Il est possible pour les applications et les bibliothèques d'insérer des messages personnalisés dans le journal de débogage, par exemple pour marquer un groupe de commandes OpenGL liées et ainsi être capable d'identifier d'éventuels messages provenant de ces commandes.
Pour ce faire, vous pouvez créer un objet QOpenGLDebugMessage en appelant createApplicationMessage() ou createThirdPartyMessage(), puis l'insérer dans le journal en appelant logMessage() :
QOpenGLDebugMessage message = QOpenGLDebugMessage::createApplicationMessage(QStringLiteral("Custom message")); logger->logMessage(message);
Notez que les implémentations OpenGL ont une limite spécifique au fournisseur pour la longueur des messages qui peuvent être insérés dans le journal de débogage. Vous pouvez récupérer cette longueur en appelant la méthode maximumMessageLength() ; les messages plus longs que la limite seront automatiquement tronqués.
Contrôle de la sortie de débogage
QOpenGLDebugMessage Le logiciel de débogage permet également d'appliquer des filtres aux messages de débogage, et donc de limiter la quantité de messages enregistrés. Vous pouvez activer ou désactiver l'enregistrement des messages en appelant respectivement enableMessages() et disableMessages(). Par défaut, tous les messages sont enregistrés.
Il est possible d'activer ou de désactiver les messages en les sélectionnant par :
- la source, le type et la gravité (en incluant tous les identifiants dans la sélection) ;
- id, source et type (et en incluant toutes les sévérités dans la sélection).
Notez que l'état "activé" d'un message donné est une propriété du tuple (id, source, type, gravité) ; les attributs du message ne forment aucune hiérarchie. Vous devez faire attention à l'ordre des appels à enableMessages() et disableMessages(), car il modifiera les messages qui seront activés/désactivés.
Il n'est pas possible de filtrer par le texte du message lui-même ; les applications doivent le faire elles-mêmes (dans les emplacements connectés au signal messageLogged(), ou après avoir récupéré les messages dans le journal de débogage interne par l'intermédiaire de loggedMessages()).
Afin de simplifier la gestion des statuts activé / désactivé, QOpenGLDebugMessage prend également en charge le concept de debug groups. Un groupe de débogage contient le groupe des configurations activées / désactivées des messages de débogage. De plus, les groupes de débogage sont organisés en pile : il est possible de pousser et de sortir des groupes en appelant respectivement pushGroup() et popGroup(). (Lorsqu'un contexte OpenGL est créé, il y a déjà un groupe dans la pile).
Les fonctions enableMessages() et disableMessages() modifient la configuration du groupe de débogage actuel, c'est-à-dire celui qui se trouve au sommet de la pile des groupes de débogage.
Lorsqu'un nouveau groupe est poussé sur la pile des groupes de débogage, il hérite de la configuration du groupe qui se trouvait précédemment au sommet de la pile. Vice versa, l'extraction d'un groupe de débogage rétablit la configuration du groupe de débogage qui devient le nouveau sommet de la pile.
Le fait de pousser (respectivement d'enlever) des groupes de débogage génère aussi automatiquement un message de débogage de type QOpenGLDebugMessage::GroupPushType (respectivement GroupPopType).
Voir aussi QOpenGLDebugMessage.
Documentation sur les types de membres
enum QOpenGLDebugLogger::LoggingMode
L'enum LoggingMode définit le mode de journalisation de l'objet logger.
| Constante | Valeur | Description du mode de journalisation |
|---|---|---|
QOpenGLDebugLogger::AsynchronousLogging | 0 | Les messages provenant du serveur OpenGL sont enregistrés de manière asynchrone. Cela signifie que les messages peuvent être enregistrés un certain temps après les actions OpenGL correspondantes qui les ont provoqués, et même être reçus dans le désordre, en fonction de l'implémentation OpenGL. Ce mode a une très faible pénalité de performance, car les implémentations d'OpenGL sont fortement threadées et asynchrones par nature. |
QOpenGLDebugLogger::SynchronousLogging | 1 | Les messages du serveur OpenGL sont enregistrés de manière synchrone et séquentielle. Ce mode a un impact sévère sur les performances, car les implémentations OpenGL sont très asynchrones par nature ; mais il est très utile pour déboguer les problèmes OpenGL, car OpenGL garantit que les messages générés par une commande OpenGL seront enregistrés avant que l'exécution de la commande correspondante ne soit retournée. Par conséquent, vous pouvez installer un point d'arrêt sur le signal messageLogged() et voir dans le backtrace quelle commande OpenGL l'a causé ; la seule mise en garde est que si vous utilisez OpenGL à partir de plusieurs threads, vous devrez peut-être forcer la connexion directe lorsque vous vous connectez au signal messageLogged(). |
Documentation sur les propriétés
[read-only] loggingMode : LoggingMode
Cette propriété contient le mode de journalisation transmis à startLogging().
Notez que la journalisation doit avoir été lancée, sinon la valeur de cette propriété n'aura pas de sens.
Fonctions d'accès :
| QOpenGLDebugLogger::LoggingMode | loggingMode() const |
Voir également startLogging() et isLogging().
Documentation des fonctions membres
[explicit] QOpenGLDebugLogger::QOpenGLDebugLogger(QObject *parent = nullptr)
Construit un nouvel objet logger avec l'adresse parent.
Note : L'objet doit être initialisé avant que l'enregistrement puisse avoir lieu.
Voir aussi initialize().
[virtual noexcept] QOpenGLDebugLogger::~QOpenGLDebugLogger()
Détruit l'objet logger.
void QOpenGLDebugLogger::disableMessages(QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource, QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType, QOpenGLDebugMessage::Severities severities = QOpenGLDebugMessage::AnySeverity)
Désactive l'enregistrement des messages avec l'adresse sources, l'adresse types et l'adresse severities, ainsi que tout identifiant de message.
L'enregistrement sera désactivé dans le groupe de contrôle actuel.
Voir aussi enableMessages(), pushGroup(), et popGroup().
void QOpenGLDebugLogger::disableMessages(const QList<GLuint> &ids, QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource, QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType)
Désactive l'enregistrement des messages portant le numéro ids, provenant du numéro sources et du numéro types, quelle que soit leur gravité.
La journalisation sera désactivée dans le groupe de contrôle actuel.
Voir aussi enableMessages(), pushGroup() et popGroup().
void QOpenGLDebugLogger::enableMessages(QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource, QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType, QOpenGLDebugMessage::Severities severities = QOpenGLDebugMessage::AnySeverity)
Active l'enregistrement des messages provenant de l'adresse sources, de l'adresse types et de l'adresse severities, ainsi que de tout identifiant de message.
La journalisation sera activée dans le groupe de contrôle actuel.
Voir aussi disableMessages(), pushGroup(), et popGroup().
void QOpenGLDebugLogger::enableMessages(const QList<GLuint> &ids, QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource, QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType)
Active l'enregistrement des messages avec l'adresse ids, de l'adresse sources et de l'adresse types et de n'importe quelle gravité.
La journalisation sera activée dans le groupe de contrôle actuel.
Voir aussi disableMessages(), pushGroup(), et popGroup().
bool QOpenGLDebugLogger::initialize()
Initialise l'objet dans le contexte OpenGL actuel. Le contexte doit supporter l'extension GL_KHR_debug pour que l'initialisation réussisse. L'objet doit être initialisé avant tout enregistrement.
Il est possible d'appeler cette fonction plusieurs fois à partir du même contexte.
Cette fonction peut également être utilisée pour changer le contexte d'un objet précédemment initialisé ; notez que dans ce cas, l'objet ne doit pas être en train de journaliser lorsque vous appelez cette fonction.
Retourne true si le logger a été initialisé avec succès ; false sinon.
Voir aussi QOpenGLContext.
bool QOpenGLDebugLogger::isLogging() const
Renvoie true si cet objet est en cours d'enregistrement, false sinon.
Voir aussi startLogging().
[slot] void QOpenGLDebugLogger::logMessage(const QOpenGLDebugMessage &debugMessage)
Insère le message debugMessage dans le journal de débogage OpenGL. Cela permet aux applications ou aux bibliothèques d'insérer des messages personnalisés qui peuvent faciliter le débogage des applications OpenGL.
Note : debugMessage doit avoir QOpenGLDebugMessage::ApplicationSource ou QOpenGLDebugMessage::ThirdPartySource comme source, et un type et une sévérité valides, sinon il ne sera pas inséré dans le journal.
Note : L'objet doit être initialisé avant que l'enregistrement puisse avoir lieu.
Voir aussi initialize().
QList<QOpenGLDebugMessage> QOpenGLDebugLogger::loggedMessages() const
Lit tous les messages disponibles dans le journal de débogage interne d'OpenGL et les renvoie. De plus, cette fonction effacera le journal de débogage interne, de sorte que les invocations suivantes ne renverront pas les messages qui ont déjà été renvoyés.
Voir aussi startLogging().
QOpenGLDebugLogger::LoggingMode QOpenGLDebugLogger::loggingMode() const
Renvoie le mode de journalisation de l'objet.
Note : Fonction Getter pour la propriété loggingMode.
Voir aussi startLogging().
qint64 QOpenGLDebugLogger::maximumMessageLength() const
Renvoie la longueur maximale supportée, en octets, pour le texte des messages passés à logMessage(). Il s'agit également de la longueur maximale d'un nom de groupe de débogage, car le fait de pousser ou de déplacer des groupes enregistrera automatiquement un message avec le nom du groupe de débogage comme texte du message.
Si le texte d'un message est trop long, il sera automatiquement tronqué par QOpenGLDebugLogger.
Note : Les textes des messages sont encodés en UTF-8 lorsqu'ils sont transmis à OpenGL, donc leur taille en octets ne correspond généralement pas à la quantité d'unités de code UTF-16, telle que retournée, par exemple, par QString::length(). (C'est le cas si le message contient uniquement des données ASCII de 7 bits, ce qui est typique pour les messages de débogage).
[signal] void QOpenGLDebugLogger::messageLogged(const QOpenGLDebugMessage &debugMessage)
Ce signal est émis lorsqu'un message de débogage (enveloppé par l'argument debugMessage ) est enregistré par le serveur OpenGL.
Selon l'implémentation d'OpenGL, ce signal peut être émis par d'autres threads que celui(s) dans lequel (lesquels) le(s) récepteur(s) vit (vivent), et même différent du thread dans lequel vit QOpenGLContext dans lequel cet objet a été initialisé. De plus, le signal peut être émis par plusieurs threads en même temps. Ce n'est normalement pas un problème, car Qt utilisera une connexion en file d'attente pour les émissions de signaux inter-threads, mais si vous forcez le type de connexion à Direct, alors vous devez être conscient des courses potentielles dans les slots connectés à ce signal.
Si la journalisation a été lancée en mode SynchronousLogging, OpenGL garantit que ce signal sera émis depuis le même thread que celui auquel QOpenGLContext a été lié, et qu'aucune invocation concurrente n'aura lieu.
Note : La journalisation doit avoir été lancée, ou ce signal ne sera pas émis.
Voir aussi startLogging().
void QOpenGLDebugLogger::popGroup()
Retire le groupe de débogage le plus haut de la pile des groupes de débogage. Si le groupe est extrait avec succès, OpenGL enregistrera automatiquement un message avec le message, l'identifiant et la source correspondant à ceux du groupe extrait, le type QOpenGLDebugMessage::GroupPopType et la sévérité QOpenGLDebugMessage::NotificationSeverity.
L'extraction d'un groupe de débogage restaurera les paramètres de filtrage des messages du groupe qui devient le sommet de la pile des groupes de débogage.
Remarque : L'objet doit être initialisé avant de gérer les groupes de débogage.
Voir aussi pushGroup().
void QOpenGLDebugLogger::pushGroup(const QString &name, GLuint id = 0, QOpenGLDebugMessage::Source source = QOpenGLDebugMessage::ApplicationSource)
Pousse un groupe de débogage avec le nom name, l'identifiant id, et la source source sur la pile des groupes de débogage. Si le groupe est poussé avec succès, OpenGL enregistrera automatiquement un message avec le message name, l'identifiant id, la source source, le type QOpenGLDebugMessage::GroupPushType et la gravité QOpenGLDebugMessage::NotificationSeverity.
Le nouveau groupe poussé héritera des mêmes paramètres de filtrage que le groupe qui était au sommet de la pile ; c'est-à-dire que le filtrage ne sera pas modifié par la poussée d'un nouveau groupe.
Remarque : source doit être soit QOpenGLDebugMessage::ApplicationSource soit QOpenGLDebugMessage::ThirdPartySource, sinon le groupe ne sera pas poussé.
Remarque : L'objet doit être initialisé avant de gérer les groupes de débogage.
Voir aussi popGroup(), enableMessages(), et disableMessages().
[slot] void QOpenGLDebugLogger::startLogging(QOpenGLDebugLogger::LoggingMode loggingMode = AsynchronousLogging)
Commence à enregistrer les messages provenant du serveur OpenGL. Lorsqu'un nouveau message est reçu, le signal messageLogged() est émis, avec le message enregistré comme argument.
loggingMode spécifie si l'enregistrement doit être asynchrone (par défaut) ou synchrone.
QOpenGLDebugLogger enregistre les valeurs de GL_DEBUG_OUTPUT et GL_DEBUG_OUTPUT_SYNCHRONOUS lorsque l'enregistrement est lancé, et les rétablit lorsque l'enregistrement est arrêté. De plus, tout callback de débogage OpenGL défini par l'utilisateur et installé lors de l'invocation de cette fonction sera restauré lors de l'arrêt de la journalisation ; QOpenGLDebugLogger s'assurera que le callback préexistant sera toujours invoqué lors de la journalisation.
Note : Il n'est pas possible de changer le mode de journalisation sans arrêter et redémarrer la journalisation. Cela pourrait changer dans une future version de Qt.
Note : L'objet doit être initialisé avant que la journalisation puisse avoir lieu.
Voir aussi stopLogging() et initialize().
[slot] void QOpenGLDebugLogger::stopLogging()
Arrête l'enregistrement des messages du serveur OpenGL.
Voir aussi startLogging().
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.