blob: 746da5e0d70db07480e0eeaf8d1e5d8b6163d27d [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
Geoff Langfeee44b2014-03-05 11:34:31 -050013#include <cstdio>
Jamie Madille31fd872016-05-27 08:35:36 -040014#include <fstream>
15#include <iostream>
16#include <vector>
17
18#include "common/angleutils.h"
19#include "common/platform.h"
20#include "common/Optional.h"
Geoff Lang68509472013-10-07 17:06:30 -040021
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000022namespace gl
23{
Jamie Madill2c7c6252015-03-12 14:15:38 -040024
25namespace
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000026{
Jamie Madille31fd872016-05-27 08:35:36 -040027
28class FormattedString final : angle::NonCopyable
29{
30 public:
31 FormattedString(const char *format, va_list vararg) : mFormat(format)
32 {
33 va_copy(mVarArg, vararg);
34 }
35
36 const char *c_str() { return str().c_str(); }
37
38 const std::string &str()
39 {
40 if (!mMessage.valid())
41 {
42 mMessage = FormatString(mFormat, mVarArg);
43 }
44 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};
Austin Kinross922a9fb2014-10-21 14:26:33 -070058enum DebugTraceOutputType
59{
60 DebugTraceOutputTypeNone,
61 DebugTraceOutputTypeSetMarker,
62 DebugTraceOutputTypeBeginEvent
63};
64
Jamie Madill2c7c6252015-03-12 14:15:38 -040065DebugAnnotator *g_debugAnnotator = nullptr;
66
67void output(bool traceInDebugOnly, MessageType messageType, DebugTraceOutputType outputType,
68 const char *format, va_list vararg)
Austin Kinross922a9fb2014-10-21 14:26:33 -070069{
Jamie Madill2c7c6252015-03-12 14:15:38 -040070 if (DebugAnnotationsActive())
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000071 {
Geoff Lang8bc361e2014-11-20 16:23:31 -050072 static std::vector<char> buffer(512);
Austin Kinross922a9fb2014-10-21 14:26:33 -070073 size_t len = FormatStringIntoVector(format, vararg, buffer);
74 std::wstring formattedWideMessage(buffer.begin(), buffer.begin() + len);
75
Jamie Madill2c7c6252015-03-12 14:15:38 -040076 ASSERT(g_debugAnnotator != nullptr);
Austin Kinross922a9fb2014-10-21 14:26:33 -070077 switch (outputType)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000078 {
Geoff Lang8bc361e2014-11-20 16:23:31 -050079 case DebugTraceOutputTypeNone:
80 break;
81 case DebugTraceOutputTypeBeginEvent:
Austin Kinross6ee1e782015-05-29 17:05:37 -070082 g_debugAnnotator->beginEvent(formattedWideMessage.c_str());
Geoff Lang8bc361e2014-11-20 16:23:31 -050083 break;
84 case DebugTraceOutputTypeSetMarker:
Austin Kinross6ee1e782015-05-29 17:05:37 -070085 g_debugAnnotator->setMarker(formattedWideMessage.c_str());
Geoff Lang8bc361e2014-11-20 16:23:31 -050086 break;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000087 }
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000088 }
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000089
Jamie Madille31fd872016-05-27 08:35:36 -040090 FormattedString formattedMessage(format, vararg);
Jamie Madill14aa40f2015-01-07 15:12:47 -050091
Jamie Madill14aa40f2015-01-07 15:12:47 -050092 if (messageType == MESSAGE_ERR)
93 {
Jamie Madille31fd872016-05-27 08:35:36 -040094 std::cerr << formattedMessage.c_str();
95#if !defined(NDEBUG) && defined(_MSC_VER)
Cooper Partin7318b7c2015-01-08 09:15:35 -080096 OutputDebugStringA(formattedMessage.c_str());
Jamie Madille31fd872016-05-27 08:35:36 -040097#endif // !defined(NDEBUG) && defined(_MSC_VER)
Jamie Madill14aa40f2015-01-07 15:12:47 -050098 }
Jamie Madill14aa40f2015-01-07 15:12:47 -050099
Austin Kinrossf0360c62014-10-20 14:26:13 -0700100#if defined(ANGLE_ENABLE_DEBUG_TRACE)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000101#if defined(NDEBUG)
Austin Kinrossfe14d452014-10-20 14:36:18 -0700102 if (traceInDebugOnly)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000103 {
104 return;
105 }
Jamie Madille31fd872016-05-27 08:35:36 -0400106#endif // NDEBUG
Geoff Langfeee44b2014-03-05 11:34:31 -0500107 static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000108 if (file)
109 {
Geoff Langda5777c2014-07-11 09:52:58 -0400110 file.write(formattedMessage.c_str(), formattedMessage.length());
Geoff Langfeee44b2014-03-05 11:34:31 -0500111 file.flush();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000112 }
Geoff Langfeee44b2014-03-05 11:34:31 -0500113
Austin Kinrossfe14d452014-10-20 14:36:18 -0700114#if defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
115 OutputDebugStringA(formattedMessage.c_str());
Jamie Madille31fd872016-05-27 08:35:36 -0400116#endif // ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER
Austin Kinrossfe14d452014-10-20 14:36:18 -0700117
Jamie Madille31fd872016-05-27 08:35:36 -0400118#endif // ANGLE_ENABLE_DEBUG_TRACE
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000119}
120
Jamie Madill2c7c6252015-03-12 14:15:38 -0400121} // namespace
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000122
Jamie Madill2c7c6252015-03-12 14:15:38 -0400123bool DebugAnnotationsActive()
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000124{
Austin Kinross570e83c2014-10-20 14:13:58 -0700125#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
Jamie Madill2c7c6252015-03-12 14:15:38 -0400126 return g_debugAnnotator != nullptr && g_debugAnnotator->getStatus();
Geoff Langf5713122013-10-07 17:06:30 -0400127#else
128 return false;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000129#endif
130}
131
Jamie Madill2c7c6252015-03-12 14:15:38 -0400132void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator)
133{
134 UninitializeDebugAnnotations();
135 g_debugAnnotator = debugAnnotator;
136}
137
138void UninitializeDebugAnnotations()
139{
140 // Pointer is not managed.
141 g_debugAnnotator = nullptr;
142}
143
144void trace(bool traceInDebugOnly, MessageType messageType, const char *format, ...)
145{
146 va_list vararg;
147 va_start(vararg, format);
148 output(traceInDebugOnly, messageType, DebugTraceOutputTypeSetMarker, format, vararg);
149 va_end(vararg);
150}
151
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000152ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
153{
Austin Kinrossf0360c62014-10-20 14:26:13 -0700154#if !defined(ANGLE_ENABLE_DEBUG_TRACE)
Jamie Madill2c7c6252015-03-12 14:15:38 -0400155 if (!DebugAnnotationsActive())
daniel@transgaming.com5dc3b8b2012-11-28 19:43:49 +0000156 {
157 return;
158 }
Austin Kinrossf0360c62014-10-20 14:26:13 -0700159#endif // !ANGLE_ENABLE_DEBUG_TRACE
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000160 va_list vararg;
161 va_start(vararg, format);
Jamie Madill14aa40f2015-01-07 15:12:47 -0500162 output(true, MESSAGE_EVENT, DebugTraceOutputTypeBeginEvent, format, vararg);
Jamie Madillb60fe312014-09-26 14:56:41 -0400163 va_end(vararg);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000164}
165
166ScopedPerfEventHelper::~ScopedPerfEventHelper()
167{
Jamie Madill2c7c6252015-03-12 14:15:38 -0400168 if (DebugAnnotationsActive())
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000169 {
Jamie Madill2c7c6252015-03-12 14:15:38 -0400170 g_debugAnnotator->endEvent();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000171 }
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000172}
Jamie Madill2c7c6252015-03-12 14:15:38 -0400173
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000174}