4#include <QtCore/private/qobject_p.h>
5#include <QtCore/qglobal.h>
6#include <QtCore/qvarlengtharray.h>
7#include <QtGui/qopengl.h>
8#include <QtGui/qopenglfunctions.h>
9#include <QtGui/qoffscreensurface.h>
15QT_IMPL_METATYPE_EXTERN(QOpenGLDebugMessage)
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
344
345
346
347
348
349
350
351
352
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
386#if defined(GL_KHR_debug) && defined(GL_DEBUG_SOURCE_API_KHR)
387#define USE_MANUAL_DEFS
396#define GL_KHR_debug 1
397#define USE_MANUAL_DEFS
402#ifndef GL_DEBUG_OUTPUT_SYNCHRONOUS
403#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
405#ifndef GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH
406#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
408#ifndef GL_DEBUG_CALLBACK_FUNCTION
409#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
411#ifndef GL_DEBUG_CALLBACK_USER_PARAM
412#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
414#ifndef GL_DEBUG_SOURCE_API
415#define GL_DEBUG_SOURCE_API 0x8246
417#ifndef GL_DEBUG_SOURCE_WINDOW_SYSTEM
418#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
420#ifndef GL_DEBUG_SOURCE_SHADER_COMPILER
421#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
423#ifndef GL_DEBUG_SOURCE_THIRD_PARTY
424#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
426#ifndef GL_DEBUG_SOURCE_APPLICATION
427#define GL_DEBUG_SOURCE_APPLICATION 0x824A
429#ifndef GL_DEBUG_SOURCE_OTHER
430#define GL_DEBUG_SOURCE_OTHER 0x824B
432#ifndef GL_DEBUG_TYPE_ERROR
433#define GL_DEBUG_TYPE_ERROR 0x824C
435#ifndef GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR
436#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
438#ifndef GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR
439#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
441#ifndef GL_DEBUG_TYPE_PORTABILITY
442#define GL_DEBUG_TYPE_PORTABILITY 0x824F
444#ifndef GL_DEBUG_TYPE_PERFORMANCE
445#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
447#ifndef GL_DEBUG_TYPE_OTHER
448#define GL_DEBUG_TYPE_OTHER 0x8251
450#ifndef GL_DEBUG_TYPE_MARKER
451#define GL_DEBUG_TYPE_MARKER 0x8268
453#ifndef GL_DEBUG_TYPE_PUSH_GROUP
454#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
456#ifndef GL_DEBUG_TYPE_POP_GROUP
457#define GL_DEBUG_TYPE_POP_GROUP 0x826A
459#ifndef GL_DEBUG_SEVERITY_NOTIFICATION
460#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
462#ifndef GL_MAX_DEBUG_GROUP_STACK_DEPTH
463#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
465#ifndef GL_DEBUG_GROUP_STACK_DEPTH
466#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
469#define GL_BUFFER 0x82E0
472#define GL_SHADER 0x82E1
475#define GL_PROGRAM 0x82E2
478#define GL_QUERY 0x82E3
480#ifndef GL_PROGRAM_PIPELINE
481#define GL_PROGRAM_PIPELINE 0x82E4
484#define GL_SAMPLER 0x82E6
486#ifndef GL_DISPLAY_LIST
487#define GL_DISPLAY_LIST 0x82E7
489#ifndef GL_MAX_LABEL_LENGTH
490#define GL_MAX_LABEL_LENGTH 0x82E8
492#ifndef GL_MAX_DEBUG_MESSAGE_LENGTH
493#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
495#ifndef GL_MAX_DEBUG_LOGGED_MESSAGES
496#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
498#ifndef GL_DEBUG_LOGGED_MESSAGES
499#define GL_DEBUG_LOGGED_MESSAGES 0x9145
501#ifndef GL_DEBUG_SEVERITY_HIGH
502#define GL_DEBUG_SEVERITY_HIGH 0x9146
504#ifndef GL_DEBUG_SEVERITY_MEDIUM
505#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
507#ifndef GL_DEBUG_SEVERITY_LOW
508#define GL_DEBUG_SEVERITY_LOW 0x9148
510#ifndef GL_DEBUG_OUTPUT
511#define GL_DEBUG_OUTPUT 0x92E0
513#ifndef GL_CONTEXT_FLAG_DEBUG_BIT
514#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
516#ifndef GL_STACK_OVERFLOW
517#define GL_STACK_OVERFLOW 0x0503
519#ifndef GL_STACK_UNDERFLOW
520#define GL_STACK_UNDERFLOW 0x0504
523typedef void (QOPENGLF_APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,
const GLchar *message,
const GLvoid *userParam);
529
530
535 return QOpenGLDebugMessage::APISource;
537 return QOpenGLDebugMessage::WindowSystemSource;
539 return QOpenGLDebugMessage::ShaderCompilerSource;
541 return QOpenGLDebugMessage::ThirdPartySource;
543 return QOpenGLDebugMessage::ApplicationSource;
545 return QOpenGLDebugMessage::OtherSource;
548 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown message source from GL");
549 return QOpenGLDebugMessage::OtherSource;
553
554
558 case QOpenGLDebugMessage::InvalidSource:
560 case QOpenGLDebugMessage::APISource:
562 case QOpenGLDebugMessage::WindowSystemSource:
564 case QOpenGLDebugMessage::ShaderCompilerSource:
566 case QOpenGLDebugMessage::ThirdPartySource:
568 case QOpenGLDebugMessage::ApplicationSource:
570 case QOpenGLDebugMessage::OtherSource:
572 case QOpenGLDebugMessage::AnySource:
576 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Invalid message source");
581
582
586 case QOpenGLDebugMessage::InvalidSource:
587 return QStringLiteral(
"InvalidSource");
588 case QOpenGLDebugMessage::APISource:
589 return QStringLiteral(
"APISource");
590 case QOpenGLDebugMessage::WindowSystemSource:
591 return QStringLiteral(
"WindowSystemSource");
592 case QOpenGLDebugMessage::ShaderCompilerSource:
593 return QStringLiteral(
"ShaderCompilerSource");
594 case QOpenGLDebugMessage::ThirdPartySource:
595 return QStringLiteral(
"ThirdPartySource");
596 case QOpenGLDebugMessage::ApplicationSource:
597 return QStringLiteral(
"ApplicationSource");
598 case QOpenGLDebugMessage::OtherSource:
599 return QStringLiteral(
"OtherSource");
600 case QOpenGLDebugMessage::AnySource:
601 return QStringLiteral(
"AnySource");
604 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown message source");
609
610
615 return QOpenGLDebugMessage::ErrorType;
617 return QOpenGLDebugMessage::DeprecatedBehaviorType;
619 return QOpenGLDebugMessage::UndefinedBehaviorType;
621 return QOpenGLDebugMessage::PortabilityType;
623 return QOpenGLDebugMessage::PerformanceType;
625 return QOpenGLDebugMessage::OtherType;
627 return QOpenGLDebugMessage::MarkerType;
629 return QOpenGLDebugMessage::GroupPushType;
631 return QOpenGLDebugMessage::GroupPopType;
634 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown message type from GL");
635 return QOpenGLDebugMessage::OtherType;
639
640
644 case QOpenGLDebugMessage::InvalidType:
646 case QOpenGLDebugMessage::ErrorType:
648 case QOpenGLDebugMessage::DeprecatedBehaviorType:
650 case QOpenGLDebugMessage::UndefinedBehaviorType:
652 case QOpenGLDebugMessage::PortabilityType:
654 case QOpenGLDebugMessage::PerformanceType:
656 case QOpenGLDebugMessage::OtherType:
658 case QOpenGLDebugMessage::MarkerType:
660 case QOpenGLDebugMessage::GroupPushType:
662 case QOpenGLDebugMessage::GroupPopType:
664 case QOpenGLDebugMessage::AnyType:
668 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Invalid message type");
673
674
678 case QOpenGLDebugMessage::InvalidType:
679 return QStringLiteral(
"InvalidType");
680 case QOpenGLDebugMessage::ErrorType:
681 return QStringLiteral(
"ErrorType");
682 case QOpenGLDebugMessage::DeprecatedBehaviorType:
683 return QStringLiteral(
"DeprecatedBehaviorType");
684 case QOpenGLDebugMessage::UndefinedBehaviorType:
685 return QStringLiteral(
"UndefinedBehaviorType");
686 case QOpenGLDebugMessage::PortabilityType:
687 return QStringLiteral(
"PortabilityType");
688 case QOpenGLDebugMessage::PerformanceType:
689 return QStringLiteral(
"PerformanceType");
690 case QOpenGLDebugMessage::OtherType:
691 return QStringLiteral(
"OtherType");
692 case QOpenGLDebugMessage::MarkerType:
693 return QStringLiteral(
"MarkerType");
694 case QOpenGLDebugMessage::GroupPushType:
695 return QStringLiteral(
"GroupPushType");
696 case QOpenGLDebugMessage::GroupPopType:
697 return QStringLiteral(
"GroupPopType");
698 case QOpenGLDebugMessage::AnyType:
699 return QStringLiteral(
"AnyType");
702 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown message type");
707
708
713 return QOpenGLDebugMessage::HighSeverity;
715 return QOpenGLDebugMessage::MediumSeverity;
717 return QOpenGLDebugMessage::LowSeverity;
719 return QOpenGLDebugMessage::NotificationSeverity;
722 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown message severity from GL");
723 return QOpenGLDebugMessage::NotificationSeverity;
727
728
732 case QOpenGLDebugMessage::InvalidSeverity:
734 case QOpenGLDebugMessage::HighSeverity:
736 case QOpenGLDebugMessage::MediumSeverity:
738 case QOpenGLDebugMessage::LowSeverity:
740 case QOpenGLDebugMessage::NotificationSeverity:
742 case QOpenGLDebugMessage::AnySeverity:
746 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Invalid message severity");
751
752
756 case QOpenGLDebugMessage::InvalidSeverity:
757 return QStringLiteral(
"InvalidSeverity");
758 case QOpenGLDebugMessage::HighSeverity:
759 return QStringLiteral(
"HighSeverity");
760 case QOpenGLDebugMessage::MediumSeverity:
761 return QStringLiteral(
"MediumSeverity");
762 case QOpenGLDebugMessage::LowSeverity:
763 return QStringLiteral(
"LowSeverity");
764 case QOpenGLDebugMessage::NotificationSeverity:
765 return QStringLiteral(
"NotificationSeverity");
766 case QOpenGLDebugMessage::AnySeverity:
767 return QStringLiteral(
"AnySeverity");
770 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown message severity");
787
788
800
801
802
803
804
805
806
807
808
809
810QOpenGLDebugMessage::QOpenGLDebugMessage()
811 : d(
new QOpenGLDebugMessagePrivate)
816
817
818
819
820QOpenGLDebugMessage::QOpenGLDebugMessage(
const QOpenGLDebugMessage &debugMessage)
826
827
828QOpenGLDebugMessage::~QOpenGLDebugMessage()
833
834
835
836QOpenGLDebugMessage &QOpenGLDebugMessage::operator=(
const QOpenGLDebugMessage &debugMessage)
843
844
845
846
849
850
851
854
855
856QOpenGLDebugMessage::Source QOpenGLDebugMessage::source()
const
862
863
864QOpenGLDebugMessage::Type QOpenGLDebugMessage::type()
const
870
871
872QOpenGLDebugMessage::Severity QOpenGLDebugMessage::severity()
const
878
879
880GLuint QOpenGLDebugMessage::id()
const
886
887
888QString QOpenGLDebugMessage::message()
const
894
895
896
897
898
899
900QOpenGLDebugMessage QOpenGLDebugMessage::createApplicationMessage(
const QString &text,
902 QOpenGLDebugMessage::Severity severity,
903 QOpenGLDebugMessage::Type type)
905 QOpenGLDebugMessage m;
908 m.d->severity = severity;
910 m.d->source = ApplicationSource;
915
916
917
918
919
920
921QOpenGLDebugMessage QOpenGLDebugMessage::createThirdPartyMessage(
const QString &text,
923 QOpenGLDebugMessage::Severity severity,
924 QOpenGLDebugMessage::Type type)
926 QOpenGLDebugMessage m;
929 m.d->severity = severity;
931 m.d->source = ThirdPartySource;
936
937
938
939
940
941
942bool QOpenGLDebugMessage::operator==(
const QOpenGLDebugMessage &debugMessage)
const
944 return (d == debugMessage.d)
945 || (d->id == debugMessage.d->id
946 && d->source == debugMessage.d->source
947 && d->type == debugMessage.d->type
948 && d->severity == debugMessage.d->severity
949 && d->message == debugMessage.d->message);
953
954
955
956
957
958
959
961#ifndef QT_NO_DEBUG_STREAM
963
964
965
966
967
968QDebug operator<<(QDebug debug, QOpenGLDebugMessage::Source source)
970 QDebugStateSaver saver(debug);
971 debug.nospace() <<
"QOpenGLDebugMessage::Source("
972 << qt_messageSourceToString(source)
978
979
980
981
982
983QDebug operator<<(QDebug debug, QOpenGLDebugMessage::Type type)
985 QDebugStateSaver saver(debug);
986 debug.nospace() <<
"QOpenGLDebugMessage::Type("
987 << qt_messageTypeToString(type)
993
994
995
996
997
998QDebug operator<<(QDebug debug, QOpenGLDebugMessage::Severity severity)
1000 QDebugStateSaver saver(debug);
1001 debug.nospace() <<
"QOpenGLDebugMessage::Severity("
1002 << qt_messageSeverityToString(severity)
1008
1009
1010
1011
1012
1013QDebug operator<<(QDebug debug,
const QOpenGLDebugMessage &message)
1015 QDebugStateSaver saver(debug);
1016 debug.nospace() <<
"QOpenGLDebugMessage("
1017 << qt_messageSourceToString(message.source()) <<
", "
1018 << message.id() <<
", "
1019 << message.message() <<
", "
1020 << qt_messageSeverityToString(message.severity()) <<
", "
1021 << qt_messageTypeToString(message.type()) <<
')';
1027typedef void (QOPENGLF_APIENTRYP qt_glDebugMessageControl_t)(GLenum source, GLenum type, GLenum severity, GLsizei count,
const GLuint *ids, GLboolean enabled);
1028typedef void (QOPENGLF_APIENTRYP qt_glDebugMessageInsert_t)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar *buf);
1029typedef void (QOPENGLF_APIENTRYP qt_glDebugMessageCallback_t)(GLDEBUGPROC callback,
const void *userParam);
1030typedef GLuint (QOPENGLF_APIENTRYP qt_glGetDebugMessageLog_t)(GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
1031typedef void (QOPENGLF_APIENTRYP qt_glPushDebugGroup_t)(GLenum source, GLuint id, GLsizei length,
const GLchar *message);
1032typedef void (QOPENGLF_APIENTRYP qt_glPopDebugGroup_t)();
1033typedef void (QOPENGLF_APIENTRYP qt_glGetPointerv_t)(GLenum pname, GLvoid **params);
1035class QOpenGLDebugLoggerPrivate :
public QObjectPrivate
1037 Q_DECLARE_PUBLIC(QOpenGLDebugLogger)
1039 QOpenGLDebugLoggerPrivate();
1041 void handleMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar *rawMessage);
1042 void controlDebugMessages(QOpenGLDebugMessage::Sources sources,
1043 QOpenGLDebugMessage::Types types,
1044 QOpenGLDebugMessage::Severities severities,
const QList<GLuint> &ids,
1045 const QByteArray &callerName,
bool enable);
1046 void _q_contextAboutToBeDestroyed();
1048 qt_glDebugMessageControl_t glDebugMessageControl;
1049 qt_glDebugMessageInsert_t glDebugMessageInsert;
1050 qt_glDebugMessageCallback_t glDebugMessageCallback;
1051 qt_glGetDebugMessageLog_t glGetDebugMessageLog;
1052 qt_glPushDebugGroup_t glPushDebugGroup;
1053 qt_glPopDebugGroup_t glPopDebugGroup;
1054 qt_glGetPointerv_t glGetPointerv;
1056 GLDEBUGPROC oldDebugCallbackFunction;
1057 void *oldDebugCallbackParameter;
1058 QOpenGLContext *context;
1059 GLint maxMessageLength;
1060 QOpenGLDebugLogger::LoggingMode loggingMode;
1061 bool initialized : 1;
1063 bool debugWasEnabled : 1;
1064 bool syncDebugWasEnabled : 1;
1068
1069
1070QOpenGLDebugLoggerPrivate::QOpenGLDebugLoggerPrivate()
1071 : glDebugMessageControl(
nullptr),
1072 glDebugMessageInsert(
nullptr),
1073 glDebugMessageCallback(
nullptr),
1074 glGetDebugMessageLog(
nullptr),
1075 glPushDebugGroup(
nullptr),
1076 glPopDebugGroup(
nullptr),
1077 oldDebugCallbackFunction(
nullptr),
1079 maxMessageLength(0),
1080 loggingMode(QOpenGLDebugLogger::AsynchronousLogging),
1083 debugWasEnabled(
false),
1084 syncDebugWasEnabled(
false)
1089
1090
1091void QOpenGLDebugLoggerPrivate::handleMessage(GLenum source,
1096 const GLchar *rawMessage)
1098 if (oldDebugCallbackFunction)
1099 oldDebugCallbackFunction(source, type, id, severity, length, rawMessage, oldDebugCallbackParameter);
1104 messagePrivate->source = qt_messageSourceFromGL(source);
1105 messagePrivate->type = qt_messageTypeFromGL(type);
1106 messagePrivate->id = id;
1107 messagePrivate->severity = qt_messageSeverityFromGL(severity);
1110 messagePrivate->message = QString::fromUtf8(rawMessage);
1112 Q_Q(QOpenGLDebugLogger);
1113 emit q->messageLogged(message);
1117
1118
1119void QOpenGLDebugLoggerPrivate::controlDebugMessages(QOpenGLDebugMessage::Sources sources,
1120 QOpenGLDebugMessage::Types types,
1121 QOpenGLDebugMessage::Severities severities,
1122 const QList<GLuint> &ids,
1123 const QByteArray &callerName,
bool enable)
1126 qWarning(
"QOpenGLDebugLogger::%s(): object must be initialized before enabling/disabling messages", callerName.constData());
1129 if (sources == QOpenGLDebugMessage::InvalidSource) {
1130 qWarning(
"QOpenGLDebugLogger::%s(): invalid source specified", callerName.constData());
1133 if (types == QOpenGLDebugMessage::InvalidType) {
1134 qWarning(
"QOpenGLDebugLogger::%s(): invalid type specified", callerName.constData());
1137 if (severities == QOpenGLDebugMessage::InvalidSeverity) {
1138 qWarning(
"QOpenGLDebugLogger::%s(): invalid severity specified", callerName.constData());
1142 QVarLengthArray<GLenum, 8> glSources;
1143 QVarLengthArray<GLenum, 8> glTypes;
1144 QVarLengthArray<GLenum, 8> glSeverities;
1146 if (ids.size() > 0) {
1147 Q_ASSERT(severities == QOpenGLDebugMessage::AnySeverity);
1160 if (sources == QOpenGLDebugMessage::AnySource) {
1161 sources = QOpenGLDebugMessage::InvalidSource;
1162 for (uint i = 1; i <= QOpenGLDebugMessage::LastSource; i = i << 1)
1163 sources |= QOpenGLDebugMessage::Source(i);
1166 if (types == QOpenGLDebugMessage::AnyType) {
1167 types = QOpenGLDebugMessage::InvalidType;
1168 for (uint i = 1; i <= QOpenGLDebugMessage::LastType; i = i << 1)
1169 types |= QOpenGLDebugMessage::Type(i);
1173#define CONVERT_TO_GL_DEBUG_MESSAGE_CONTROL_PARAMETERS(type, source, target)
1174 if (source == QOpenGLDebugMessage::Any ## type) {
1175 target << GL_DONT_CARE;
1177 for (uint i = 1
; i <= QOpenGLDebugMessage::Last ## type; i = i << 1
)
1178 if (source.testFlag(QOpenGLDebugMessage:: type (i)))
1179 target << qt_message ## type ## ToGL (QOpenGLDebugMessage:: type (i));
1185#undef CONVERT_TO_GL_DEBUG_MESSAGE_CONTROL_PARAMETERS
1187 const GLsizei idCount = ids.size();
1190 const GLuint *
const idPtr = idCount ? ids.constData() :
nullptr;
1192 for (GLenum source : glSources)
1193 for (GLenum type : glTypes)
1194 for (GLenum severity : glSeverities)
1195 glDebugMessageControl(source, type, severity, idCount, idPtr, GLboolean(enable));
1199
1200
1201void QOpenGLDebugLoggerPrivate::_q_contextAboutToBeDestroyed()
1208 QOpenGLContext *currentContext = QOpenGLContext::currentContext();
1209 QSurface *currentSurface =
nullptr;
1211 QScopedPointer<QOffscreenSurface> offscreenSurface;
1213 if (context != currentContext) {
1216 currentSurface = currentContext->surface();
1218 offscreenSurface.reset(
new QOffscreenSurface);
1219 offscreenSurface->setFormat(context->format());
1220 offscreenSurface->create();
1221 if (!context->makeCurrent(offscreenSurface.data()))
1222 qWarning(
"QOpenGLDebugLoggerPrivate::_q_contextAboutToBeDestroyed(): could not make the owning GL context current for cleanup");
1225 Q_Q(QOpenGLDebugLogger);
1228 if (offscreenSurface) {
1231 currentContext->makeCurrent(currentSurface);
1233 context->doneCurrent();
1236 QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
1238 initialized =
false;
1242static void QOPENGLF_APIENTRY qt_opengl_debug_callback(GLenum source,
1247 const GLchar *rawMessage,
1248 const GLvoid *userParam)
1250 QOpenGLDebugLoggerPrivate *loggerPrivate =
static_cast<QOpenGLDebugLoggerPrivate *>(
const_cast<GLvoid *>(userParam));
1251 loggerPrivate->handleMessage(source, type, id, severity, length, rawMessage);
1256
1257
1258
1259
1260
1261
1262QOpenGLDebugLogger::QOpenGLDebugLogger(QObject *parent)
1263 : QObject(*
new QOpenGLDebugLoggerPrivate, parent)
1268 qRegisterMetaType<QOpenGLDebugMessage>();
1272
1273
1274QOpenGLDebugLogger::~QOpenGLDebugLogger()
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294bool QOpenGLDebugLogger::initialize()
1296 QOpenGLContext *context = QOpenGLContext::currentContext();
1298 qWarning(
"QOpenGLDebugLogger::initialize(): no current OpenGL context found.");
1302 Q_D(QOpenGLDebugLogger);
1303 if (d->context == context) {
1305 Q_ASSERT(d->initialized);
1310 qWarning(
"QOpenGLDebugLogger::initialize(): cannot initialize the object while logging. Please stop the logging first.");
1315 disconnect(d->context, SIGNAL(aboutToBeDestroyed()),
this, SLOT(_q_contextAboutToBeDestroyed()));
1317 d->initialized =
false;
1318 d->context =
nullptr;
1320 if (!context->hasExtension(QByteArrayLiteral(
"GL_KHR_debug")))
1323 d->context = context;
1324 connect(d->context, SIGNAL(aboutToBeDestroyed()),
this, SLOT(_q_contextAboutToBeDestroyed()));
1326#define GET_DEBUG_PROC_ADDRESS(procName)
1327 d->procName = reinterpret_cast< qt_ ## procName ## _t >(
1328 d->context->getProcAddress(d->context->isOpenGLES() ? (#procName "KHR") : (#procName))
1339#undef GET_DEBUG_PROC_ADDRESS
1344 if (!d->context->format().testOption(QSurfaceFormat::DebugContext)) {
1345 qWarning(
"QOpenGLDebugLogger::initialize(): the current context is not a debug context:\n"
1346 " this means that the GL may not generate any debug output at all.\n"
1347 " To avoid this warning, try creating the context with the\n"
1348 " QSurfaceFormat::DebugContext surface format option.");
1352 d->initialized =
true;
1357
1358
1359
1360
1361bool QOpenGLDebugLogger::isLogging()
const
1363 Q_D(
const QOpenGLDebugLogger);
1364 return d->isLogging;
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389void QOpenGLDebugLogger::startLogging(QOpenGLDebugLogger::LoggingMode loggingMode)
1391 Q_D(QOpenGLDebugLogger);
1392 if (!d->initialized) {
1393 qWarning(
"QOpenGLDebugLogger::startLogging(): object must be initialized before logging can start");
1397 qWarning(
"QOpenGLDebugLogger::startLogging(): this object is already logging");
1401 d->isLogging =
true;
1402 d->loggingMode = loggingMode;
1407 d->glDebugMessageCallback(&qt_opengl_debug_callback, d);
1409 QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
1413 if (d->loggingMode == SynchronousLogging)
1422
1423
1424
1425
1426QOpenGLDebugLogger::LoggingMode QOpenGLDebugLogger::loggingMode()
const
1428 Q_D(
const QOpenGLDebugLogger);
1429 return d->loggingMode;
1433
1434
1435
1436
1437void QOpenGLDebugLogger::stopLogging()
1439 Q_D(QOpenGLDebugLogger);
1443 QOpenGLContext *currentContext = QOpenGLContext::currentContext();
1444 if (!currentContext || currentContext != d->context) {
1445 qWarning(
"QOpenGLDebugLogger::stopLogging(): attempting to stop logging with the wrong OpenGL context current");
1449 d->isLogging =
false;
1451 d->glDebugMessageCallback(d->oldDebugCallbackFunction, d->oldDebugCallbackParameter);
1453 QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
1454 if (!d->debugWasEnabled)
1457 if (d->syncDebugWasEnabled)
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476void QOpenGLDebugLogger::logMessage(
const QOpenGLDebugMessage &debugMessage)
1478 Q_D(QOpenGLDebugLogger);
1479 if (!d->initialized) {
1480 qWarning(
"QOpenGLDebugLogger::logMessage(): object must be initialized before logging messages");
1483 if (debugMessage.source() != QOpenGLDebugMessage::ApplicationSource
1484 && debugMessage.source() != QOpenGLDebugMessage::ThirdPartySource) {
1485 qWarning(
"QOpenGLDebugLogger::logMessage(): using a message source different from ApplicationSource\n"
1486 " or ThirdPartySource is not supported by GL_KHR_debug. The message will not be logged.");
1489 if (debugMessage.type() == QOpenGLDebugMessage::InvalidType
1490 || debugMessage.type() == QOpenGLDebugMessage::AnyType
1491 || debugMessage.severity() == QOpenGLDebugMessage::InvalidSeverity
1492 || debugMessage.severity() == QOpenGLDebugMessage::AnySeverity) {
1493 qWarning(
"QOpenGLDebugLogger::logMessage(): the message has a non-valid type and/or severity. The message will not be logged.");
1497 const GLenum source = qt_messageSourceToGL(debugMessage.source());
1498 const GLenum type = qt_messageTypeToGL(debugMessage.type());
1499 const GLenum severity = qt_messageSeverityToGL(debugMessage.severity());
1500 QByteArray rawMessage = debugMessage.message().toUtf8();
1501 rawMessage.append(
'\0');
1503 if (rawMessage.size() > d->maxMessageLength) {
1504 qWarning(
"QOpenGLDebugLogger::logMessage(): message too long, truncating it\n"
1505 " (%d bytes long, but the GL accepts up to %d bytes)",
int(rawMessage.size()), d->maxMessageLength);
1506 rawMessage.resize(d->maxMessageLength - 1);
1507 rawMessage.append(
'\0');
1513 d->glDebugMessageInsert(source,
1518 rawMessage.constData());
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539void QOpenGLDebugLogger::pushGroup(
const QString &name, GLuint id, QOpenGLDebugMessage::Source source)
1541 Q_D(QOpenGLDebugLogger);
1542 if (!d->initialized) {
1543 qWarning(
"QOpenGLDebugLogger::pushGroup(): object must be initialized before pushing a debug group");
1546 if (source != QOpenGLDebugMessage::ApplicationSource
1547 && source != QOpenGLDebugMessage::ThirdPartySource) {
1548 qWarning(
"QOpenGLDebugLogger::pushGroup(): using a source different from ApplicationSource\n"
1549 " or ThirdPartySource is not supported by GL_KHR_debug. The group will not be pushed.");
1553 QByteArray rawName = name.toUtf8();
1554 rawName.append(
'\0');
1555 if (rawName.size() > d->maxMessageLength) {
1556 qWarning(
"QOpenGLDebugLogger::pushGroup(): group name too long, truncating it\n"
1557 " (%d bytes long, but the GL accepts up to %d bytes)",
int(rawName.size()), d->maxMessageLength);
1558 rawName.resize(d->maxMessageLength - 1);
1559 rawName.append(
'\0');
1565 d->glPushDebugGroup(qt_messageSourceToGL(source), id, -1, rawName.constData());
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582void QOpenGLDebugLogger::popGroup()
1584 Q_D(QOpenGLDebugLogger);
1585 if (!d->initialized) {
1586 qWarning(
"QOpenGLDebugLogger::pushGroup(): object must be initialized before popping a debug group");
1590 d->glPopDebugGroup();
1594
1595
1596
1597
1598
1599
1600
1601void QOpenGLDebugLogger::enableMessages(QOpenGLDebugMessage::Sources sources,
1602 QOpenGLDebugMessage::Types types,
1603 QOpenGLDebugMessage::Severities severities)
1605 Q_D(QOpenGLDebugLogger);
1606 d->controlDebugMessages(sources, types, severities, QList<GLuint>(),
1607 QByteArrayLiteral(
"enableMessages"),
true);
1611
1612
1613
1614
1615
1616
1617
1618void QOpenGLDebugLogger::enableMessages(
const QList<GLuint> &ids,
1619 QOpenGLDebugMessage::Sources sources,
1620 QOpenGLDebugMessage::Types types)
1622 Q_D(QOpenGLDebugLogger);
1623 d->controlDebugMessages(sources,
1625 QOpenGLDebugMessage::AnySeverity,
1627 QByteArrayLiteral(
"enableMessages"),
1632
1633
1634
1635
1636
1637
1638
1639void QOpenGLDebugLogger::disableMessages(QOpenGLDebugMessage::Sources sources,
1640 QOpenGLDebugMessage::Types types,
1641 QOpenGLDebugMessage::Severities severities)
1643 Q_D(QOpenGLDebugLogger);
1644 d->controlDebugMessages(sources, types, severities, QList<GLuint>(),
1645 QByteArrayLiteral(
"disableMessages"),
false);
1649
1650
1651
1652
1653
1654
1655
1656void QOpenGLDebugLogger::disableMessages(
const QList<GLuint> &ids,
1657 QOpenGLDebugMessage::Sources sources,
1658 QOpenGLDebugMessage::Types types)
1660 Q_D(QOpenGLDebugLogger);
1661 d->controlDebugMessages(sources,
1663 QOpenGLDebugMessage::AnySeverity,
1665 QByteArrayLiteral(
"disableMessages"),
1670
1671
1672
1673
1674
1675
1676
1677QList<QOpenGLDebugMessage> QOpenGLDebugLogger::loggedMessages()
const
1679 Q_D(
const QOpenGLDebugLogger);
1680 if (!d->initialized) {
1681 qWarning(
"QOpenGLDebugLogger::loggedMessages(): object must be initialized before reading logged messages");
1682 return QList<QOpenGLDebugMessage>();
1685 static const GLuint maxMessageCount = 128;
1686 GLuint messagesRead;
1687 GLenum messageSources[maxMessageCount];
1688 GLenum messageTypes[maxMessageCount];
1689 GLuint messageIds[maxMessageCount];
1690 GLenum messageSeverities[maxMessageCount];
1691 GLsizei messageLengths[maxMessageCount];
1693 QByteArray messagesBuffer;
1694 messagesBuffer.resize(maxMessageCount * d->maxMessageLength);
1696 QList<QOpenGLDebugMessage> messages;
1698 messagesRead = d->glGetDebugMessageLog(maxMessageCount,
1699 GLsizei(messagesBuffer.size()),
1705 messagesBuffer.data());
1707 const char *messagesBufferPtr = messagesBuffer.constData();
1708 for (GLuint i = 0; i < messagesRead; ++i) {
1709 QOpenGLDebugMessage message;
1711 QOpenGLDebugMessagePrivate *messagePrivate = message.d.data();
1712 messagePrivate->source = qt_messageSourceFromGL(messageSources[i]);
1713 messagePrivate->type = qt_messageTypeFromGL(messageTypes[i]);
1714 messagePrivate->id = messageIds[i];
1715 messagePrivate->severity = qt_messageSeverityFromGL(messageSeverities[i]);
1716 messagePrivate->message = QString::fromUtf8(messagesBufferPtr, messageLengths[i] - 1);
1718 messagesBufferPtr += messageLengths[i];
1719 messages << message;
1721 }
while (messagesRead == maxMessageCount);
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764qint64 QOpenGLDebugLogger::maximumMessageLength()
const
1766 Q_D(
const QOpenGLDebugLogger);
1767 if (!d->initialized) {
1768 qWarning(
"QOpenGLDebugLogger::maximumMessageLength(): object must be initialized before reading the maximum message length");
1771 return d->maxMessageLength;
1777#include "moc_qopengldebug.cpp"
QOpenGLDebugMessagePrivate()
The QOpenGLDebugMessage class wraps an OpenGL debug message.
static GLenum qt_messageTypeToGL(QOpenGLDebugMessage::Type type)
static QOpenGLDebugMessage::Severity qt_messageSeverityFromGL(GLenum severity)
static QOpenGLDebugMessage::Type qt_messageTypeFromGL(GLenum type)
static GLenum qt_messageSourceToGL(QOpenGLDebugMessage::Source source)
static GLenum qt_messageSeverityToGL(QOpenGLDebugMessage::Severity severity)
static QString qt_messageTypeToString(QOpenGLDebugMessage::Type type)
#define CONVERT_TO_GL_DEBUG_MESSAGE_CONTROL_PARAMETERS(type, source, target)
#define GET_DEBUG_PROC_ADDRESS(procName)
static QString qt_messageSourceToString(QOpenGLDebugMessage::Source source)
static QOpenGLDebugMessage::Source qt_messageSourceFromGL(GLenum source)
static QString qt_messageSeverityToString(QOpenGLDebugMessage::Severity severity)
#define GL_DEBUG_TYPE_MARKER
#define GL_DEBUG_SEVERITY_LOW
#define GL_DEBUG_SOURCE_THIRD_PARTY
#define GL_DEBUG_TYPE_PORTABILITY
#define GL_DEBUG_TYPE_OTHER
#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR
#define GL_MAX_DEBUG_MESSAGE_LENGTH
#define GL_DEBUG_TYPE_PUSH_GROUP
#define GL_DEBUG_SOURCE_APPLICATION
#define GL_DEBUG_SOURCE_OTHER
#define GL_DEBUG_SEVERITY_MEDIUM
#define GL_DEBUG_SOURCE_SHADER_COMPILER
#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR
#define GL_DEBUG_SEVERITY_NOTIFICATION
#define GL_DEBUG_TYPE_POP_GROUP
#define GL_DEBUG_SOURCE_WINDOW_SYSTEM
#define GL_DEBUG_SOURCE_API
#define GL_DEBUG_CALLBACK_USER_PARAM
#define GL_DEBUG_TYPE_ERROR
#define GL_DEBUG_CALLBACK_FUNCTION
#define GL_DEBUG_SEVERITY_HIGH
#define GL_DEBUG_OUTPUT_SYNCHRONOUS
#define GL_DEBUG_TYPE_PERFORMANCE