xref: /aosp_15_r20/external/virglrenderer/src/virgl_util.c (revision bbecb9d118dfdb95f99bd754f8fa9be01f189df3)
1*bbecb9d1SAndroid Build Coastguard Worker /**************************************************************************
2*bbecb9d1SAndroid Build Coastguard Worker  *
3*bbecb9d1SAndroid Build Coastguard Worker  * Copyright (C) 2019 Chromium.
4*bbecb9d1SAndroid Build Coastguard Worker  *
5*bbecb9d1SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
6*bbecb9d1SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
7*bbecb9d1SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
8*bbecb9d1SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9*bbecb9d1SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
10*bbecb9d1SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
11*bbecb9d1SAndroid Build Coastguard Worker  *
12*bbecb9d1SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included
13*bbecb9d1SAndroid Build Coastguard Worker  * in all copies or substantial portions of the Software.
14*bbecb9d1SAndroid Build Coastguard Worker  *
15*bbecb9d1SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16*bbecb9d1SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*bbecb9d1SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*bbecb9d1SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19*bbecb9d1SAndroid Build Coastguard Worker  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20*bbecb9d1SAndroid Build Coastguard Worker  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21*bbecb9d1SAndroid Build Coastguard Worker  * OTHER DEALINGS IN THE SOFTWARE.
22*bbecb9d1SAndroid Build Coastguard Worker  *
23*bbecb9d1SAndroid Build Coastguard Worker     **************************************************************************/
24*bbecb9d1SAndroid Build Coastguard Worker 
25*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
26*bbecb9d1SAndroid Build Coastguard Worker #include "config.h"
27*bbecb9d1SAndroid Build Coastguard Worker #endif
28*bbecb9d1SAndroid Build Coastguard Worker 
29*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_util.h"
30*bbecb9d1SAndroid Build Coastguard Worker 
31*bbecb9d1SAndroid Build Coastguard Worker #include <errno.h>
32*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EVENTFD_H
33*bbecb9d1SAndroid Build Coastguard Worker #include <sys/eventfd.h>
34*bbecb9d1SAndroid Build Coastguard Worker #endif
35*bbecb9d1SAndroid Build Coastguard Worker #include <unistd.h>
36*bbecb9d1SAndroid Build Coastguard Worker 
37*bbecb9d1SAndroid Build Coastguard Worker #include "util/os_misc.h"
38*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_pointer.h"
39*bbecb9d1SAndroid Build Coastguard Worker 
40*bbecb9d1SAndroid Build Coastguard Worker #include <assert.h>
41*bbecb9d1SAndroid Build Coastguard Worker #include <stdarg.h>
42*bbecb9d1SAndroid Build Coastguard Worker #include <stdio.h>
43*bbecb9d1SAndroid Build Coastguard Worker 
44*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
45*bbecb9d1SAndroid Build Coastguard Worker #include "config.h"
46*bbecb9d1SAndroid Build Coastguard Worker #endif
47*bbecb9d1SAndroid Build Coastguard Worker 
48*bbecb9d1SAndroid Build Coastguard Worker #if ENABLE_TRACING == TRACE_WITH_PERFETTO
49*bbecb9d1SAndroid Build Coastguard Worker #include <vperfetto-min.h>
50*bbecb9d1SAndroid Build Coastguard Worker #endif
51*bbecb9d1SAndroid Build Coastguard Worker 
52*bbecb9d1SAndroid Build Coastguard Worker #if ENABLE_TRACING == TRACE_WITH_STDERR
53*bbecb9d1SAndroid Build Coastguard Worker #include <stdio.h>
54*bbecb9d1SAndroid Build Coastguard Worker #endif
55*bbecb9d1SAndroid Build Coastguard Worker 
hash_func_u32(const void * key)56*bbecb9d1SAndroid Build Coastguard Worker uint32_t hash_func_u32(const void *key)
57*bbecb9d1SAndroid Build Coastguard Worker {
58*bbecb9d1SAndroid Build Coastguard Worker    intptr_t ip = pointer_to_intptr(key);
59*bbecb9d1SAndroid Build Coastguard Worker    return (uint32_t)(ip & 0xffffffff);
60*bbecb9d1SAndroid Build Coastguard Worker }
61*bbecb9d1SAndroid Build Coastguard Worker 
equal_func(const void * key1,const void * key2)62*bbecb9d1SAndroid Build Coastguard Worker bool equal_func(const void *key1, const void *key2)
63*bbecb9d1SAndroid Build Coastguard Worker {
64*bbecb9d1SAndroid Build Coastguard Worker    return key1 == key2;
65*bbecb9d1SAndroid Build Coastguard Worker }
66*bbecb9d1SAndroid Build Coastguard Worker 
has_eventfd(void)67*bbecb9d1SAndroid Build Coastguard Worker bool has_eventfd(void)
68*bbecb9d1SAndroid Build Coastguard Worker {
69*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EVENTFD_H
70*bbecb9d1SAndroid Build Coastguard Worker    return true;
71*bbecb9d1SAndroid Build Coastguard Worker #else
72*bbecb9d1SAndroid Build Coastguard Worker    return false;
73*bbecb9d1SAndroid Build Coastguard Worker #endif
74*bbecb9d1SAndroid Build Coastguard Worker }
75*bbecb9d1SAndroid Build Coastguard Worker 
create_eventfd(unsigned int initval)76*bbecb9d1SAndroid Build Coastguard Worker int create_eventfd(unsigned int initval)
77*bbecb9d1SAndroid Build Coastguard Worker {
78*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EVENTFD_H
79*bbecb9d1SAndroid Build Coastguard Worker    return eventfd(initval, EFD_CLOEXEC | EFD_NONBLOCK);
80*bbecb9d1SAndroid Build Coastguard Worker #else
81*bbecb9d1SAndroid Build Coastguard Worker    (void)initval;
82*bbecb9d1SAndroid Build Coastguard Worker    return -1;
83*bbecb9d1SAndroid Build Coastguard Worker #endif
84*bbecb9d1SAndroid Build Coastguard Worker }
85*bbecb9d1SAndroid Build Coastguard Worker 
write_eventfd(int fd,uint64_t val)86*bbecb9d1SAndroid Build Coastguard Worker int write_eventfd(int fd, uint64_t val)
87*bbecb9d1SAndroid Build Coastguard Worker {
88*bbecb9d1SAndroid Build Coastguard Worker    const char *buf = (const char *)&val;
89*bbecb9d1SAndroid Build Coastguard Worker    size_t count = sizeof(val);
90*bbecb9d1SAndroid Build Coastguard Worker    ssize_t ret = 0;
91*bbecb9d1SAndroid Build Coastguard Worker 
92*bbecb9d1SAndroid Build Coastguard Worker    while (count) {
93*bbecb9d1SAndroid Build Coastguard Worker       ret = write(fd, buf, count);
94*bbecb9d1SAndroid Build Coastguard Worker       if (ret < 0) {
95*bbecb9d1SAndroid Build Coastguard Worker          if (errno == EINTR)
96*bbecb9d1SAndroid Build Coastguard Worker             continue;
97*bbecb9d1SAndroid Build Coastguard Worker          break;
98*bbecb9d1SAndroid Build Coastguard Worker       }
99*bbecb9d1SAndroid Build Coastguard Worker       count -= ret;
100*bbecb9d1SAndroid Build Coastguard Worker       buf += ret;
101*bbecb9d1SAndroid Build Coastguard Worker    }
102*bbecb9d1SAndroid Build Coastguard Worker 
103*bbecb9d1SAndroid Build Coastguard Worker    return count ? -1 : 0;
104*bbecb9d1SAndroid Build Coastguard Worker }
105*bbecb9d1SAndroid Build Coastguard Worker 
flush_eventfd(int fd)106*bbecb9d1SAndroid Build Coastguard Worker void flush_eventfd(int fd)
107*bbecb9d1SAndroid Build Coastguard Worker {
108*bbecb9d1SAndroid Build Coastguard Worker     ssize_t len;
109*bbecb9d1SAndroid Build Coastguard Worker     uint64_t value;
110*bbecb9d1SAndroid Build Coastguard Worker     do {
111*bbecb9d1SAndroid Build Coastguard Worker        len = read(fd, &value, sizeof(value));
112*bbecb9d1SAndroid Build Coastguard Worker     } while ((len == -1 && errno == EINTR) || len == sizeof(value));
113*bbecb9d1SAndroid Build Coastguard Worker }
114*bbecb9d1SAndroid Build Coastguard Worker 
115*bbecb9d1SAndroid Build Coastguard Worker static
virgl_default_logger(const char * fmt,va_list va)116*bbecb9d1SAndroid Build Coastguard Worker void virgl_default_logger(const char *fmt, va_list va)
117*bbecb9d1SAndroid Build Coastguard Worker {
118*bbecb9d1SAndroid Build Coastguard Worker    static FILE* fp = NULL;
119*bbecb9d1SAndroid Build Coastguard Worker    if (NULL == fp) {
120*bbecb9d1SAndroid Build Coastguard Worker       const char* log = getenv("VIRGL_LOG_FILE");
121*bbecb9d1SAndroid Build Coastguard Worker       if (log) {
122*bbecb9d1SAndroid Build Coastguard Worker          char *log_prefix = strdup(log);
123*bbecb9d1SAndroid Build Coastguard Worker          char *log_suffix = strstr(log_prefix, "%PID%");
124*bbecb9d1SAndroid Build Coastguard Worker          if (log_suffix) {
125*bbecb9d1SAndroid Build Coastguard Worker             *log_suffix = 0;
126*bbecb9d1SAndroid Build Coastguard Worker             log_suffix += 5;
127*bbecb9d1SAndroid Build Coastguard Worker             int len = strlen(log) + 32;
128*bbecb9d1SAndroid Build Coastguard Worker             char *name = malloc(len);
129*bbecb9d1SAndroid Build Coastguard Worker             snprintf(name, len, "%s%d%s", log_prefix, getpid(), log_suffix);
130*bbecb9d1SAndroid Build Coastguard Worker             fp = fopen(name, "a");
131*bbecb9d1SAndroid Build Coastguard Worker             free(name);
132*bbecb9d1SAndroid Build Coastguard Worker          } else {
133*bbecb9d1SAndroid Build Coastguard Worker             fp = fopen(log, "a");
134*bbecb9d1SAndroid Build Coastguard Worker          }
135*bbecb9d1SAndroid Build Coastguard Worker          free(log_prefix);
136*bbecb9d1SAndroid Build Coastguard Worker          if (NULL == fp) {
137*bbecb9d1SAndroid Build Coastguard Worker             fprintf(stderr, "Can't open %s\n", log);
138*bbecb9d1SAndroid Build Coastguard Worker             fp = stderr;
139*bbecb9d1SAndroid Build Coastguard Worker          }
140*bbecb9d1SAndroid Build Coastguard Worker       } else {
141*bbecb9d1SAndroid Build Coastguard Worker             fp = stderr;
142*bbecb9d1SAndroid Build Coastguard Worker       }
143*bbecb9d1SAndroid Build Coastguard Worker    }
144*bbecb9d1SAndroid Build Coastguard Worker    vfprintf(fp, fmt, va);
145*bbecb9d1SAndroid Build Coastguard Worker    fflush(fp);
146*bbecb9d1SAndroid Build Coastguard Worker }
147*bbecb9d1SAndroid Build Coastguard Worker 
148*bbecb9d1SAndroid Build Coastguard Worker static
virgl_null_logger(UNUSED const char * fmt,UNUSED va_list va)149*bbecb9d1SAndroid Build Coastguard Worker void virgl_null_logger(UNUSED const char *fmt, UNUSED va_list va)
150*bbecb9d1SAndroid Build Coastguard Worker {
151*bbecb9d1SAndroid Build Coastguard Worker }
152*bbecb9d1SAndroid Build Coastguard Worker 
153*bbecb9d1SAndroid Build Coastguard Worker static virgl_debug_callback_type virgl_logger = virgl_default_logger;
154*bbecb9d1SAndroid Build Coastguard Worker 
virgl_log_set_logger(virgl_debug_callback_type logger)155*bbecb9d1SAndroid Build Coastguard Worker virgl_debug_callback_type virgl_log_set_logger(virgl_debug_callback_type logger)
156*bbecb9d1SAndroid Build Coastguard Worker {
157*bbecb9d1SAndroid Build Coastguard Worker    virgl_debug_callback_type old = virgl_logger;
158*bbecb9d1SAndroid Build Coastguard Worker 
159*bbecb9d1SAndroid Build Coastguard Worker    /* virgl_null_logger is internal */
160*bbecb9d1SAndroid Build Coastguard Worker    if (old == virgl_null_logger)
161*bbecb9d1SAndroid Build Coastguard Worker       old = NULL;
162*bbecb9d1SAndroid Build Coastguard Worker    if (!logger)
163*bbecb9d1SAndroid Build Coastguard Worker       logger = virgl_null_logger;
164*bbecb9d1SAndroid Build Coastguard Worker 
165*bbecb9d1SAndroid Build Coastguard Worker    virgl_logger = logger;
166*bbecb9d1SAndroid Build Coastguard Worker    return old;
167*bbecb9d1SAndroid Build Coastguard Worker }
168*bbecb9d1SAndroid Build Coastguard Worker 
virgl_logv(const char * fmt,va_list va)169*bbecb9d1SAndroid Build Coastguard Worker void virgl_logv(const char *fmt, va_list va)
170*bbecb9d1SAndroid Build Coastguard Worker {
171*bbecb9d1SAndroid Build Coastguard Worker    assert(virgl_logger);
172*bbecb9d1SAndroid Build Coastguard Worker    virgl_logger(fmt, va);
173*bbecb9d1SAndroid Build Coastguard Worker }
174*bbecb9d1SAndroid Build Coastguard Worker 
175*bbecb9d1SAndroid Build Coastguard Worker #if ENABLE_TRACING == TRACE_WITH_PERCETTO
PERCETTO_CATEGORY_DEFINE(VIRGL_PERCETTO_CATEGORIES)176*bbecb9d1SAndroid Build Coastguard Worker PERCETTO_CATEGORY_DEFINE(VIRGL_PERCETTO_CATEGORIES)
177*bbecb9d1SAndroid Build Coastguard Worker 
178*bbecb9d1SAndroid Build Coastguard Worker void trace_init(void)
179*bbecb9d1SAndroid Build Coastguard Worker {
180*bbecb9d1SAndroid Build Coastguard Worker   PERCETTO_INIT(PERCETTO_CLOCK_DONT_CARE);
181*bbecb9d1SAndroid Build Coastguard Worker }
182*bbecb9d1SAndroid Build Coastguard Worker #endif
183*bbecb9d1SAndroid Build Coastguard Worker 
184*bbecb9d1SAndroid Build Coastguard Worker #if ENABLE_TRACING == TRACE_WITH_PERFETTO
on_tracing_state_change(bool enabled)185*bbecb9d1SAndroid Build Coastguard Worker static void on_tracing_state_change(bool enabled) {
186*bbecb9d1SAndroid Build Coastguard Worker     virgl_log("%s: tracing state change: %d\n", __func__, enabled);
187*bbecb9d1SAndroid Build Coastguard Worker }
188*bbecb9d1SAndroid Build Coastguard Worker 
trace_init(void)189*bbecb9d1SAndroid Build Coastguard Worker void trace_init(void)
190*bbecb9d1SAndroid Build Coastguard Worker {
191*bbecb9d1SAndroid Build Coastguard Worker    struct vperfetto_min_config config = {
192*bbecb9d1SAndroid Build Coastguard Worker       .on_tracing_state_change = on_tracing_state_change,
193*bbecb9d1SAndroid Build Coastguard Worker       .init_flags = VPERFETTO_INIT_FLAG_USE_SYSTEM_BACKEND,
194*bbecb9d1SAndroid Build Coastguard Worker             .filename = NULL,
195*bbecb9d1SAndroid Build Coastguard Worker             .shmem_size_hint_kb = 32 * 1024,
196*bbecb9d1SAndroid Build Coastguard Worker    };
197*bbecb9d1SAndroid Build Coastguard Worker 
198*bbecb9d1SAndroid Build Coastguard Worker    vperfetto_min_startTracing(&config);
199*bbecb9d1SAndroid Build Coastguard Worker }
200*bbecb9d1SAndroid Build Coastguard Worker 
trace_begin(const char * scope)201*bbecb9d1SAndroid Build Coastguard Worker const char *trace_begin(const char *scope)
202*bbecb9d1SAndroid Build Coastguard Worker {
203*bbecb9d1SAndroid Build Coastguard Worker    vperfetto_min_beginTrackEvent_VMM(scope);
204*bbecb9d1SAndroid Build Coastguard Worker    return scope;
205*bbecb9d1SAndroid Build Coastguard Worker }
206*bbecb9d1SAndroid Build Coastguard Worker 
trace_end(const char ** dummy)207*bbecb9d1SAndroid Build Coastguard Worker void trace_end(const char **dummy)
208*bbecb9d1SAndroid Build Coastguard Worker {
209*bbecb9d1SAndroid Build Coastguard Worker    (void)dummy;
210*bbecb9d1SAndroid Build Coastguard Worker    vperfetto_min_endTrackEvent_VMM();
211*bbecb9d1SAndroid Build Coastguard Worker }
212*bbecb9d1SAndroid Build Coastguard Worker #endif
213*bbecb9d1SAndroid Build Coastguard Worker 
214*bbecb9d1SAndroid Build Coastguard Worker #if ENABLE_TRACING == TRACE_WITH_STDERR
215*bbecb9d1SAndroid Build Coastguard Worker static int nesting_depth = 0;
trace_init(void)216*bbecb9d1SAndroid Build Coastguard Worker void trace_init(void)
217*bbecb9d1SAndroid Build Coastguard Worker {
218*bbecb9d1SAndroid Build Coastguard Worker }
219*bbecb9d1SAndroid Build Coastguard Worker 
trace_begin(const char * scope)220*bbecb9d1SAndroid Build Coastguard Worker const char *trace_begin(const char *scope)
221*bbecb9d1SAndroid Build Coastguard Worker {
222*bbecb9d1SAndroid Build Coastguard Worker    for (int i = 0; i < nesting_depth; ++i)
223*bbecb9d1SAndroid Build Coastguard Worker       fprintf(stderr, "  ");
224*bbecb9d1SAndroid Build Coastguard Worker 
225*bbecb9d1SAndroid Build Coastguard Worker    fprintf(stderr, "ENTER:%s\n", scope);
226*bbecb9d1SAndroid Build Coastguard Worker    nesting_depth++;
227*bbecb9d1SAndroid Build Coastguard Worker 
228*bbecb9d1SAndroid Build Coastguard Worker    return scope;
229*bbecb9d1SAndroid Build Coastguard Worker }
230*bbecb9d1SAndroid Build Coastguard Worker 
trace_end(const char ** func_name)231*bbecb9d1SAndroid Build Coastguard Worker void trace_end(const char **func_name)
232*bbecb9d1SAndroid Build Coastguard Worker {
233*bbecb9d1SAndroid Build Coastguard Worker    --nesting_depth;
234*bbecb9d1SAndroid Build Coastguard Worker    for (int i = 0; i < nesting_depth; ++i)
235*bbecb9d1SAndroid Build Coastguard Worker       fprintf(stderr, "  ");
236*bbecb9d1SAndroid Build Coastguard Worker    fprintf(stderr, "LEAVE %s\n", *func_name);
237*bbecb9d1SAndroid Build Coastguard Worker }
238*bbecb9d1SAndroid Build Coastguard Worker #endif
239