xref: /aosp_15_r20/external/mesa3d/src/egl/main/egllog.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /**************************************************************************
2  *
3  * Copyright 2008 VMware, Inc.
4  * Copyright 2009-2010 Chia-I Wu <[email protected]>
5  * Copyright 2010 LunarG, Inc.
6  * All Rights Reserved.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the
10  * "Software"), to deal in the Software without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sub license, and/or sell copies of the Software, and to
13  * permit persons to whom the Software is furnished to do so, subject to
14  * the following conditions:
15  *
16  * The above copyright notice and this permission notice (including the
17  * next paragraph) shall be included in all copies or substantial portions
18  * of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  * DEALINGS IN THE SOFTWARE.
27  *
28  **************************************************************************/
29 
30 /**
31  * Logging facility for debug/info messages.
32  * _EGL_FATAL messages are printed to stderr
33  * The EGL_LOG_LEVEL var controls the output of other warning/info/debug msgs.
34  */
35 
36 #include <stdarg.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include "c11/threads.h"
41 #include "util/macros.h"
42 #include "util/os_misc.h"
43 #include "util/simple_mtx.h"
44 #include "util/u_string.h"
45 
46 #include "egllog.h"
47 
48 #ifdef HAVE_ANDROID_PLATFORM
49 #define LOG_TAG "EGL-MAIN"
50 #if ANDROID_API_LEVEL >= 26
51 #include <log/log.h>
52 #else
53 #include <cutils/log.h>
54 #endif /* use log/log.h start from android 8 major version */
55 
56 #endif /* HAVE_ANDROID_PLATFORM */
57 
58 #define MAXSTRING          1000
59 #define FALLBACK_LOG_LEVEL _EGL_WARNING
60 
61 static struct {
62    simple_mtx_t mutex;
63 
64    EGLBoolean initialized;
65    EGLint level;
66 } logging = {
67    .mutex = SIMPLE_MTX_INITIALIZER,
68    .initialized = EGL_FALSE,
69    .level = FALLBACK_LOG_LEVEL,
70 };
71 
72 static const char *level_strings[] = {
73    [_EGL_FATAL] = "fatal",
74    [_EGL_WARNING] = "warning",
75    [_EGL_INFO] = "info",
76    [_EGL_DEBUG] = "debug",
77 };
78 
79 /**
80  * The default logger.  It prints the message to stderr.
81  */
82 static void
_eglDefaultLogger(EGLint level,const char * msg)83 _eglDefaultLogger(EGLint level, const char *msg)
84 {
85 #ifdef HAVE_ANDROID_PLATFORM
86    static const int egl2alog[] = {
87       [_EGL_FATAL] = ANDROID_LOG_ERROR,
88       [_EGL_WARNING] = ANDROID_LOG_WARN,
89       [_EGL_INFO] = ANDROID_LOG_INFO,
90       [_EGL_DEBUG] = ANDROID_LOG_DEBUG,
91    };
92    LOG_PRI(egl2alog[level], LOG_TAG, "%s", msg);
93 #else
94    fprintf(stderr, "libEGL %s: %s\n", level_strings[level], msg);
95 #endif /* HAVE_ANDROID_PLATFORM */
96 }
97 
98 /**
99  * Initialize the logging facility.
100  */
101 static void
_eglInitLogger(void)102 _eglInitLogger(void)
103 {
104    const char *log_env;
105    EGLint i, level = -1;
106 
107    if (logging.initialized)
108       return;
109 
110    log_env = os_get_option("EGL_LOG_LEVEL");
111    if (log_env) {
112       for (i = 0; i < ARRAY_SIZE(level_strings); i++) {
113          if (strcasecmp(log_env, level_strings[i]) == 0) {
114             level = i;
115             break;
116          }
117       }
118    }
119 
120    logging.level = (level >= 0) ? level : FALLBACK_LOG_LEVEL;
121    logging.initialized = EGL_TRUE;
122 
123    /* it is fine to call _eglLog now */
124    if (log_env && level < 0) {
125       _eglLog(_EGL_WARNING,
126               "Unrecognized EGL_LOG_LEVEL environment variable value. "
127               "Expected one of \"fatal\", \"warning\", \"info\", \"debug\". "
128               "Got \"%s\". Falling back to \"%s\".",
129               log_env, level_strings[FALLBACK_LOG_LEVEL]);
130    }
131 }
132 
133 /**
134  * Return the log level.
135  */
136 EGLint
_eglGetLogLevel(void)137 _eglGetLogLevel(void)
138 {
139    return logging.level;
140 }
141 
142 /**
143  * Log a message with message logger.
144  * \param level one of _EGL_FATAL, _EGL_WARNING, _EGL_INFO, _EGL_DEBUG.
145  */
146 void
_eglLog(EGLint level,const char * fmtStr,...)147 _eglLog(EGLint level, const char *fmtStr, ...)
148 {
149    va_list args;
150    char msg[MAXSTRING];
151    int ret;
152 
153    /* one-time initialization; a little race here is fine */
154    if (!logging.initialized)
155       _eglInitLogger();
156    if (level > logging.level || level < 0)
157       return;
158 
159    simple_mtx_lock(&logging.mutex);
160 
161    va_start(args, fmtStr);
162    ret = vsnprintf(msg, MAXSTRING, fmtStr, args);
163    if (ret < 0 || ret >= MAXSTRING)
164       strcpy(msg, "<message truncated>");
165    va_end(args);
166 
167    _eglDefaultLogger(level, msg);
168 
169    simple_mtx_unlock(&logging.mutex);
170 
171    if (level == _EGL_FATAL)
172       exit(1); /* or abort()? */
173 }
174