blob: 375558efc5c5b2aeb5d061abbdd7fb7bcac6d8ba [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 Lang83217792014-01-16 09:52:38 -050010#include <stdarg.h>
Geoff Langfeee44b2014-03-05 11:34:31 -050011#include <vector>
12#include <fstream>
13#include <cstdio>
Geoff Lang68509472013-10-07 17:06:30 -040014
Geoff Langf5713122013-10-07 17:06:30 -040015#if defined(ANGLE_ENABLE_PERF)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000016#include <d3d9.h>
Geoff Lang68509472013-10-07 17:06:30 -040017#endif
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000018
19namespace gl
20{
Geoff Langf5713122013-10-07 17:06:30 -040021#if defined(ANGLE_ENABLE_PERF)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000022typedef void (WINAPI *PerfOutputFunction)(D3DCOLOR, LPCWSTR);
Geoff Lang68509472013-10-07 17:06:30 -040023#else
24typedef void (*PerfOutputFunction)(unsigned int, const wchar_t*);
25#endif
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000026
27static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg)
28{
Geoff Langfeee44b2014-03-05 11:34:31 -050029#if defined(ANGLE_ENABLE_PERF) || defined(ANGLE_ENABLE_TRACE)
30 static std::vector<char> asciiMessageBuffer(512);
31
32 // Attempt to just print to the current buffer
33 int len = std::vsnprintf(&asciiMessageBuffer[0], asciiMessageBuffer.size(), format, vararg);
34 if (len < 0 || static_cast<size_t>(len) >= asciiMessageBuffer.size())
35 {
36 // Buffer was not large enough, calculate the required size and resize the buffer
37 len = std::vsnprintf(NULL, 0, format, vararg);
38 asciiMessageBuffer.resize(len + 1);
39
40 // Print again
41 std::vsnprintf(&asciiMessageBuffer[0], asciiMessageBuffer.size(), format, vararg);
42 }
43
44 // NULL terminate the buffer to be safe
45 asciiMessageBuffer[len] = '\0';
46#endif
47
Geoff Langf5713122013-10-07 17:06:30 -040048#if defined(ANGLE_ENABLE_PERF)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000049 if (perfActive())
50 {
Geoff Langfeee44b2014-03-05 11:34:31 -050051 // The perf function only accepts wide strings, widen the ascii message
52 static std::wstring wideMessage;
53 if (wideMessage.capacity() < asciiMessageBuffer.size())
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000054 {
Geoff Langfeee44b2014-03-05 11:34:31 -050055 wideMessage.reserve(asciiMessageBuffer.size());
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000056 }
57
Geoff Langfeee44b2014-03-05 11:34:31 -050058 wideMessage.assign(asciiMessageBuffer.begin(), asciiMessageBuffer.begin() + len);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000059
Geoff Langfeee44b2014-03-05 11:34:31 -050060 perfFunc(0, wideMessage.c_str());
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000061 }
Geoff Langf5713122013-10-07 17:06:30 -040062#endif // ANGLE_ENABLE_PERF
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000063
Geoff Langf5713122013-10-07 17:06:30 -040064#if defined(ANGLE_ENABLE_TRACE)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000065#if defined(NDEBUG)
66 if (traceFileDebugOnly)
67 {
68 return;
69 }
Geoff Langf5713122013-10-07 17:06:30 -040070#endif // NDEBUG
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000071
Geoff Langfeee44b2014-03-05 11:34:31 -050072 static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000073 if (file)
74 {
Geoff Langfeee44b2014-03-05 11:34:31 -050075 file.write(&asciiMessageBuffer[0], len);
76 file.flush();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000077 }
Geoff Langfeee44b2014-03-05 11:34:31 -050078
Geoff Langf5713122013-10-07 17:06:30 -040079#endif // ANGLE_ENABLE_TRACE
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000080}
81
82void trace(bool traceFileDebugOnly, const char *format, ...)
83{
84 va_list vararg;
85 va_start(vararg, format);
Geoff Langf5713122013-10-07 17:06:30 -040086#if defined(ANGLE_ENABLE_PERF)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000087 output(traceFileDebugOnly, D3DPERF_SetMarker, format, vararg);
Geoff Langf5713122013-10-07 17:06:30 -040088#else
89 output(traceFileDebugOnly, NULL, format, vararg);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000090#endif
91 va_end(vararg);
92}
93
94bool perfActive()
95{
Geoff Langf5713122013-10-07 17:06:30 -040096#if defined(ANGLE_ENABLE_PERF)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000097 static bool active = D3DPERF_GetStatus() != 0;
98 return active;
Geoff Langf5713122013-10-07 17:06:30 -040099#else
100 return false;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000101#endif
102}
103
104ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
105{
Geoff Langf5713122013-10-07 17:06:30 -0400106#if defined(ANGLE_ENABLE_PERF)
107#if !defined(ANGLE_ENABLE_TRACE)
daniel@transgaming.com5dc3b8b2012-11-28 19:43:49 +0000108 if (!perfActive())
109 {
110 return;
111 }
Geoff Langf5713122013-10-07 17:06:30 -0400112#endif // !ANGLE_ENABLE_TRACE
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000113 va_list vararg;
114 va_start(vararg, format);
115 output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg);
116 va_end(vararg);
Geoff Langf5713122013-10-07 17:06:30 -0400117#endif // ANGLE_ENABLE_PERF
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000118}
119
120ScopedPerfEventHelper::~ScopedPerfEventHelper()
121{
Geoff Langf5713122013-10-07 17:06:30 -0400122#if defined(ANGLE_ENABLE_PERF)
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000123 if (perfActive())
124 {
125 D3DPERF_EndEvent();
126 }
127#endif
128}
129}