1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Worker // Debug.h: Defines debug state used for GL_KHR_debug
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #ifndef LIBANGLE_DEBUG_H_
10*8975f5c5SAndroid Build Coastguard Worker #define LIBANGLE_DEBUG_H_
11*8975f5c5SAndroid Build Coastguard Worker
12*8975f5c5SAndroid Build Coastguard Worker #include "angle_gl.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "common/PackedEnums.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "common/SimpleMutex.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "common/angleutils.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/AttributeMap.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Error.h"
18*8975f5c5SAndroid Build Coastguard Worker
19*8975f5c5SAndroid Build Coastguard Worker #include <atomic>
20*8975f5c5SAndroid Build Coastguard Worker #include <deque>
21*8975f5c5SAndroid Build Coastguard Worker #include <string>
22*8975f5c5SAndroid Build Coastguard Worker #include <vector>
23*8975f5c5SAndroid Build Coastguard Worker
24*8975f5c5SAndroid Build Coastguard Worker namespace gl
25*8975f5c5SAndroid Build Coastguard Worker {
26*8975f5c5SAndroid Build Coastguard Worker class Context;
27*8975f5c5SAndroid Build Coastguard Worker
28*8975f5c5SAndroid Build Coastguard Worker class LabeledObject
29*8975f5c5SAndroid Build Coastguard Worker {
30*8975f5c5SAndroid Build Coastguard Worker public:
~LabeledObject()31*8975f5c5SAndroid Build Coastguard Worker virtual ~LabeledObject() {}
32*8975f5c5SAndroid Build Coastguard Worker virtual angle::Result setLabel(const Context *context, const std::string &label) = 0;
33*8975f5c5SAndroid Build Coastguard Worker virtual const std::string &getLabel() const = 0;
34*8975f5c5SAndroid Build Coastguard Worker };
35*8975f5c5SAndroid Build Coastguard Worker
36*8975f5c5SAndroid Build Coastguard Worker class Debug : angle::NonCopyable
37*8975f5c5SAndroid Build Coastguard Worker {
38*8975f5c5SAndroid Build Coastguard Worker public:
39*8975f5c5SAndroid Build Coastguard Worker Debug(bool initialDebugState);
40*8975f5c5SAndroid Build Coastguard Worker ~Debug();
41*8975f5c5SAndroid Build Coastguard Worker
42*8975f5c5SAndroid Build Coastguard Worker void setMaxLoggedMessages(GLuint maxLoggedMessages);
43*8975f5c5SAndroid Build Coastguard Worker
44*8975f5c5SAndroid Build Coastguard Worker void setOutputEnabled(bool enabled);
45*8975f5c5SAndroid Build Coastguard Worker bool isOutputEnabled() const;
46*8975f5c5SAndroid Build Coastguard Worker
47*8975f5c5SAndroid Build Coastguard Worker void setOutputSynchronous(bool synchronous);
48*8975f5c5SAndroid Build Coastguard Worker bool isOutputSynchronous() const;
49*8975f5c5SAndroid Build Coastguard Worker
50*8975f5c5SAndroid Build Coastguard Worker void setCallback(GLDEBUGPROCKHR callback, const void *userParam);
51*8975f5c5SAndroid Build Coastguard Worker GLDEBUGPROCKHR getCallback() const;
52*8975f5c5SAndroid Build Coastguard Worker const void *getUserParam() const;
53*8975f5c5SAndroid Build Coastguard Worker
54*8975f5c5SAndroid Build Coastguard Worker void insertMessage(GLenum source,
55*8975f5c5SAndroid Build Coastguard Worker GLenum type,
56*8975f5c5SAndroid Build Coastguard Worker GLuint id,
57*8975f5c5SAndroid Build Coastguard Worker GLenum severity,
58*8975f5c5SAndroid Build Coastguard Worker const std::string &message,
59*8975f5c5SAndroid Build Coastguard Worker gl::LogSeverity logSeverity,
60*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint) const;
61*8975f5c5SAndroid Build Coastguard Worker void insertMessage(GLenum source,
62*8975f5c5SAndroid Build Coastguard Worker GLenum type,
63*8975f5c5SAndroid Build Coastguard Worker GLuint id,
64*8975f5c5SAndroid Build Coastguard Worker GLenum severity,
65*8975f5c5SAndroid Build Coastguard Worker std::string &&message,
66*8975f5c5SAndroid Build Coastguard Worker gl::LogSeverity logSeverity,
67*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint) const;
68*8975f5c5SAndroid Build Coastguard Worker
69*8975f5c5SAndroid Build Coastguard Worker void setMessageControl(GLenum source,
70*8975f5c5SAndroid Build Coastguard Worker GLenum type,
71*8975f5c5SAndroid Build Coastguard Worker GLenum severity,
72*8975f5c5SAndroid Build Coastguard Worker std::vector<GLuint> &&ids,
73*8975f5c5SAndroid Build Coastguard Worker bool enabled);
74*8975f5c5SAndroid Build Coastguard Worker size_t getMessages(GLuint count,
75*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
76*8975f5c5SAndroid Build Coastguard Worker GLenum *sources,
77*8975f5c5SAndroid Build Coastguard Worker GLenum *types,
78*8975f5c5SAndroid Build Coastguard Worker GLuint *ids,
79*8975f5c5SAndroid Build Coastguard Worker GLenum *severities,
80*8975f5c5SAndroid Build Coastguard Worker GLsizei *lengths,
81*8975f5c5SAndroid Build Coastguard Worker GLchar *messageLog);
82*8975f5c5SAndroid Build Coastguard Worker size_t getNextMessageLength() const;
83*8975f5c5SAndroid Build Coastguard Worker size_t getMessageCount() const;
84*8975f5c5SAndroid Build Coastguard Worker
85*8975f5c5SAndroid Build Coastguard Worker void pushGroup(GLenum source, GLuint id, std::string &&message);
86*8975f5c5SAndroid Build Coastguard Worker void popGroup();
87*8975f5c5SAndroid Build Coastguard Worker size_t getGroupStackDepth() const;
88*8975f5c5SAndroid Build Coastguard Worker
89*8975f5c5SAndroid Build Coastguard Worker // Helper for ANGLE_PERF_WARNING
90*8975f5c5SAndroid Build Coastguard Worker void insertPerfWarning(GLenum severity, bool isLastRepeat, const char *message) const;
91*8975f5c5SAndroid Build Coastguard Worker
92*8975f5c5SAndroid Build Coastguard Worker private:
93*8975f5c5SAndroid Build Coastguard Worker bool isMessageEnabled(GLenum source, GLenum type, GLuint id, GLenum severity) const;
94*8975f5c5SAndroid Build Coastguard Worker
95*8975f5c5SAndroid Build Coastguard Worker void pushDefaultGroup();
96*8975f5c5SAndroid Build Coastguard Worker
97*8975f5c5SAndroid Build Coastguard Worker struct Message
98*8975f5c5SAndroid Build Coastguard Worker {
99*8975f5c5SAndroid Build Coastguard Worker GLenum source;
100*8975f5c5SAndroid Build Coastguard Worker GLenum type;
101*8975f5c5SAndroid Build Coastguard Worker GLuint id;
102*8975f5c5SAndroid Build Coastguard Worker GLenum severity;
103*8975f5c5SAndroid Build Coastguard Worker std::string message;
104*8975f5c5SAndroid Build Coastguard Worker };
105*8975f5c5SAndroid Build Coastguard Worker
106*8975f5c5SAndroid Build Coastguard Worker struct Control
107*8975f5c5SAndroid Build Coastguard Worker {
108*8975f5c5SAndroid Build Coastguard Worker Control();
109*8975f5c5SAndroid Build Coastguard Worker ~Control();
110*8975f5c5SAndroid Build Coastguard Worker Control(const Control &other);
111*8975f5c5SAndroid Build Coastguard Worker
112*8975f5c5SAndroid Build Coastguard Worker GLenum source;
113*8975f5c5SAndroid Build Coastguard Worker GLenum type;
114*8975f5c5SAndroid Build Coastguard Worker GLenum severity;
115*8975f5c5SAndroid Build Coastguard Worker std::vector<GLuint> ids;
116*8975f5c5SAndroid Build Coastguard Worker bool enabled;
117*8975f5c5SAndroid Build Coastguard Worker };
118*8975f5c5SAndroid Build Coastguard Worker
119*8975f5c5SAndroid Build Coastguard Worker struct Group
120*8975f5c5SAndroid Build Coastguard Worker {
121*8975f5c5SAndroid Build Coastguard Worker Group();
122*8975f5c5SAndroid Build Coastguard Worker ~Group();
123*8975f5c5SAndroid Build Coastguard Worker Group(const Group &other);
124*8975f5c5SAndroid Build Coastguard Worker
125*8975f5c5SAndroid Build Coastguard Worker GLenum source;
126*8975f5c5SAndroid Build Coastguard Worker GLuint id;
127*8975f5c5SAndroid Build Coastguard Worker std::string message;
128*8975f5c5SAndroid Build Coastguard Worker
129*8975f5c5SAndroid Build Coastguard Worker std::vector<Control> controls;
130*8975f5c5SAndroid Build Coastguard Worker };
131*8975f5c5SAndroid Build Coastguard Worker
132*8975f5c5SAndroid Build Coastguard Worker bool mOutputEnabled;
133*8975f5c5SAndroid Build Coastguard Worker mutable angle::SimpleMutex mMutex;
134*8975f5c5SAndroid Build Coastguard Worker GLDEBUGPROCKHR mCallbackFunction;
135*8975f5c5SAndroid Build Coastguard Worker const void *mCallbackUserParam;
136*8975f5c5SAndroid Build Coastguard Worker mutable std::deque<Message> mMessages;
137*8975f5c5SAndroid Build Coastguard Worker GLuint mMaxLoggedMessages;
138*8975f5c5SAndroid Build Coastguard Worker bool mOutputSynchronous;
139*8975f5c5SAndroid Build Coastguard Worker std::vector<Group> mGroups;
140*8975f5c5SAndroid Build Coastguard Worker };
141*8975f5c5SAndroid Build Coastguard Worker } // namespace gl
142*8975f5c5SAndroid Build Coastguard Worker
143*8975f5c5SAndroid Build Coastguard Worker namespace egl
144*8975f5c5SAndroid Build Coastguard Worker {
145*8975f5c5SAndroid Build Coastguard Worker class LabeledObject
146*8975f5c5SAndroid Build Coastguard Worker {
147*8975f5c5SAndroid Build Coastguard Worker public:
~LabeledObject()148*8975f5c5SAndroid Build Coastguard Worker virtual ~LabeledObject() {}
149*8975f5c5SAndroid Build Coastguard Worker virtual void setLabel(EGLLabelKHR label) = 0;
150*8975f5c5SAndroid Build Coastguard Worker virtual EGLLabelKHR getLabel() const = 0;
151*8975f5c5SAndroid Build Coastguard Worker };
152*8975f5c5SAndroid Build Coastguard Worker
153*8975f5c5SAndroid Build Coastguard Worker class Debug : angle::NonCopyable
154*8975f5c5SAndroid Build Coastguard Worker {
155*8975f5c5SAndroid Build Coastguard Worker public:
156*8975f5c5SAndroid Build Coastguard Worker Debug();
157*8975f5c5SAndroid Build Coastguard Worker
158*8975f5c5SAndroid Build Coastguard Worker void setCallback(EGLDEBUGPROCKHR callback, const AttributeMap &attribs);
159*8975f5c5SAndroid Build Coastguard Worker EGLDEBUGPROCKHR getCallback() const;
160*8975f5c5SAndroid Build Coastguard Worker bool isMessageTypeEnabled(MessageType type) const;
161*8975f5c5SAndroid Build Coastguard Worker
162*8975f5c5SAndroid Build Coastguard Worker void insertMessage(EGLenum error,
163*8975f5c5SAndroid Build Coastguard Worker const char *command,
164*8975f5c5SAndroid Build Coastguard Worker MessageType messageType,
165*8975f5c5SAndroid Build Coastguard Worker EGLLabelKHR threadLabel,
166*8975f5c5SAndroid Build Coastguard Worker EGLLabelKHR objectLabel,
167*8975f5c5SAndroid Build Coastguard Worker const std::string &message) const;
168*8975f5c5SAndroid Build Coastguard Worker
169*8975f5c5SAndroid Build Coastguard Worker private:
170*8975f5c5SAndroid Build Coastguard Worker EGLDEBUGPROCKHR mCallback;
171*8975f5c5SAndroid Build Coastguard Worker angle::PackedEnumBitSet<MessageType> mEnabledMessageTypes;
172*8975f5c5SAndroid Build Coastguard Worker };
173*8975f5c5SAndroid Build Coastguard Worker } // namespace egl
174*8975f5c5SAndroid Build Coastguard Worker
175*8975f5c5SAndroid Build Coastguard Worker namespace
176*8975f5c5SAndroid Build Coastguard Worker {
PerfCounterBelowMaxRepeat(std::atomic<uint32_t> * counter,bool * isLastRepeat)177*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE bool PerfCounterBelowMaxRepeat(std::atomic<uint32_t> *counter, bool *isLastRepeat)
178*8975f5c5SAndroid Build Coastguard Worker {
179*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kMaxPerfRepeat = 4;
180*8975f5c5SAndroid Build Coastguard Worker // Stop incrementing the counter after max value to avoid unnecessary cache effects
181*8975f5c5SAndroid Build Coastguard Worker if (counter->load(std::memory_order_relaxed) < kMaxPerfRepeat)
182*8975f5c5SAndroid Build Coastguard Worker {
183*8975f5c5SAndroid Build Coastguard Worker uint32_t count = counter->fetch_add(1, std::memory_order_relaxed);
184*8975f5c5SAndroid Build Coastguard Worker // Check not strictly necessary as worst case is an additional log, but is good practice.
185*8975f5c5SAndroid Build Coastguard Worker if (count < kMaxPerfRepeat)
186*8975f5c5SAndroid Build Coastguard Worker {
187*8975f5c5SAndroid Build Coastguard Worker if (count == kMaxPerfRepeat - 1)
188*8975f5c5SAndroid Build Coastguard Worker {
189*8975f5c5SAndroid Build Coastguard Worker *isLastRepeat = true;
190*8975f5c5SAndroid Build Coastguard Worker }
191*8975f5c5SAndroid Build Coastguard Worker return true;
192*8975f5c5SAndroid Build Coastguard Worker }
193*8975f5c5SAndroid Build Coastguard Worker }
194*8975f5c5SAndroid Build Coastguard Worker return false;
195*8975f5c5SAndroid Build Coastguard Worker }
196*8975f5c5SAndroid Build Coastguard Worker } // namespace
197*8975f5c5SAndroid Build Coastguard Worker
198*8975f5c5SAndroid Build Coastguard Worker // Generate a perf warning. Only outputs the same message a few times to avoid spamming the logs.
199*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_PERF_WARNING(debug, severity, ...) \
200*8975f5c5SAndroid Build Coastguard Worker do \
201*8975f5c5SAndroid Build Coastguard Worker { \
202*8975f5c5SAndroid Build Coastguard Worker static std::atomic<uint32_t> sRepeatCount = 0; \
203*8975f5c5SAndroid Build Coastguard Worker bool isLastRepeat = false; \
204*8975f5c5SAndroid Build Coastguard Worker if (PerfCounterBelowMaxRepeat(&sRepeatCount, &isLastRepeat)) \
205*8975f5c5SAndroid Build Coastguard Worker { \
206*8975f5c5SAndroid Build Coastguard Worker char ANGLE_MESSAGE[200]; \
207*8975f5c5SAndroid Build Coastguard Worker snprintf(ANGLE_MESSAGE, sizeof(ANGLE_MESSAGE), __VA_ARGS__); \
208*8975f5c5SAndroid Build Coastguard Worker (debug).insertPerfWarning(severity, isLastRepeat, ANGLE_MESSAGE); \
209*8975f5c5SAndroid Build Coastguard Worker } \
210*8975f5c5SAndroid Build Coastguard Worker } while (0)
211*8975f5c5SAndroid Build Coastguard Worker
212*8975f5c5SAndroid Build Coastguard Worker #endif // LIBANGLE_DEBUG_H_
213