1f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu/************************************************************************** 2f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * 3f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 4f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com> 5f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Copyright 2010 LunarG, Inc. 6f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * All Rights Reserved. 7f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * 8f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Permission is hereby granted, free of charge, to any person obtaining a 9f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * copy of this software and associated documentation files (the 10f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * "Software"), to deal in the Software without restriction, including 11f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * without limitation the rights to use, copy, modify, merge, publish, 12f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * distribute, sub license, and/or sell copies of the Software, and to 13f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * permit persons to whom the Software is furnished to do so, subject to 14f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * the following conditions: 15f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * 16f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * The above copyright notice and this permission notice (including the 17f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * next paragraph) shall be included in all copies or substantial portions 18f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * of the Software. 19f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * 20f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * DEALINGS IN THE SOFTWARE. 27f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * 28f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu **************************************************************************/ 29f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu 30f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu 31f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul/** 32f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul * Logging facility for debug/info messages. 33f6e030f531f7292a373a7cd633e8af9f97726266Brian Paul * _EGL_FATAL messages are printed to stderr 34f6e030f531f7292a373a7cd633e8af9f97726266Brian Paul * The EGL_LOG_LEVEL var controls the output of other warning/info/debug msgs. 35f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul */ 36f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul 37f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul 38f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul#include <stdarg.h> 39f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul#include <stdio.h> 40f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul#include <stdlib.h> 41f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 42f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul#include "egllog.h" 431e6c10f4be9e36cc052a6b47fb2cb1eae60caa00Chia-I Wu#include "eglstring.h" 44f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu#include "eglmutex.h" 45f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul 46f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul#define MAXSTRING 1000 47f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu#define FALLBACK_LOG_LEVEL _EGL_WARNING 48f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul 49f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul 50f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wustatic struct { 51f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu _EGLMutex mutex; 5220e851bb9a6737194bc0effcb155b2fdb23acaaaChristian Neumair 53f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu EGLBoolean initialized; 54f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu EGLint level; 55f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu _EGLLogProc logger; 56f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu EGLint num_messages; 57f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu} logging = { 58f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu _EGL_MUTEX_INITIALIZER, 59f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu EGL_FALSE, 60f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu FALLBACK_LOG_LEVEL, 61f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu NULL, 62f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 0 63f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu}; 64f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 65f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wustatic const char *level_strings[] = { 66f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu /* the order is important */ 67f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu "fatal", 68f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu "warning", 69f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu "info", 70f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu "debug", 71f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu NULL 72f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu}; 73f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 74f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 75f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu/** 76f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu * Set the function to be called when there is a message to log. 77f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu * Note that the function will be called with an internal lock held. 78f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu * Recursive logging is not allowed. 79f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu */ 80f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wuvoid 81f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu_eglSetLogProc(_EGLLogProc logger) 8220e851bb9a6737194bc0effcb155b2fdb23acaaaChristian Neumair{ 83f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu EGLint num_messages = 0; 8420e851bb9a6737194bc0effcb155b2fdb23acaaaChristian Neumair 85f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu _eglLockMutex(&logging.mutex); 86f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 87f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu if (logging.logger != logger) { 88f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu logging.logger = logger; 89f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 90f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu num_messages = logging.num_messages; 91f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu logging.num_messages = 0; 9220e851bb9a6737194bc0effcb155b2fdb23acaaaChristian Neumair } 93f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 94f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu _eglUnlockMutex(&logging.mutex); 95f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 96f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu if (num_messages) 97f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu _eglLog(_EGL_DEBUG, 98f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu "New logger installed. " 99f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu "Messages before the new logger might not be available."); 100f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu} 101f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 102f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 103f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu/** 104f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu * Set the log reporting level. 105f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu */ 106f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wuvoid 107f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu_eglSetLogLevel(EGLint level) 108f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu{ 109f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu switch (level) { 110f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu case _EGL_FATAL: 111f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu case _EGL_WARNING: 112f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu case _EGL_INFO: 113f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu case _EGL_DEBUG: 114f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu _eglLockMutex(&logging.mutex); 115f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu logging.level = level; 116f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu _eglUnlockMutex(&logging.mutex); 117f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu break; 118f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu default: 119f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu break; 12020e851bb9a6737194bc0effcb155b2fdb23acaaaChristian Neumair } 121f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu} 122f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 123f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 124f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu/** 125f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu * The default logger. It prints the message to stderr. 126f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu */ 127f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wustatic void 128f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu_eglDefaultLogger(EGLint level, const char *msg) 129f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu{ 130f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu fprintf(stderr, "libEGL %s: %s\n", level_strings[level], msg); 131f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu} 132f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 133f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 134f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu/** 135f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu * Initialize the logging facility. 136f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu */ 137f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wustatic void 138f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu_eglInitLogger(void) 139f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu{ 140f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu const char *log_env; 141f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu EGLint i, level = -1; 142f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 143f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu if (logging.initialized) 144f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu return; 145f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 146f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu log_env = getenv("EGL_LOG_LEVEL"); 147f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu if (log_env) { 148f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu for (i = 0; level_strings[i]; i++) { 1491e6c10f4be9e36cc052a6b47fb2cb1eae60caa00Chia-I Wu if (_eglstrcasecmp(log_env, level_strings[i]) == 0) { 150f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu level = i; 151f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu break; 152f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu } 153f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu } 15420e851bb9a6737194bc0effcb155b2fdb23acaaaChristian Neumair } 15520e851bb9a6737194bc0effcb155b2fdb23acaaaChristian Neumair else { 156f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu level = FALLBACK_LOG_LEVEL; 157f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu } 158f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 159f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu logging.logger = _eglDefaultLogger; 160f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu logging.level = (level >= 0) ? level : FALLBACK_LOG_LEVEL; 161f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu logging.initialized = EGL_TRUE; 162f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 163f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu /* it is fine to call _eglLog now */ 164f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu if (log_env && level < 0) { 165f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu _eglLog(_EGL_WARNING, 166f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu "Unrecognized EGL_LOG_LEVEL environment variable value. " 167f6e030f531f7292a373a7cd633e8af9f97726266Brian Paul "Expected one of \"fatal\", \"warning\", \"info\", \"debug\". " 168f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu "Got \"%s\". Falling back to \"%s\".", 169f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu log_env, level_strings[FALLBACK_LOG_LEVEL]); 17020e851bb9a6737194bc0effcb155b2fdb23acaaaChristian Neumair } 17120e851bb9a6737194bc0effcb155b2fdb23acaaaChristian Neumair} 172f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul 173f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul 174f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul/** 175f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu * Log a message with message logger. 176f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul * \param level one of _EGL_FATAL, _EGL_WARNING, _EGL_INFO, _EGL_DEBUG. 177f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul */ 178f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paulvoid 179f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul_eglLog(EGLint level, const char *fmtStr, ...) 180f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul{ 181f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul va_list args; 182f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul char msg[MAXSTRING]; 183ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu int ret; 18420e851bb9a6737194bc0effcb155b2fdb23acaaaChristian Neumair 185f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu /* one-time initialization; a little race here is fine */ 186f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu if (!logging.initialized) 187f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu _eglInitLogger(); 188f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu if (level > logging.level || level < 0) 189f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu return; 190f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul 191f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu _eglLockMutex(&logging.mutex); 192f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul 193f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu if (logging.logger) { 194f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul va_start(args, fmtStr); 195ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu ret = vsnprintf(msg, MAXSTRING, fmtStr, args); 196ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu if (ret < 0 || ret >= MAXSTRING) 197ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu strcpy(msg, "<message truncated>"); 198f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul va_end(args); 199f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul 200f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu logging.logger(level, msg); 201f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu logging.num_messages++; 202f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul } 203f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 204f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu _eglUnlockMutex(&logging.mutex); 205f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu 206f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu if (level == _EGL_FATAL) 207f1c5cab5525dfcb8edffa275e7c8c3e753c7536fChia-I Wu exit(1); /* or abort()? */ 208f049ca4e33e0e5d06223a1c05815bc564b4bf06eBrian Paul} 209