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 /* create our own EGL offscreen rendering context via gbm and rendernodes */
25*bbecb9d1SAndroid Build Coastguard Worker
26*bbecb9d1SAndroid Build Coastguard Worker
27*bbecb9d1SAndroid Build Coastguard Worker /* if we are using EGL and rendernodes then we talk via file descriptors to the remote
28*bbecb9d1SAndroid Build Coastguard Worker node */
29*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
30*bbecb9d1SAndroid Build Coastguard Worker #include "config.h"
31*bbecb9d1SAndroid Build Coastguard Worker #endif
32*bbecb9d1SAndroid Build Coastguard Worker
33*bbecb9d1SAndroid Build Coastguard Worker #define EGL_EGLEXT_PROTOTYPES
34*bbecb9d1SAndroid Build Coastguard Worker #include <errno.h>
35*bbecb9d1SAndroid Build Coastguard Worker #include <fcntl.h>
36*bbecb9d1SAndroid Build Coastguard Worker #include <poll.h>
37*bbecb9d1SAndroid Build Coastguard Worker #include <stdbool.h>
38*bbecb9d1SAndroid Build Coastguard Worker #include <unistd.h>
39*bbecb9d1SAndroid Build Coastguard Worker
40*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_memory.h"
41*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_hw.h"
42*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_util.h"
43*bbecb9d1SAndroid Build Coastguard Worker #include "virglrenderer.h"
44*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_winsys.h"
45*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_winsys_egl.h"
46*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_winsys_gbm.h"
47*bbecb9d1SAndroid Build Coastguard Worker
48*bbecb9d1SAndroid Build Coastguard Worker #define EGL_KHR_SURFACELESS_CONTEXT BIT(0)
49*bbecb9d1SAndroid Build Coastguard Worker #define EGL_KHR_CREATE_CONTEXT BIT(1)
50*bbecb9d1SAndroid Build Coastguard Worker #define EGL_MESA_DRM_IMAGE BIT(2)
51*bbecb9d1SAndroid Build Coastguard Worker #define EGL_MESA_IMAGE_DMA_BUF_EXPORT BIT(3)
52*bbecb9d1SAndroid Build Coastguard Worker #define EGL_MESA_DMA_BUF_IMAGE_IMPORT BIT(4)
53*bbecb9d1SAndroid Build Coastguard Worker #define EGL_KHR_GL_COLORSPACE BIT(5)
54*bbecb9d1SAndroid Build Coastguard Worker #define EGL_EXT_IMAGE_DMA_BUF_IMPORT BIT(6)
55*bbecb9d1SAndroid Build Coastguard Worker #define EGL_EXT_IMAGE_DMA_BUF_IMPORT_MODIFIERS BIT(7)
56*bbecb9d1SAndroid Build Coastguard Worker #define EGL_KHR_FENCE_SYNC_ANDROID BIT(8)
57*bbecb9d1SAndroid Build Coastguard Worker
58*bbecb9d1SAndroid Build Coastguard Worker static const struct {
59*bbecb9d1SAndroid Build Coastguard Worker uint32_t bit;
60*bbecb9d1SAndroid Build Coastguard Worker const char *string;
61*bbecb9d1SAndroid Build Coastguard Worker } extensions_list[] = {
62*bbecb9d1SAndroid Build Coastguard Worker { EGL_KHR_SURFACELESS_CONTEXT, "EGL_KHR_surfaceless_context" },
63*bbecb9d1SAndroid Build Coastguard Worker { EGL_KHR_CREATE_CONTEXT, "EGL_KHR_create_context" },
64*bbecb9d1SAndroid Build Coastguard Worker { EGL_MESA_DRM_IMAGE, "EGL_MESA_drm_image" },
65*bbecb9d1SAndroid Build Coastguard Worker { EGL_MESA_IMAGE_DMA_BUF_EXPORT, "EGL_MESA_image_dma_buf_export" },
66*bbecb9d1SAndroid Build Coastguard Worker { EGL_KHR_GL_COLORSPACE, "EGL_KHR_gl_colorspace" },
67*bbecb9d1SAndroid Build Coastguard Worker { EGL_EXT_IMAGE_DMA_BUF_IMPORT, "EGL_EXT_image_dma_buf_import" },
68*bbecb9d1SAndroid Build Coastguard Worker { EGL_EXT_IMAGE_DMA_BUF_IMPORT_MODIFIERS, "EGL_EXT_image_dma_buf_import_modifiers" },
69*bbecb9d1SAndroid Build Coastguard Worker { EGL_KHR_FENCE_SYNC_ANDROID, "EGL_ANDROID_native_fence_sync"}
70*bbecb9d1SAndroid Build Coastguard Worker };
71*bbecb9d1SAndroid Build Coastguard Worker
72*bbecb9d1SAndroid Build Coastguard Worker struct virgl_egl {
73*bbecb9d1SAndroid Build Coastguard Worker struct virgl_gbm *gbm;
74*bbecb9d1SAndroid Build Coastguard Worker EGLDisplay egl_display;
75*bbecb9d1SAndroid Build Coastguard Worker EGLConfig egl_conf;
76*bbecb9d1SAndroid Build Coastguard Worker EGLContext egl_ctx;
77*bbecb9d1SAndroid Build Coastguard Worker uint32_t extension_bits;
78*bbecb9d1SAndroid Build Coastguard Worker EGLSyncKHR signaled_fence;
79*bbecb9d1SAndroid Build Coastguard Worker bool different_gpu;
80*bbecb9d1SAndroid Build Coastguard Worker };
81*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_has_extension_in_string(const char * haystack,const char * needle)82*bbecb9d1SAndroid Build Coastguard Worker static bool virgl_egl_has_extension_in_string(const char *haystack, const char *needle)
83*bbecb9d1SAndroid Build Coastguard Worker {
84*bbecb9d1SAndroid Build Coastguard Worker const unsigned needle_len = strlen(needle);
85*bbecb9d1SAndroid Build Coastguard Worker
86*bbecb9d1SAndroid Build Coastguard Worker if (!haystack)
87*bbecb9d1SAndroid Build Coastguard Worker return false;
88*bbecb9d1SAndroid Build Coastguard Worker
89*bbecb9d1SAndroid Build Coastguard Worker if (needle_len == 0)
90*bbecb9d1SAndroid Build Coastguard Worker return false;
91*bbecb9d1SAndroid Build Coastguard Worker
92*bbecb9d1SAndroid Build Coastguard Worker while (true) {
93*bbecb9d1SAndroid Build Coastguard Worker const char *const s = strstr(haystack, needle);
94*bbecb9d1SAndroid Build Coastguard Worker
95*bbecb9d1SAndroid Build Coastguard Worker if (s == NULL)
96*bbecb9d1SAndroid Build Coastguard Worker return false;
97*bbecb9d1SAndroid Build Coastguard Worker
98*bbecb9d1SAndroid Build Coastguard Worker if (s[needle_len] == ' ' || s[needle_len] == '\0') {
99*bbecb9d1SAndroid Build Coastguard Worker return true;
100*bbecb9d1SAndroid Build Coastguard Worker }
101*bbecb9d1SAndroid Build Coastguard Worker
102*bbecb9d1SAndroid Build Coastguard Worker /* strstr found an extension whose name begins with
103*bbecb9d1SAndroid Build Coastguard Worker * needle, but whose name is not equal to needle.
104*bbecb9d1SAndroid Build Coastguard Worker * Restart the search at s + needle_len so that we
105*bbecb9d1SAndroid Build Coastguard Worker * don't just find the same extension again and go
106*bbecb9d1SAndroid Build Coastguard Worker * into an infinite loop.
107*bbecb9d1SAndroid Build Coastguard Worker */
108*bbecb9d1SAndroid Build Coastguard Worker haystack = s + needle_len;
109*bbecb9d1SAndroid Build Coastguard Worker }
110*bbecb9d1SAndroid Build Coastguard Worker
111*bbecb9d1SAndroid Build Coastguard Worker return false;
112*bbecb9d1SAndroid Build Coastguard Worker }
113*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_init_extensions(struct virgl_egl * egl,const char * extensions)114*bbecb9d1SAndroid Build Coastguard Worker static int virgl_egl_init_extensions(struct virgl_egl *egl, const char *extensions)
115*bbecb9d1SAndroid Build Coastguard Worker {
116*bbecb9d1SAndroid Build Coastguard Worker for (uint32_t i = 0; i < ARRAY_SIZE(extensions_list); i++) {
117*bbecb9d1SAndroid Build Coastguard Worker if (virgl_egl_has_extension_in_string(extensions, extensions_list[i].string))
118*bbecb9d1SAndroid Build Coastguard Worker egl->extension_bits |= extensions_list[i].bit;
119*bbecb9d1SAndroid Build Coastguard Worker }
120*bbecb9d1SAndroid Build Coastguard Worker
121*bbecb9d1SAndroid Build Coastguard Worker if (!has_bits(egl->extension_bits, EGL_KHR_SURFACELESS_CONTEXT | EGL_KHR_CREATE_CONTEXT)) {
122*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "Missing EGL_KHR_surfaceless_context or EGL_KHR_create_context\n");
123*bbecb9d1SAndroid Build Coastguard Worker return -1;
124*bbecb9d1SAndroid Build Coastguard Worker }
125*bbecb9d1SAndroid Build Coastguard Worker
126*bbecb9d1SAndroid Build Coastguard Worker return 0;
127*bbecb9d1SAndroid Build Coastguard Worker }
128*bbecb9d1SAndroid Build Coastguard Worker
129*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
130*bbecb9d1SAndroid Build Coastguard Worker
131*bbecb9d1SAndroid Build Coastguard Worker struct egl_funcs {
132*bbecb9d1SAndroid Build Coastguard Worker PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplay;
133*bbecb9d1SAndroid Build Coastguard Worker PFNEGLQUERYDEVICESEXTPROC eglQueryDevices;
134*bbecb9d1SAndroid Build Coastguard Worker PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceString;
135*bbecb9d1SAndroid Build Coastguard Worker };
136*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_get_interface(struct egl_funcs * funcs)137*bbecb9d1SAndroid Build Coastguard Worker static bool virgl_egl_get_interface(struct egl_funcs *funcs)
138*bbecb9d1SAndroid Build Coastguard Worker {
139*bbecb9d1SAndroid Build Coastguard Worker const char *client_extensions = eglQueryString (NULL, EGL_EXTENSIONS);
140*bbecb9d1SAndroid Build Coastguard Worker
141*bbecb9d1SAndroid Build Coastguard Worker assert(funcs);
142*bbecb9d1SAndroid Build Coastguard Worker
143*bbecb9d1SAndroid Build Coastguard Worker if (virgl_egl_has_extension_in_string(client_extensions, "EGL_EXT_platform_base")) {
144*bbecb9d1SAndroid Build Coastguard Worker funcs->eglGetPlatformDisplay =
145*bbecb9d1SAndroid Build Coastguard Worker (PFNEGLGETPLATFORMDISPLAYEXTPROC) eglGetProcAddress ("eglGetPlatformDisplayEXT");
146*bbecb9d1SAndroid Build Coastguard Worker }
147*bbecb9d1SAndroid Build Coastguard Worker
148*bbecb9d1SAndroid Build Coastguard Worker if (!funcs->eglGetPlatformDisplay)
149*bbecb9d1SAndroid Build Coastguard Worker return false;
150*bbecb9d1SAndroid Build Coastguard Worker
151*bbecb9d1SAndroid Build Coastguard Worker if (!virgl_egl_has_extension_in_string(client_extensions, "EGL_EXT_platform_device"))
152*bbecb9d1SAndroid Build Coastguard Worker return false;
153*bbecb9d1SAndroid Build Coastguard Worker
154*bbecb9d1SAndroid Build Coastguard Worker if (!virgl_egl_has_extension_in_string(client_extensions, "EGL_EXT_device_enumeration"))
155*bbecb9d1SAndroid Build Coastguard Worker return false;
156*bbecb9d1SAndroid Build Coastguard Worker
157*bbecb9d1SAndroid Build Coastguard Worker funcs->eglQueryDevices = (PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress ("eglQueryDevicesEXT");
158*bbecb9d1SAndroid Build Coastguard Worker if (!funcs->eglQueryDevices)
159*bbecb9d1SAndroid Build Coastguard Worker return false;
160*bbecb9d1SAndroid Build Coastguard Worker
161*bbecb9d1SAndroid Build Coastguard Worker if (!virgl_egl_has_extension_in_string(client_extensions, "EGL_EXT_device_query"))
162*bbecb9d1SAndroid Build Coastguard Worker return false;
163*bbecb9d1SAndroid Build Coastguard Worker
164*bbecb9d1SAndroid Build Coastguard Worker funcs->eglQueryDeviceString = (PFNEGLQUERYDEVICESTRINGEXTPROC)eglGetProcAddress("eglQueryDeviceStringEXT");
165*bbecb9d1SAndroid Build Coastguard Worker if (!funcs->eglQueryDeviceString)
166*bbecb9d1SAndroid Build Coastguard Worker return false;
167*bbecb9d1SAndroid Build Coastguard Worker
168*bbecb9d1SAndroid Build Coastguard Worker return true;
169*bbecb9d1SAndroid Build Coastguard Worker }
170*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_find_3d_device(struct gbm_device_info * dev_infos,EGLint num_devices,uint32_t flags)171*bbecb9d1SAndroid Build Coastguard Worker static EGLint virgl_egl_find_3d_device(struct gbm_device_info *dev_infos, EGLint num_devices, uint32_t flags)
172*bbecb9d1SAndroid Build Coastguard Worker {
173*bbecb9d1SAndroid Build Coastguard Worker EGLint d;
174*bbecb9d1SAndroid Build Coastguard Worker
175*bbecb9d1SAndroid Build Coastguard Worker for (d = 0; d < num_devices; d++) {
176*bbecb9d1SAndroid Build Coastguard Worker if ((dev_infos[d].dev_type_flags & flags) == flags
177*bbecb9d1SAndroid Build Coastguard Worker && dev_infos[d].dev_type_flags & GBM_DEV_TYPE_FLAG_3D)
178*bbecb9d1SAndroid Build Coastguard Worker return d;
179*bbecb9d1SAndroid Build Coastguard Worker }
180*bbecb9d1SAndroid Build Coastguard Worker
181*bbecb9d1SAndroid Build Coastguard Worker return -1;
182*bbecb9d1SAndroid Build Coastguard Worker }
183*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_find_matching_device(struct gbm_device_info * dev_infos,EGLint num_devices,int dri_node_num)184*bbecb9d1SAndroid Build Coastguard Worker static EGLint virgl_egl_find_matching_device(struct gbm_device_info *dev_infos, EGLint num_devices, int dri_node_num)
185*bbecb9d1SAndroid Build Coastguard Worker {
186*bbecb9d1SAndroid Build Coastguard Worker EGLint d;
187*bbecb9d1SAndroid Build Coastguard Worker
188*bbecb9d1SAndroid Build Coastguard Worker for (d = 0; d < num_devices; d++) {
189*bbecb9d1SAndroid Build Coastguard Worker if (dev_infos[d].dri_node_num == dri_node_num)
190*bbecb9d1SAndroid Build Coastguard Worker return d;
191*bbecb9d1SAndroid Build Coastguard Worker }
192*bbecb9d1SAndroid Build Coastguard Worker
193*bbecb9d1SAndroid Build Coastguard Worker return -1;
194*bbecb9d1SAndroid Build Coastguard Worker }
195*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_get_device(struct virgl_egl * egl,struct egl_funcs * funcs)196*bbecb9d1SAndroid Build Coastguard Worker static EGLDeviceEXT virgl_egl_get_device(struct virgl_egl *egl, struct egl_funcs *funcs) {
197*bbecb9d1SAndroid Build Coastguard Worker EGLint num_devices = 0;
198*bbecb9d1SAndroid Build Coastguard Worker EGLint max_devices = 64;
199*bbecb9d1SAndroid Build Coastguard Worker EGLDeviceEXT devices[64];
200*bbecb9d1SAndroid Build Coastguard Worker struct gbm_device_info dev_infos[64];
201*bbecb9d1SAndroid Build Coastguard Worker struct gbm_device_info gbm_dev_info;
202*bbecb9d1SAndroid Build Coastguard Worker EGLint device_num = -1;
203*bbecb9d1SAndroid Build Coastguard Worker EGLint d;
204*bbecb9d1SAndroid Build Coastguard Worker
205*bbecb9d1SAndroid Build Coastguard Worker if (gbm_detect_device_info(0, gbm_device_get_fd(egl->gbm->device), &gbm_dev_info) < 0)
206*bbecb9d1SAndroid Build Coastguard Worker return EGL_NO_DEVICE_EXT;
207*bbecb9d1SAndroid Build Coastguard Worker
208*bbecb9d1SAndroid Build Coastguard Worker if (!funcs->eglQueryDevices(max_devices, devices, &num_devices))
209*bbecb9d1SAndroid Build Coastguard Worker return EGL_NO_DEVICE_EXT;
210*bbecb9d1SAndroid Build Coastguard Worker
211*bbecb9d1SAndroid Build Coastguard Worker /* We query EGL_DRM_DEVICE_FILE_EXT without checking EGL_EXT_device_drm extension,
212*bbecb9d1SAndroid Build Coastguard Worker * we just get NULL when it is not available. Otherwise we would have to query it
213*bbecb9d1SAndroid Build Coastguard Worker * after initializing display for every device.
214*bbecb9d1SAndroid Build Coastguard Worker */
215*bbecb9d1SAndroid Build Coastguard Worker for (d = 0; d < num_devices; d++) {
216*bbecb9d1SAndroid Build Coastguard Worker const char *dev_node = funcs->eglQueryDeviceString(devices[d], EGL_DRM_DEVICE_FILE_EXT);
217*bbecb9d1SAndroid Build Coastguard Worker memset(&dev_infos[d], 0, sizeof(dev_infos[d]));
218*bbecb9d1SAndroid Build Coastguard Worker if (dev_node) {
219*bbecb9d1SAndroid Build Coastguard Worker if (gbm_detect_device_info_path(0, dev_node, dev_infos+d) < 0)
220*bbecb9d1SAndroid Build Coastguard Worker return false;
221*bbecb9d1SAndroid Build Coastguard Worker } else {
222*bbecb9d1SAndroid Build Coastguard Worker dev_infos[d].dri_node_num = -1;
223*bbecb9d1SAndroid Build Coastguard Worker }
224*bbecb9d1SAndroid Build Coastguard Worker }
225*bbecb9d1SAndroid Build Coastguard Worker
226*bbecb9d1SAndroid Build Coastguard Worker if (getenv("VIRGL_PREFER_DGPU"))
227*bbecb9d1SAndroid Build Coastguard Worker /* Find a discrete GPU. */
228*bbecb9d1SAndroid Build Coastguard Worker device_num = virgl_egl_find_3d_device(dev_infos, num_devices, GBM_DEV_TYPE_FLAG_DISCRETE);
229*bbecb9d1SAndroid Build Coastguard Worker
230*bbecb9d1SAndroid Build Coastguard Worker if (device_num >= 0) {
231*bbecb9d1SAndroid Build Coastguard Worker egl->different_gpu = dev_infos[device_num].dri_node_num != gbm_dev_info.dri_node_num;
232*bbecb9d1SAndroid Build Coastguard Worker } else if (gbm_dev_info.dev_type_flags & GBM_DEV_TYPE_FLAG_ARMSOC) {
233*bbecb9d1SAndroid Build Coastguard Worker /* Find 3D device on ARM SOC. */
234*bbecb9d1SAndroid Build Coastguard Worker device_num = virgl_egl_find_3d_device(dev_infos, num_devices, GBM_DEV_TYPE_FLAG_ARMSOC);
235*bbecb9d1SAndroid Build Coastguard Worker }
236*bbecb9d1SAndroid Build Coastguard Worker
237*bbecb9d1SAndroid Build Coastguard Worker if (device_num < 0) {
238*bbecb9d1SAndroid Build Coastguard Worker /* Try to match GBM device. */
239*bbecb9d1SAndroid Build Coastguard Worker device_num = virgl_egl_find_matching_device(dev_infos, num_devices, gbm_dev_info.dri_node_num);
240*bbecb9d1SAndroid Build Coastguard Worker }
241*bbecb9d1SAndroid Build Coastguard Worker if (device_num < 0)
242*bbecb9d1SAndroid Build Coastguard Worker return EGL_NO_DEVICE_EXT;
243*bbecb9d1SAndroid Build Coastguard Worker
244*bbecb9d1SAndroid Build Coastguard Worker return devices[device_num];
245*bbecb9d1SAndroid Build Coastguard Worker }
246*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_get_display(struct virgl_egl * egl)247*bbecb9d1SAndroid Build Coastguard Worker static bool virgl_egl_get_display(struct virgl_egl *egl)
248*bbecb9d1SAndroid Build Coastguard Worker {
249*bbecb9d1SAndroid Build Coastguard Worker struct egl_funcs funcs = { 0 };
250*bbecb9d1SAndroid Build Coastguard Worker EGLDeviceEXT device;
251*bbecb9d1SAndroid Build Coastguard Worker
252*bbecb9d1SAndroid Build Coastguard Worker if (!egl->gbm)
253*bbecb9d1SAndroid Build Coastguard Worker return false;
254*bbecb9d1SAndroid Build Coastguard Worker
255*bbecb9d1SAndroid Build Coastguard Worker if (!virgl_egl_get_interface(&funcs))
256*bbecb9d1SAndroid Build Coastguard Worker return false;
257*bbecb9d1SAndroid Build Coastguard Worker
258*bbecb9d1SAndroid Build Coastguard Worker device = virgl_egl_get_device(egl, &funcs);
259*bbecb9d1SAndroid Build Coastguard Worker
260*bbecb9d1SAndroid Build Coastguard Worker if (device == EGL_NO_DEVICE_EXT)
261*bbecb9d1SAndroid Build Coastguard Worker return false;
262*bbecb9d1SAndroid Build Coastguard Worker
263*bbecb9d1SAndroid Build Coastguard Worker egl->egl_display = funcs.eglGetPlatformDisplay(EGL_PLATFORM_DEVICE_EXT, device, NULL);
264*bbecb9d1SAndroid Build Coastguard Worker return true;
265*bbecb9d1SAndroid Build Coastguard Worker }
266*bbecb9d1SAndroid Build Coastguard Worker #endif /* ENABLE_MINIGBM_ALLOCATION */
267*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_init(struct virgl_gbm * gbm,bool surfaceless,bool gles)268*bbecb9d1SAndroid Build Coastguard Worker struct virgl_egl *virgl_egl_init(struct virgl_gbm *gbm, bool surfaceless, bool gles)
269*bbecb9d1SAndroid Build Coastguard Worker {
270*bbecb9d1SAndroid Build Coastguard Worker static EGLint conf_att[] = {
271*bbecb9d1SAndroid Build Coastguard Worker EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
272*bbecb9d1SAndroid Build Coastguard Worker EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
273*bbecb9d1SAndroid Build Coastguard Worker EGL_RED_SIZE, 1,
274*bbecb9d1SAndroid Build Coastguard Worker EGL_GREEN_SIZE, 1,
275*bbecb9d1SAndroid Build Coastguard Worker EGL_BLUE_SIZE, 1,
276*bbecb9d1SAndroid Build Coastguard Worker EGL_ALPHA_SIZE, 0,
277*bbecb9d1SAndroid Build Coastguard Worker EGL_NONE,
278*bbecb9d1SAndroid Build Coastguard Worker };
279*bbecb9d1SAndroid Build Coastguard Worker static const EGLint ctx_att[] = {
280*bbecb9d1SAndroid Build Coastguard Worker EGL_CONTEXT_CLIENT_VERSION, 2,
281*bbecb9d1SAndroid Build Coastguard Worker EGL_NONE
282*bbecb9d1SAndroid Build Coastguard Worker };
283*bbecb9d1SAndroid Build Coastguard Worker EGLBoolean success;
284*bbecb9d1SAndroid Build Coastguard Worker EGLenum api;
285*bbecb9d1SAndroid Build Coastguard Worker EGLint major, minor, num_configs;
286*bbecb9d1SAndroid Build Coastguard Worker const char *extensions;
287*bbecb9d1SAndroid Build Coastguard Worker struct virgl_egl *egl;
288*bbecb9d1SAndroid Build Coastguard Worker
289*bbecb9d1SAndroid Build Coastguard Worker egl = calloc(1, sizeof(struct virgl_egl));
290*bbecb9d1SAndroid Build Coastguard Worker if (!egl)
291*bbecb9d1SAndroid Build Coastguard Worker return NULL;
292*bbecb9d1SAndroid Build Coastguard Worker
293*bbecb9d1SAndroid Build Coastguard Worker if (gles)
294*bbecb9d1SAndroid Build Coastguard Worker conf_att[3] = EGL_OPENGL_ES2_BIT;
295*bbecb9d1SAndroid Build Coastguard Worker
296*bbecb9d1SAndroid Build Coastguard Worker if (surfaceless)
297*bbecb9d1SAndroid Build Coastguard Worker conf_att[1] = EGL_PBUFFER_BIT;
298*bbecb9d1SAndroid Build Coastguard Worker else if (!gbm)
299*bbecb9d1SAndroid Build Coastguard Worker goto fail;
300*bbecb9d1SAndroid Build Coastguard Worker
301*bbecb9d1SAndroid Build Coastguard Worker egl->gbm = gbm;
302*bbecb9d1SAndroid Build Coastguard Worker egl->different_gpu = false;
303*bbecb9d1SAndroid Build Coastguard Worker const char *client_extensions = eglQueryString (NULL, EGL_EXTENSIONS);
304*bbecb9d1SAndroid Build Coastguard Worker
305*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
306*bbecb9d1SAndroid Build Coastguard Worker if (virgl_egl_get_display(egl)) {
307*bbecb9d1SAndroid Build Coastguard Worker /* Make -Wdangling-else happy. */
308*bbecb9d1SAndroid Build Coastguard Worker } else /* Fallback to surfaceless. */
309*bbecb9d1SAndroid Build Coastguard Worker #endif
310*bbecb9d1SAndroid Build Coastguard Worker if (virgl_egl_has_extension_in_string(client_extensions, "EGL_EXT_platform_base")) {
311*bbecb9d1SAndroid Build Coastguard Worker PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display =
312*bbecb9d1SAndroid Build Coastguard Worker (PFNEGLGETPLATFORMDISPLAYEXTPROC) eglGetProcAddress ("eglGetPlatformDisplayEXT");
313*bbecb9d1SAndroid Build Coastguard Worker
314*bbecb9d1SAndroid Build Coastguard Worker if (!get_platform_display)
315*bbecb9d1SAndroid Build Coastguard Worker goto fail;
316*bbecb9d1SAndroid Build Coastguard Worker
317*bbecb9d1SAndroid Build Coastguard Worker if (surfaceless) {
318*bbecb9d1SAndroid Build Coastguard Worker egl->egl_display = get_platform_display (EGL_PLATFORM_SURFACELESS_MESA,
319*bbecb9d1SAndroid Build Coastguard Worker EGL_DEFAULT_DISPLAY, NULL);
320*bbecb9d1SAndroid Build Coastguard Worker } else
321*bbecb9d1SAndroid Build Coastguard Worker egl->egl_display = get_platform_display (EGL_PLATFORM_GBM_KHR,
322*bbecb9d1SAndroid Build Coastguard Worker (EGLNativeDisplayType)egl->gbm->device, NULL);
323*bbecb9d1SAndroid Build Coastguard Worker } else {
324*bbecb9d1SAndroid Build Coastguard Worker if (egl->gbm && egl->gbm->device) {
325*bbecb9d1SAndroid Build Coastguard Worker egl->egl_display = eglGetDisplay((EGLNativeDisplayType)egl->gbm->device);
326*bbecb9d1SAndroid Build Coastguard Worker }
327*bbecb9d1SAndroid Build Coastguard Worker }
328*bbecb9d1SAndroid Build Coastguard Worker
329*bbecb9d1SAndroid Build Coastguard Worker if (!egl->egl_display) {
330*bbecb9d1SAndroid Build Coastguard Worker /*
331*bbecb9d1SAndroid Build Coastguard Worker * Don't fallback to the default display if the fd provided by (*get_drm_fd)
332*bbecb9d1SAndroid Build Coastguard Worker * can't be used.
333*bbecb9d1SAndroid Build Coastguard Worker */
334*bbecb9d1SAndroid Build Coastguard Worker if (egl->gbm && egl->gbm->fd < 0)
335*bbecb9d1SAndroid Build Coastguard Worker goto fail;
336*bbecb9d1SAndroid Build Coastguard Worker
337*bbecb9d1SAndroid Build Coastguard Worker egl->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
338*bbecb9d1SAndroid Build Coastguard Worker if (!egl->egl_display)
339*bbecb9d1SAndroid Build Coastguard Worker goto fail;
340*bbecb9d1SAndroid Build Coastguard Worker }
341*bbecb9d1SAndroid Build Coastguard Worker
342*bbecb9d1SAndroid Build Coastguard Worker success = eglInitialize(egl->egl_display, &major, &minor);
343*bbecb9d1SAndroid Build Coastguard Worker if (!success)
344*bbecb9d1SAndroid Build Coastguard Worker goto fail;
345*bbecb9d1SAndroid Build Coastguard Worker
346*bbecb9d1SAndroid Build Coastguard Worker extensions = eglQueryString(egl->egl_display, EGL_EXTENSIONS);
347*bbecb9d1SAndroid Build Coastguard Worker #ifdef VIRGL_EGL_DEBUG
348*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "EGL major/minor: %d.%d\n", major, minor);
349*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "EGL version: %s\n",
350*bbecb9d1SAndroid Build Coastguard Worker eglQueryString(egl->egl_display, EGL_VERSION));
351*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "EGL vendor: %s\n",
352*bbecb9d1SAndroid Build Coastguard Worker eglQueryString(egl->egl_display, EGL_VENDOR));
353*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "EGL extensions: %s\n", extensions);
354*bbecb9d1SAndroid Build Coastguard Worker #endif
355*bbecb9d1SAndroid Build Coastguard Worker
356*bbecb9d1SAndroid Build Coastguard Worker if (virgl_egl_init_extensions(egl, extensions))
357*bbecb9d1SAndroid Build Coastguard Worker goto fail;
358*bbecb9d1SAndroid Build Coastguard Worker
359*bbecb9d1SAndroid Build Coastguard Worker if (gles)
360*bbecb9d1SAndroid Build Coastguard Worker api = EGL_OPENGL_ES_API;
361*bbecb9d1SAndroid Build Coastguard Worker else
362*bbecb9d1SAndroid Build Coastguard Worker api = EGL_OPENGL_API;
363*bbecb9d1SAndroid Build Coastguard Worker success = eglBindAPI(api);
364*bbecb9d1SAndroid Build Coastguard Worker if (!success)
365*bbecb9d1SAndroid Build Coastguard Worker goto fail;
366*bbecb9d1SAndroid Build Coastguard Worker
367*bbecb9d1SAndroid Build Coastguard Worker success = eglChooseConfig(egl->egl_display, conf_att, &egl->egl_conf,
368*bbecb9d1SAndroid Build Coastguard Worker 1, &num_configs);
369*bbecb9d1SAndroid Build Coastguard Worker if (!success || num_configs != 1)
370*bbecb9d1SAndroid Build Coastguard Worker goto fail;
371*bbecb9d1SAndroid Build Coastguard Worker
372*bbecb9d1SAndroid Build Coastguard Worker egl->egl_ctx = eglCreateContext(egl->egl_display, egl->egl_conf, EGL_NO_CONTEXT,
373*bbecb9d1SAndroid Build Coastguard Worker ctx_att);
374*bbecb9d1SAndroid Build Coastguard Worker if (!egl->egl_ctx)
375*bbecb9d1SAndroid Build Coastguard Worker goto fail;
376*bbecb9d1SAndroid Build Coastguard Worker
377*bbecb9d1SAndroid Build Coastguard Worker eglMakeCurrent(egl->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
378*bbecb9d1SAndroid Build Coastguard Worker egl->egl_ctx);
379*bbecb9d1SAndroid Build Coastguard Worker
380*bbecb9d1SAndroid Build Coastguard Worker if (gles && virgl_egl_supports_fences(egl)) {
381*bbecb9d1SAndroid Build Coastguard Worker egl->signaled_fence = eglCreateSyncKHR(egl->egl_display,
382*bbecb9d1SAndroid Build Coastguard Worker EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
383*bbecb9d1SAndroid Build Coastguard Worker if (!egl->signaled_fence) {
384*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("Failed to create signaled fence");
385*bbecb9d1SAndroid Build Coastguard Worker goto fail;
386*bbecb9d1SAndroid Build Coastguard Worker }
387*bbecb9d1SAndroid Build Coastguard Worker }
388*bbecb9d1SAndroid Build Coastguard Worker
389*bbecb9d1SAndroid Build Coastguard Worker return egl;
390*bbecb9d1SAndroid Build Coastguard Worker
391*bbecb9d1SAndroid Build Coastguard Worker fail:
392*bbecb9d1SAndroid Build Coastguard Worker free(egl);
393*bbecb9d1SAndroid Build Coastguard Worker return NULL;
394*bbecb9d1SAndroid Build Coastguard Worker }
395*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_destroy(struct virgl_egl * egl)396*bbecb9d1SAndroid Build Coastguard Worker void virgl_egl_destroy(struct virgl_egl *egl)
397*bbecb9d1SAndroid Build Coastguard Worker {
398*bbecb9d1SAndroid Build Coastguard Worker if (egl->signaled_fence) {
399*bbecb9d1SAndroid Build Coastguard Worker eglDestroySyncKHR(egl->egl_display, egl->signaled_fence);
400*bbecb9d1SAndroid Build Coastguard Worker }
401*bbecb9d1SAndroid Build Coastguard Worker eglMakeCurrent(egl->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
402*bbecb9d1SAndroid Build Coastguard Worker EGL_NO_CONTEXT);
403*bbecb9d1SAndroid Build Coastguard Worker eglDestroyContext(egl->egl_display, egl->egl_ctx);
404*bbecb9d1SAndroid Build Coastguard Worker eglTerminate(egl->egl_display);
405*bbecb9d1SAndroid Build Coastguard Worker free(egl);
406*bbecb9d1SAndroid Build Coastguard Worker }
407*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_init_external(EGLDisplay egl_display)408*bbecb9d1SAndroid Build Coastguard Worker struct virgl_egl *virgl_egl_init_external(EGLDisplay egl_display)
409*bbecb9d1SAndroid Build Coastguard Worker {
410*bbecb9d1SAndroid Build Coastguard Worker const char *extensions;
411*bbecb9d1SAndroid Build Coastguard Worker struct virgl_egl *egl;
412*bbecb9d1SAndroid Build Coastguard Worker
413*bbecb9d1SAndroid Build Coastguard Worker egl = calloc(1, sizeof(struct virgl_egl));
414*bbecb9d1SAndroid Build Coastguard Worker if (!egl)
415*bbecb9d1SAndroid Build Coastguard Worker return NULL;
416*bbecb9d1SAndroid Build Coastguard Worker
417*bbecb9d1SAndroid Build Coastguard Worker egl->egl_display = egl_display;
418*bbecb9d1SAndroid Build Coastguard Worker
419*bbecb9d1SAndroid Build Coastguard Worker extensions = eglQueryString(egl->egl_display, EGL_EXTENSIONS);
420*bbecb9d1SAndroid Build Coastguard Worker #ifdef VIRGL_EGL_DEBUG
421*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "EGL version: %s\n",
422*bbecb9d1SAndroid Build Coastguard Worker eglQueryString(egl->egl_display, EGL_VERSION));
423*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "EGL vendor: %s\n",
424*bbecb9d1SAndroid Build Coastguard Worker eglQueryString(egl->egl_display, EGL_VENDOR));
425*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "EGL extensions: %s\n", extensions);
426*bbecb9d1SAndroid Build Coastguard Worker #endif
427*bbecb9d1SAndroid Build Coastguard Worker
428*bbecb9d1SAndroid Build Coastguard Worker if (virgl_egl_init_extensions(egl, extensions)) {
429*bbecb9d1SAndroid Build Coastguard Worker free(egl);
430*bbecb9d1SAndroid Build Coastguard Worker return NULL;
431*bbecb9d1SAndroid Build Coastguard Worker }
432*bbecb9d1SAndroid Build Coastguard Worker
433*bbecb9d1SAndroid Build Coastguard Worker gbm = virgl_gbm_init(-1);
434*bbecb9d1SAndroid Build Coastguard Worker egl->gbm = gbm;
435*bbecb9d1SAndroid Build Coastguard Worker
436*bbecb9d1SAndroid Build Coastguard Worker return egl;
437*bbecb9d1SAndroid Build Coastguard Worker }
438*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_create_context(struct virgl_egl * egl,struct virgl_gl_ctx_param * vparams)439*bbecb9d1SAndroid Build Coastguard Worker virgl_renderer_gl_context virgl_egl_create_context(struct virgl_egl *egl, struct virgl_gl_ctx_param *vparams)
440*bbecb9d1SAndroid Build Coastguard Worker {
441*bbecb9d1SAndroid Build Coastguard Worker EGLContext egl_ctx;
442*bbecb9d1SAndroid Build Coastguard Worker EGLint ctx_att[] = {
443*bbecb9d1SAndroid Build Coastguard Worker EGL_CONTEXT_CLIENT_VERSION, vparams->major_ver,
444*bbecb9d1SAndroid Build Coastguard Worker EGL_CONTEXT_MINOR_VERSION_KHR, vparams->minor_ver,
445*bbecb9d1SAndroid Build Coastguard Worker EGL_NONE
446*bbecb9d1SAndroid Build Coastguard Worker };
447*bbecb9d1SAndroid Build Coastguard Worker egl_ctx = eglCreateContext(egl->egl_display,
448*bbecb9d1SAndroid Build Coastguard Worker egl->egl_conf,
449*bbecb9d1SAndroid Build Coastguard Worker vparams->shared ? eglGetCurrentContext() : EGL_NO_CONTEXT,
450*bbecb9d1SAndroid Build Coastguard Worker ctx_att);
451*bbecb9d1SAndroid Build Coastguard Worker return (virgl_renderer_gl_context)egl_ctx;
452*bbecb9d1SAndroid Build Coastguard Worker }
453*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_destroy_context(struct virgl_egl * egl,virgl_renderer_gl_context virglctx)454*bbecb9d1SAndroid Build Coastguard Worker void virgl_egl_destroy_context(struct virgl_egl *egl, virgl_renderer_gl_context virglctx)
455*bbecb9d1SAndroid Build Coastguard Worker {
456*bbecb9d1SAndroid Build Coastguard Worker EGLContext egl_ctx = (EGLContext)virglctx;
457*bbecb9d1SAndroid Build Coastguard Worker eglDestroyContext(egl->egl_display, egl_ctx);
458*bbecb9d1SAndroid Build Coastguard Worker }
459*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_make_context_current(struct virgl_egl * egl,virgl_renderer_gl_context virglctx)460*bbecb9d1SAndroid Build Coastguard Worker int virgl_egl_make_context_current(struct virgl_egl *egl, virgl_renderer_gl_context virglctx)
461*bbecb9d1SAndroid Build Coastguard Worker {
462*bbecb9d1SAndroid Build Coastguard Worker EGLContext egl_ctx = (EGLContext)virglctx;
463*bbecb9d1SAndroid Build Coastguard Worker
464*bbecb9d1SAndroid Build Coastguard Worker return eglMakeCurrent(egl->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
465*bbecb9d1SAndroid Build Coastguard Worker egl_ctx) ? 0 : -1;
466*bbecb9d1SAndroid Build Coastguard Worker }
467*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_get_current_context(UNUSED struct virgl_egl * egl)468*bbecb9d1SAndroid Build Coastguard Worker virgl_renderer_gl_context virgl_egl_get_current_context(UNUSED struct virgl_egl *egl)
469*bbecb9d1SAndroid Build Coastguard Worker {
470*bbecb9d1SAndroid Build Coastguard Worker EGLContext egl_ctx = eglGetCurrentContext();
471*bbecb9d1SAndroid Build Coastguard Worker return (virgl_renderer_gl_context)egl_ctx;
472*bbecb9d1SAndroid Build Coastguard Worker }
473*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_get_fourcc_for_texture(struct virgl_egl * egl,uint32_t tex_id,uint32_t format,int * fourcc)474*bbecb9d1SAndroid Build Coastguard Worker int virgl_egl_get_fourcc_for_texture(struct virgl_egl *egl, uint32_t tex_id, uint32_t format, int *fourcc)
475*bbecb9d1SAndroid Build Coastguard Worker {
476*bbecb9d1SAndroid Build Coastguard Worker int ret = EINVAL;
477*bbecb9d1SAndroid Build Coastguard Worker uint32_t gbm_format = 0;
478*bbecb9d1SAndroid Build Coastguard Worker
479*bbecb9d1SAndroid Build Coastguard Worker EGLImageKHR image;
480*bbecb9d1SAndroid Build Coastguard Worker EGLBoolean success;
481*bbecb9d1SAndroid Build Coastguard Worker
482*bbecb9d1SAndroid Build Coastguard Worker if (!has_bit(egl->extension_bits, EGL_MESA_IMAGE_DMA_BUF_EXPORT)) {
483*bbecb9d1SAndroid Build Coastguard Worker ret = 0;
484*bbecb9d1SAndroid Build Coastguard Worker goto fallback;
485*bbecb9d1SAndroid Build Coastguard Worker }
486*bbecb9d1SAndroid Build Coastguard Worker
487*bbecb9d1SAndroid Build Coastguard Worker image = eglCreateImageKHR(egl->egl_display, eglGetCurrentContext(), EGL_GL_TEXTURE_2D_KHR,
488*bbecb9d1SAndroid Build Coastguard Worker (EGLClientBuffer)(uintptr_t)tex_id, NULL);
489*bbecb9d1SAndroid Build Coastguard Worker
490*bbecb9d1SAndroid Build Coastguard Worker if (!image)
491*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
492*bbecb9d1SAndroid Build Coastguard Worker
493*bbecb9d1SAndroid Build Coastguard Worker success = eglExportDMABUFImageQueryMESA(egl->egl_display, image, fourcc, NULL, NULL);
494*bbecb9d1SAndroid Build Coastguard Worker if (!success)
495*bbecb9d1SAndroid Build Coastguard Worker goto out_destroy;
496*bbecb9d1SAndroid Build Coastguard Worker ret = 0;
497*bbecb9d1SAndroid Build Coastguard Worker out_destroy:
498*bbecb9d1SAndroid Build Coastguard Worker eglDestroyImageKHR(egl->egl_display, image);
499*bbecb9d1SAndroid Build Coastguard Worker return ret;
500*bbecb9d1SAndroid Build Coastguard Worker
501*bbecb9d1SAndroid Build Coastguard Worker fallback:
502*bbecb9d1SAndroid Build Coastguard Worker ret = virgl_gbm_convert_format(&format, &gbm_format);
503*bbecb9d1SAndroid Build Coastguard Worker *fourcc = (int)gbm_format;
504*bbecb9d1SAndroid Build Coastguard Worker return ret;
505*bbecb9d1SAndroid Build Coastguard Worker }
506*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_get_fd_for_texture2(struct virgl_egl * egl,uint32_t tex_id,int * fd,int * stride,int * offset)507*bbecb9d1SAndroid Build Coastguard Worker int virgl_egl_get_fd_for_texture2(struct virgl_egl *egl, uint32_t tex_id, int *fd,
508*bbecb9d1SAndroid Build Coastguard Worker int *stride, int *offset)
509*bbecb9d1SAndroid Build Coastguard Worker {
510*bbecb9d1SAndroid Build Coastguard Worker int ret = EINVAL;
511*bbecb9d1SAndroid Build Coastguard Worker EGLImageKHR image = eglCreateImageKHR(egl->egl_display, eglGetCurrentContext(),
512*bbecb9d1SAndroid Build Coastguard Worker EGL_GL_TEXTURE_2D_KHR,
513*bbecb9d1SAndroid Build Coastguard Worker (EGLClientBuffer)(uintptr_t)tex_id, NULL);
514*bbecb9d1SAndroid Build Coastguard Worker if (!image)
515*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
516*bbecb9d1SAndroid Build Coastguard Worker if (!has_bit(egl->extension_bits, EGL_MESA_IMAGE_DMA_BUF_EXPORT))
517*bbecb9d1SAndroid Build Coastguard Worker goto out_destroy;
518*bbecb9d1SAndroid Build Coastguard Worker
519*bbecb9d1SAndroid Build Coastguard Worker if (!eglExportDMABUFImageMESA(egl->egl_display, image, fd,
520*bbecb9d1SAndroid Build Coastguard Worker stride, offset))
521*bbecb9d1SAndroid Build Coastguard Worker goto out_destroy;
522*bbecb9d1SAndroid Build Coastguard Worker
523*bbecb9d1SAndroid Build Coastguard Worker ret = 0;
524*bbecb9d1SAndroid Build Coastguard Worker
525*bbecb9d1SAndroid Build Coastguard Worker out_destroy:
526*bbecb9d1SAndroid Build Coastguard Worker eglDestroyImageKHR(egl->egl_display, image);
527*bbecb9d1SAndroid Build Coastguard Worker return ret;
528*bbecb9d1SAndroid Build Coastguard Worker }
529*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_get_fd_for_texture(struct virgl_egl * egl,uint32_t tex_id,int * fd)530*bbecb9d1SAndroid Build Coastguard Worker int virgl_egl_get_fd_for_texture(struct virgl_egl *egl, uint32_t tex_id, int *fd)
531*bbecb9d1SAndroid Build Coastguard Worker {
532*bbecb9d1SAndroid Build Coastguard Worker EGLImageKHR image;
533*bbecb9d1SAndroid Build Coastguard Worker EGLint stride;
534*bbecb9d1SAndroid Build Coastguard Worker EGLint offset;
535*bbecb9d1SAndroid Build Coastguard Worker EGLBoolean success;
536*bbecb9d1SAndroid Build Coastguard Worker int ret;
537*bbecb9d1SAndroid Build Coastguard Worker image = eglCreateImageKHR(egl->egl_display, eglGetCurrentContext(), EGL_GL_TEXTURE_2D_KHR,
538*bbecb9d1SAndroid Build Coastguard Worker (EGLClientBuffer)(uintptr_t)tex_id, NULL);
539*bbecb9d1SAndroid Build Coastguard Worker
540*bbecb9d1SAndroid Build Coastguard Worker if (!image)
541*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
542*bbecb9d1SAndroid Build Coastguard Worker
543*bbecb9d1SAndroid Build Coastguard Worker ret = EINVAL;
544*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(egl->extension_bits, EGL_MESA_IMAGE_DMA_BUF_EXPORT)) {
545*bbecb9d1SAndroid Build Coastguard Worker success = eglExportDMABUFImageMESA(egl->egl_display, image, fd, &stride,
546*bbecb9d1SAndroid Build Coastguard Worker &offset);
547*bbecb9d1SAndroid Build Coastguard Worker if (!success)
548*bbecb9d1SAndroid Build Coastguard Worker goto out_destroy;
549*bbecb9d1SAndroid Build Coastguard Worker } else if (has_bit(egl->extension_bits, EGL_MESA_DRM_IMAGE)) {
550*bbecb9d1SAndroid Build Coastguard Worker EGLint handle;
551*bbecb9d1SAndroid Build Coastguard Worker success = eglExportDRMImageMESA(egl->egl_display, image, NULL, &handle,
552*bbecb9d1SAndroid Build Coastguard Worker &stride);
553*bbecb9d1SAndroid Build Coastguard Worker
554*bbecb9d1SAndroid Build Coastguard Worker if (!success)
555*bbecb9d1SAndroid Build Coastguard Worker goto out_destroy;
556*bbecb9d1SAndroid Build Coastguard Worker
557*bbecb9d1SAndroid Build Coastguard Worker if (!egl->gbm)
558*bbecb9d1SAndroid Build Coastguard Worker goto out_destroy;
559*bbecb9d1SAndroid Build Coastguard Worker
560*bbecb9d1SAndroid Build Coastguard Worker ret = virgl_gbm_export_fd(egl->gbm->device, handle, fd);
561*bbecb9d1SAndroid Build Coastguard Worker if (ret < 0)
562*bbecb9d1SAndroid Build Coastguard Worker goto out_destroy;
563*bbecb9d1SAndroid Build Coastguard Worker } else {
564*bbecb9d1SAndroid Build Coastguard Worker goto out_destroy;
565*bbecb9d1SAndroid Build Coastguard Worker }
566*bbecb9d1SAndroid Build Coastguard Worker
567*bbecb9d1SAndroid Build Coastguard Worker ret = 0;
568*bbecb9d1SAndroid Build Coastguard Worker out_destroy:
569*bbecb9d1SAndroid Build Coastguard Worker eglDestroyImageKHR(egl->egl_display, image);
570*bbecb9d1SAndroid Build Coastguard Worker return ret;
571*bbecb9d1SAndroid Build Coastguard Worker }
572*bbecb9d1SAndroid Build Coastguard Worker
virgl_has_egl_khr_gl_colorspace(struct virgl_egl * egl)573*bbecb9d1SAndroid Build Coastguard Worker bool virgl_has_egl_khr_gl_colorspace(struct virgl_egl *egl)
574*bbecb9d1SAndroid Build Coastguard Worker {
575*bbecb9d1SAndroid Build Coastguard Worker return has_bit(egl->extension_bits, EGL_KHR_GL_COLORSPACE);
576*bbecb9d1SAndroid Build Coastguard Worker }
577*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_image_from_dmabuf(struct virgl_egl * egl,uint32_t width,uint32_t height,uint32_t drm_format,uint64_t drm_modifier,uint32_t plane_count,const int * plane_fds,const uint32_t * plane_strides,const uint32_t * plane_offsets)578*bbecb9d1SAndroid Build Coastguard Worker void *virgl_egl_image_from_dmabuf(struct virgl_egl *egl,
579*bbecb9d1SAndroid Build Coastguard Worker uint32_t width,
580*bbecb9d1SAndroid Build Coastguard Worker uint32_t height,
581*bbecb9d1SAndroid Build Coastguard Worker uint32_t drm_format,
582*bbecb9d1SAndroid Build Coastguard Worker uint64_t drm_modifier,
583*bbecb9d1SAndroid Build Coastguard Worker uint32_t plane_count,
584*bbecb9d1SAndroid Build Coastguard Worker const int *plane_fds,
585*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *plane_strides,
586*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *plane_offsets)
587*bbecb9d1SAndroid Build Coastguard Worker {
588*bbecb9d1SAndroid Build Coastguard Worker EGLint attrs[6 + VIRGL_GBM_MAX_PLANES * 10 + 1];
589*bbecb9d1SAndroid Build Coastguard Worker uint32_t count;
590*bbecb9d1SAndroid Build Coastguard Worker
591*bbecb9d1SAndroid Build Coastguard Worker assert(VIRGL_GBM_MAX_PLANES <= 4);
592*bbecb9d1SAndroid Build Coastguard Worker assert(plane_count && plane_count <= VIRGL_GBM_MAX_PLANES);
593*bbecb9d1SAndroid Build Coastguard Worker
594*bbecb9d1SAndroid Build Coastguard Worker count = 0;
595*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = EGL_WIDTH;
596*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = width;
597*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = EGL_HEIGHT;
598*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = height;
599*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = EGL_LINUX_DRM_FOURCC_EXT;
600*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = drm_format;
601*bbecb9d1SAndroid Build Coastguard Worker for (uint32_t i = 0; i < plane_count; i++) {
602*bbecb9d1SAndroid Build Coastguard Worker if (i < 3) {
603*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = EGL_DMA_BUF_PLANE0_FD_EXT + i * 3;
604*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = plane_fds[i];
605*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = EGL_DMA_BUF_PLANE0_PITCH_EXT + i * 3;
606*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = plane_strides[i];
607*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT + i * 3;
608*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = plane_offsets[i];
609*bbecb9d1SAndroid Build Coastguard Worker }
610*bbecb9d1SAndroid Build Coastguard Worker
611*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(egl->extension_bits, EGL_EXT_IMAGE_DMA_BUF_IMPORT_MODIFIERS)) {
612*bbecb9d1SAndroid Build Coastguard Worker if (i == 3) {
613*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = EGL_DMA_BUF_PLANE3_FD_EXT;
614*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = plane_fds[i];
615*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = EGL_DMA_BUF_PLANE3_PITCH_EXT;
616*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = plane_strides[i];
617*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = EGL_DMA_BUF_PLANE3_OFFSET_EXT;
618*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = plane_offsets[i];
619*bbecb9d1SAndroid Build Coastguard Worker }
620*bbecb9d1SAndroid Build Coastguard Worker
621*bbecb9d1SAndroid Build Coastguard Worker if (drm_modifier != DRM_FORMAT_MOD_INVALID) {
622*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT + i * 2;
623*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = (uint32_t)drm_modifier;
624*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT + i * 2;
625*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = (uint32_t)(drm_modifier >> 32);
626*bbecb9d1SAndroid Build Coastguard Worker }
627*bbecb9d1SAndroid Build Coastguard Worker }
628*bbecb9d1SAndroid Build Coastguard Worker }
629*bbecb9d1SAndroid Build Coastguard Worker attrs[count++] = EGL_NONE;
630*bbecb9d1SAndroid Build Coastguard Worker assert(count <= ARRAY_SIZE(attrs));
631*bbecb9d1SAndroid Build Coastguard Worker
632*bbecb9d1SAndroid Build Coastguard Worker return (void *)eglCreateImageKHR(egl->egl_display,
633*bbecb9d1SAndroid Build Coastguard Worker EGL_NO_CONTEXT,
634*bbecb9d1SAndroid Build Coastguard Worker EGL_LINUX_DMA_BUF_EXT,
635*bbecb9d1SAndroid Build Coastguard Worker (EGLClientBuffer)NULL,
636*bbecb9d1SAndroid Build Coastguard Worker attrs);
637*bbecb9d1SAndroid Build Coastguard Worker }
638*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_image_destroy(struct virgl_egl * egl,void * image)639*bbecb9d1SAndroid Build Coastguard Worker void virgl_egl_image_destroy(struct virgl_egl *egl, void *image)
640*bbecb9d1SAndroid Build Coastguard Worker {
641*bbecb9d1SAndroid Build Coastguard Worker eglDestroyImageKHR(egl->egl_display, image);
642*bbecb9d1SAndroid Build Coastguard Worker }
643*bbecb9d1SAndroid Build Coastguard Worker
644*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
virgl_egl_image_from_gbm_bo(struct virgl_egl * egl,struct gbm_bo * bo)645*bbecb9d1SAndroid Build Coastguard Worker void *virgl_egl_image_from_gbm_bo(struct virgl_egl *egl, struct gbm_bo *bo)
646*bbecb9d1SAndroid Build Coastguard Worker {
647*bbecb9d1SAndroid Build Coastguard Worker int ret;
648*bbecb9d1SAndroid Build Coastguard Worker void *image = NULL;
649*bbecb9d1SAndroid Build Coastguard Worker int fds[VIRGL_GBM_MAX_PLANES] = {-1, -1, -1, -1};
650*bbecb9d1SAndroid Build Coastguard Worker uint32_t strides[VIRGL_GBM_MAX_PLANES];
651*bbecb9d1SAndroid Build Coastguard Worker uint32_t offsets[VIRGL_GBM_MAX_PLANES];
652*bbecb9d1SAndroid Build Coastguard Worker int num_planes = gbm_bo_get_plane_count(bo);
653*bbecb9d1SAndroid Build Coastguard Worker
654*bbecb9d1SAndroid Build Coastguard Worker if (num_planes < 0 || num_planes > VIRGL_GBM_MAX_PLANES)
655*bbecb9d1SAndroid Build Coastguard Worker return NULL;
656*bbecb9d1SAndroid Build Coastguard Worker
657*bbecb9d1SAndroid Build Coastguard Worker for (int plane = 0; plane < num_planes; plane++) {
658*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = gbm_bo_get_handle_for_plane(bo, plane).u32;
659*bbecb9d1SAndroid Build Coastguard Worker ret = virgl_gbm_export_fd(egl->gbm->device, handle, &fds[plane]);
660*bbecb9d1SAndroid Build Coastguard Worker if (ret < 0) {
661*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "failed to export plane handle\n");
662*bbecb9d1SAndroid Build Coastguard Worker goto out_close;
663*bbecb9d1SAndroid Build Coastguard Worker }
664*bbecb9d1SAndroid Build Coastguard Worker
665*bbecb9d1SAndroid Build Coastguard Worker strides[plane] = gbm_bo_get_stride_for_plane(bo, plane);
666*bbecb9d1SAndroid Build Coastguard Worker offsets[plane] = gbm_bo_get_offset(bo, plane);
667*bbecb9d1SAndroid Build Coastguard Worker }
668*bbecb9d1SAndroid Build Coastguard Worker
669*bbecb9d1SAndroid Build Coastguard Worker image = virgl_egl_image_from_dmabuf(egl,
670*bbecb9d1SAndroid Build Coastguard Worker gbm_bo_get_width(bo),
671*bbecb9d1SAndroid Build Coastguard Worker gbm_bo_get_height(bo),
672*bbecb9d1SAndroid Build Coastguard Worker gbm_bo_get_format(bo),
673*bbecb9d1SAndroid Build Coastguard Worker gbm_bo_get_modifier(bo),
674*bbecb9d1SAndroid Build Coastguard Worker num_planes,
675*bbecb9d1SAndroid Build Coastguard Worker fds,
676*bbecb9d1SAndroid Build Coastguard Worker strides,
677*bbecb9d1SAndroid Build Coastguard Worker offsets);
678*bbecb9d1SAndroid Build Coastguard Worker
679*bbecb9d1SAndroid Build Coastguard Worker out_close:
680*bbecb9d1SAndroid Build Coastguard Worker for (int plane = 0; plane < num_planes; plane++)
681*bbecb9d1SAndroid Build Coastguard Worker close(fds[plane]);
682*bbecb9d1SAndroid Build Coastguard Worker
683*bbecb9d1SAndroid Build Coastguard Worker return image;
684*bbecb9d1SAndroid Build Coastguard Worker }
685*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_aux_plane_image_from_gbm_bo(struct virgl_egl * egl,struct gbm_bo * bo,int plane)686*bbecb9d1SAndroid Build Coastguard Worker void *virgl_egl_aux_plane_image_from_gbm_bo(struct virgl_egl *egl, struct gbm_bo *bo, int plane)
687*bbecb9d1SAndroid Build Coastguard Worker {
688*bbecb9d1SAndroid Build Coastguard Worker int ret;
689*bbecb9d1SAndroid Build Coastguard Worker void *image = NULL;
690*bbecb9d1SAndroid Build Coastguard Worker int fd = -1;
691*bbecb9d1SAndroid Build Coastguard Worker
692*bbecb9d1SAndroid Build Coastguard Worker int bytes_per_pixel = virgl_gbm_get_plane_bytes_per_pixel(bo, plane);
693*bbecb9d1SAndroid Build Coastguard Worker if (bytes_per_pixel != 1 && bytes_per_pixel != 2)
694*bbecb9d1SAndroid Build Coastguard Worker return NULL;
695*bbecb9d1SAndroid Build Coastguard Worker
696*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle = gbm_bo_get_handle_for_plane(bo, plane).u32;
697*bbecb9d1SAndroid Build Coastguard Worker ret = drmPrimeHandleToFD(gbm_device_get_fd(egl->gbm->device), handle, DRM_CLOEXEC, &fd);
698*bbecb9d1SAndroid Build Coastguard Worker if (ret < 0) {
699*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("failed to export plane handle %d\n", errno);
700*bbecb9d1SAndroid Build Coastguard Worker return NULL;
701*bbecb9d1SAndroid Build Coastguard Worker }
702*bbecb9d1SAndroid Build Coastguard Worker
703*bbecb9d1SAndroid Build Coastguard Worker const uint32_t format = bytes_per_pixel == 1 ? GBM_FORMAT_R8 : GBM_FORMAT_GR88;
704*bbecb9d1SAndroid Build Coastguard Worker const uint32_t stride = gbm_bo_get_stride_for_plane(bo, plane);
705*bbecb9d1SAndroid Build Coastguard Worker const uint32_t offset = gbm_bo_get_offset(bo, plane);
706*bbecb9d1SAndroid Build Coastguard Worker image = virgl_egl_image_from_dmabuf(egl,
707*bbecb9d1SAndroid Build Coastguard Worker virgl_gbm_get_plane_width(bo, plane),
708*bbecb9d1SAndroid Build Coastguard Worker virgl_gbm_get_plane_height(bo, plane),
709*bbecb9d1SAndroid Build Coastguard Worker format,
710*bbecb9d1SAndroid Build Coastguard Worker gbm_bo_get_modifier(bo),
711*bbecb9d1SAndroid Build Coastguard Worker 1,
712*bbecb9d1SAndroid Build Coastguard Worker &fd,
713*bbecb9d1SAndroid Build Coastguard Worker &stride,
714*bbecb9d1SAndroid Build Coastguard Worker &offset);
715*bbecb9d1SAndroid Build Coastguard Worker close(fd);
716*bbecb9d1SAndroid Build Coastguard Worker
717*bbecb9d1SAndroid Build Coastguard Worker return image;
718*bbecb9d1SAndroid Build Coastguard Worker }
719*bbecb9d1SAndroid Build Coastguard Worker #endif /* ENABLE_MINIGBM_ALLOCATION */
720*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_supports_fences(struct virgl_egl * egl)721*bbecb9d1SAndroid Build Coastguard Worker bool virgl_egl_supports_fences(struct virgl_egl *egl)
722*bbecb9d1SAndroid Build Coastguard Worker {
723*bbecb9d1SAndroid Build Coastguard Worker return (egl && has_bit(egl->extension_bits, EGL_KHR_FENCE_SYNC_ANDROID));
724*bbecb9d1SAndroid Build Coastguard Worker }
725*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_fence_create(struct virgl_egl * egl)726*bbecb9d1SAndroid Build Coastguard Worker EGLSyncKHR virgl_egl_fence_create(struct virgl_egl *egl)
727*bbecb9d1SAndroid Build Coastguard Worker {
728*bbecb9d1SAndroid Build Coastguard Worker if (!egl || !has_bit(egl->extension_bits, EGL_KHR_FENCE_SYNC_ANDROID)) {
729*bbecb9d1SAndroid Build Coastguard Worker return EGL_NO_SYNC_KHR;
730*bbecb9d1SAndroid Build Coastguard Worker }
731*bbecb9d1SAndroid Build Coastguard Worker
732*bbecb9d1SAndroid Build Coastguard Worker return eglCreateSyncKHR(egl->egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
733*bbecb9d1SAndroid Build Coastguard Worker }
734*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_fence_destroy(struct virgl_egl * egl,EGLSyncKHR fence)735*bbecb9d1SAndroid Build Coastguard Worker void virgl_egl_fence_destroy(struct virgl_egl *egl, EGLSyncKHR fence) {
736*bbecb9d1SAndroid Build Coastguard Worker eglDestroySyncKHR(egl->egl_display, fence);
737*bbecb9d1SAndroid Build Coastguard Worker }
738*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_client_wait_fence(struct virgl_egl * egl,EGLSyncKHR fence,bool blocking)739*bbecb9d1SAndroid Build Coastguard Worker bool virgl_egl_client_wait_fence(struct virgl_egl *egl, EGLSyncKHR fence, bool blocking)
740*bbecb9d1SAndroid Build Coastguard Worker {
741*bbecb9d1SAndroid Build Coastguard Worker /* attempt to poll the native fence fd instead of eglClientWaitSyncKHR() to
742*bbecb9d1SAndroid Build Coastguard Worker * avoid Mesa's eglapi global-display-lock synchronizing vrend's sync_thread.
743*bbecb9d1SAndroid Build Coastguard Worker */
744*bbecb9d1SAndroid Build Coastguard Worker int fd = -1;
745*bbecb9d1SAndroid Build Coastguard Worker if (!virgl_egl_export_fence(egl, fence, &fd)) {
746*bbecb9d1SAndroid Build Coastguard Worker EGLint egl_result = eglClientWaitSyncKHR(egl->egl_display, fence, 0,
747*bbecb9d1SAndroid Build Coastguard Worker blocking ? EGL_FOREVER_KHR : 0);
748*bbecb9d1SAndroid Build Coastguard Worker if (egl_result == EGL_FALSE)
749*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("wait sync failed\n");
750*bbecb9d1SAndroid Build Coastguard Worker return egl_result != EGL_TIMEOUT_EXPIRED_KHR;
751*bbecb9d1SAndroid Build Coastguard Worker }
752*bbecb9d1SAndroid Build Coastguard Worker assert(fd >= 0);
753*bbecb9d1SAndroid Build Coastguard Worker
754*bbecb9d1SAndroid Build Coastguard Worker int ret;
755*bbecb9d1SAndroid Build Coastguard Worker struct pollfd pfd = {
756*bbecb9d1SAndroid Build Coastguard Worker .fd = fd,
757*bbecb9d1SAndroid Build Coastguard Worker .events = POLLIN,
758*bbecb9d1SAndroid Build Coastguard Worker };
759*bbecb9d1SAndroid Build Coastguard Worker do {
760*bbecb9d1SAndroid Build Coastguard Worker ret = poll(&pfd, 1, blocking ? -1 : 0);
761*bbecb9d1SAndroid Build Coastguard Worker if (ret > 0 && (pfd.revents & (POLLERR | POLLNVAL))) {
762*bbecb9d1SAndroid Build Coastguard Worker ret = -1;
763*bbecb9d1SAndroid Build Coastguard Worker break;
764*bbecb9d1SAndroid Build Coastguard Worker }
765*bbecb9d1SAndroid Build Coastguard Worker } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
766*bbecb9d1SAndroid Build Coastguard Worker close(fd);
767*bbecb9d1SAndroid Build Coastguard Worker
768*bbecb9d1SAndroid Build Coastguard Worker if (ret < 0)
769*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("wait sync failed\n");
770*bbecb9d1SAndroid Build Coastguard Worker return ret != 0;
771*bbecb9d1SAndroid Build Coastguard Worker }
772*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_export_signaled_fence(struct virgl_egl * egl,int * out_fd)773*bbecb9d1SAndroid Build Coastguard Worker bool virgl_egl_export_signaled_fence(struct virgl_egl *egl, int *out_fd) {
774*bbecb9d1SAndroid Build Coastguard Worker return virgl_egl_export_fence(egl, egl->signaled_fence, out_fd);
775*bbecb9d1SAndroid Build Coastguard Worker }
776*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_export_fence(struct virgl_egl * egl,EGLSyncKHR fence,int * out_fd)777*bbecb9d1SAndroid Build Coastguard Worker bool virgl_egl_export_fence(struct virgl_egl *egl, EGLSyncKHR fence, int *out_fd) {
778*bbecb9d1SAndroid Build Coastguard Worker *out_fd = eglDupNativeFenceFDANDROID(egl->egl_display, fence);
779*bbecb9d1SAndroid Build Coastguard Worker return *out_fd != EGL_NO_NATIVE_FENCE_FD_ANDROID;
780*bbecb9d1SAndroid Build Coastguard Worker }
781*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_different_gpu(struct virgl_egl * egl)782*bbecb9d1SAndroid Build Coastguard Worker bool virgl_egl_different_gpu(struct virgl_egl *egl)
783*bbecb9d1SAndroid Build Coastguard Worker {
784*bbecb9d1SAndroid Build Coastguard Worker return egl->different_gpu;
785*bbecb9d1SAndroid Build Coastguard Worker }
786*bbecb9d1SAndroid Build Coastguard Worker
virgl_egl_error_string(EGLint error)787*bbecb9d1SAndroid Build Coastguard Worker const char *virgl_egl_error_string(EGLint error)
788*bbecb9d1SAndroid Build Coastguard Worker {
789*bbecb9d1SAndroid Build Coastguard Worker switch (error) {
790*bbecb9d1SAndroid Build Coastguard Worker #define CASE_STR( value ) case value: return #value;
791*bbecb9d1SAndroid Build Coastguard Worker CASE_STR( EGL_SUCCESS )
792*bbecb9d1SAndroid Build Coastguard Worker CASE_STR( EGL_NOT_INITIALIZED )
793*bbecb9d1SAndroid Build Coastguard Worker CASE_STR( EGL_BAD_ACCESS )
794*bbecb9d1SAndroid Build Coastguard Worker CASE_STR( EGL_BAD_ALLOC )
795*bbecb9d1SAndroid Build Coastguard Worker CASE_STR( EGL_BAD_ATTRIBUTE )
796*bbecb9d1SAndroid Build Coastguard Worker CASE_STR( EGL_BAD_CONTEXT )
797*bbecb9d1SAndroid Build Coastguard Worker CASE_STR( EGL_BAD_CONFIG )
798*bbecb9d1SAndroid Build Coastguard Worker CASE_STR( EGL_BAD_CURRENT_SURFACE )
799*bbecb9d1SAndroid Build Coastguard Worker CASE_STR( EGL_BAD_DISPLAY )
800*bbecb9d1SAndroid Build Coastguard Worker CASE_STR( EGL_BAD_SURFACE )
801*bbecb9d1SAndroid Build Coastguard Worker CASE_STR( EGL_BAD_MATCH )
802*bbecb9d1SAndroid Build Coastguard Worker CASE_STR( EGL_BAD_PARAMETER )
803*bbecb9d1SAndroid Build Coastguard Worker CASE_STR( EGL_BAD_NATIVE_PIXMAP )
804*bbecb9d1SAndroid Build Coastguard Worker CASE_STR( EGL_BAD_NATIVE_WINDOW )
805*bbecb9d1SAndroid Build Coastguard Worker CASE_STR( EGL_CONTEXT_LOST )
806*bbecb9d1SAndroid Build Coastguard Worker #undef CASE_STR
807*bbecb9d1SAndroid Build Coastguard Worker default: return "Unknown error";
808*bbecb9d1SAndroid Build Coastguard Worker }
809*bbecb9d1SAndroid Build Coastguard Worker }
810