• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright (C) 2014 Red Hat Inc.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21  * OTHER DEALINGS IN THE SOFTWARE.
22  *
23  **************************************************************************/
24 
25 #include "vrend_winsys.h"
26 
27 #ifdef HAVE_EPOXY_GLX_H
28 #include "vrend_winsys_glx.h"
29 #endif
30 
31 #include <stddef.h>
32 
33 enum {
34    CONTEXT_NONE,
35    CONTEXT_EGL,
36    CONTEXT_GLX
37 };
38 
39 static int use_context = CONTEXT_NONE;
40 
41 #ifdef HAVE_EPOXY_EGL_H
42 struct virgl_egl *egl = NULL;
43 struct virgl_gbm *gbm = NULL;
44 #endif
45 
46 #ifdef HAVE_EPOXY_GLX_H
47 static struct virgl_glx *glx_info = NULL;
48 #endif
49 
vrend_winsys_init(uint32_t flags,int preferred_fd)50 int vrend_winsys_init(uint32_t flags, int preferred_fd)
51 {
52    if (flags & VIRGL_RENDERER_USE_EGL) {
53 #ifdef HAVE_EPOXY_EGL_H
54       /*
55        * If the user specifies a preferred DRM fd and we can't use it, fail. If the user doesn't
56        * specify an fd, it's possible to initialize EGL without one.
57        */
58       gbm = virgl_gbm_init(preferred_fd);
59       if (preferred_fd > 0 && !gbm)
60          return -1;
61 
62       egl = virgl_egl_init(gbm, flags & VIRGL_RENDERER_USE_SURFACELESS,
63                            flags & VIRGL_RENDERER_USE_GLES);
64       if (!egl) {
65          if (gbm) {
66             virgl_gbm_fini(gbm);
67             gbm = NULL;
68          }
69 
70          return -1;
71       }
72 
73       use_context = CONTEXT_EGL;
74 #else
75       (void)preferred_fd;
76       vrend_printf( "EGL is not supported on this platform\n");
77       return -1;
78 #endif
79    } else if (flags & VIRGL_RENDERER_USE_GLX) {
80 #ifdef HAVE_EPOXY_GLX_H
81       glx_info = virgl_glx_init();
82       if (!glx_info)
83          return -1;
84       use_context = CONTEXT_GLX;
85 #else
86       vrend_printf( "GLX is not supported on this platform\n");
87       return -1;
88 #endif
89    }
90 
91    return 0;
92 }
93 
vrend_winsys_cleanup(void)94 void vrend_winsys_cleanup(void)
95 {
96 #ifdef HAVE_EPOXY_EGL_H
97    if (use_context == CONTEXT_EGL) {
98       virgl_egl_destroy(egl);
99       egl = NULL;
100       use_context = CONTEXT_NONE;
101       if (gbm) {
102          virgl_gbm_fini(gbm);
103          gbm = NULL;
104       }
105    }
106 #endif
107 #ifdef HAVE_EPOXY_GLX_H
108    if (use_context == CONTEXT_GLX) {
109       virgl_glx_destroy(glx_info);
110       glx_info = NULL;
111       use_context = CONTEXT_NONE;
112    }
113 #endif
114 }
115 
vrend_winsys_create_context(struct virgl_gl_ctx_param * param)116 virgl_renderer_gl_context vrend_winsys_create_context(struct virgl_gl_ctx_param *param)
117 {
118 #ifdef HAVE_EPOXY_EGL_H
119    if (use_context == CONTEXT_EGL)
120       return virgl_egl_create_context(egl, param);
121 #endif
122 #ifdef HAVE_EPOXY_GLX_H
123    if (use_context == CONTEXT_GLX)
124       return virgl_glx_create_context(glx_info, param);
125 #endif
126    return NULL;
127 }
128 
vrend_winsys_destroy_context(virgl_renderer_gl_context ctx)129 void vrend_winsys_destroy_context(virgl_renderer_gl_context ctx)
130 {
131 #ifdef HAVE_EPOXY_EGL_H
132    if (use_context == CONTEXT_EGL) {
133       virgl_egl_destroy_context(egl, ctx);
134       return;
135    }
136 #endif
137 #ifdef HAVE_EPOXY_GLX_H
138    if (use_context == CONTEXT_GLX) {
139       virgl_glx_destroy_context(glx_info, ctx);
140       return;
141    }
142 #endif
143 }
144 
vrend_winsys_make_context_current(virgl_renderer_gl_context ctx)145 int vrend_winsys_make_context_current(virgl_renderer_gl_context ctx)
146 {
147 #ifdef HAVE_EPOXY_EGL_H
148    if (use_context == CONTEXT_EGL)
149       return virgl_egl_make_context_current(egl, ctx);
150 #endif
151 #ifdef HAVE_EPOXY_GLX_H
152    if (use_context == CONTEXT_GLX)
153       return virgl_glx_make_context_current(glx_info, ctx);
154 #endif
155    return -1;
156 }
157 
vrend_winsys_has_gl_colorspace(void)158 int vrend_winsys_has_gl_colorspace(void)
159 {
160    bool egl_colorspace = false;
161 #ifdef HAVE_EPOXY_EGL_H
162    if (egl)
163       egl_colorspace = virgl_has_egl_khr_gl_colorspace(egl);
164 #endif
165    return use_context == CONTEXT_NONE ||
166          use_context == CONTEXT_GLX ||
167          (use_context == CONTEXT_EGL && egl_colorspace);
168 }
169 
vrend_winsys_get_fourcc_for_texture(uint32_t tex_id,uint32_t format,int * fourcc)170 int vrend_winsys_get_fourcc_for_texture(uint32_t tex_id, uint32_t format, int *fourcc)
171 {
172 #ifdef HAVE_EPOXY_EGL_H
173    if (use_context == CONTEXT_EGL)
174       return virgl_egl_get_fourcc_for_texture(egl, tex_id, format, fourcc);
175 #else
176    (void)tex_id;
177    (void)format;
178    (void)fourcc;
179 #endif
180    return 0;
181 }
182 
vrend_winsys_get_fd_for_texture(uint32_t tex_id,int * fd)183 int vrend_winsys_get_fd_for_texture(uint32_t tex_id, int *fd)
184 {
185 #ifdef HAVE_EPOXY_EGL_H
186    if (!egl)
187       return -1;
188 
189    return virgl_egl_get_fd_for_texture(egl, tex_id, fd);
190 #else
191    (void)tex_id;
192    (void)fd;
193    return -1;
194 #endif
195 }
196 
vrend_winsys_get_fd_for_texture2(uint32_t tex_id,int * fd,int * stride,int * offset)197 int vrend_winsys_get_fd_for_texture2(uint32_t tex_id, int *fd, int *stride, int *offset)
198 {
199 #ifdef HAVE_EPOXY_EGL_H
200    if (!egl)
201       return -1;
202 
203    return virgl_egl_get_fd_for_texture2(egl, tex_id, fd, stride, offset);
204 #else
205    (void)tex_id;
206    (void)fd;
207    (void)stride;
208    (void)offset;
209    return -1;
210 #endif
211 }
212 
vrend_winsys_query_video_memory(void)213 uint32_t vrend_winsys_query_video_memory(void)
214 {
215 #ifdef HAVE_EPOXY_GLX_H
216    return virgl_glx_query_video_memory(glx_info);
217 #else
218    return 0;
219 #endif
220 }
221 
222 /* different_gpu means that GBM and GL renderer are on two different DRM devices.
223  * Linear buffers are used for scanouts to make them shareable.
224  * Advise the client to use drawable shadowing for performance.
225  */
vrend_winsys_different_gpu(void)226 bool vrend_winsys_different_gpu(void)
227 {
228 #ifdef HAVE_EPOXY_EGL_H
229    if (egl)
230       return virgl_egl_different_gpu(egl);
231 #endif
232    return false;
233 }
234