5#include <QtCore/private/qobject_p.h>
6#include <QtCore/qglobal.h>
7#include <QtCore/qvarlengtharray.h>
8#include <QtGui/qopengl.h>
9#include <QtGui/qopenglfunctions.h>
10#include <QtGui/qoffscreensurface.h>
16QT_IMPL_METATYPE_EXTERN(QOpenGLDebugMessage)
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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
236
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
271
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
315
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
345
346
347
348
349
350
351
352
353
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
387#if defined(GL_KHR_debug) && defined(GL_DEBUG_SOURCE_API_KHR)
388#define USE_MANUAL_DEFS
397#define GL_KHR_debug 1
398#define USE_MANUAL_DEFS
403#ifndef GL_DEBUG_OUTPUT_SYNCHRONOUS
404#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
406#ifndef GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH
407#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
409#ifndef GL_DEBUG_CALLBACK_FUNCTION
410#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
412#ifndef GL_DEBUG_CALLBACK_USER_PARAM
413#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
415#ifndef GL_DEBUG_SOURCE_API
416#define GL_DEBUG_SOURCE_API 0x8246
418#ifndef GL_DEBUG_SOURCE_WINDOW_SYSTEM
419#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
421#ifndef GL_DEBUG_SOURCE_SHADER_COMPILER
422#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
424#ifndef GL_DEBUG_SOURCE_THIRD_PARTY
425#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
427#ifndef GL_DEBUG_SOURCE_APPLICATION
428#define GL_DEBUG_SOURCE_APPLICATION 0x824A
430#ifndef GL_DEBUG_SOURCE_OTHER
431#define GL_DEBUG_SOURCE_OTHER 0x824B
433#ifndef GL_DEBUG_TYPE_ERROR
434#define GL_DEBUG_TYPE_ERROR 0x824C
436#ifndef GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR
437#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
439#ifndef GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR
440#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
442#ifndef GL_DEBUG_TYPE_PORTABILITY
443#define GL_DEBUG_TYPE_PORTABILITY 0x824F
445#ifndef GL_DEBUG_TYPE_PERFORMANCE
446#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
448#ifndef GL_DEBUG_TYPE_OTHER
449#define GL_DEBUG_TYPE_OTHER 0x8251
451#ifndef GL_DEBUG_TYPE_MARKER
452#define GL_DEBUG_TYPE_MARKER 0x8268
454#ifndef GL_DEBUG_TYPE_PUSH_GROUP
455#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
457#ifndef GL_DEBUG_TYPE_POP_GROUP
458#define GL_DEBUG_TYPE_POP_GROUP 0x826A
460#ifndef GL_DEBUG_SEVERITY_NOTIFICATION
461#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
463#ifndef GL_MAX_DEBUG_GROUP_STACK_DEPTH
464#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
466#ifndef GL_DEBUG_GROUP_STACK_DEPTH
467#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
470#define GL_BUFFER 0x82E0
473#define GL_SHADER 0x82E1
476#define GL_PROGRAM 0x82E2
479#define GL_QUERY 0x82E3
481#ifndef GL_PROGRAM_PIPELINE
482#define GL_PROGRAM_PIPELINE 0x82E4
485#define GL_SAMPLER 0x82E6
487#ifndef GL_DISPLAY_LIST
488#define GL_DISPLAY_LIST 0x82E7
490#ifndef GL_MAX_LABEL_LENGTH
491#define GL_MAX_LABEL_LENGTH 0x82E8
493#ifndef GL_MAX_DEBUG_MESSAGE_LENGTH
494#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
496#ifndef GL_MAX_DEBUG_LOGGED_MESSAGES
497#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
499#ifndef GL_DEBUG_LOGGED_MESSAGES
500#define GL_DEBUG_LOGGED_MESSAGES 0x9145
502#ifndef GL_DEBUG_SEVERITY_HIGH
503#define GL_DEBUG_SEVERITY_HIGH 0x9146
505#ifndef GL_DEBUG_SEVERITY_MEDIUM
506#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
508#ifndef GL_DEBUG_SEVERITY_LOW
509#define GL_DEBUG_SEVERITY_LOW 0x9148
511#ifndef GL_DEBUG_OUTPUT
512#define GL_DEBUG_OUTPUT 0x92E0
514#ifndef GL_CONTEXT_FLAG_DEBUG_BIT
515#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
517#ifndef GL_STACK_OVERFLOW
518#define GL_STACK_OVERFLOW 0x0503
520#ifndef GL_STACK_UNDERFLOW
521#define GL_STACK_UNDERFLOW 0x0504
524typedef void (QOPENGLF_APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,
const GLchar *message,
const GLvoid *userParam);
530
531
536 return QOpenGLDebugMessage::APISource;
538 return QOpenGLDebugMessage::WindowSystemSource;
540 return QOpenGLDebugMessage::ShaderCompilerSource;
542 return QOpenGLDebugMessage::ThirdPartySource;
544 return QOpenGLDebugMessage::ApplicationSource;
546 return QOpenGLDebugMessage::OtherSource;
549 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown message source from GL");
550 return QOpenGLDebugMessage::OtherSource;
554
555
559 case QOpenGLDebugMessage::InvalidSource:
561 case QOpenGLDebugMessage::APISource:
563 case QOpenGLDebugMessage::WindowSystemSource:
565 case QOpenGLDebugMessage::ShaderCompilerSource:
567 case QOpenGLDebugMessage::ThirdPartySource:
569 case QOpenGLDebugMessage::ApplicationSource:
571 case QOpenGLDebugMessage::OtherSource:
573 case QOpenGLDebugMessage::AnySource:
577 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Invalid message source");
582
583
587 case QOpenGLDebugMessage::InvalidSource:
588 return QStringLiteral(
"InvalidSource");
589 case QOpenGLDebugMessage::APISource:
590 return QStringLiteral(
"APISource");
591 case QOpenGLDebugMessage::WindowSystemSource:
592 return QStringLiteral(
"WindowSystemSource");
593 case QOpenGLDebugMessage::ShaderCompilerSource:
594 return QStringLiteral(
"ShaderCompilerSource");
595 case QOpenGLDebugMessage::ThirdPartySource:
596 return QStringLiteral(
"ThirdPartySource");
597 case QOpenGLDebugMessage::ApplicationSource:
598 return QStringLiteral(
"ApplicationSource");
599 case QOpenGLDebugMessage::OtherSource:
600 return QStringLiteral(
"OtherSource");
601 case QOpenGLDebugMessage::AnySource:
602 return QStringLiteral(
"AnySource");
605 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown message source");
610
611
616 return QOpenGLDebugMessage::ErrorType;
618 return QOpenGLDebugMessage::DeprecatedBehaviorType;
620 return QOpenGLDebugMessage::UndefinedBehaviorType;
622 return QOpenGLDebugMessage::PortabilityType;
624 return QOpenGLDebugMessage::PerformanceType;
626 return QOpenGLDebugMessage::OtherType;
628 return QOpenGLDebugMessage::MarkerType;
630 return QOpenGLDebugMessage::GroupPushType;
632 return QOpenGLDebugMessage::GroupPopType;
635 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown message type from GL");
636 return QOpenGLDebugMessage::OtherType;
640
641
645 case QOpenGLDebugMessage::InvalidType:
647 case QOpenGLDebugMessage::ErrorType:
649 case QOpenGLDebugMessage::DeprecatedBehaviorType:
651 case QOpenGLDebugMessage::UndefinedBehaviorType:
653 case QOpenGLDebugMessage::PortabilityType:
655 case QOpenGLDebugMessage::PerformanceType:
657 case QOpenGLDebugMessage::OtherType:
659 case QOpenGLDebugMessage::MarkerType:
661 case QOpenGLDebugMessage::GroupPushType:
663 case QOpenGLDebugMessage::GroupPopType:
665 case QOpenGLDebugMessage::AnyType:
669 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Invalid message type");
674
675
679 case QOpenGLDebugMessage::InvalidType:
680 return QStringLiteral(
"InvalidType");
681 case QOpenGLDebugMessage::ErrorType:
682 return QStringLiteral(
"ErrorType");
683 case QOpenGLDebugMessage::DeprecatedBehaviorType:
684 return QStringLiteral(
"DeprecatedBehaviorType");
685 case QOpenGLDebugMessage::UndefinedBehaviorType:
686 return QStringLiteral(
"UndefinedBehaviorType");
687 case QOpenGLDebugMessage::PortabilityType:
688 return QStringLiteral(
"PortabilityType");
689 case QOpenGLDebugMessage::PerformanceType:
690 return QStringLiteral(
"PerformanceType");
691 case QOpenGLDebugMessage::OtherType:
692 return QStringLiteral(
"OtherType");
693 case QOpenGLDebugMessage::MarkerType:
694 return QStringLiteral(
"MarkerType");
695 case QOpenGLDebugMessage::GroupPushType:
696 return QStringLiteral(
"GroupPushType");
697 case QOpenGLDebugMessage::GroupPopType:
698 return QStringLiteral(
"GroupPopType");
699 case QOpenGLDebugMessage::AnyType:
700 return QStringLiteral(
"AnyType");
703 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown message type");
708
709
714 return QOpenGLDebugMessage::HighSeverity;
716 return QOpenGLDebugMessage::MediumSeverity;
718 return QOpenGLDebugMessage::LowSeverity;
720 return QOpenGLDebugMessage::NotificationSeverity;
723 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown message severity from GL");
724 return QOpenGLDebugMessage::NotificationSeverity;
728
729
733 case QOpenGLDebugMessage::InvalidSeverity:
735 case QOpenGLDebugMessage::HighSeverity:
737 case QOpenGLDebugMessage::MediumSeverity:
739 case QOpenGLDebugMessage::LowSeverity:
741 case QOpenGLDebugMessage::NotificationSeverity:
743 case QOpenGLDebugMessage::AnySeverity:
747 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Invalid message severity");
752
753
757 case QOpenGLDebugMessage::InvalidSeverity:
758 return QStringLiteral(
"InvalidSeverity");
759 case QOpenGLDebugMessage::HighSeverity:
760 return QStringLiteral(
"HighSeverity");
761 case QOpenGLDebugMessage::MediumSeverity:
762 return QStringLiteral(
"MediumSeverity");
763 case QOpenGLDebugMessage::LowSeverity:
764 return QStringLiteral(
"LowSeverity");
765 case QOpenGLDebugMessage::NotificationSeverity:
766 return QStringLiteral(
"NotificationSeverity");
767 case QOpenGLDebugMessage::AnySeverity:
768 return QStringLiteral(
"AnySeverity");
771 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown message severity");
788
789
801
802
803
804
805
806
807
808
809
810
811QOpenGLDebugMessage::QOpenGLDebugMessage()
812 : d(
new QOpenGLDebugMessagePrivate)
817
818
819
820
821QOpenGLDebugMessage::QOpenGLDebugMessage(
const QOpenGLDebugMessage &debugMessage)
827
828
829QOpenGLDebugMessage::~QOpenGLDebugMessage()
834
835
836
837QOpenGLDebugMessage &QOpenGLDebugMessage::operator=(
const QOpenGLDebugMessage &debugMessage)
844
845
846
847
850
851
852
855
856
857QOpenGLDebugMessage::Source QOpenGLDebugMessage::source()
const
863
864
865QOpenGLDebugMessage::Type QOpenGLDebugMessage::type()
const
871
872
873QOpenGLDebugMessage::Severity QOpenGLDebugMessage::severity()
const
879
880
881GLuint QOpenGLDebugMessage::id()
const
887
888
889QString QOpenGLDebugMessage::message()
const
895
896
897
898
899
900
901QOpenGLDebugMessage QOpenGLDebugMessage::createApplicationMessage(
const QString &text,
903 QOpenGLDebugMessage::Severity severity,
904 QOpenGLDebugMessage::Type type)
906 QOpenGLDebugMessage m;
909 m.d->severity = severity;
911 m.d->source = ApplicationSource;
916
917
918
919
920
921
922QOpenGLDebugMessage QOpenGLDebugMessage::createThirdPartyMessage(
const QString &text,
924 QOpenGLDebugMessage::Severity severity,
925 QOpenGLDebugMessage::Type type)
927 QOpenGLDebugMessage m;
930 m.d->severity = severity;
932 m.d->source = ThirdPartySource;
937
938
939
940
941
942
943bool QOpenGLDebugMessage::operator==(
const QOpenGLDebugMessage &debugMessage)
const
945 return (d == debugMessage.d)
946 || (d->id == debugMessage.d->id
947 && d->source == debugMessage.d->source
948 && d->type == debugMessage.d->type
949 && d->severity == debugMessage.d->severity
950 && d->message == debugMessage.d->message);
954
955
956
957
958
959
960
962#ifndef QT_NO_DEBUG_STREAM
964
965
966
967
968
969QDebug operator<<(QDebug debug, QOpenGLDebugMessage::Source source)
971 QDebugStateSaver saver(debug);
972 debug.nospace() <<
"QOpenGLDebugMessage::Source("
973 << qt_messageSourceToString(source)
979
980
981
982
983
984QDebug operator<<(QDebug debug, QOpenGLDebugMessage::Type type)
986 QDebugStateSaver saver(debug);
987 debug.nospace() <<
"QOpenGLDebugMessage::Type("
988 << qt_messageTypeToString(type)
994
995
996
997
998
999QDebug operator<<(QDebug debug, QOpenGLDebugMessage::Severity severity)
1001 QDebugStateSaver saver(debug);
1002 debug.nospace() <<
"QOpenGLDebugMessage::Severity("
1003 << qt_messageSeverityToString(severity)
1009
1010
1011
1012
1013
1014QDebug operator<<(QDebug debug,
const QOpenGLDebugMessage &message)
1016 QDebugStateSaver saver(debug);
1017 debug.nospace() <<
"QOpenGLDebugMessage("
1018 << qt_messageSourceToString(message.source()) <<
", "
1019 << message.id() <<
", "
1020 << message.message() <<
", "
1021 << qt_messageSeverityToString(message.severity()) <<
", "
1022 << qt_messageTypeToString(message.type()) <<
')';
1028typedef void (QOPENGLF_APIENTRYP qt_glDebugMessageControl_t)(GLenum source, GLenum type, GLenum severity, GLsizei count,
const GLuint *ids, GLboolean enabled);
1029typedef void (QOPENGLF_APIENTRYP qt_glDebugMessageInsert_t)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar *buf);
1030typedef void (QOPENGLF_APIENTRYP qt_glDebugMessageCallback_t)(GLDEBUGPROC callback,
const void *userParam);
1031typedef GLuint (QOPENGLF_APIENTRYP qt_glGetDebugMessageLog_t)(GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
1032typedef void (QOPENGLF_APIENTRYP qt_glPushDebugGroup_t)(GLenum source, GLuint id, GLsizei length,
const GLchar *message);
1033typedef void (QOPENGLF_APIENTRYP qt_glPopDebugGroup_t)();
1034typedef void (QOPENGLF_APIENTRYP qt_glGetPointerv_t)(GLenum pname, GLvoid **params);
1036class QOpenGLDebugLoggerPrivate :
public QObjectPrivate
1038 Q_DECLARE_PUBLIC(QOpenGLDebugLogger)
1040 QOpenGLDebugLoggerPrivate();
1042 void handleMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar *rawMessage);
1043 void controlDebugMessages(QOpenGLDebugMessage::Sources sources,
1044 QOpenGLDebugMessage::Types types,
1045 QOpenGLDebugMessage::Severities severities,
const QList<GLuint> &ids,
1046 const QByteArray &callerName,
bool enable);
1047 void _q_contextAboutToBeDestroyed();
1049 qt_glDebugMessageControl_t glDebugMessageControl;
1050 qt_glDebugMessageInsert_t glDebugMessageInsert;
1051 qt_glDebugMessageCallback_t glDebugMessageCallback;
1052 qt_glGetDebugMessageLog_t glGetDebugMessageLog;
1053 qt_glPushDebugGroup_t glPushDebugGroup;
1054 qt_glPopDebugGroup_t glPopDebugGroup;
1055 qt_glGetPointerv_t glGetPointerv;
1057 GLDEBUGPROC oldDebugCallbackFunction;
1058 void *oldDebugCallbackParameter;
1059 QOpenGLContext *context;
1060 GLint maxMessageLength;
1061 QOpenGLDebugLogger::LoggingMode loggingMode;
1062 bool initialized : 1;
1064 bool debugWasEnabled : 1;
1065 bool syncDebugWasEnabled : 1;
1069
1070
1071QOpenGLDebugLoggerPrivate::QOpenGLDebugLoggerPrivate()
1072 : glDebugMessageControl(
nullptr),
1073 glDebugMessageInsert(
nullptr),
1074 glDebugMessageCallback(
nullptr),
1075 glGetDebugMessageLog(
nullptr),
1076 glPushDebugGroup(
nullptr),
1077 glPopDebugGroup(
nullptr),
1078 oldDebugCallbackFunction(
nullptr),
1080 maxMessageLength(0),
1081 loggingMode(QOpenGLDebugLogger::AsynchronousLogging),
1084 debugWasEnabled(
false),
1085 syncDebugWasEnabled(
false)
1090
1091
1092void QOpenGLDebugLoggerPrivate::handleMessage(GLenum source,
1097 const GLchar *rawMessage)
1099 if (oldDebugCallbackFunction)
1100 oldDebugCallbackFunction(source, type, id, severity, length, rawMessage, oldDebugCallbackParameter);
1105 messagePrivate->source = qt_messageSourceFromGL(source);
1106 messagePrivate->type = qt_messageTypeFromGL(type);
1107 messagePrivate->id = id;
1108 messagePrivate->severity = qt_messageSeverityFromGL(severity);
1111 messagePrivate->message = QString::fromUtf8(rawMessage);
1113 Q_Q(QOpenGLDebugLogger);
1114 emit q->messageLogged(message);
1118
1119
1120void QOpenGLDebugLoggerPrivate::controlDebugMessages(QOpenGLDebugMessage::Sources sources,
1121 QOpenGLDebugMessage::Types types,
1122 QOpenGLDebugMessage::Severities severities,
1123 const QList<GLuint> &ids,
1124 const QByteArray &callerName,
bool enable)
1127 qWarning(
"QOpenGLDebugLogger::%s(): object must be initialized before enabling/disabling messages", callerName.constData());
1130 if (sources == QOpenGLDebugMessage::InvalidSource) {
1131 qWarning(
"QOpenGLDebugLogger::%s(): invalid source specified", callerName.constData());
1134 if (types == QOpenGLDebugMessage::InvalidType) {
1135 qWarning(
"QOpenGLDebugLogger::%s(): invalid type specified", callerName.constData());
1138 if (severities == QOpenGLDebugMessage::InvalidSeverity) {
1139 qWarning(
"QOpenGLDebugLogger::%s(): invalid severity specified", callerName.constData());
1143 QVarLengthArray<GLenum, 8> glSources;
1144 QVarLengthArray<GLenum, 8> glTypes;
1145 QVarLengthArray<GLenum, 8> glSeverities;
1147 if (ids.size() > 0) {
1148 Q_ASSERT(severities == QOpenGLDebugMessage::AnySeverity);
1161 if (sources == QOpenGLDebugMessage::AnySource) {
1162 sources = QOpenGLDebugMessage::InvalidSource;
1163 for (uint i = 1; i <= QOpenGLDebugMessage::LastSource; i = i << 1)
1164 sources |= QOpenGLDebugMessage::Source(i);
1167 if (types == QOpenGLDebugMessage::AnyType) {
1168 types = QOpenGLDebugMessage::InvalidType;
1169 for (uint i = 1; i <= QOpenGLDebugMessage::LastType; i = i << 1)
1170 types |= QOpenGLDebugMessage::Type(i);
1174#define CONVERT_TO_GL_DEBUG_MESSAGE_CONTROL_PARAMETERS(type, source, target)
1175 if (source == QOpenGLDebugMessage::Any ## type) {
1176 target << GL_DONT_CARE;
1178 for (uint i = 1
; i <= QOpenGLDebugMessage::Last ## type; i = i << 1
)
1179 if (source.testFlag(QOpenGLDebugMessage:: type (i)))
1180 target << qt_message ## type ## ToGL (QOpenGLDebugMessage:: type (i));
1186#undef CONVERT_TO_GL_DEBUG_MESSAGE_CONTROL_PARAMETERS
1188 const GLsizei idCount = ids.size();
1191 const GLuint *
const idPtr = idCount ? ids.constData() :
nullptr;
1193 for (GLenum source : glSources)
1194 for (GLenum type : glTypes)
1195 for (GLenum severity : glSeverities)
1196 glDebugMessageControl(source, type, severity, idCount, idPtr, GLboolean(enable));
1200
1201
1202void QOpenGLDebugLoggerPrivate::_q_contextAboutToBeDestroyed()
1209 QOpenGLContext *currentContext = QOpenGLContext::currentContext();
1210 QSurface *currentSurface =
nullptr;
1212 QScopedPointer<QOffscreenSurface> offscreenSurface;
1214 if (context != currentContext) {
1217 currentSurface = currentContext->surface();
1219 offscreenSurface.reset(
new QOffscreenSurface);
1220 offscreenSurface->setFormat(context->format());
1221 offscreenSurface->create();
1222 if (!context->makeCurrent(offscreenSurface.data()))
1223 qWarning(
"QOpenGLDebugLoggerPrivate::_q_contextAboutToBeDestroyed(): could not make the owning GL context current for cleanup");
1226 Q_Q(QOpenGLDebugLogger);
1229 if (offscreenSurface) {
1232 currentContext->makeCurrent(currentSurface);
1234 context->doneCurrent();
1237 QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
1239 initialized =
false;
1243static void QOPENGLF_APIENTRY qt_opengl_debug_callback(GLenum source,
1248 const GLchar *rawMessage,
1249 const GLvoid *userParam)
1251 QOpenGLDebugLoggerPrivate *loggerPrivate =
static_cast<QOpenGLDebugLoggerPrivate *>(
const_cast<GLvoid *>(userParam));
1252 loggerPrivate->handleMessage(source, type, id, severity, length, rawMessage);
1257
1258
1259
1260
1261
1262
1263QOpenGLDebugLogger::QOpenGLDebugLogger(QObject *parent)
1264 : QObject(*
new QOpenGLDebugLoggerPrivate, parent)
1269 qRegisterMetaType<QOpenGLDebugMessage>();
1273
1274
1275QOpenGLDebugLogger::~QOpenGLDebugLogger()
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295bool QOpenGLDebugLogger::initialize()
1297 QOpenGLContext *context = QOpenGLContext::currentContext();
1299 qWarning(
"QOpenGLDebugLogger::initialize(): no current OpenGL context found.");
1303 Q_D(QOpenGLDebugLogger);
1304 if (d->context == context) {
1306 Q_ASSERT(d->initialized);
1311 qWarning(
"QOpenGLDebugLogger::initialize(): cannot initialize the object while logging. Please stop the logging first.");
1316 disconnect(d->context, SIGNAL(aboutToBeDestroyed()),
this, SLOT(_q_contextAboutToBeDestroyed()));
1318 d->initialized =
false;
1319 d->context =
nullptr;
1321 if (!context->hasExtension(QByteArrayLiteral(
"GL_KHR_debug")))
1324 d->context = context;
1325 connect(d->context, SIGNAL(aboutToBeDestroyed()),
this, SLOT(_q_contextAboutToBeDestroyed()));
1327#define GET_DEBUG_PROC_ADDRESS(procName)
1328 d->procName = reinterpret_cast< qt_ ## procName ## _t >(
1329 d->context->getProcAddress(d->context->isOpenGLES() ? (#procName "KHR") : (#procName))
1340#undef GET_DEBUG_PROC_ADDRESS
1345 if (!d->context->format().testOption(QSurfaceFormat::DebugContext)) {
1346 qWarning(
"QOpenGLDebugLogger::initialize(): the current context is not a debug context:\n"
1347 " this means that the GL may not generate any debug output at all.\n"
1348 " To avoid this warning, try creating the context with the\n"
1349 " QSurfaceFormat::DebugContext surface format option.");
1353 d->initialized =
true;
1358
1359
1360
1361
1362bool QOpenGLDebugLogger::isLogging()
const
1364 Q_D(
const QOpenGLDebugLogger);
1365 return d->isLogging;
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390void QOpenGLDebugLogger::startLogging(QOpenGLDebugLogger::LoggingMode loggingMode)
1392 Q_D(QOpenGLDebugLogger);
1393 if (!d->initialized) {
1394 qWarning(
"QOpenGLDebugLogger::startLogging(): object must be initialized before logging can start");
1398 qWarning(
"QOpenGLDebugLogger::startLogging(): this object is already logging");
1402 d->isLogging =
true;
1403 d->loggingMode = loggingMode;
1408 d->glDebugMessageCallback(&qt_opengl_debug_callback, d);
1410 QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
1414 if (d->loggingMode == SynchronousLogging)
1423
1424
1425
1426
1427QOpenGLDebugLogger::LoggingMode QOpenGLDebugLogger::loggingMode()
const
1429 Q_D(
const QOpenGLDebugLogger);
1430 return d->loggingMode;
1434
1435
1436
1437
1438void QOpenGLDebugLogger::stopLogging()
1440 Q_D(QOpenGLDebugLogger);
1444 QOpenGLContext *currentContext = QOpenGLContext::currentContext();
1445 if (!currentContext || currentContext != d->context) {
1446 qWarning(
"QOpenGLDebugLogger::stopLogging(): attempting to stop logging with the wrong OpenGL context current");
1450 d->isLogging =
false;
1452 d->glDebugMessageCallback(d->oldDebugCallbackFunction, d->oldDebugCallbackParameter);
1454 QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
1455 if (!d->debugWasEnabled)
1458 if (d->syncDebugWasEnabled)
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477void QOpenGLDebugLogger::logMessage(
const QOpenGLDebugMessage &debugMessage)
1479 Q_D(QOpenGLDebugLogger);
1480 if (!d->initialized) {
1481 qWarning(
"QOpenGLDebugLogger::logMessage(): object must be initialized before logging messages");
1484 if (debugMessage.source() != QOpenGLDebugMessage::ApplicationSource
1485 && debugMessage.source() != QOpenGLDebugMessage::ThirdPartySource) {
1486 qWarning(
"QOpenGLDebugLogger::logMessage(): using a message source different from ApplicationSource\n"
1487 " or ThirdPartySource is not supported by GL_KHR_debug. The message will not be logged.");
1490 if (debugMessage.type() == QOpenGLDebugMessage::InvalidType
1491 || debugMessage.type() == QOpenGLDebugMessage::AnyType
1492 || debugMessage.severity() == QOpenGLDebugMessage::InvalidSeverity
1493 || debugMessage.severity() == QOpenGLDebugMessage::AnySeverity) {
1494 qWarning(
"QOpenGLDebugLogger::logMessage(): the message has a non-valid type and/or severity. The message will not be logged.");
1498 const GLenum source = qt_messageSourceToGL(debugMessage.source());
1499 const GLenum type = qt_messageTypeToGL(debugMessage.type());
1500 const GLenum severity = qt_messageSeverityToGL(debugMessage.severity());
1501 QByteArray rawMessage = debugMessage.message().toUtf8();
1502 rawMessage.append(
'\0');
1504 if (rawMessage.size() > d->maxMessageLength) {
1505 qWarning(
"QOpenGLDebugLogger::logMessage(): message too long, truncating it\n"
1506 " (%d bytes long, but the GL accepts up to %d bytes)",
int(rawMessage.size()), d->maxMessageLength);
1507 rawMessage.resize(d->maxMessageLength - 1);
1508 rawMessage.append(
'\0');
1514 d->glDebugMessageInsert(source,
1519 rawMessage.constData());
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540void QOpenGLDebugLogger::pushGroup(
const QString &name, GLuint id, QOpenGLDebugMessage::Source source)
1542 Q_D(QOpenGLDebugLogger);
1543 if (!d->initialized) {
1544 qWarning(
"QOpenGLDebugLogger::pushGroup(): object must be initialized before pushing a debug group");
1547 if (source != QOpenGLDebugMessage::ApplicationSource
1548 && source != QOpenGLDebugMessage::ThirdPartySource) {
1549 qWarning(
"QOpenGLDebugLogger::pushGroup(): using a source different from ApplicationSource\n"
1550 " or ThirdPartySource is not supported by GL_KHR_debug. The group will not be pushed.");
1554 QByteArray rawName = name.toUtf8();
1555 rawName.append(
'\0');
1556 if (rawName.size() > d->maxMessageLength) {
1557 qWarning(
"QOpenGLDebugLogger::pushGroup(): group name too long, truncating it\n"
1558 " (%d bytes long, but the GL accepts up to %d bytes)",
int(rawName.size()), d->maxMessageLength);
1559 rawName.resize(d->maxMessageLength - 1);
1560 rawName.append(
'\0');
1566 d->glPushDebugGroup(qt_messageSourceToGL(source), id, -1, rawName.constData());
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583void QOpenGLDebugLogger::popGroup()
1585 Q_D(QOpenGLDebugLogger);
1586 if (!d->initialized) {
1587 qWarning(
"QOpenGLDebugLogger::pushGroup(): object must be initialized before popping a debug group");
1591 d->glPopDebugGroup();
1595
1596
1597
1598
1599
1600
1601
1602void QOpenGLDebugLogger::enableMessages(QOpenGLDebugMessage::Sources sources,
1603 QOpenGLDebugMessage::Types types,
1604 QOpenGLDebugMessage::Severities severities)
1606 Q_D(QOpenGLDebugLogger);
1607 d->controlDebugMessages(sources, types, severities, QList<GLuint>(),
1608 QByteArrayLiteral(
"enableMessages"),
true);
1612
1613
1614
1615
1616
1617
1618
1619void QOpenGLDebugLogger::enableMessages(
const QList<GLuint> &ids,
1620 QOpenGLDebugMessage::Sources sources,
1621 QOpenGLDebugMessage::Types types)
1623 Q_D(QOpenGLDebugLogger);
1624 d->controlDebugMessages(sources,
1626 QOpenGLDebugMessage::AnySeverity,
1628 QByteArrayLiteral(
"enableMessages"),
1633
1634
1635
1636
1637
1638
1639
1640void QOpenGLDebugLogger::disableMessages(QOpenGLDebugMessage::Sources sources,
1641 QOpenGLDebugMessage::Types types,
1642 QOpenGLDebugMessage::Severities severities)
1644 Q_D(QOpenGLDebugLogger);
1645 d->controlDebugMessages(sources, types, severities, QList<GLuint>(),
1646 QByteArrayLiteral(
"disableMessages"),
false);
1650
1651
1652
1653
1654
1655
1656
1657void QOpenGLDebugLogger::disableMessages(
const QList<GLuint> &ids,
1658 QOpenGLDebugMessage::Sources sources,
1659 QOpenGLDebugMessage::Types types)
1661 Q_D(QOpenGLDebugLogger);
1662 d->controlDebugMessages(sources,
1664 QOpenGLDebugMessage::AnySeverity,
1666 QByteArrayLiteral(
"disableMessages"),
1671
1672
1673
1674
1675
1676
1677
1678QList<QOpenGLDebugMessage> QOpenGLDebugLogger::loggedMessages()
const
1680 Q_D(
const QOpenGLDebugLogger);
1681 if (!d->initialized) {
1682 qWarning(
"QOpenGLDebugLogger::loggedMessages(): object must be initialized before reading logged messages");
1683 return QList<QOpenGLDebugMessage>();
1686 static const GLuint maxMessageCount = 128;
1687 GLuint messagesRead;
1688 GLenum messageSources[maxMessageCount];
1689 GLenum messageTypes[maxMessageCount];
1690 GLuint messageIds[maxMessageCount];
1691 GLenum messageSeverities[maxMessageCount];
1692 GLsizei messageLengths[maxMessageCount];
1694 QByteArray messagesBuffer;
1695 messagesBuffer.resize(maxMessageCount * d->maxMessageLength);
1697 QList<QOpenGLDebugMessage> messages;
1699 messagesRead = d->glGetDebugMessageLog(maxMessageCount,
1700 GLsizei(messagesBuffer.size()),
1706 messagesBuffer.data());
1708 const char *messagesBufferPtr = messagesBuffer.constData();
1709 for (GLuint i = 0; i < messagesRead; ++i) {
1710 QOpenGLDebugMessage message;
1712 QOpenGLDebugMessagePrivate *messagePrivate = message.d.data();
1713 messagePrivate->source = qt_messageSourceFromGL(messageSources[i]);
1714 messagePrivate->type = qt_messageTypeFromGL(messageTypes[i]);
1715 messagePrivate->id = messageIds[i];
1716 messagePrivate->severity = qt_messageSeverityFromGL(messageSeverities[i]);
1717 messagePrivate->message = QString::fromUtf8(messagesBufferPtr, messageLengths[i] - 1);
1719 messagesBufferPtr += messageLengths[i];
1720 messages << message;
1722 }
while (messagesRead == maxMessageCount);
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765qint64 QOpenGLDebugLogger::maximumMessageLength()
const
1767 Q_D(
const QOpenGLDebugLogger);
1768 if (!d->initialized) {
1769 qWarning(
"QOpenGLDebugLogger::maximumMessageLength(): object must be initialized before reading the maximum message length");
1772 return d->maxMessageLength;
1778#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