QOpenGLDebugLogger Class
QOpenGLDebugLogger habilita el registro de mensajes de depuracion de OpenGL. Más...
| Cabecera: | #include <QOpenGLDebugLogger> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS OpenGL)target_link_libraries(mytarget PRIVATE Qt6::OpenGL) |
| qmake: | QT += opengl |
| Hereda: | QObject |
- Lista de todos los miembros, incluyendo los heredados
- QOpenGLDebugLogger es parte de Renderizado en 3D.
Tipos Públicos
| enum | LoggingMode { AsynchronousLogging, SynchronousLogging } |
Propiedades
- loggingMode : LoggingMode
Funciones públicas
| 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) |
Ranuras públicas
| void | logMessage(const QOpenGLDebugMessage &debugMessage) |
| void | startLogging(QOpenGLDebugLogger::LoggingMode loggingMode = AsynchronousLogging) |
| void | stopLogging() |
Señales
| void | messageLogged(const QOpenGLDebugMessage &debugMessage) |
Descripción detallada
Introducción
La programación OpenGL puede ser muy propensa a errores. La mayoría de las veces, una sola llamada fallida a OpenGL puede hacer que toda una parte de una aplicación deje de funcionar, sin que se dibuje nada en la pantalla.
La única forma de estar seguro de que no se devuelven errores desde la implementación de OpenGL es comprobarlo con glGetError después de cada llamada a la API. Además, los errores de OpenGL se apilan, por lo que glGetError debería usarse siempre en un bucle como éste:
GLenum error = GL_NO_ERROR; do { error = glGetError(); if (error != GL_NO_ERROR) { // handle the error } } while (error != GL_NO_ERROR);
Si intentas limpiar la pila de errores, asegúrate no sólo de seguir hasta que se devuelva GL_NO_ERROR sino también de romper en GL_CONTEXT_LOST ya que ese valor de error seguirá repitiéndose.
También hay mucha otra información que nos interesa (como desarrolladores de aplicaciones), por ejemplo problemas de rendimiento, o advertencias sobre el uso de APIs obsoletas. Este tipo de mensajes no se reportan a través de los mecanismos ordinarios de reporte de errores de OpenGL.
QOpenGLDebugLogger pretende solucionar estos problemas proporcionando acceso al registro de depuración de OpenGL. Si tu implementación de OpenGL lo soporta (exponiendo la extensión GL_KHR_debug ), los mensajes del servidor OpenGL se registrarán en un registro interno de OpenGL, o se pasarán en "tiempo real" a los oyentes cuando se generen desde OpenGL.
QOpenGLDebugLogger soporta ambos modos de operación. Consulta las siguientes secciones para conocer las diferencias entre ellos.
Creando un Contexto de Depuración OpenGL
Por razones de eficiencia, a las implementaciones OpenGL se les permite no crear ninguna salida de depuración, a menos que el contexto OpenGL sea un contexto de depuración. Para crear un contexto de depuración desde Qt, debe establecer la opción de formato QSurfaceFormat::DebugContext en el QSurfaceFormat utilizado para crear el objeto 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();
Tenga en cuenta que solicitar un perfil 3.2 OpenGL Core Profile es sólo para los propósitos del ejemplo; esta clase no está ligada a ninguna versión específica de OpenGL u OpenGL ES, ya que depende de la disponibilidad de la extensión GL_KHR_debug (ver más abajo).
Creando e Inicializando un QOpenGLDebugLogger
QOpenGLDebugLogger es una simple clase derivada de QObject. Como todas las subclases de QObject, creas una instancia (y opcionalmente especificas un objeto padre), y como las otras funciones OpenGL en Qt debes inicializarla antes de usarla llamando a initialize() mientras haya un contexto OpenGL actual:
QOpenGLContext *ctx = QOpenGLContext::currentContext(); QOpenGLDebugLogger *logger = new QOpenGLDebugLogger(this); logger->initialize(); // initializes in the current context, i.e. ctx
Ten en cuenta que la extensión GL_KHR_debug debe estar disponible en el contexto para poder acceder a los mensajes registrados por OpenGL. Puedes comprobar la presencia de esta extensión llamando a:
ctx->hasExtension(QByteArrayLiteral("GL_KHR_debug"));
donde ctx es un QOpenGLContext válido. Si la extensión no está disponible, initialize() devolverá false.
Lectura del registro de depuración interno de OpenGL
Las implementaciones de OpenGL mantienen un registro interno de mensajes de depuración. Los mensajes almacenados en este registro pueden ser recuperados utilizando la función loggedMessages():
const QList<QOpenGLDebugMessage> messages = logger->loggedMessages();for(const QOpenGLDebugMessage &mensaje: mensajes) qDebug() << message;
El registro interno tiene un tamaño limitado; cuando se llene, los mensajes antiguos se descartarán para hacer sitio a los nuevos mensajes entrantes. Cuando llame a loggedMessages(), el registro interno también se vaciará.
Si quieres asegurarte de no perder ningún mensaje de depuración, debes utilizar el registro en tiempo real en lugar de llamar a esta función. Sin embargo, es posible que se sigan generando mensajes de depuración en el intervalo de tiempo entre la creación del contexto y la activación del registro en tiempo real (o, en general, cuando el registro en tiempo real está desactivado).
Registro de mensajes en tiempo real
También es posible recibir un flujo de mensajes de depuración del servidor OpenGL a medida que son generados por la implementación. Para ello, es necesario conectar una ranura adecuada a la señal messageLogged(), e iniciar el registro llamando a startLogging():
connect(logger, &QOpenGLDebugLogger::messageLogged, receiver, &LogHandler::handleLoggedMessage); logger->startLogging();
Del mismo modo, el registro puede desactivarse en cualquier momento llamando a la función stopLogging().
El registro en tiempo real puede ser asíncrono o síncrono, dependiendo del parámetro que se pase a startLogging(). Cuando el registro se realiza en modo asíncrono (el predeterminado, ya que tiene una sobrecarga muy pequeña), la implementación de OpenGL puede generar mensajes en cualquier momento, y/o en un orden diferente del orden de los comandos de OpenGL que causaron que se registraran esos mensajes. Los mensajes también podrían ser generados desde un hilo diferente al hilo al que el contexto está actualmente vinculado. Esto se debe a que las implementaciones de OpenGL suelen estar muy hiladas y ser asíncronas, por lo que no se ofrecen garantías sobre el orden relativo y los tiempos de los mensajes de depuración.
Por otro lado, el registro en modo síncrono tiene una sobrecarga elevada, pero la implementación de OpenGL garantiza que todos los mensajes causados por un determinado comando se reciben en orden, antes de que el comando regrese, y desde el mismo hilo al que está vinculado el contexto OpenGL.
Esto significa que cuando se registra en modo síncrono podrás ejecutar tu aplicación OpenGL en un depurador, poner un punto de interrupción en una ranura conectada a la señal messageLogged(), y ver en el backtrace la llamada exacta que causó el mensaje registrado. Esto puede ser extremadamente útil para depurar un problema de OpenGL. Ten en cuenta que si el renderizado OpenGL está ocurriendo en otro hilo, debes forzar el tipo de conexión señal/ranura a Qt::DirectConnection para poder ver el backtrace real.
Consulte la documentación LoggingMode enum para obtener más información sobre los modos de registro.
Nota: Cuando se activa el registro en tiempo real, los mensajes de depuración ya no se insertarán en el registro de depuración interno de OpenGL; los mensajes ya presentes en el registro interno no se eliminarán, ni se emitirán a través de la señal messageLogged(). Dado que algunos mensajes pueden generarse antes de que se inicie el registro en tiempo real (y por tanto mantenerse en el registro interno de OpenGL), es importante comprobar siempre si contiene algún mensaje después de llamar a startLogging().
Inserción de mensajes en el registro de depuración
Es posible para aplicaciones y librerías insertar mensajes personalizados en el registro de depuración, por ejemplo para marcar un grupo de comandos OpenGL relacionados y así poder identificar eventuales mensajes provenientes de ellos.
Para ello, puedes crear un objeto QOpenGLDebugMessage llamando a createApplicationMessage() o createThirdPartyMessage(), y luego insertarlo en el registro llamando a logMessage():
QOpenGLDebugMessage message = QOpenGLDebugMessage::createApplicationMessage(QStringLiteral("Custom message")); logger->logMessage(message);
Ten en cuenta que las implementaciones de OpenGL tienen un límite específico del fabricante en cuanto a la longitud de los mensajes que pueden insertarse en el registro de depuración. Puedes recuperar esta longitud llamando al método maximumMessageLength(); los mensajes más largos que el límite se truncarán automáticamente.
Control de la salida de depuración
QOpenGLDebugMessage también puede aplicar filtros a los mensajes de depuración y, por tanto, limitar la cantidad de mensajes registrados. Puede activar o desactivar el registro de mensajes llamando a enableMessages() y disableMessages() respectivamente. Por defecto, se registran todos los mensajes.
Es posible activar o desactivar los mensajes seleccionándolos por:
- fuente, tipo y gravedad (e incluyendo todos los ids en la selección);
- id, fuente y tipo (e incluyendo todas las severidades en la selección).
Tenga en cuenta que el estado "activado" de un mensaje determinado es una propiedad de la tupla (id, source, type, severity); los atributos del mensaje no forman una jerarquía de ningún tipo. Debes tener cuidado con el orden de las llamadas a enableMessages() y disableMessages(), ya que cambiará qué mensajes se habilitarán / deshabilitarán.
No es posible filtrar por el propio texto del mensaje; las aplicaciones tienen que hacerlo por su cuenta (en las ranuras conectadas a la señal messageLogged(), o después de obtener los mensajes en el registro de depuración interno a través de loggedMessages()).
Para simplificar la gestión de los estados habilitados / deshabilitados, QOpenGLDebugMessage también soporta el concepto de debug groups. Un grupo de depuración contiene el grupo de configuraciones habilitadas / deshabilitadas de los mensajes de depuración. Además, los grupos de depuración se organizan en una pila: es posible insertar y extraer grupos llamando a pushGroup() y popGroup() respectivamente. (Cuando se crea un contexto OpenGL, ya hay un grupo en la pila).
Las funciones enableMessages() y disableMessages() modificarán la configuración del grupo de depuración actual, es decir, el que se encuentra en la parte superior de la pila de grupos de depuración.
Cuando se introduce un nuevo grupo en la pila de grupos de depuración, heredará la configuración del grupo que se encontraba anteriormente en la parte superior de la pila. A la inversa, al hacer popping de un grupo de depuración se restaurará la configuración del grupo de depuración que se convierte en el nuevo top.
La inserción (o extracción) de grupos de depuración también generará automáticamente un mensaje de depuración del tipo QOpenGLDebugMessage::GroupPushType (o GroupPopType).
Véase también QOpenGLDebugMessage.
Documentación de tipos de miembros
enum QOpenGLDebugLogger::LoggingMode
El enum LoggingMode define el modo de registro del objeto logger.
| Constante | Valor | Descripción |
|---|---|---|
QOpenGLDebugLogger::AsynchronousLogging | 0 | Los mensajes del servidor OpenGL se registran de forma asíncrona. Esto significa que los mensajes pueden ser registrados algún tiempo después de las correspondientes acciones OpenGL que los causaron, e incluso ser recibidos de forma desordenada, dependiendo de la implementación OpenGL. Este modo tiene una penalización de rendimiento muy baja, ya que las implementaciones de OpenGL están fuertemente enhebradas y son asíncronas por naturaleza. |
QOpenGLDebugLogger::SynchronousLogging | 1 | Los mensajes del servidor OpenGL se registran de forma sincrónica y secuencial. Esto tiene una penalización de rendimiento muy severa, ya que las implementaciones de OpenGL son muy asíncronas por naturaleza; pero es muy útil para depurar problemas de OpenGL, ya que OpenGL garantiza que los mensajes generados por un comando OpenGL se registrarán antes de que la ejecución del comando correspondiente haya vuelto. Por lo tanto, puedes instalar un breakpoint en la señal messageLogged() y ver en el backtrace qué comando OpenGL lo causó; la única advertencia es que si estás usando OpenGL desde múltiples hilos puede que necesites forzar la conexión directa cuando te conectes a la señal messageLogged(). |
Documentación de propiedades
[read-only] loggingMode : LoggingMode
Esta propiedad contiene el modo de registro pasado a startLogging().
Tenga en cuenta que el registro debe haberse iniciado o el valor de esta propiedad no tendrá sentido.
Funciones de acceso:
| QOpenGLDebugLogger::LoggingMode | loggingMode() const |
Véase también startLogging() y isLogging().
Documentación de las funciones miembro
[explicit] QOpenGLDebugLogger::QOpenGLDebugLogger(QObject *parent = nullptr)
Crea un nuevo objeto logger con la dirección parent.
Nota: El objeto debe ser inicializado antes de que el registro pueda ocurrir.
Véase también initialize().
[virtual noexcept] QOpenGLDebugLogger::~QOpenGLDebugLogger()
Destruye el objeto logger.
void QOpenGLDebugLogger::disableMessages(QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource, QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType, QOpenGLDebugMessage::Severities severities = QOpenGLDebugMessage::AnySeverity)
Desactiva el registro de mensajes con el sources dado , del types dado y con el severities dado y cualquier id de mensaje.
El registro se desactivará en el grupo de control actual.
Véase también enableMessages(), pushGroup() y popGroup().
void QOpenGLDebugLogger::disableMessages(const QList<GLuint> &ids, QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource, QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType)
Desactiva el registro de mensajes con la dirección ids, de la dirección sources y de la dirección types y de cualquier gravedad.
El registro se desactivará en el grupo de control actual.
Véase también enableMessages(), pushGroup() y popGroup().
void QOpenGLDebugLogger::enableMessages(QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource, QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType, QOpenGLDebugMessage::Severities severities = QOpenGLDebugMessage::AnySeverity)
Habilita el registro de mensajes de sources, de types y con severities y cualquier id de mensaje.
El registro se habilitará en el grupo de control actual.
Véase también disableMessages(), pushGroup(), y popGroup().
void QOpenGLDebugLogger::enableMessages(const QList<GLuint> &ids, QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource, QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType)
Habilita el registro de mensajes con la dirección ids, de la dirección sources y de la dirección types y de cualquier gravedad.
El registro se habilitará en el grupo de control actual.
Véase también disableMessages(), pushGroup() y popGroup().
bool QOpenGLDebugLogger::initialize()
Inicializa el objeto en el contexto OpenGL actual. El contexto debe soportar la extensión GL_KHR_debug para que la inicialización tenga éxito. El objeto debe ser inicializado antes de que pueda producirse cualquier registro.
Es seguro llamar a esta función varias veces desde el mismo contexto.
Esta función también puede usarse para cambiar el contexto de un objeto previamente inicializado; tenga en cuenta que en este caso el objeto no debe estar registrando cuando llame a esta función.
Devuelve true si el logger se ha inicializado correctamente; false en caso contrario.
Véase también QOpenGLContext.
bool QOpenGLDebugLogger::isLogging() const
Devuelve true si este objeto está registrando actualmente, false en caso contrario.
Véase también startLogging().
[slot] void QOpenGLDebugLogger::logMessage(const QOpenGLDebugMessage &debugMessage)
Inserta el mensaje debugMessage en el registro de depuración de OpenGL. Esto permite a las aplicaciones o bibliotecas insertar mensajes personalizados que pueden facilitar la depuración de las aplicaciones OpenGL.
Nota: debugMessage debe tener QOpenGLDebugMessage::ApplicationSource o QOpenGLDebugMessage::ThirdPartySource como fuente, y un tipo y severidad válidos, de lo contrario no será insertado en el registro.
Nota: El objeto debe ser inicializado antes de que pueda producirse el registro.
Véase también initialize().
QList<QOpenGLDebugMessage> QOpenGLDebugLogger::loggedMessages() const
Lee todos los mensajes disponibles en el registro de depuración interno de OpenGL y los devuelve. Además, esta función borrará el registro de depuración interno, de modo que las invocaciones posteriores no devolverán mensajes que ya fueron devueltos.
Véase también startLogging().
QOpenGLDebugLogger::LoggingMode QOpenGLDebugLogger::loggingMode() const
Devuelve el modo de registro del objeto.
Nota: Función Getter para la propiedad loggingMode.
Véase también startLogging().
qint64 QOpenGLDebugLogger::maximumMessageLength() const
Devuelve la longitud máxima admitida, en bytes, para el texto de los mensajes pasados a logMessage(). Esta es también la longitud máxima del nombre de un grupo de depuración, ya que al insertar o extraer grupos se registrará automáticamente un mensaje con el nombre del grupo de depuración como texto del mensaje.
Si el texto de un mensaje es demasiado largo, será truncado automáticamente por QOpenGLDebugLogger.
Nota: Los textos de los mensajes se codifican en UTF-8 cuando se pasan a OpenGL, por lo que su tamaño en bytes no suele coincidir con la cantidad de unidades de código UTF-16, tal y como devuelve, por ejemplo, QString::length(). (Sí lo hace si el mensaje contiene sólo datos ASCII de 7 bits, que es lo habitual en los mensajes de depuración).
[signal] void QOpenGLDebugLogger::messageLogged(const QOpenGLDebugMessage &debugMessage)
Esta señal es emitida cuando un mensaje de depuración (envuelto por el argumento debugMessage ) es registrado desde el servidor OpenGL.
Dependiendo de la implementación de OpenGL, esta señal puede ser emitida desde hilos distintos de aquel en el que vive el receptor o receptores, e incluso distintos del hilo en el que vive el QOpenGLContext en el que se ha inicializado este objeto. Además, la señal podría ser emitida desde múltiples hilos al mismo tiempo. Esto normalmente no es un problema, ya que Qt utilizará una conexión en cola para las emisiones de señales entre hilos, pero si fuerzas el tipo de conexión a Direct entonces debes ser consciente de las potenciales carreras en las ranuras conectadas a esta señal.
Si se ha iniciado el registro en el modo SynchronousLogging, OpenGL garantiza que esta señal se emitirá desde el mismo subproceso al que se ha vinculado QOpenGLContext, y nunca se producirán invocaciones concurrentes.
Nota: El registro debe haber sido iniciado, o esta señal no será emitida.
Véase también startLogging().
void QOpenGLDebugLogger::popGroup()
Expulsa el grupo de depuración superior de la pila de grupos de depuración. Si el grupo se salta con éxito, OpenGL registrará automáticamente un mensaje con mensaje, id y origen que coincidan con los del grupo saltado, tipo QOpenGLDebugMessage::GroupPopType y gravedad QOpenGLDebugMessage::NotificationSeverity.
Al saltar un grupo de depuración se restaurará la configuración de filtrado de mensajes del grupo que se convierte en el primero de la pila de grupos de depuración.
Nota: El objeto debe inicializarse antes de gestionar los grupos de depuración.
Véase también pushGroup().
void QOpenGLDebugLogger::pushGroup(const QString &name, GLuint id = 0, QOpenGLDebugMessage::Source source = QOpenGLDebugMessage::ApplicationSource)
Empuja un grupo de depuración con nombre name, id id, y fuente source a la pila de grupos de depuración. Si el grupo se empuja con éxito, OpenGL registrará automáticamente un mensaje con el nombre name, id id, source source, type QOpenGLDebugMessage::GroupPushType y severity QOpenGLDebugMessage::NotificationSeverity.
El grupo recién empujado heredará los mismos ajustes de filtrado del grupo que estaba en la parte superior de la pila; es decir, el filtrado no cambiará al empujar un nuevo grupo.
Nota: source debe ser QOpenGLDebugMessage::ApplicationSource o QOpenGLDebugMessage::ThirdPartySource, de lo contrario el grupo no será empujado.
Nota: El objeto debe inicializarse antes de gestionar los grupos de depuración.
Véase también popGroup(), enableMessages(), y disableMessages().
[slot] void QOpenGLDebugLogger::startLogging(QOpenGLDebugLogger::LoggingMode loggingMode = AsynchronousLogging)
Inicia el registro de mensajes procedentes del servidor OpenGL. Cuando se recibe un nuevo mensaje, se emite la señal messageLogged(), que lleva como argumento el mensaje registrado.
loggingMode especifica si el registro debe ser asíncrono (por defecto) o síncrono.
QOpenGLDebugLogger registrará los valores de GL_DEBUG_OUTPUT y GL_DEBUG_OUTPUT_SYNCHRONOUS cuando se inicie el registro, y los restablecerá cuando se detenga. Además, cualquier llamada de retorno de depuración OpenGL definida por el usuario e instalada cuando se invoca esta función será restaurada cuando se detenga el registro; QOpenGLDebugLogger se asegurará de que la llamada de retorno preexistente seguirá siendo invocada cuando se inicie el registro.
Nota: No es posible cambiar el modo de registro sin detener e iniciar de nuevo el registro. Esto podría cambiar en una futura versión de Qt.
Nota: El objeto debe ser inicializado antes de que el registro pueda ocurrir.
Ver también stopLogging() y initialize().
[slot] void QOpenGLDebugLogger::stopLogging()
Detiene el registro de mensajes del servidor OpenGL.
Véase también 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.