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