1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QOPENGLDEBUG_H
41 #define QOPENGLDEBUG_H
42 
43 #include <QtGui/qtguiglobal.h>
44 
45 #ifndef QT_NO_OPENGL
46 
47 #include <QtCore/qshareddata.h>
48 #include <QtCore/qflags.h>
49 #include <QtCore/qlist.h>
50 #include <QtCore/qvector.h>
51 #include <QtCore/qmetatype.h>
52 #include <QtCore/qdebug.h>
53 #include <QtGui/qopenglcontext.h>
54 
55 #if defined(Q_CLANG_QDOC)
56 #undef GLuint
57 typedef unsigned int GLuint;
58 #endif
59 
60 QT_BEGIN_NAMESPACE
61 
62 class QOpenGLDebugLogger;
63 class QOpenGLDebugLoggerPrivate;
64 class QOpenGLDebugMessagePrivate;
65 
66 class Q_GUI_EXPORT QOpenGLDebugMessage
67 {
68 public:
69     enum Source {
70         InvalidSource        = 0x00000000,
71         APISource            = 0x00000001,
72         WindowSystemSource   = 0x00000002,
73         ShaderCompilerSource = 0x00000004,
74         ThirdPartySource     = 0x00000008,
75         ApplicationSource    = 0x00000010,
76         OtherSource          = 0x00000020,
77         LastSource           = OtherSource, // private API
78         AnySource            = 0xffffffff
79     };
80     Q_DECLARE_FLAGS(Sources, Source)
81 
82     enum Type {
83         InvalidType            = 0x00000000,
84         ErrorType              = 0x00000001,
85         DeprecatedBehaviorType = 0x00000002,
86         UndefinedBehaviorType  = 0x00000004,
87         PortabilityType        = 0x00000008,
88         PerformanceType        = 0x00000010,
89         OtherType              = 0x00000020,
90         MarkerType             = 0x00000040,
91         GroupPushType          = 0x00000080,
92         GroupPopType           = 0x00000100,
93         LastType               = GroupPopType, // private API
94         AnyType                = 0xffffffff
95     };
96     Q_DECLARE_FLAGS(Types, Type)
97 
98     enum Severity {
99         InvalidSeverity      = 0x00000000,
100         HighSeverity         = 0x00000001,
101         MediumSeverity       = 0x00000002,
102         LowSeverity          = 0x00000004,
103         NotificationSeverity = 0x00000008,
104         LastSeverity         = NotificationSeverity, // private API
105         AnySeverity          = 0xffffffff
106     };
107     Q_DECLARE_FLAGS(Severities, Severity)
108 
109     QOpenGLDebugMessage();
110     QOpenGLDebugMessage(const QOpenGLDebugMessage &debugMessage);
111 
112     QOpenGLDebugMessage &operator=(const QOpenGLDebugMessage &debugMessage);
113     QOpenGLDebugMessage &operator=(QOpenGLDebugMessage &&other) noexcept { swap(other); return *this; }
114     ~QOpenGLDebugMessage();
115 
swap(QOpenGLDebugMessage & other)116     void swap(QOpenGLDebugMessage &other) noexcept { qSwap(d, other.d); }
117 
118     Source source() const;
119     Type type() const;
120     Severity severity() const;
121     GLuint id() const;
122     QString message() const;
123 
124     static QOpenGLDebugMessage createApplicationMessage(const QString &text,
125                                                         GLuint id = 0,
126                                                         Severity severity = NotificationSeverity,
127                                                         Type type = OtherType);
128     static QOpenGLDebugMessage createThirdPartyMessage(const QString &text,
129                                                        GLuint id = 0,
130                                                        Severity severity = NotificationSeverity,
131                                                        Type type = OtherType);
132 
133     bool operator==(const QOpenGLDebugMessage &debugMessage) const;
134     inline bool operator!=(const QOpenGLDebugMessage &debugMessage) const { return !operator==(debugMessage); }
135 
136 private:
137     friend class QOpenGLDebugLogger;
138     friend class QOpenGLDebugLoggerPrivate;
139     QSharedDataPointer<QOpenGLDebugMessagePrivate> d;
140 };
141 
142 Q_DECLARE_SHARED(QOpenGLDebugMessage)
143 Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLDebugMessage::Sources)
144 Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLDebugMessage::Types)
145 Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLDebugMessage::Severities)
146 
147 #ifndef QT_NO_DEBUG_STREAM
148 Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QOpenGLDebugMessage &message);
149 Q_GUI_EXPORT QDebug operator<<(QDebug debug, QOpenGLDebugMessage::Source source);
150 Q_GUI_EXPORT QDebug operator<<(QDebug debug, QOpenGLDebugMessage::Type type);
151 Q_GUI_EXPORT QDebug operator<<(QDebug debug, QOpenGLDebugMessage::Severity severity);
152 #endif
153 
154 class QOpenGLDebugLoggerPrivate;
155 
156 class Q_GUI_EXPORT QOpenGLDebugLogger : public QObject
157 {
158     Q_OBJECT
159     Q_PROPERTY(LoggingMode loggingMode READ loggingMode)
160 
161 public:
162     enum LoggingMode {
163         AsynchronousLogging,
164         SynchronousLogging
165     };
166     Q_ENUM(LoggingMode)
167 
168     explicit QOpenGLDebugLogger(QObject *parent = nullptr);
169     ~QOpenGLDebugLogger();
170 
171     bool initialize();
172 
173     bool isLogging() const;
174     LoggingMode loggingMode() const;
175 
176     qint64 maximumMessageLength() const;
177 
178     void pushGroup(const QString &name,
179                    GLuint id = 0,
180                    QOpenGLDebugMessage::Source source = QOpenGLDebugMessage::ApplicationSource);
181     void popGroup();
182 
183     void enableMessages(QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource,
184                         QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType,
185                         QOpenGLDebugMessage::Severities severities = QOpenGLDebugMessage::AnySeverity);
186 
187     void enableMessages(const QVector<GLuint> &ids,
188                         QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource,
189                         QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType);
190 
191     void disableMessages(QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource,
192                          QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType,
193                          QOpenGLDebugMessage::Severities severities = QOpenGLDebugMessage::AnySeverity);
194 
195     void disableMessages(const QVector<GLuint> &ids,
196                          QOpenGLDebugMessage::Sources sources = QOpenGLDebugMessage::AnySource,
197                          QOpenGLDebugMessage::Types types = QOpenGLDebugMessage::AnyType);
198 
199     QList<QOpenGLDebugMessage> loggedMessages() const;
200 
201 public Q_SLOTS:
202     void logMessage(const QOpenGLDebugMessage &debugMessage);
203     void startLogging(LoggingMode loggingMode = AsynchronousLogging);
204     void stopLogging();
205 
206 Q_SIGNALS:
207     void messageLogged(const QOpenGLDebugMessage &debugMessage);
208 
209 private:
210     Q_DISABLE_COPY(QOpenGLDebugLogger)
211     Q_DECLARE_PRIVATE(QOpenGLDebugLogger)
212     Q_PRIVATE_SLOT(d_func(), void _q_contextAboutToBeDestroyed())
213 };
214 
215 QT_END_NAMESPACE
216 
217 Q_DECLARE_METATYPE(QOpenGLDebugMessage)
218 
219 #endif // QT_NO_OPENGL
220 
221 #endif // QOPENGLDEBUG_H
222