blob: cea1a24e1df0b80212686cf9ab97ec660446905e [file] [log] [blame]
/*
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2014-2016 Valve Corporation. All rights reserved.
* Copyright (C) 2014-2016 LunarG, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Author: Jon Ashburn <jon@lunarg.com>
* Author: Peter Lohrmann <peterl@valvesoftware.com>
*/
#include "vktrace_platform.h"
#include "vktrace_tracelog.h"
#include "vktrace_trace_packet_utils.h"
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
// filelike thing that is used for outputting trace messages
static FileLike* g_pFileOut = NULL;
VKTRACE_TRACER_ID g_tracelog_tracer_id = VKTRACE_TID_RESERVED;
void vktrace_trace_set_trace_file(FileLike* pFileLike)
{
g_pFileOut = pFileLike;
}
// set initial value to 0 but once we read the trace file version
// we will update this and use for version checks
static uint32_t g_trace_version_num = 0;
void vktrace_set_trace_version(uint32_t version)
{
g_trace_version_num = version;
}
BOOL vktrace_check_min_version(uint32_t version)
{
return ((g_trace_version_num) >= (version) ? true : false);
}
FileLike* vktrace_trace_get_trace_file()
{
return g_pFileOut;
}
void vktrace_tracelog_set_tracer_id(uint8_t tracerId)
{
g_tracelog_tracer_id = (VKTRACE_TRACER_ID)tracerId;
}
VKTRACE_REPORT_CALLBACK_FUNCTION s_reportFunc;
VktraceLogLevel s_logLevel = VKTRACE_LOG_ERROR;
const char* vktrace_LogLevelToString(VktraceLogLevel level)
{
switch(level)
{
case VKTRACE_LOG_NONE: return "Quiet";
case VKTRACE_LOG_DEBUG: return "Debug";
case VKTRACE_LOG_ERROR: return "Errors";
case VKTRACE_LOG_WARNING: return "Warnings";
case VKTRACE_LOG_VERBOSE: return "Info";
default:
return "Unknown";
}
}
const char* vktrace_LogLevelToShortString(VktraceLogLevel level)
{
switch(level)
{
case VKTRACE_LOG_NONE: return "Quiet";
case VKTRACE_LOG_DEBUG: return "Debug";
case VKTRACE_LOG_ERROR: return "Errors";
case VKTRACE_LOG_WARNING: return "Warnings";
case VKTRACE_LOG_VERBOSE: return "Info";
default:
return "Unknown";
}
}
// For use by both tools and libraries.
void vktrace_LogSetCallback(VKTRACE_REPORT_CALLBACK_FUNCTION pCallback)
{
s_reportFunc = pCallback;
}
void vktrace_LogSetLevel(VktraceLogLevel level)
{
vktrace_LogDebug("Log Level = %u (%s)", level, vktrace_LogLevelToString(level));
s_logLevel = level;
}
BOOL vktrace_LogIsLogging(VktraceLogLevel level)
{
return (level <= s_logLevel) ? TRUE : FALSE;
}
void LogGuts(VktraceLogLevel level, const char* fmt, va_list args)
{
#if defined(WIN32)
int requiredLength = _vscprintf(fmt, args) + 1;
#elif defined(PLATFORM_LINUX) || defined(PLATFORM_OSX)
int requiredLength;
va_list argcopy;
va_copy(argcopy, args);
requiredLength = vsnprintf(NULL, 0, fmt, argcopy) + 1;
va_end(argcopy);
#endif
static VKTRACE_THREAD_LOCAL BOOL logging = FALSE;
// Don't recursively log problems found during logging
if (logging)
{
return;
}
logging = TRUE;
char* message = (char*)vktrace_malloc(requiredLength);
#if defined(WIN32)
_vsnprintf_s(message, requiredLength, requiredLength - 1, fmt, args);
#elif defined(PLATFORM_LINUX) || defined(PLATFORM_OSX)
vsnprintf(message, requiredLength, fmt, args);
#endif
if (s_reportFunc != NULL)
{
s_reportFunc(level, message);
}
else
{
#ifdef ANDROID
#include <android/log.h>
__android_log_print(ANDROID_LOG_INFO, "vktrace", "%s: %s\n", vktrace_LogLevelToString(level), message);
#else
printf("%s: %s\n", vktrace_LogLevelToString(level), message);
#endif
}
vktrace_free(message);
logging = FALSE;
}
void vktrace_LogAlways(const char* format, ...)
{
va_list args;
va_start(args, format);
LogGuts(VKTRACE_LOG_VERBOSE, format, args);
va_end(args);
}
void vktrace_LogDebug(const char* format, ...)
{
#if defined(_DEBUG)
if (vktrace_LogIsLogging(VKTRACE_LOG_DEBUG))
{
va_list args;
va_start(args, format);
LogGuts(VKTRACE_LOG_DEBUG, format, args);
va_end(args);
}
#endif
}
void vktrace_LogError(const char* format, ...)
{
if (vktrace_LogIsLogging(VKTRACE_LOG_ERROR))
{
va_list args;
va_start(args, format);
LogGuts(VKTRACE_LOG_ERROR, format, args);
va_end(args);
}
}
void vktrace_LogWarning(const char* format, ...)
{
if (vktrace_LogIsLogging(VKTRACE_LOG_WARNING))
{
va_list args;
va_start(args, format);
LogGuts(VKTRACE_LOG_WARNING, format, args);
va_end(args);
}
}
void vktrace_LogVerbose(const char* format, ...)
{
if (vktrace_LogIsLogging(VKTRACE_LOG_VERBOSE))
{
va_list args;
va_start(args, format);
LogGuts(VKTRACE_LOG_VERBOSE, format, args);
va_end(args);
}
}