1 /**************************************************************************
3 * Copyright 2015, 2018 Collabora
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
28 #include "util/macros.h"
30 #include "eglcurrent.h"
31 #include "egldevice.h"
32 #include "eglglobals.h"
33 #include "egltypedefs.h"
39 const char *extensions
;
41 EGLBoolean MESA_device_software
;
47 _EGLDevice
*dev_list
, *dev
;
49 /* atexit function is called with global mutex locked */
51 dev_list
= _eglGlobal
.DeviceList
;
53 /* The first device is static allocated SW device */
55 assert(_eglDeviceSupports(dev_list
, _EGL_DEVICE_SOFTWARE
));
56 dev_list
= dev_list
->Next
;
61 dev_list
= dev_list
->Next
;
66 _eglGlobal
.DeviceList
= NULL
;
70 _eglCheckDeviceHandle(EGLDeviceEXT device
)
74 mtx_lock(_eglGlobal
.Mutex
);
75 cur
= _eglGlobal
.DeviceList
;
77 if (cur
== (_EGLDevice
*) device
)
81 mtx_unlock(_eglGlobal
.Mutex
);
85 _EGLDevice _eglSoftwareDevice
= {
86 .extensions
= "EGL_MESA_device_software",
87 .MESA_device_software
= EGL_TRUE
,
90 /* Adds a device in DeviceList, if needed for the given fd.
92 * If a software device, the fd is ignored.
95 _eglAddDevice(int fd
, bool software
)
99 mtx_lock(_eglGlobal
.Mutex
);
100 dev
= _eglGlobal
.DeviceList
;
102 /* The first device is always software */
104 assert(_eglDeviceSupports(dev
, _EGL_DEVICE_SOFTWARE
));
111 mtx_unlock(_eglGlobal
.Mutex
);
116 _eglDeviceSupports(_EGLDevice
*dev
, _EGLDeviceExtension ext
)
119 case _EGL_DEVICE_SOFTWARE
:
120 return dev
->MESA_device_software
;
128 _eglQueryDeviceAttribEXT(_EGLDevice
*dev
, EGLint attribute
,
133 _eglError(EGL_BAD_ATTRIBUTE
, "eglQueryDeviceStringEXT");
139 _eglQueryDeviceStringEXT(_EGLDevice
*dev
, EGLint name
)
143 return dev
->extensions
;
145 _eglError(EGL_BAD_PARAMETER
, "eglQueryDeviceStringEXT");
150 /* Do a fresh lookup for devices.
152 * Walks through the DeviceList, discarding no longer available ones
153 * and adding new ones as applicable.
155 * Must be called with the global lock held.
158 _eglRefreshDeviceList(void)
160 MAYBE_UNUSED _EGLDevice
*dev
;
163 dev
= _eglGlobal
.DeviceList
;
165 /* The first device is always software */
167 assert(_eglDeviceSupports(dev
, _EGL_DEVICE_SOFTWARE
));
174 _eglQueryDevicesEXT(EGLint max_devices
,
175 _EGLDevice
**devices
,
178 _EGLDevice
*dev
, *devs
;
181 if ((devices
&& max_devices
<= 0) || !num_devices
)
182 return _eglError(EGL_BAD_PARAMETER
, "eglQueryDevicesEXT");
184 mtx_lock(_eglGlobal
.Mutex
);
186 num_devs
= _eglRefreshDeviceList();
187 devs
= _eglGlobal
.DeviceList
;
189 /* bail early if we only care about the count */
191 *num_devices
= num_devs
;
195 *num_devices
= MIN2(num_devs
, max_devices
);
197 for (i
= 0, dev
= devs
; i
< *num_devices
; i
++) {
203 mtx_unlock(_eglGlobal
.Mutex
);