xref: /aosp_15_r20/external/virglrenderer/src/vrend_winsys.c (revision bbecb9d118dfdb95f99bd754f8fa9be01f189df3)
1*bbecb9d1SAndroid Build Coastguard Worker /**************************************************************************
2*bbecb9d1SAndroid Build Coastguard Worker  *
3*bbecb9d1SAndroid Build Coastguard Worker  * Copyright (C) 2014 Red Hat Inc.
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 #include "vrend_winsys.h"
26*bbecb9d1SAndroid Build Coastguard Worker 
27*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_GLX_H
28*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_winsys_glx.h"
29*bbecb9d1SAndroid Build Coastguard Worker #endif
30*bbecb9d1SAndroid Build Coastguard Worker 
31*bbecb9d1SAndroid Build Coastguard Worker #include <stddef.h>
32*bbecb9d1SAndroid Build Coastguard Worker 
33*bbecb9d1SAndroid Build Coastguard Worker enum {
34*bbecb9d1SAndroid Build Coastguard Worker    CONTEXT_NONE,
35*bbecb9d1SAndroid Build Coastguard Worker    CONTEXT_EGL,
36*bbecb9d1SAndroid Build Coastguard Worker    CONTEXT_GLX,
37*bbecb9d1SAndroid Build Coastguard Worker    CONTEXT_EGL_EXTERNAL
38*bbecb9d1SAndroid Build Coastguard Worker };
39*bbecb9d1SAndroid Build Coastguard Worker 
40*bbecb9d1SAndroid Build Coastguard Worker static int use_context = CONTEXT_NONE;
41*bbecb9d1SAndroid Build Coastguard Worker 
42*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
43*bbecb9d1SAndroid Build Coastguard Worker struct virgl_egl *egl = NULL;
44*bbecb9d1SAndroid Build Coastguard Worker struct virgl_gbm *gbm = NULL;
45*bbecb9d1SAndroid Build Coastguard Worker #endif
46*bbecb9d1SAndroid Build Coastguard Worker 
47*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_GLX_H
48*bbecb9d1SAndroid Build Coastguard Worker static struct virgl_glx *glx_info = NULL;
49*bbecb9d1SAndroid Build Coastguard Worker #endif
50*bbecb9d1SAndroid Build Coastguard Worker 
vrend_winsys_init(uint32_t flags,int preferred_fd)51*bbecb9d1SAndroid Build Coastguard Worker int vrend_winsys_init(uint32_t flags, int preferred_fd)
52*bbecb9d1SAndroid Build Coastguard Worker {
53*bbecb9d1SAndroid Build Coastguard Worker    if (flags & VIRGL_RENDERER_USE_EGL) {
54*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
55*bbecb9d1SAndroid Build Coastguard Worker       /*
56*bbecb9d1SAndroid Build Coastguard Worker        * If the user specifies a preferred DRM fd and we can't use it, fail. If the user doesn't
57*bbecb9d1SAndroid Build Coastguard Worker        * specify an fd, it's possible to initialize EGL without one.
58*bbecb9d1SAndroid Build Coastguard Worker        */
59*bbecb9d1SAndroid Build Coastguard Worker       gbm = virgl_gbm_init(preferred_fd);
60*bbecb9d1SAndroid Build Coastguard Worker       if (preferred_fd > 0 && !gbm)
61*bbecb9d1SAndroid Build Coastguard Worker          return -1;
62*bbecb9d1SAndroid Build Coastguard Worker 
63*bbecb9d1SAndroid Build Coastguard Worker       egl = virgl_egl_init(gbm, flags & VIRGL_RENDERER_USE_SURFACELESS,
64*bbecb9d1SAndroid Build Coastguard Worker                            flags & VIRGL_RENDERER_USE_GLES);
65*bbecb9d1SAndroid Build Coastguard Worker       if (!egl) {
66*bbecb9d1SAndroid Build Coastguard Worker          if (gbm) {
67*bbecb9d1SAndroid Build Coastguard Worker             virgl_gbm_fini(gbm);
68*bbecb9d1SAndroid Build Coastguard Worker             gbm = NULL;
69*bbecb9d1SAndroid Build Coastguard Worker          }
70*bbecb9d1SAndroid Build Coastguard Worker 
71*bbecb9d1SAndroid Build Coastguard Worker          return -1;
72*bbecb9d1SAndroid Build Coastguard Worker       }
73*bbecb9d1SAndroid Build Coastguard Worker 
74*bbecb9d1SAndroid Build Coastguard Worker       use_context = CONTEXT_EGL;
75*bbecb9d1SAndroid Build Coastguard Worker #else
76*bbecb9d1SAndroid Build Coastguard Worker       (void)preferred_fd;
77*bbecb9d1SAndroid Build Coastguard Worker       vrend_printf( "EGL is not supported on this platform\n");
78*bbecb9d1SAndroid Build Coastguard Worker       return -1;
79*bbecb9d1SAndroid Build Coastguard Worker #endif
80*bbecb9d1SAndroid Build Coastguard Worker    } else if (flags & VIRGL_RENDERER_USE_GLX) {
81*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_GLX_H
82*bbecb9d1SAndroid Build Coastguard Worker       glx_info = virgl_glx_init();
83*bbecb9d1SAndroid Build Coastguard Worker       if (!glx_info)
84*bbecb9d1SAndroid Build Coastguard Worker          return -1;
85*bbecb9d1SAndroid Build Coastguard Worker       use_context = CONTEXT_GLX;
86*bbecb9d1SAndroid Build Coastguard Worker #else
87*bbecb9d1SAndroid Build Coastguard Worker       vrend_printf( "GLX is not supported on this platform\n");
88*bbecb9d1SAndroid Build Coastguard Worker       return -1;
89*bbecb9d1SAndroid Build Coastguard Worker #endif
90*bbecb9d1SAndroid Build Coastguard Worker    }
91*bbecb9d1SAndroid Build Coastguard Worker 
92*bbecb9d1SAndroid Build Coastguard Worker    return 0;
93*bbecb9d1SAndroid Build Coastguard Worker }
94*bbecb9d1SAndroid Build Coastguard Worker 
vrend_winsys_cleanup(void)95*bbecb9d1SAndroid Build Coastguard Worker void vrend_winsys_cleanup(void)
96*bbecb9d1SAndroid Build Coastguard Worker {
97*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
98*bbecb9d1SAndroid Build Coastguard Worker    if (use_context == CONTEXT_EGL) {
99*bbecb9d1SAndroid Build Coastguard Worker       virgl_egl_destroy(egl);
100*bbecb9d1SAndroid Build Coastguard Worker       egl = NULL;
101*bbecb9d1SAndroid Build Coastguard Worker       use_context = CONTEXT_NONE;
102*bbecb9d1SAndroid Build Coastguard Worker       if (gbm) {
103*bbecb9d1SAndroid Build Coastguard Worker          virgl_gbm_fini(gbm);
104*bbecb9d1SAndroid Build Coastguard Worker          gbm = NULL;
105*bbecb9d1SAndroid Build Coastguard Worker       }
106*bbecb9d1SAndroid Build Coastguard Worker    } else if (use_context == CONTEXT_EGL_EXTERNAL) {
107*bbecb9d1SAndroid Build Coastguard Worker       free(egl);
108*bbecb9d1SAndroid Build Coastguard Worker       egl = NULL;
109*bbecb9d1SAndroid Build Coastguard Worker       use_context = CONTEXT_NONE;
110*bbecb9d1SAndroid Build Coastguard Worker    }
111*bbecb9d1SAndroid Build Coastguard Worker #endif
112*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_GLX_H
113*bbecb9d1SAndroid Build Coastguard Worker    if (use_context == CONTEXT_GLX) {
114*bbecb9d1SAndroid Build Coastguard Worker       virgl_glx_destroy(glx_info);
115*bbecb9d1SAndroid Build Coastguard Worker       glx_info = NULL;
116*bbecb9d1SAndroid Build Coastguard Worker       use_context = CONTEXT_NONE;
117*bbecb9d1SAndroid Build Coastguard Worker    }
118*bbecb9d1SAndroid Build Coastguard Worker #endif
119*bbecb9d1SAndroid Build Coastguard Worker }
120*bbecb9d1SAndroid Build Coastguard Worker 
vrend_winsys_init_external(void * egl_display)121*bbecb9d1SAndroid Build Coastguard Worker int vrend_winsys_init_external(void *egl_display)
122*bbecb9d1SAndroid Build Coastguard Worker {
123*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
124*bbecb9d1SAndroid Build Coastguard Worker       egl = virgl_egl_init_external(egl_display);
125*bbecb9d1SAndroid Build Coastguard Worker       if (!egl)
126*bbecb9d1SAndroid Build Coastguard Worker          return -1;
127*bbecb9d1SAndroid Build Coastguard Worker 
128*bbecb9d1SAndroid Build Coastguard Worker       use_context = CONTEXT_EGL_EXTERNAL;
129*bbecb9d1SAndroid Build Coastguard Worker #else
130*bbecb9d1SAndroid Build Coastguard Worker    (void)egl_display;
131*bbecb9d1SAndroid Build Coastguard Worker    vrend_printf( "EGL is not supported on this platform\n");
132*bbecb9d1SAndroid Build Coastguard Worker    return -1;
133*bbecb9d1SAndroid Build Coastguard Worker #endif
134*bbecb9d1SAndroid Build Coastguard Worker 
135*bbecb9d1SAndroid Build Coastguard Worker    return 0;
136*bbecb9d1SAndroid Build Coastguard Worker }
137*bbecb9d1SAndroid Build Coastguard Worker 
vrend_winsys_create_context(struct virgl_gl_ctx_param * param)138*bbecb9d1SAndroid Build Coastguard Worker virgl_renderer_gl_context vrend_winsys_create_context(struct virgl_gl_ctx_param *param)
139*bbecb9d1SAndroid Build Coastguard Worker {
140*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
141*bbecb9d1SAndroid Build Coastguard Worker    if (use_context == CONTEXT_EGL)
142*bbecb9d1SAndroid Build Coastguard Worker       return virgl_egl_create_context(egl, param);
143*bbecb9d1SAndroid Build Coastguard Worker #endif
144*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_GLX_H
145*bbecb9d1SAndroid Build Coastguard Worker    if (use_context == CONTEXT_GLX)
146*bbecb9d1SAndroid Build Coastguard Worker       return virgl_glx_create_context(glx_info, param);
147*bbecb9d1SAndroid Build Coastguard Worker #endif
148*bbecb9d1SAndroid Build Coastguard Worker    return NULL;
149*bbecb9d1SAndroid Build Coastguard Worker }
150*bbecb9d1SAndroid Build Coastguard Worker 
vrend_winsys_destroy_context(virgl_renderer_gl_context ctx)151*bbecb9d1SAndroid Build Coastguard Worker void vrend_winsys_destroy_context(virgl_renderer_gl_context ctx)
152*bbecb9d1SAndroid Build Coastguard Worker {
153*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
154*bbecb9d1SAndroid Build Coastguard Worker    if (use_context == CONTEXT_EGL) {
155*bbecb9d1SAndroid Build Coastguard Worker       virgl_egl_destroy_context(egl, ctx);
156*bbecb9d1SAndroid Build Coastguard Worker       return;
157*bbecb9d1SAndroid Build Coastguard Worker    }
158*bbecb9d1SAndroid Build Coastguard Worker #endif
159*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_GLX_H
160*bbecb9d1SAndroid Build Coastguard Worker    if (use_context == CONTEXT_GLX) {
161*bbecb9d1SAndroid Build Coastguard Worker       virgl_glx_destroy_context(glx_info, ctx);
162*bbecb9d1SAndroid Build Coastguard Worker       return;
163*bbecb9d1SAndroid Build Coastguard Worker    }
164*bbecb9d1SAndroid Build Coastguard Worker #endif
165*bbecb9d1SAndroid Build Coastguard Worker }
166*bbecb9d1SAndroid Build Coastguard Worker 
vrend_winsys_make_context_current(virgl_renderer_gl_context ctx)167*bbecb9d1SAndroid Build Coastguard Worker int vrend_winsys_make_context_current(virgl_renderer_gl_context ctx)
168*bbecb9d1SAndroid Build Coastguard Worker {
169*bbecb9d1SAndroid Build Coastguard Worker    int ret = -1;
170*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
171*bbecb9d1SAndroid Build Coastguard Worker    if (use_context == CONTEXT_EGL) {
172*bbecb9d1SAndroid Build Coastguard Worker       ret = virgl_egl_make_context_current(egl, ctx);
173*bbecb9d1SAndroid Build Coastguard Worker       if (ret)
174*bbecb9d1SAndroid Build Coastguard Worker          vrend_printf("%s: Error switching context: %s\n",
175*bbecb9d1SAndroid Build Coastguard Worker                       __func__, virgl_egl_error_string(eglGetError()));
176*bbecb9d1SAndroid Build Coastguard Worker    }
177*bbecb9d1SAndroid Build Coastguard Worker #endif
178*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_GLX_H
179*bbecb9d1SAndroid Build Coastguard Worker    if (use_context == CONTEXT_GLX) {
180*bbecb9d1SAndroid Build Coastguard Worker       ret = virgl_glx_make_context_current(glx_info, ctx);
181*bbecb9d1SAndroid Build Coastguard Worker       if (ret)
182*bbecb9d1SAndroid Build Coastguard Worker          vrend_printf("%s: Error switching context\n", __func__);
183*bbecb9d1SAndroid Build Coastguard Worker    }
184*bbecb9d1SAndroid Build Coastguard Worker #endif
185*bbecb9d1SAndroid Build Coastguard Worker    assert(!ret && "Failed to switch GL context");
186*bbecb9d1SAndroid Build Coastguard Worker    return ret;
187*bbecb9d1SAndroid Build Coastguard Worker }
188*bbecb9d1SAndroid Build Coastguard Worker 
vrend_winsys_has_gl_colorspace(void)189*bbecb9d1SAndroid Build Coastguard Worker int vrend_winsys_has_gl_colorspace(void)
190*bbecb9d1SAndroid Build Coastguard Worker {
191*bbecb9d1SAndroid Build Coastguard Worker    bool egl_colorspace = false;
192*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
193*bbecb9d1SAndroid Build Coastguard Worker    if (egl)
194*bbecb9d1SAndroid Build Coastguard Worker       egl_colorspace = virgl_has_egl_khr_gl_colorspace(egl);
195*bbecb9d1SAndroid Build Coastguard Worker #endif
196*bbecb9d1SAndroid Build Coastguard Worker    return use_context == CONTEXT_NONE ||
197*bbecb9d1SAndroid Build Coastguard Worker          use_context == CONTEXT_GLX ||
198*bbecb9d1SAndroid Build Coastguard Worker          (use_context == CONTEXT_EGL && egl_colorspace) ||
199*bbecb9d1SAndroid Build Coastguard Worker          (use_context == CONTEXT_EGL_EXTERNAL && egl_colorspace);
200*bbecb9d1SAndroid Build Coastguard Worker }
201*bbecb9d1SAndroid Build Coastguard Worker 
vrend_winsys_get_fourcc_for_texture(uint32_t tex_id,uint32_t format,int * fourcc)202*bbecb9d1SAndroid Build Coastguard Worker int vrend_winsys_get_fourcc_for_texture(uint32_t tex_id, uint32_t format, int *fourcc)
203*bbecb9d1SAndroid Build Coastguard Worker {
204*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
205*bbecb9d1SAndroid Build Coastguard Worker    if (use_context == CONTEXT_EGL)
206*bbecb9d1SAndroid Build Coastguard Worker       return virgl_egl_get_fourcc_for_texture(egl, tex_id, format, fourcc);
207*bbecb9d1SAndroid Build Coastguard Worker #else
208*bbecb9d1SAndroid Build Coastguard Worker    (void)tex_id;
209*bbecb9d1SAndroid Build Coastguard Worker    (void)format;
210*bbecb9d1SAndroid Build Coastguard Worker    (void)fourcc;
211*bbecb9d1SAndroid Build Coastguard Worker #endif
212*bbecb9d1SAndroid Build Coastguard Worker    return 0;
213*bbecb9d1SAndroid Build Coastguard Worker }
214*bbecb9d1SAndroid Build Coastguard Worker 
vrend_winsys_get_fd_for_texture(uint32_t tex_id,int * fd)215*bbecb9d1SAndroid Build Coastguard Worker int vrend_winsys_get_fd_for_texture(uint32_t tex_id, int *fd)
216*bbecb9d1SAndroid Build Coastguard Worker {
217*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
218*bbecb9d1SAndroid Build Coastguard Worker    if (!egl)
219*bbecb9d1SAndroid Build Coastguard Worker       return -1;
220*bbecb9d1SAndroid Build Coastguard Worker 
221*bbecb9d1SAndroid Build Coastguard Worker    return virgl_egl_get_fd_for_texture(egl, tex_id, fd);
222*bbecb9d1SAndroid Build Coastguard Worker #else
223*bbecb9d1SAndroid Build Coastguard Worker    (void)tex_id;
224*bbecb9d1SAndroid Build Coastguard Worker    (void)fd;
225*bbecb9d1SAndroid Build Coastguard Worker    return -1;
226*bbecb9d1SAndroid Build Coastguard Worker #endif
227*bbecb9d1SAndroid Build Coastguard Worker }
228*bbecb9d1SAndroid Build Coastguard Worker 
vrend_winsys_get_fd_for_texture2(uint32_t tex_id,int * fd,int * stride,int * offset)229*bbecb9d1SAndroid Build Coastguard Worker int vrend_winsys_get_fd_for_texture2(uint32_t tex_id, int *fd, int *stride, int *offset)
230*bbecb9d1SAndroid Build Coastguard Worker {
231*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
232*bbecb9d1SAndroid Build Coastguard Worker    if (!egl)
233*bbecb9d1SAndroid Build Coastguard Worker       return -1;
234*bbecb9d1SAndroid Build Coastguard Worker 
235*bbecb9d1SAndroid Build Coastguard Worker    return virgl_egl_get_fd_for_texture2(egl, tex_id, fd, stride, offset);
236*bbecb9d1SAndroid Build Coastguard Worker #else
237*bbecb9d1SAndroid Build Coastguard Worker    (void)tex_id;
238*bbecb9d1SAndroid Build Coastguard Worker    (void)fd;
239*bbecb9d1SAndroid Build Coastguard Worker    (void)stride;
240*bbecb9d1SAndroid Build Coastguard Worker    (void)offset;
241*bbecb9d1SAndroid Build Coastguard Worker    return -1;
242*bbecb9d1SAndroid Build Coastguard Worker #endif
243*bbecb9d1SAndroid Build Coastguard Worker }
244*bbecb9d1SAndroid Build Coastguard Worker 
vrend_winsys_query_video_memory(void)245*bbecb9d1SAndroid Build Coastguard Worker uint32_t vrend_winsys_query_video_memory(void)
246*bbecb9d1SAndroid Build Coastguard Worker {
247*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_GLX_H
248*bbecb9d1SAndroid Build Coastguard Worker    return virgl_glx_query_video_memory(glx_info);
249*bbecb9d1SAndroid Build Coastguard Worker #else
250*bbecb9d1SAndroid Build Coastguard Worker    return 0;
251*bbecb9d1SAndroid Build Coastguard Worker #endif
252*bbecb9d1SAndroid Build Coastguard Worker }
253*bbecb9d1SAndroid Build Coastguard Worker 
254*bbecb9d1SAndroid Build Coastguard Worker /* different_gpu means that GBM and GL renderer are on two different DRM devices.
255*bbecb9d1SAndroid Build Coastguard Worker  * Linear buffers are used for scanouts to make them shareable.
256*bbecb9d1SAndroid Build Coastguard Worker  * Advise the client to use drawable shadowing for performance.
257*bbecb9d1SAndroid Build Coastguard Worker  */
vrend_winsys_different_gpu(void)258*bbecb9d1SAndroid Build Coastguard Worker bool vrend_winsys_different_gpu(void)
259*bbecb9d1SAndroid Build Coastguard Worker {
260*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
261*bbecb9d1SAndroid Build Coastguard Worker    if (egl)
262*bbecb9d1SAndroid Build Coastguard Worker       return virgl_egl_different_gpu(egl);
263*bbecb9d1SAndroid Build Coastguard Worker #endif
264*bbecb9d1SAndroid Build Coastguard Worker    return false;
265*bbecb9d1SAndroid Build Coastguard Worker }
266