Commit e786472b8d4c5a532c51d024cf019f6e2d9b302f

  • avatar
  • Chia-I Wu <olvaffe @gm…l.com>
  • Tue Sep 29 12:33:53 CEST 2009
egl: Improve logging facility.

Add _eglSetLogger and _eglSetLogLevel to allow drivers to change the
message logger or report level.
  
1818 0, /* NumDrivers */
1919 { NULL }, /* Drivers */
2020 2, /* NumAtExitCalls */
21 { /* AtExitCalls */
22 _eglFiniDisplay,
23 _eglUnloadDrivers
21 {
22 /* default AtExitCalls, called in reverse order */
23 _eglUnloadDrivers, /* always called last */
24 _eglFiniDisplay
2425 },
2526};
2627
  
99#include <stdio.h>
1010#include <stdlib.h>
1111#include <string.h>
12
1213#include "egllog.h"
14#include "eglmutex.h"
1315
1416#define MAXSTRING 1000
15#define FALLBACK_LOG_LEVEL _EGL_WARNING
16#define FALLBACK_LOG_LEVEL_STR "warning"
17#define FALLBACK_LOG_LEVEL _EGL_WARNING
1718
18static EGLint ReportingLevel = -1;
1919
20static struct {
21 _EGLMutex mutex;
2022
21static void
22log_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
35static 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 */
50void
51_eglSetLogProc(_EGLLogProc logger)
2352{
24 char *log_env = getenv("EGL_LOG_LEVEL");
53 EGLint num_messages = 0;
2554
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;
2862 }
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 */
76void
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;
3190 }
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 */
97static 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 */
107static 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 }
34124 }
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 }
41125 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. "
43137 "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]);
47140 }
48141}
49142
50143
51144/**
52 * Log a message to stderr.
145 * Log a message with message logger.
53146 * \param level one of _EGL_FATAL, _EGL_WARNING, _EGL_INFO, _EGL_DEBUG.
54147 */
55148void
150150{
151151 va_list args;
152152 char msg[MAXSTRING];
153 const char *levelStr;
154 static int log_level_initialized = 0;
155153
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;
160159
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);
178161
162 if (logging.logger) {
179163 va_start(args, fmtStr);
180164 vsnprintf(msg, MAXSTRING, fmtStr, args);
181165 va_end(args);
182166
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++;
188169 }
170
171 _eglUnlockMutex(&logging.mutex);
172
173 if (level == _EGL_FATAL)
174 exit(1); /* or abort()? */
189175}
  
99#define _EGL_DEBUG 3 /* useful info for debugging */
1010
1111
12typedef void (*_EGLLogProc)(EGLint level, const char *msg);
13
14
15extern void
16_eglSetLogProc(_EGLLogProc logger);
17
18
19extern void
20_eglSetLogLevel(EGLint level);
21
22
1223extern void
1324_eglLog(EGLint level, const char *fmtStr, ...);
1425