Commit e786472b8d4c5a532c51d024cf019f6e2d9b302f
- Diff rendering mode:
- inline
- side by side
src/egl/main/eglglobals.c
(4 / 3)
|   | |||
| 18 | 18 | 0, /* NumDrivers */ | |
| 19 | 19 | { NULL }, /* Drivers */ | |
| 20 | 20 | 2, /* NumAtExitCalls */ | |
| 21 | { /* AtExitCalls */ | ||
| 22 | _eglFiniDisplay, | ||
| 23 | _eglUnloadDrivers | ||
| 21 | { | ||
| 22 | /* default AtExitCalls, called in reverse order */ | ||
| 23 | _eglUnloadDrivers, /* always called last */ | ||
| 24 | _eglFiniDisplay | ||
| 24 | 25 | }, | |
| 25 | 26 | }; | |
| 26 | 27 |
src/egl/main/egllog.c
(130 / 51)
|   | |||
| 9 | 9 | #include <stdio.h> | |
| 10 | 10 | #include <stdlib.h> | |
| 11 | 11 | #include <string.h> | |
| 12 | |||
| 12 | 13 | #include "egllog.h" | |
| 14 | #include "eglmutex.h" | ||
| 13 | 15 | ||
| 14 | 16 | #define MAXSTRING 1000 | |
| 15 | #define FALLBACK_LOG_LEVEL _EGL_WARNING | ||
| 16 | #define FALLBACK_LOG_LEVEL_STR "warning" | ||
| 17 | #define FALLBACK_LOG_LEVEL _EGL_WARNING | ||
| 17 | 18 | ||
| 18 | static EGLint ReportingLevel = -1; | ||
| 19 | 19 | ||
| 20 | static struct { | ||
| 21 | _EGLMutex mutex; | ||
| 20 | 22 | ||
| 21 | static void | ||
| 22 | log_level_initialize(void) | ||
| 23 | EGLBoolean initialized; | ||
| 24 | EGLint level; | ||
| 25 | _EGLLogProc logger; | ||
| 26 | EGLint num_messages; | ||
| 27 | } logging = { | ||
| 28 | _EGL_MUTEX_INITIALIZER, | ||
| 29 | EGL_FALSE, | ||
| 30 | FALLBACK_LOG_LEVEL, | ||
| 31 | NULL, | ||
| 32 | 0 | ||
| 33 | }; | ||
| 34 | |||
| 35 | static const char *level_strings[] = { | ||
| 36 | /* the order is important */ | ||
| 37 | "fatal", | ||
| 38 | "warning", | ||
| 39 | "info", | ||
| 40 | "debug", | ||
| 41 | NULL | ||
| 42 | }; | ||
| 43 | |||
| 44 | |||
| 45 | /** | ||
| 46 | * Set the function to be called when there is a message to log. | ||
| 47 | * Note that the function will be called with an internal lock held. | ||
| 48 | * Recursive logging is not allowed. | ||
| 49 | */ | ||
| 50 | void | ||
| 51 | _eglSetLogProc(_EGLLogProc logger) | ||
| 23 | 52 | { | |
| 24 | char *log_env = getenv("EGL_LOG_LEVEL"); | ||
| 53 | EGLint num_messages = 0; | ||
| 25 | 54 | ||
| 26 | if (log_env == NULL) { | ||
| 27 | ReportingLevel = FALLBACK_LOG_LEVEL; | ||
| 55 | _eglLockMutex(&logging.mutex); | ||
| 56 | |||
| 57 | if (logging.logger != logger) { | ||
| 58 | logging.logger = logger; | ||
| 59 | |||
| 60 | num_messages = logging.num_messages; | ||
| 61 | logging.num_messages = 0; | ||
| 28 | 62 | } | |
| 29 | else if (strcasecmp(log_env, "fatal") == 0) { | ||
| 30 | ReportingLevel = _EGL_FATAL; | ||
| 63 | |||
| 64 | _eglUnlockMutex(&logging.mutex); | ||
| 65 | |||
| 66 | if (num_messages) | ||
| 67 | _eglLog(_EGL_DEBUG, | ||
| 68 | "New logger installed. " | ||
| 69 | "Messages before the new logger might not be available."); | ||
| 70 | } | ||
| 71 | |||
| 72 | |||
| 73 | /** | ||
| 74 | * Set the log reporting level. | ||
| 75 | */ | ||
| 76 | void | ||
| 77 | _eglSetLogLevel(EGLint level) | ||
| 78 | { | ||
| 79 | switch (level) { | ||
| 80 | case _EGL_FATAL: | ||
| 81 | case _EGL_WARNING: | ||
| 82 | case _EGL_INFO: | ||
| 83 | case _EGL_DEBUG: | ||
| 84 | _eglLockMutex(&logging.mutex); | ||
| 85 | logging.level = level; | ||
| 86 | _eglUnlockMutex(&logging.mutex); | ||
| 87 | break; | ||
| 88 | default: | ||
| 89 | break; | ||
| 31 | 90 | } | |
| 32 | else if (strcasecmp(log_env, "warning") == 0) { | ||
| 33 | ReportingLevel = _EGL_WARNING; | ||
| 91 | } | ||
| 92 | |||
| 93 | |||
| 94 | /** | ||
| 95 | * The default logger. It prints the message to stderr. | ||
| 96 | */ | ||
| 97 | static void | ||
| 98 | _eglDefaultLogger(EGLint level, const char *msg) | ||
| 99 | { | ||
| 100 | fprintf(stderr, "libEGL %s: %s\n", level_strings[level], msg); | ||
| 101 | } | ||
| 102 | |||
| 103 | |||
| 104 | /** | ||
| 105 | * Initialize the logging facility. | ||
| 106 | */ | ||
| 107 | static void | ||
| 108 | _eglInitLogger(void) | ||
| 109 | { | ||
| 110 | const char *log_env; | ||
| 111 | EGLint i, level = -1; | ||
| 112 | |||
| 113 | if (logging.initialized) | ||
| 114 | return; | ||
| 115 | |||
| 116 | log_env = getenv("EGL_LOG_LEVEL"); | ||
| 117 | if (log_env) { | ||
| 118 | for (i = 0; level_strings[i]; i++) { | ||
| 119 | if (strcasecmp(log_env, level_strings[i]) == 0) { | ||
| 120 | level = i; | ||
| 121 | break; | ||
| 122 | } | ||
| 123 | } | ||
| 34 | 124 | } | |
| 35 | else if (strcasecmp(log_env, "info") == 0) { | ||
| 36 | ReportingLevel = _EGL_INFO; | ||
| 37 | } | ||
| 38 | else if (strcasecmp(log_env, "debug") == 0) { | ||
| 39 | ReportingLevel = _EGL_DEBUG; | ||
| 40 | } | ||
| 41 | 125 | else { | |
| 42 | fprintf(stderr, "Unrecognized EGL_LOG_LEVEL environment variable value. " | ||
| 126 | level = FALLBACK_LOG_LEVEL; | ||
| 127 | } | ||
| 128 | |||
| 129 | logging.logger = _eglDefaultLogger; | ||
| 130 | logging.level = (level >= 0) ? level : FALLBACK_LOG_LEVEL; | ||
| 131 | logging.initialized = EGL_TRUE; | ||
| 132 | |||
| 133 | /* it is fine to call _eglLog now */ | ||
| 134 | if (log_env && level < 0) { | ||
| 135 | _eglLog(_EGL_WARNING, | ||
| 136 | "Unrecognized EGL_LOG_LEVEL environment variable value. " | ||
| 43 | 137 | "Expected one of \"fatal\", \"warning\", \"info\", \"debug\". " | |
| 44 | "Got \"%s\". Falling back to \"%s\".\n", | ||
| 45 | log_env, FALLBACK_LOG_LEVEL_STR); | ||
| 46 | ReportingLevel = FALLBACK_LOG_LEVEL; | ||
| 138 | "Got \"%s\". Falling back to \"%s\".", | ||
| 139 | log_env, level_strings[FALLBACK_LOG_LEVEL]); | ||
| 47 | 140 | } | |
| 48 | 141 | } | |
| 49 | 142 | ||
| 50 | 143 | ||
| 51 | 144 | /** | |
| 52 | * Log a message to stderr. | ||
| 145 | * Log a message with message logger. | ||
| 53 | 146 | * \param level one of _EGL_FATAL, _EGL_WARNING, _EGL_INFO, _EGL_DEBUG. | |
| 54 | 147 | */ | |
| 55 | 148 | void | |
| … | … | ||
| 150 | 150 | { | |
| 151 | 151 | va_list args; | |
| 152 | 152 | char msg[MAXSTRING]; | |
| 153 | const char *levelStr; | ||
| 154 | static int log_level_initialized = 0; | ||
| 155 | 153 | ||
| 156 | if (!log_level_initialized) { | ||
| 157 | log_level_initialize(); | ||
| 158 | log_level_initialized = 1; | ||
| 159 | } | ||
| 154 | /* one-time initialization; a little race here is fine */ | ||
| 155 | if (!logging.initialized) | ||
| 156 | _eglInitLogger(); | ||
| 157 | if (level > logging.level || level < 0) | ||
| 158 | return; | ||
| 160 | 159 | ||
| 161 | if (level <= ReportingLevel) { | ||
| 162 | switch (level) { | ||
| 163 | case _EGL_FATAL: | ||
| 164 | levelStr = "Fatal"; | ||
| 165 | break; | ||
| 166 | case _EGL_WARNING: | ||
| 167 | levelStr = "Warning"; | ||
| 168 | break; | ||
| 169 | case _EGL_INFO: | ||
| 170 | levelStr = "Info"; | ||
| 171 | break; | ||
| 172 | case _EGL_DEBUG: | ||
| 173 | levelStr = "Debug"; | ||
| 174 | break; | ||
| 175 | default: | ||
| 176 | levelStr = ""; | ||
| 177 | } | ||
| 160 | _eglLockMutex(&logging.mutex); | ||
| 178 | 161 | ||
| 162 | if (logging.logger) { | ||
| 179 | 163 | va_start(args, fmtStr); | |
| 180 | 164 | vsnprintf(msg, MAXSTRING, fmtStr, args); | |
| 181 | 165 | va_end(args); | |
| 182 | 166 | ||
| 183 | fprintf(stderr, "libEGL %s: %s\n", levelStr, msg); | ||
| 184 | |||
| 185 | if (level == _EGL_FATAL) { | ||
| 186 | exit(1); /* or abort()? */ | ||
| 187 | } | ||
| 167 | logging.logger(level, msg); | ||
| 168 | logging.num_messages++; | ||
| 188 | 169 | } | |
| 170 | |||
| 171 | _eglUnlockMutex(&logging.mutex); | ||
| 172 | |||
| 173 | if (level == _EGL_FATAL) | ||
| 174 | exit(1); /* or abort()? */ | ||
| 189 | 175 | } |
src/egl/main/egllog.h
(11 / 0)
|   | |||
| 9 | 9 | #define _EGL_DEBUG 3 /* useful info for debugging */ | |
| 10 | 10 | ||
| 11 | 11 | ||
| 12 | typedef void (*_EGLLogProc)(EGLint level, const char *msg); | ||
| 13 | |||
| 14 | |||
| 15 | extern void | ||
| 16 | _eglSetLogProc(_EGLLogProc logger); | ||
| 17 | |||
| 18 | |||
| 19 | extern void | ||
| 20 | _eglSetLogLevel(EGLint level); | ||
| 21 | |||
| 22 | |||
| 12 | 23 | extern void | |
| 13 | 24 | _eglLog(EGLint level, const char *fmtStr, ...); | |
| 14 | 25 |

