1 /*
2  * This file is part of libplacebo.
3  *
4  * libplacebo is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * libplacebo is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with libplacebo. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #pragma once
19 
20 #include <stdarg.h>
21 #include <time.h>
22 
23 #include "common.h"
24 
25 // Internal logging-related functions
26 
27 // Warning: Not entirely thread-safe. Exercise caution when using. May result
28 // in either false positives or false negatives. Make sure to re-run this
29 // function while `lock` is held, to ensure no race conditions on the check.
pl_msg_test(pl_log log,enum pl_log_level lev)30 static inline bool pl_msg_test(pl_log log, enum pl_log_level lev)
31 {
32     return log && log->params.log_cb && log->params.log_level >= lev;
33 }
34 
35 void pl_msg(pl_log log, enum pl_log_level lev, const char *fmt, ...)
36     PL_PRINTF(3, 4);
37 
38 // Convenience macros
39 #define pl_fatal(log, ...)      pl_msg(log, PL_LOG_FATAL, __VA_ARGS__)
40 #define pl_err(log, ...)        pl_msg(log, PL_LOG_ERR, __VA_ARGS__)
41 #define pl_warn(log, ...)       pl_msg(log, PL_LOG_WARN, __VA_ARGS__)
42 #define pl_info(log, ...)       pl_msg(log, PL_LOG_INFO, __VA_ARGS__)
43 #define pl_debug(log, ...)      pl_msg(log, PL_LOG_DEBUG, __VA_ARGS__)
44 #define pl_trace(log, ...)      pl_msg(log, PL_LOG_TRACE, __VA_ARGS__)
45 
46 #define PL_MSG(obj, lev, ...)   pl_msg((obj)->log, lev, __VA_ARGS__)
47 
48 #define PL_FATAL(obj, ...)      PL_MSG(obj, PL_LOG_FATAL, __VA_ARGS__)
49 #define PL_ERR(obj, ...)        PL_MSG(obj, PL_LOG_ERR, __VA_ARGS__)
50 #define PL_WARN(obj, ...)       PL_MSG(obj, PL_LOG_WARN, __VA_ARGS__)
51 #define PL_INFO(obj, ...)       PL_MSG(obj, PL_LOG_INFO, __VA_ARGS__)
52 #define PL_DEBUG(obj, ...)      PL_MSG(obj, PL_LOG_DEBUG, __VA_ARGS__)
53 #define PL_TRACE(obj, ...)      PL_MSG(obj, PL_LOG_TRACE, __VA_ARGS__)
54 
55 // Log something with line numbers included
56 void pl_msg_source(pl_log log, enum pl_log_level lev, const char *src);
57 
58 // Temporarily cap the log level to a certain verbosity. This is intended for
59 // things like probing formats, attempting to create buffers that may fail, and
60 // other types of operations in which we want to suppress errors. Call with
61 // PL_LOG_NONE to disable this cap.
62 //
63 // Warning: This is generally not thread-safe, and only provided as a temporary
64 // hack until a better solution can be thought of.
65 void pl_log_level_cap(pl_log log, enum pl_log_level cap);
66 
67 // CPU execution time reporting helper
pl_log_cpu_time(pl_log log,time_t start,time_t stop,const char * operation)68 static inline void pl_log_cpu_time(pl_log log, time_t start, time_t stop,
69                                    const char *operation)
70 {
71     double ms = (stop - start) * 1e3 / CLOCKS_PER_SEC;
72     enum pl_log_level lev = PL_LOG_DEBUG;
73     if (ms > 10)
74         lev = PL_LOG_INFO;
75     if (ms > 1000)
76         lev = PL_LOG_WARN;
77 
78     pl_msg(log, lev, "Spent %.3f ms %s%s", ms, operation,
79            ms > 100 ? " (slow!)" : "");
80 }
81