blob: 48cabb7e7b440469347ea55a5510012d432277b2 [file] [log] [blame]
daniel@transgaming.com95a758f2012-07-12 15:17:06 +00001//
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"
Geoff Lang44fa7592014-05-30 11:50:07 -040010
Geoff Lang83217792014-01-16 09:52:38 -050011#include <stdarg.h>
Jamie Madille31fd872016-05-27 08:35:36 -040012
Yuly Novikovafcc41c2016-12-13 12:59:39 -050013#include <array>
Geoff Langfeee44b2014-03-05 11:34:31 -050014#include <cstdio>
Jamie Madille31fd872016-05-27 08:35:36 -040015#include <fstream>
16#include <iostream>
17#include <vector>
18
19#include "common/angleutils.h"
20#include "common/platform.h"
21#include "common/Optional.h"
Geoff Lang68509472013-10-07 17:06:30 -040022
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000023namespace gl
24{
Jamie Madill2c7c6252015-03-12 14:15:38 -040025
26namespace
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000027{
Jamie Madille31fd872016-05-27 08:35:36 -040028
Jamie Madill2c7c6252015-03-12 14:15:38 -040029DebugAnnotator *g_debugAnnotator = nullptr;
30
Yuly Novikovafcc41c2016-12-13 12:59:39 -050031constexpr std::array<const char *, LOG_NUM_SEVERITIES> g_logSeverityNames = {
32 {"EVENT", "WARN", "ERR"}};
33
34constexpr const char *LogSeverityName(int severity)
Austin Kinross922a9fb2014-10-21 14:26:33 -070035{
Yuly Novikovafcc41c2016-12-13 12:59:39 -050036 return (severity >= 0 && severity < LOG_NUM_SEVERITIES) ? g_logSeverityNames[severity]
37 : "UNKNOWN";
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000038}
39
Jamie Madill2c7c6252015-03-12 14:15:38 -040040} // namespace
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000041
Jamie Madill2c7c6252015-03-12 14:15:38 -040042bool DebugAnnotationsActive()
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000043{
Austin Kinross570e83c2014-10-20 14:13:58 -070044#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
Jamie Madill2c7c6252015-03-12 14:15:38 -040045 return g_debugAnnotator != nullptr && g_debugAnnotator->getStatus();
Geoff Langf5713122013-10-07 17:06:30 -040046#else
47 return false;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000048#endif
49}
50
Jamie Madill2c7c6252015-03-12 14:15:38 -040051void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator)
52{
53 UninitializeDebugAnnotations();
54 g_debugAnnotator = debugAnnotator;
55}
56
57void UninitializeDebugAnnotations()
58{
59 // Pointer is not managed.
60 g_debugAnnotator = nullptr;
61}
62
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000063ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
64{
Austin Kinrossf0360c62014-10-20 14:26:13 -070065#if !defined(ANGLE_ENABLE_DEBUG_TRACE)
Jamie Madill2c7c6252015-03-12 14:15:38 -040066 if (!DebugAnnotationsActive())
daniel@transgaming.com5dc3b8b2012-11-28 19:43:49 +000067 {
68 return;
69 }
Austin Kinrossf0360c62014-10-20 14:26:13 -070070#endif // !ANGLE_ENABLE_DEBUG_TRACE
Yuly Novikovafcc41c2016-12-13 12:59:39 -050071
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000072 va_list vararg;
73 va_start(vararg, format);
Yuly Novikovafcc41c2016-12-13 12:59:39 -050074 std::vector<char> buffer(512);
75 size_t len = FormatStringIntoVector(format, vararg, buffer);
76 ANGLE_LOG(EVENT) << std::string(&buffer[0], len);
Jamie Madillb60fe312014-09-26 14:56:41 -040077 va_end(vararg);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000078}
79
80ScopedPerfEventHelper::~ScopedPerfEventHelper()
81{
Jamie Madill2c7c6252015-03-12 14:15:38 -040082 if (DebugAnnotationsActive())
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000083 {
Jamie Madill2c7c6252015-03-12 14:15:38 -040084 g_debugAnnotator->endEvent();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000085 }
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000086}
Jamie Madill2c7c6252015-03-12 14:15:38 -040087
Yuly Novikovafcc41c2016-12-13 12:59:39 -050088namespace priv
89{
90
Jamie Madill60e6edf2016-10-31 12:17:19 -040091std::ostream &DummyStream()
92{
93 return std::cout;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000094}
Jamie Madill60e6edf2016-10-31 12:17:19 -040095
Yuly Novikovafcc41c2016-12-13 12:59:39 -050096bool ShouldCreateLogMessage(LogSeverity severity)
97{
98#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
99 return true;
100#elif defined(ANGLE_ENABLE_ASSERTS)
101 return severity == LOG_ERR;
102#else
103 return false;
104#endif
105}
106
107LogMessage::LogMessage(const char *function, int line, LogSeverity severity)
108 : mSeverity(severity), mFunction(function), mLine(line)
109{
110 init(function, line);
111}
112
113LogMessage::~LogMessage()
114{
115 mStream << std::endl;
116 std::string str(mStream.str());
117
118 if (DebugAnnotationsActive())
119 {
120 std::wstring formattedWideMessage(str.begin(), str.end());
121
122 switch (mSeverity)
123 {
124 case LOG_EVENT:
125 g_debugAnnotator->beginEvent(formattedWideMessage.c_str());
126 break;
127 default:
128 g_debugAnnotator->setMarker(formattedWideMessage.c_str());
129 break;
130 }
131 }
132
133 // Give any log message handler first dibs on the message.
134 bool handled = g_debugAnnotator != nullptr &&
135 g_debugAnnotator->logMessage(mSeverity, mFunction, mLine, mMessageStart, str);
136
137 if (!handled && mSeverity == LOG_ERR)
138 {
139 std::cerr << str;
140#if !defined(NDEBUG) && defined(_MSC_VER)
141 OutputDebugStringA(str.c_str());
142#endif // !defined(NDEBUG) && defined(_MSC_VER)
143 }
144
145#if defined(ANGLE_ENABLE_DEBUG_TRACE)
146#if defined(NDEBUG)
147 if (mSeverity == LOG_EVENT || mSeverity == LOG_WARN)
148 {
149 return;
150 }
151#endif // NDEBUG
152 static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
153 if (file)
154 {
155 file.write(str.c_str(), str.length());
156 file.flush();
157 }
158
159#if defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
160 OutputDebugStringA(str.c_str());
161#endif // ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER
162
163#endif // ANGLE_ENABLE_DEBUG_TRACE
164}
165
166// writes the common header info to the stream
167void LogMessage::init(const char *function, int line)
168{
169 if (mSeverity >= 0)
170 mStream << LogSeverityName(mSeverity);
171 else
172 mStream << "VERBOSE" << -mSeverity;
173
174 mStream << ": " << function << "(" << line << "): ";
175
176 mMessageStart = mStream.str().length();
177}
178
179} // namespace priv
180
181#if defined(ANGLE_PLATFORM_WINDOWS)
182std::ostream &operator<<(std::ostream &os, const FmtHR &fmt)
183{
184 os << "HRESULT: ";
185 return FmtHexInt(os, fmt.mHR);
186}
187#endif // defined(ANGLE_PLATFORM_WINDOWS)
188
Jamie Madill60e6edf2016-10-31 12:17:19 -0400189} // namespace gl