1848b8605Smrg/************************************************************************** 2848b8605Smrg * 3848b8605Smrg * Copyright 2008 VMware, Inc. 4848b8605Smrg * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com> 5848b8605Smrg * Copyright 2010 LunarG, Inc. 6848b8605Smrg * All Rights Reserved. 7848b8605Smrg * 8848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 9848b8605Smrg * copy of this software and associated documentation files (the 10848b8605Smrg * "Software"), to deal in the Software without restriction, including 11848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish, 12848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to 13848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to 14848b8605Smrg * the following conditions: 15848b8605Smrg * 16848b8605Smrg * The above copyright notice and this permission notice (including the 17848b8605Smrg * next paragraph) shall be included in all copies or substantial portions 18848b8605Smrg * of the Software. 19848b8605Smrg * 20848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26848b8605Smrg * DEALINGS IN THE SOFTWARE. 27848b8605Smrg * 28848b8605Smrg **************************************************************************/ 29848b8605Smrg 30848b8605Smrg 31848b8605Smrg/** 32848b8605Smrg * Logging facility for debug/info messages. 33848b8605Smrg * _EGL_FATAL messages are printed to stderr 34848b8605Smrg * The EGL_LOG_LEVEL var controls the output of other warning/info/debug msgs. 35848b8605Smrg */ 36848b8605Smrg 37848b8605Smrg 38848b8605Smrg#include <stdarg.h> 39848b8605Smrg#include <stdio.h> 40848b8605Smrg#include <stdlib.h> 41b8e80941Smrg#include <string.h> 42b8e80941Smrg#include <strings.h> 43b8e80941Smrg#include "c11/threads.h" 44b8e80941Smrg#include "util/macros.h" 45848b8605Smrg 46848b8605Smrg#include "egllog.h" 47b8e80941Smrg 48b8e80941Smrg#ifdef HAVE_ANDROID_PLATFORM 49b8e80941Smrg#define LOG_TAG "EGL-MAIN" 50b8e80941Smrg#if ANDROID_API_LEVEL >= 26 51b8e80941Smrg#include <log/log.h> 52b8e80941Smrg#else 53b8e80941Smrg#include <cutils/log.h> 54b8e80941Smrg#endif /* use log/log.h start from android 8 major version */ 55b8e80941Smrg 56b8e80941Smrg#endif /* HAVE_ANDROID_PLATFORM */ 57848b8605Smrg 58848b8605Smrg#define MAXSTRING 1000 59848b8605Smrg#define FALLBACK_LOG_LEVEL _EGL_WARNING 60848b8605Smrg 61848b8605Smrg 62848b8605Smrgstatic struct { 63b8e80941Smrg mtx_t mutex; 64848b8605Smrg 65848b8605Smrg EGLBoolean initialized; 66848b8605Smrg EGLint level; 67848b8605Smrg} logging = { 68b8e80941Smrg .mutex = _MTX_INITIALIZER_NP, 69b8e80941Smrg .initialized = EGL_FALSE, 70b8e80941Smrg .level = FALLBACK_LOG_LEVEL, 71848b8605Smrg}; 72848b8605Smrg 73848b8605Smrgstatic const char *level_strings[] = { 74b8e80941Smrg [_EGL_FATAL] = "fatal", 75b8e80941Smrg [_EGL_WARNING] = "warning", 76b8e80941Smrg [_EGL_INFO] = "info", 77b8e80941Smrg [_EGL_DEBUG] = "debug", 78848b8605Smrg}; 79848b8605Smrg 80848b8605Smrg 81848b8605Smrg/** 82848b8605Smrg * The default logger. It prints the message to stderr. 83848b8605Smrg */ 84848b8605Smrgstatic void 85848b8605Smrg_eglDefaultLogger(EGLint level, const char *msg) 86848b8605Smrg{ 87b8e80941Smrg#ifdef HAVE_ANDROID_PLATFORM 88b8e80941Smrg static const int egl2alog[] = { 89b8e80941Smrg [_EGL_FATAL] = ANDROID_LOG_ERROR, 90b8e80941Smrg [_EGL_WARNING] = ANDROID_LOG_WARN, 91b8e80941Smrg [_EGL_INFO] = ANDROID_LOG_INFO, 92b8e80941Smrg [_EGL_DEBUG] = ANDROID_LOG_DEBUG, 93b8e80941Smrg }; 94b8e80941Smrg LOG_PRI(egl2alog[level], LOG_TAG, "%s", msg); 95b8e80941Smrg#else 96848b8605Smrg fprintf(stderr, "libEGL %s: %s\n", level_strings[level], msg); 97b8e80941Smrg#endif /* HAVE_ANDROID_PLATFORM */ 98848b8605Smrg} 99848b8605Smrg 100848b8605Smrg 101848b8605Smrg/** 102848b8605Smrg * Initialize the logging facility. 103848b8605Smrg */ 104848b8605Smrgstatic void 105848b8605Smrg_eglInitLogger(void) 106848b8605Smrg{ 107848b8605Smrg const char *log_env; 108848b8605Smrg EGLint i, level = -1; 109848b8605Smrg 110848b8605Smrg if (logging.initialized) 111848b8605Smrg return; 112848b8605Smrg 113848b8605Smrg log_env = getenv("EGL_LOG_LEVEL"); 114848b8605Smrg if (log_env) { 115b8e80941Smrg for (i = 0; i < ARRAY_SIZE(level_strings); i++) { 116b8e80941Smrg if (strcasecmp(log_env, level_strings[i]) == 0) { 117848b8605Smrg level = i; 118848b8605Smrg break; 119848b8605Smrg } 120848b8605Smrg } 121848b8605Smrg } 122848b8605Smrg 123848b8605Smrg logging.level = (level >= 0) ? level : FALLBACK_LOG_LEVEL; 124848b8605Smrg logging.initialized = EGL_TRUE; 125848b8605Smrg 126848b8605Smrg /* it is fine to call _eglLog now */ 127848b8605Smrg if (log_env && level < 0) { 128848b8605Smrg _eglLog(_EGL_WARNING, 129848b8605Smrg "Unrecognized EGL_LOG_LEVEL environment variable value. " 130848b8605Smrg "Expected one of \"fatal\", \"warning\", \"info\", \"debug\". " 131848b8605Smrg "Got \"%s\". Falling back to \"%s\".", 132848b8605Smrg log_env, level_strings[FALLBACK_LOG_LEVEL]); 133848b8605Smrg } 134848b8605Smrg} 135848b8605Smrg 136848b8605Smrg 137848b8605Smrg/** 138848b8605Smrg * Log a message with message logger. 139848b8605Smrg * \param level one of _EGL_FATAL, _EGL_WARNING, _EGL_INFO, _EGL_DEBUG. 140848b8605Smrg */ 141848b8605Smrgvoid 142848b8605Smrg_eglLog(EGLint level, const char *fmtStr, ...) 143848b8605Smrg{ 144848b8605Smrg va_list args; 145848b8605Smrg char msg[MAXSTRING]; 146848b8605Smrg int ret; 147848b8605Smrg 148848b8605Smrg /* one-time initialization; a little race here is fine */ 149848b8605Smrg if (!logging.initialized) 150848b8605Smrg _eglInitLogger(); 151848b8605Smrg if (level > logging.level || level < 0) 152848b8605Smrg return; 153848b8605Smrg 154b8e80941Smrg mtx_lock(&logging.mutex); 155848b8605Smrg 156b8e80941Smrg va_start(args, fmtStr); 157b8e80941Smrg ret = vsnprintf(msg, MAXSTRING, fmtStr, args); 158b8e80941Smrg if (ret < 0 || ret >= MAXSTRING) 159b8e80941Smrg strcpy(msg, "<message truncated>"); 160b8e80941Smrg va_end(args); 161848b8605Smrg 162b8e80941Smrg _eglDefaultLogger(level, msg); 163848b8605Smrg 164b8e80941Smrg mtx_unlock(&logging.mutex); 165848b8605Smrg 166848b8605Smrg if (level == _EGL_FATAL) 167848b8605Smrg exit(1); /* or abort()? */ 168848b8605Smrg} 169