195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com//
295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com// Use of this source code is governed by a BSD-style license that can be
495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com// found in the LICENSE file.
595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com//
695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com// debug.cpp: Debugging utilities.
895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com#include "common/debug.h"
1044fa7594bc518b1b004b1deb91d1c2f125df9f68Geoff Lang#include "common/platform.h"
11da5777cf9f131dbafcf91c88026624545db2cc87Geoff Lang#include "common/angleutils.h"
1244fa7594bc518b1b004b1deb91d1c2f125df9f68Geoff Lang
1383217796ed57efe8954fc3b53d743aae1a6cfe6bGeoff Lang#include <stdarg.h>
14feee44bf9a92c9d36c40fea9a4fb861b0e6d0fc4Geoff Lang#include <vector>
15feee44bf9a92c9d36c40fea9a4fb861b0e6d0fc4Geoff Lang#include <fstream>
16feee44bf9a92c9d36c40fea9a4fb861b0e6d0fc4Geoff Lang#include <cstdio>
176850947e144818ccdf9bab267b3d8c9fe3b88abbGeoff Lang
1895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comnamespace gl
1995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
20f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang#if defined(ANGLE_ENABLE_PERF)
2195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comtypedef void (WINAPI *PerfOutputFunction)(D3DCOLOR, LPCWSTR);
226850947e144818ccdf9bab267b3d8c9fe3b88abbGeoff Lang#else
236850947e144818ccdf9bab267b3d8c9fe3b88abbGeoff Langtypedef void (*PerfOutputFunction)(unsigned int, const wchar_t*);
246850947e144818ccdf9bab267b3d8c9fe3b88abbGeoff Lang#endif
2595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
2695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comstatic void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg)
2795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
28feee44bf9a92c9d36c40fea9a4fb861b0e6d0fc4Geoff Lang#if defined(ANGLE_ENABLE_PERF) || defined(ANGLE_ENABLE_TRACE)
29da5777cf9f131dbafcf91c88026624545db2cc87Geoff Lang    std::string formattedMessage = FormatString(format, vararg);
30feee44bf9a92c9d36c40fea9a4fb861b0e6d0fc4Geoff Lang#endif
31feee44bf9a92c9d36c40fea9a4fb861b0e6d0fc4Geoff Lang
32f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang#if defined(ANGLE_ENABLE_PERF)
3395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (perfActive())
3495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
35feee44bf9a92c9d36c40fea9a4fb861b0e6d0fc4Geoff Lang        // The perf function only accepts wide strings, widen the ascii message
36feee44bf9a92c9d36c40fea9a4fb861b0e6d0fc4Geoff Lang        static std::wstring wideMessage;
37da5777cf9f131dbafcf91c88026624545db2cc87Geoff Lang        if (wideMessage.capacity() < formattedMessage.length())
3895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
39da5777cf9f131dbafcf91c88026624545db2cc87Geoff Lang            wideMessage.reserve(formattedMessage.size());
4095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
4195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
42da5777cf9f131dbafcf91c88026624545db2cc87Geoff Lang        wideMessage.assign(formattedMessage.begin(), formattedMessage.end());
4395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
44feee44bf9a92c9d36c40fea9a4fb861b0e6d0fc4Geoff Lang        perfFunc(0, wideMessage.c_str());
4595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
46f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang#endif // ANGLE_ENABLE_PERF
4795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
48f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang#if defined(ANGLE_ENABLE_TRACE)
4995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com#if defined(NDEBUG)
5095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (traceFileDebugOnly)
5195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
5295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return;
5395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
54f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang#endif // NDEBUG
5595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
56feee44bf9a92c9d36c40fea9a4fb861b0e6d0fc4Geoff Lang    static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
5795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (file)
5895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
59da5777cf9f131dbafcf91c88026624545db2cc87Geoff Lang        file.write(formattedMessage.c_str(), formattedMessage.length());
60feee44bf9a92c9d36c40fea9a4fb861b0e6d0fc4Geoff Lang        file.flush();
6195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
62feee44bf9a92c9d36c40fea9a4fb861b0e6d0fc4Geoff Lang
63f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang#endif // ANGLE_ENABLE_TRACE
6495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
6595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
6695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comvoid trace(bool traceFileDebugOnly, const char *format, ...)
6795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
6895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    va_list vararg;
6995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    va_start(vararg, format);
70f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang#if defined(ANGLE_ENABLE_PERF)
7195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    output(traceFileDebugOnly, D3DPERF_SetMarker, format, vararg);
72f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang#else
73f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang    output(traceFileDebugOnly, NULL, format, vararg);
7495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com#endif
7595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    va_end(vararg);
7695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
7795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
7895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.combool perfActive()
7995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
80f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang#if defined(ANGLE_ENABLE_PERF)
8195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    static bool active = D3DPERF_GetStatus() != 0;
8295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    return active;
83f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang#else
84f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang    return false;
8595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com#endif
8695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
8795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
8895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
8995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
90f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang#if defined(ANGLE_ENABLE_PERF)
91f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang#if !defined(ANGLE_ENABLE_TRACE)
925dc3b8b47659e9632bc35277d4069610ccb0aabfdaniel@transgaming.com    if (!perfActive())
935dc3b8b47659e9632bc35277d4069610ccb0aabfdaniel@transgaming.com    {
945dc3b8b47659e9632bc35277d4069610ccb0aabfdaniel@transgaming.com        return;
955dc3b8b47659e9632bc35277d4069610ccb0aabfdaniel@transgaming.com    }
96f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang#endif // !ANGLE_ENABLE_TRACE
9795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    va_list vararg;
9895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    va_start(vararg, format);
9995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg);
10095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    va_end(vararg);
101f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang#endif // ANGLE_ENABLE_PERF
10295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
10395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
10495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comScopedPerfEventHelper::~ScopedPerfEventHelper()
10595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
106f571312409c7895c23ecbf01f9f5f042f0966d35Geoff Lang#if defined(ANGLE_ENABLE_PERF)
10795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (perfActive())
10895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
10995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        D3DPERF_EndEvent();
11095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
11195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com#endif
11295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
11395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
114