Line data Source code
1 : //
2 : // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3 : // Use of this source code is governed by a BSD-style license that can be
4 : // found in the LICENSE file.
5 : //
6 :
7 : // debug.cpp: Debugging utilities.
8 :
9 : #include "common/debug.h"
10 :
11 : #include <stdarg.h>
12 :
13 : #include <cstdio>
14 : #include <fstream>
15 : #include <iostream>
16 : #include <vector>
17 :
18 : #include "common/angleutils.h"
19 : #include "common/platform.h"
20 : #include "common/Optional.h"
21 :
22 : namespace gl
23 : {
24 :
25 : namespace
26 : {
27 :
28 0 : class FormattedString final : angle::NonCopyable
29 : {
30 : public:
31 0 : FormattedString(const char *format, va_list vararg) : mFormat(format)
32 : {
33 0 : va_copy(mVarArg, vararg);
34 0 : }
35 :
36 0 : const char *c_str() { return str().c_str(); }
37 :
38 0 : const std::string &str()
39 : {
40 0 : if (!mMessage.valid())
41 : {
42 0 : mMessage = FormatString(mFormat, mVarArg);
43 : }
44 0 : return mMessage.value();
45 : }
46 :
47 : size_t length()
48 : {
49 : c_str();
50 : return mMessage.value().length();
51 : }
52 :
53 : private:
54 : const char *mFormat;
55 : va_list mVarArg;
56 : Optional<std::string> mMessage;
57 : };
58 : enum DebugTraceOutputType
59 : {
60 : DebugTraceOutputTypeNone,
61 : DebugTraceOutputTypeSetMarker,
62 : DebugTraceOutputTypeBeginEvent
63 : };
64 :
65 : DebugAnnotator *g_debugAnnotator = nullptr;
66 :
67 0 : void output(bool traceInDebugOnly, MessageType messageType, DebugTraceOutputType outputType,
68 : const char *format, va_list vararg)
69 : {
70 0 : if (DebugAnnotationsActive())
71 : {
72 0 : static std::vector<char> buffer(512);
73 0 : size_t len = FormatStringIntoVector(format, vararg, buffer);
74 0 : std::wstring formattedWideMessage(buffer.begin(), buffer.begin() + len);
75 :
76 0 : ASSERT(g_debugAnnotator != nullptr);
77 0 : switch (outputType)
78 : {
79 : case DebugTraceOutputTypeNone:
80 0 : break;
81 : case DebugTraceOutputTypeBeginEvent:
82 0 : g_debugAnnotator->beginEvent(formattedWideMessage.c_str());
83 0 : break;
84 : case DebugTraceOutputTypeSetMarker:
85 0 : g_debugAnnotator->setMarker(formattedWideMessage.c_str());
86 0 : break;
87 : }
88 : }
89 :
90 0 : FormattedString formattedMessage(format, vararg);
91 :
92 0 : if (messageType == MESSAGE_ERR)
93 : {
94 0 : std::cerr << formattedMessage.c_str();
95 : #if !defined(NDEBUG) && defined(_MSC_VER)
96 : OutputDebugStringA(formattedMessage.c_str());
97 : #endif // !defined(NDEBUG) && defined(_MSC_VER)
98 : }
99 :
100 : #if defined(ANGLE_ENABLE_DEBUG_TRACE)
101 : #if defined(NDEBUG)
102 : if (traceInDebugOnly)
103 : {
104 : return;
105 : }
106 : #endif // NDEBUG
107 : static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
108 : if (file)
109 : {
110 : file.write(formattedMessage.c_str(), formattedMessage.length());
111 : file.flush();
112 : }
113 :
114 : #if defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
115 : OutputDebugStringA(formattedMessage.c_str());
116 : #endif // ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER
117 :
118 : #endif // ANGLE_ENABLE_DEBUG_TRACE
119 0 : }
120 :
121 : } // namespace
122 :
123 0 : bool DebugAnnotationsActive()
124 : {
125 : #if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
126 : return g_debugAnnotator != nullptr && g_debugAnnotator->getStatus();
127 : #else
128 0 : return false;
129 : #endif
130 : }
131 :
132 0 : void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator)
133 : {
134 0 : UninitializeDebugAnnotations();
135 0 : g_debugAnnotator = debugAnnotator;
136 0 : }
137 :
138 0 : void UninitializeDebugAnnotations()
139 : {
140 : // Pointer is not managed.
141 0 : g_debugAnnotator = nullptr;
142 0 : }
143 :
144 0 : void trace(bool traceInDebugOnly, MessageType messageType, const char *format, ...)
145 : {
146 : va_list vararg;
147 0 : va_start(vararg, format);
148 0 : output(traceInDebugOnly, messageType, DebugTraceOutputTypeSetMarker, format, vararg);
149 0 : va_end(vararg);
150 0 : }
151 :
152 0 : ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
153 : {
154 : #if !defined(ANGLE_ENABLE_DEBUG_TRACE)
155 0 : if (!DebugAnnotationsActive())
156 : {
157 0 : return;
158 : }
159 : #endif // !ANGLE_ENABLE_DEBUG_TRACE
160 : va_list vararg;
161 0 : va_start(vararg, format);
162 0 : output(true, MESSAGE_EVENT, DebugTraceOutputTypeBeginEvent, format, vararg);
163 0 : va_end(vararg);
164 : }
165 :
166 0 : ScopedPerfEventHelper::~ScopedPerfEventHelper()
167 : {
168 0 : if (DebugAnnotationsActive())
169 : {
170 0 : g_debugAnnotator->endEvent();
171 : }
172 0 : }
173 :
174 0 : std::ostream &DummyStream()
175 : {
176 0 : return std::cout;
177 : }
178 :
179 : } // namespace gl
|