1*61046927SAndroid Build Coastguard Worker /**************************************************************************
2*61046927SAndroid Build Coastguard Worker *
3*61046927SAndroid Build Coastguard Worker * Copyright 2015, 2018 Collabora
4*61046927SAndroid Build Coastguard Worker * All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker *
6*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
7*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the
8*61046927SAndroid Build Coastguard Worker * "Software"), to deal in the Software without restriction, including
9*61046927SAndroid Build Coastguard Worker * without limitation the rights to use, copy, modify, merge, publish,
10*61046927SAndroid Build Coastguard Worker * distribute, sub license, and/or sell copies of the Software, and to
11*61046927SAndroid Build Coastguard Worker * permit persons to whom the Software is furnished to do so, subject to
12*61046927SAndroid Build Coastguard Worker * the following conditions:
13*61046927SAndroid Build Coastguard Worker *
14*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the
15*61046927SAndroid Build Coastguard Worker * next paragraph) shall be included in all copies or substantial portions
16*61046927SAndroid Build Coastguard Worker * of the Software.
17*61046927SAndroid Build Coastguard Worker *
18*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24*61046927SAndroid Build Coastguard Worker * DEALINGS IN THE SOFTWARE.
25*61046927SAndroid Build Coastguard Worker *
26*61046927SAndroid Build Coastguard Worker **************************************************************************/
27*61046927SAndroid Build Coastguard Worker
28*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
29*61046927SAndroid Build Coastguard Worker #include <xf86drm.h>
30*61046927SAndroid Build Coastguard Worker #endif
31*61046927SAndroid Build Coastguard Worker #include "util/compiler.h"
32*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
33*61046927SAndroid Build Coastguard Worker
34*61046927SAndroid Build Coastguard Worker #include "eglcurrent.h"
35*61046927SAndroid Build Coastguard Worker #include "egldevice.h"
36*61046927SAndroid Build Coastguard Worker #include "eglglobals.h"
37*61046927SAndroid Build Coastguard Worker #include "egllog.h"
38*61046927SAndroid Build Coastguard Worker #include "egltypedefs.h"
39*61046927SAndroid Build Coastguard Worker
40*61046927SAndroid Build Coastguard Worker struct _egl_device {
41*61046927SAndroid Build Coastguard Worker _EGLDevice *Next;
42*61046927SAndroid Build Coastguard Worker
43*61046927SAndroid Build Coastguard Worker const char *extensions;
44*61046927SAndroid Build Coastguard Worker
45*61046927SAndroid Build Coastguard Worker EGLBoolean MESA_device_software;
46*61046927SAndroid Build Coastguard Worker EGLBoolean EXT_device_drm;
47*61046927SAndroid Build Coastguard Worker EGLBoolean EXT_device_drm_render_node;
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
50*61046927SAndroid Build Coastguard Worker drmDevicePtr device;
51*61046927SAndroid Build Coastguard Worker #endif
52*61046927SAndroid Build Coastguard Worker };
53*61046927SAndroid Build Coastguard Worker
54*61046927SAndroid Build Coastguard Worker void
_eglFiniDevice(void)55*61046927SAndroid Build Coastguard Worker _eglFiniDevice(void)
56*61046927SAndroid Build Coastguard Worker {
57*61046927SAndroid Build Coastguard Worker _EGLDevice *dev_list, *dev;
58*61046927SAndroid Build Coastguard Worker
59*61046927SAndroid Build Coastguard Worker /* atexit function is called with global mutex locked */
60*61046927SAndroid Build Coastguard Worker
61*61046927SAndroid Build Coastguard Worker dev_list = _eglGlobal.DeviceList;
62*61046927SAndroid Build Coastguard Worker
63*61046927SAndroid Build Coastguard Worker /* The first device is static allocated SW device */
64*61046927SAndroid Build Coastguard Worker assert(dev_list);
65*61046927SAndroid Build Coastguard Worker assert(_eglDeviceSupports(dev_list, _EGL_DEVICE_SOFTWARE));
66*61046927SAndroid Build Coastguard Worker dev_list = dev_list->Next;
67*61046927SAndroid Build Coastguard Worker
68*61046927SAndroid Build Coastguard Worker while (dev_list) {
69*61046927SAndroid Build Coastguard Worker /* pop list head */
70*61046927SAndroid Build Coastguard Worker dev = dev_list;
71*61046927SAndroid Build Coastguard Worker dev_list = dev_list->Next;
72*61046927SAndroid Build Coastguard Worker
73*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
74*61046927SAndroid Build Coastguard Worker assert(_eglDeviceSupports(dev, _EGL_DEVICE_DRM));
75*61046927SAndroid Build Coastguard Worker drmFreeDevice(&dev->device);
76*61046927SAndroid Build Coastguard Worker #endif
77*61046927SAndroid Build Coastguard Worker free(dev);
78*61046927SAndroid Build Coastguard Worker }
79*61046927SAndroid Build Coastguard Worker
80*61046927SAndroid Build Coastguard Worker _eglGlobal.DeviceList = NULL;
81*61046927SAndroid Build Coastguard Worker }
82*61046927SAndroid Build Coastguard Worker
83*61046927SAndroid Build Coastguard Worker EGLBoolean
_eglCheckDeviceHandle(EGLDeviceEXT device)84*61046927SAndroid Build Coastguard Worker _eglCheckDeviceHandle(EGLDeviceEXT device)
85*61046927SAndroid Build Coastguard Worker {
86*61046927SAndroid Build Coastguard Worker _EGLDevice *cur;
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Worker simple_mtx_lock(_eglGlobal.Mutex);
89*61046927SAndroid Build Coastguard Worker cur = _eglGlobal.DeviceList;
90*61046927SAndroid Build Coastguard Worker while (cur) {
91*61046927SAndroid Build Coastguard Worker if (cur == (_EGLDevice *)device)
92*61046927SAndroid Build Coastguard Worker break;
93*61046927SAndroid Build Coastguard Worker cur = cur->Next;
94*61046927SAndroid Build Coastguard Worker }
95*61046927SAndroid Build Coastguard Worker simple_mtx_unlock(_eglGlobal.Mutex);
96*61046927SAndroid Build Coastguard Worker return (cur != NULL);
97*61046927SAndroid Build Coastguard Worker }
98*61046927SAndroid Build Coastguard Worker
99*61046927SAndroid Build Coastguard Worker _EGLDevice _eglSoftwareDevice = {
100*61046927SAndroid Build Coastguard Worker /* TODO: EGL_EXT_device_drm support for KMS + llvmpipe */
101*61046927SAndroid Build Coastguard Worker .extensions = "EGL_MESA_device_software EGL_EXT_device_drm_render_node",
102*61046927SAndroid Build Coastguard Worker .MESA_device_software = EGL_TRUE,
103*61046927SAndroid Build Coastguard Worker .EXT_device_drm_render_node = EGL_TRUE,
104*61046927SAndroid Build Coastguard Worker };
105*61046927SAndroid Build Coastguard Worker
106*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
107*61046927SAndroid Build Coastguard Worker /*
108*61046927SAndroid Build Coastguard Worker * Negative value on error, zero if newly added, one if already in list.
109*61046927SAndroid Build Coastguard Worker */
110*61046927SAndroid Build Coastguard Worker static int
_eglAddDRMDevice(drmDevicePtr device)111*61046927SAndroid Build Coastguard Worker _eglAddDRMDevice(drmDevicePtr device)
112*61046927SAndroid Build Coastguard Worker {
113*61046927SAndroid Build Coastguard Worker _EGLDevice *dev;
114*61046927SAndroid Build Coastguard Worker
115*61046927SAndroid Build Coastguard Worker assert(device->available_nodes & ((1 << DRM_NODE_RENDER)));
116*61046927SAndroid Build Coastguard Worker
117*61046927SAndroid Build Coastguard Worker /* TODO: uncomment this assert, which is a sanity check.
118*61046927SAndroid Build Coastguard Worker *
119*61046927SAndroid Build Coastguard Worker * assert(device->available_nodes & ((1 << DRM_NODE_PRIMARY)));
120*61046927SAndroid Build Coastguard Worker *
121*61046927SAndroid Build Coastguard Worker * DRM shim does not expose a primary node, so the CI would fail if we had
122*61046927SAndroid Build Coastguard Worker * this assert. DRM shim is being used to run shader-db. We need to
123*61046927SAndroid Build Coastguard Worker * investigate what should be done (probably fixing DRM shim).
124*61046927SAndroid Build Coastguard Worker */
125*61046927SAndroid Build Coastguard Worker
126*61046927SAndroid Build Coastguard Worker dev = _eglGlobal.DeviceList;
127*61046927SAndroid Build Coastguard Worker
128*61046927SAndroid Build Coastguard Worker /* The first device is always software */
129*61046927SAndroid Build Coastguard Worker assert(dev);
130*61046927SAndroid Build Coastguard Worker assert(_eglDeviceSupports(dev, _EGL_DEVICE_SOFTWARE));
131*61046927SAndroid Build Coastguard Worker
132*61046927SAndroid Build Coastguard Worker while (dev->Next) {
133*61046927SAndroid Build Coastguard Worker dev = dev->Next;
134*61046927SAndroid Build Coastguard Worker
135*61046927SAndroid Build Coastguard Worker assert(_eglDeviceSupports(dev, _EGL_DEVICE_DRM));
136*61046927SAndroid Build Coastguard Worker if (drmDevicesEqual(device, dev->device) != 0)
137*61046927SAndroid Build Coastguard Worker return 1;
138*61046927SAndroid Build Coastguard Worker }
139*61046927SAndroid Build Coastguard Worker
140*61046927SAndroid Build Coastguard Worker dev->Next = calloc(1, sizeof(_EGLDevice));
141*61046927SAndroid Build Coastguard Worker if (!dev->Next)
142*61046927SAndroid Build Coastguard Worker return -1;
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker dev = dev->Next;
145*61046927SAndroid Build Coastguard Worker dev->extensions = "EGL_EXT_device_drm EGL_EXT_device_drm_render_node";
146*61046927SAndroid Build Coastguard Worker dev->EXT_device_drm = EGL_TRUE;
147*61046927SAndroid Build Coastguard Worker dev->EXT_device_drm_render_node = EGL_TRUE;
148*61046927SAndroid Build Coastguard Worker dev->device = device;
149*61046927SAndroid Build Coastguard Worker
150*61046927SAndroid Build Coastguard Worker return 0;
151*61046927SAndroid Build Coastguard Worker }
152*61046927SAndroid Build Coastguard Worker #endif
153*61046927SAndroid Build Coastguard Worker
154*61046927SAndroid Build Coastguard Worker /* Finds a device in DeviceList, for the given fd.
155*61046927SAndroid Build Coastguard Worker *
156*61046927SAndroid Build Coastguard Worker * The fd must be of a render-capable device, as there are only render-capable
157*61046927SAndroid Build Coastguard Worker * devices in DeviceList.
158*61046927SAndroid Build Coastguard Worker *
159*61046927SAndroid Build Coastguard Worker * If a software device, the fd is ignored.
160*61046927SAndroid Build Coastguard Worker */
161*61046927SAndroid Build Coastguard Worker _EGLDevice *
_eglFindDevice(int fd,bool software)162*61046927SAndroid Build Coastguard Worker _eglFindDevice(int fd, bool software)
163*61046927SAndroid Build Coastguard Worker {
164*61046927SAndroid Build Coastguard Worker _EGLDevice *dev;
165*61046927SAndroid Build Coastguard Worker
166*61046927SAndroid Build Coastguard Worker simple_mtx_lock(_eglGlobal.Mutex);
167*61046927SAndroid Build Coastguard Worker dev = _eglGlobal.DeviceList;
168*61046927SAndroid Build Coastguard Worker
169*61046927SAndroid Build Coastguard Worker /* The first device is always software */
170*61046927SAndroid Build Coastguard Worker assert(dev);
171*61046927SAndroid Build Coastguard Worker assert(_eglDeviceSupports(dev, _EGL_DEVICE_SOFTWARE));
172*61046927SAndroid Build Coastguard Worker if (software)
173*61046927SAndroid Build Coastguard Worker goto out;
174*61046927SAndroid Build Coastguard Worker
175*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
176*61046927SAndroid Build Coastguard Worker drmDevicePtr device;
177*61046927SAndroid Build Coastguard Worker
178*61046927SAndroid Build Coastguard Worker if (drmGetDevice2(fd, 0, &device) != 0) {
179*61046927SAndroid Build Coastguard Worker dev = NULL;
180*61046927SAndroid Build Coastguard Worker goto out;
181*61046927SAndroid Build Coastguard Worker }
182*61046927SAndroid Build Coastguard Worker
183*61046927SAndroid Build Coastguard Worker while (dev->Next) {
184*61046927SAndroid Build Coastguard Worker dev = dev->Next;
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker if (_eglDeviceSupports(dev, _EGL_DEVICE_DRM) &&
187*61046927SAndroid Build Coastguard Worker drmDevicesEqual(device, dev->device) != 0) {
188*61046927SAndroid Build Coastguard Worker goto cleanup_drm;
189*61046927SAndroid Build Coastguard Worker }
190*61046927SAndroid Build Coastguard Worker }
191*61046927SAndroid Build Coastguard Worker
192*61046927SAndroid Build Coastguard Worker /* Couldn't find an EGLDevice for the device. */
193*61046927SAndroid Build Coastguard Worker dev = NULL;
194*61046927SAndroid Build Coastguard Worker
195*61046927SAndroid Build Coastguard Worker cleanup_drm:
196*61046927SAndroid Build Coastguard Worker drmFreeDevice(&device);
197*61046927SAndroid Build Coastguard Worker
198*61046927SAndroid Build Coastguard Worker #else
199*61046927SAndroid Build Coastguard Worker _eglLog(_EGL_FATAL,
200*61046927SAndroid Build Coastguard Worker "Driver bug: Built without libdrm, yet looking for HW device");
201*61046927SAndroid Build Coastguard Worker dev = NULL;
202*61046927SAndroid Build Coastguard Worker #endif
203*61046927SAndroid Build Coastguard Worker
204*61046927SAndroid Build Coastguard Worker out:
205*61046927SAndroid Build Coastguard Worker simple_mtx_unlock(_eglGlobal.Mutex);
206*61046927SAndroid Build Coastguard Worker return dev;
207*61046927SAndroid Build Coastguard Worker }
208*61046927SAndroid Build Coastguard Worker
209*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
210*61046927SAndroid Build Coastguard Worker drmDevicePtr
_eglDeviceDrm(_EGLDevice * dev)211*61046927SAndroid Build Coastguard Worker _eglDeviceDrm(_EGLDevice *dev)
212*61046927SAndroid Build Coastguard Worker {
213*61046927SAndroid Build Coastguard Worker if (!dev)
214*61046927SAndroid Build Coastguard Worker return NULL;
215*61046927SAndroid Build Coastguard Worker
216*61046927SAndroid Build Coastguard Worker return dev->device;
217*61046927SAndroid Build Coastguard Worker }
218*61046927SAndroid Build Coastguard Worker #endif
219*61046927SAndroid Build Coastguard Worker
220*61046927SAndroid Build Coastguard Worker _EGLDevice *
_eglDeviceNext(_EGLDevice * dev)221*61046927SAndroid Build Coastguard Worker _eglDeviceNext(_EGLDevice *dev)
222*61046927SAndroid Build Coastguard Worker {
223*61046927SAndroid Build Coastguard Worker if (!dev)
224*61046927SAndroid Build Coastguard Worker return NULL;
225*61046927SAndroid Build Coastguard Worker
226*61046927SAndroid Build Coastguard Worker return dev->Next;
227*61046927SAndroid Build Coastguard Worker }
228*61046927SAndroid Build Coastguard Worker
229*61046927SAndroid Build Coastguard Worker EGLBoolean
_eglDeviceSupports(_EGLDevice * dev,_EGLDeviceExtension ext)230*61046927SAndroid Build Coastguard Worker _eglDeviceSupports(_EGLDevice *dev, _EGLDeviceExtension ext)
231*61046927SAndroid Build Coastguard Worker {
232*61046927SAndroid Build Coastguard Worker switch (ext) {
233*61046927SAndroid Build Coastguard Worker case _EGL_DEVICE_SOFTWARE:
234*61046927SAndroid Build Coastguard Worker return dev->MESA_device_software;
235*61046927SAndroid Build Coastguard Worker case _EGL_DEVICE_DRM:
236*61046927SAndroid Build Coastguard Worker return dev->EXT_device_drm;
237*61046927SAndroid Build Coastguard Worker case _EGL_DEVICE_DRM_RENDER_NODE:
238*61046927SAndroid Build Coastguard Worker return dev->EXT_device_drm_render_node;
239*61046927SAndroid Build Coastguard Worker default:
240*61046927SAndroid Build Coastguard Worker assert(0);
241*61046927SAndroid Build Coastguard Worker return EGL_FALSE;
242*61046927SAndroid Build Coastguard Worker };
243*61046927SAndroid Build Coastguard Worker }
244*61046927SAndroid Build Coastguard Worker
245*61046927SAndroid Build Coastguard Worker EGLBoolean
_eglQueryDeviceAttribEXT(_EGLDevice * dev,EGLint attribute,EGLAttrib * value)246*61046927SAndroid Build Coastguard Worker _eglQueryDeviceAttribEXT(_EGLDevice *dev, EGLint attribute, EGLAttrib *value)
247*61046927SAndroid Build Coastguard Worker {
248*61046927SAndroid Build Coastguard Worker switch (attribute) {
249*61046927SAndroid Build Coastguard Worker default:
250*61046927SAndroid Build Coastguard Worker _eglError(EGL_BAD_ATTRIBUTE, "eglQueryDeviceAttribEXT");
251*61046927SAndroid Build Coastguard Worker return EGL_FALSE;
252*61046927SAndroid Build Coastguard Worker }
253*61046927SAndroid Build Coastguard Worker }
254*61046927SAndroid Build Coastguard Worker
255*61046927SAndroid Build Coastguard Worker const char *
_eglQueryDeviceStringEXT(_EGLDevice * dev,EGLint name)256*61046927SAndroid Build Coastguard Worker _eglQueryDeviceStringEXT(_EGLDevice *dev, EGLint name)
257*61046927SAndroid Build Coastguard Worker {
258*61046927SAndroid Build Coastguard Worker switch (name) {
259*61046927SAndroid Build Coastguard Worker case EGL_EXTENSIONS:
260*61046927SAndroid Build Coastguard Worker return dev->extensions;
261*61046927SAndroid Build Coastguard Worker case EGL_DRM_DEVICE_FILE_EXT:
262*61046927SAndroid Build Coastguard Worker if (!_eglDeviceSupports(dev, _EGL_DEVICE_DRM))
263*61046927SAndroid Build Coastguard Worker break;
264*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
265*61046927SAndroid Build Coastguard Worker return dev->device->nodes[DRM_NODE_PRIMARY];
266*61046927SAndroid Build Coastguard Worker #else
267*61046927SAndroid Build Coastguard Worker /* This should never happen: we don't yet support EGL_DEVICE_DRM for the
268*61046927SAndroid Build Coastguard Worker * software device, and physical devices are only exposed when libdrm is
269*61046927SAndroid Build Coastguard Worker * available. */
270*61046927SAndroid Build Coastguard Worker assert(0);
271*61046927SAndroid Build Coastguard Worker break;
272*61046927SAndroid Build Coastguard Worker #endif
273*61046927SAndroid Build Coastguard Worker case EGL_DRM_RENDER_NODE_FILE_EXT:
274*61046927SAndroid Build Coastguard Worker if (!_eglDeviceSupports(dev, _EGL_DEVICE_DRM_RENDER_NODE))
275*61046927SAndroid Build Coastguard Worker break;
276*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
277*61046927SAndroid Build Coastguard Worker /* EGLDevice represents a software device, so no render node
278*61046927SAndroid Build Coastguard Worker * should be advertised. */
279*61046927SAndroid Build Coastguard Worker if (_eglDeviceSupports(dev, _EGL_DEVICE_SOFTWARE))
280*61046927SAndroid Build Coastguard Worker return NULL;
281*61046927SAndroid Build Coastguard Worker /* We create EGLDevice's only for render capable devices. */
282*61046927SAndroid Build Coastguard Worker assert(dev->device->available_nodes & (1 << DRM_NODE_RENDER));
283*61046927SAndroid Build Coastguard Worker return dev->device->nodes[DRM_NODE_RENDER];
284*61046927SAndroid Build Coastguard Worker #else
285*61046927SAndroid Build Coastguard Worker /* Physical devices are only exposed when libdrm is available. */
286*61046927SAndroid Build Coastguard Worker assert(_eglDeviceSupports(dev, _EGL_DEVICE_SOFTWARE));
287*61046927SAndroid Build Coastguard Worker return NULL;
288*61046927SAndroid Build Coastguard Worker #endif
289*61046927SAndroid Build Coastguard Worker }
290*61046927SAndroid Build Coastguard Worker _eglError(EGL_BAD_PARAMETER, "eglQueryDeviceStringEXT");
291*61046927SAndroid Build Coastguard Worker return NULL;
292*61046927SAndroid Build Coastguard Worker }
293*61046927SAndroid Build Coastguard Worker
294*61046927SAndroid Build Coastguard Worker /* Do a fresh lookup for devices.
295*61046927SAndroid Build Coastguard Worker *
296*61046927SAndroid Build Coastguard Worker * Walks through the DeviceList, discarding no longer available ones
297*61046927SAndroid Build Coastguard Worker * and adding new ones as applicable.
298*61046927SAndroid Build Coastguard Worker *
299*61046927SAndroid Build Coastguard Worker * Must be called with the global lock held.
300*61046927SAndroid Build Coastguard Worker */
301*61046927SAndroid Build Coastguard Worker int
_eglDeviceRefreshList(void)302*61046927SAndroid Build Coastguard Worker _eglDeviceRefreshList(void)
303*61046927SAndroid Build Coastguard Worker {
304*61046927SAndroid Build Coastguard Worker ASSERTED _EGLDevice *dev;
305*61046927SAndroid Build Coastguard Worker int count = 0;
306*61046927SAndroid Build Coastguard Worker
307*61046927SAndroid Build Coastguard Worker dev = _eglGlobal.DeviceList;
308*61046927SAndroid Build Coastguard Worker
309*61046927SAndroid Build Coastguard Worker /* The first device is always software */
310*61046927SAndroid Build Coastguard Worker assert(dev);
311*61046927SAndroid Build Coastguard Worker assert(_eglDeviceSupports(dev, _EGL_DEVICE_SOFTWARE));
312*61046927SAndroid Build Coastguard Worker count++;
313*61046927SAndroid Build Coastguard Worker
314*61046927SAndroid Build Coastguard Worker #ifdef HAVE_LIBDRM
315*61046927SAndroid Build Coastguard Worker drmDevicePtr devices[64];
316*61046927SAndroid Build Coastguard Worker int num_devs, ret;
317*61046927SAndroid Build Coastguard Worker
318*61046927SAndroid Build Coastguard Worker num_devs = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
319*61046927SAndroid Build Coastguard Worker for (int i = 0; i < num_devs; i++) {
320*61046927SAndroid Build Coastguard Worker if (!(devices[i]->available_nodes & (1 << DRM_NODE_RENDER))) {
321*61046927SAndroid Build Coastguard Worker drmFreeDevice(&devices[i]);
322*61046927SAndroid Build Coastguard Worker continue;
323*61046927SAndroid Build Coastguard Worker }
324*61046927SAndroid Build Coastguard Worker
325*61046927SAndroid Build Coastguard Worker ret = _eglAddDRMDevice(devices[i]);
326*61046927SAndroid Build Coastguard Worker
327*61046927SAndroid Build Coastguard Worker /* Device is not added - error or already present */
328*61046927SAndroid Build Coastguard Worker if (ret != 0)
329*61046927SAndroid Build Coastguard Worker drmFreeDevice(&devices[i]);
330*61046927SAndroid Build Coastguard Worker
331*61046927SAndroid Build Coastguard Worker if (ret >= 0)
332*61046927SAndroid Build Coastguard Worker count++;
333*61046927SAndroid Build Coastguard Worker }
334*61046927SAndroid Build Coastguard Worker #endif
335*61046927SAndroid Build Coastguard Worker
336*61046927SAndroid Build Coastguard Worker return count;
337*61046927SAndroid Build Coastguard Worker }
338*61046927SAndroid Build Coastguard Worker
339*61046927SAndroid Build Coastguard Worker EGLBoolean
_eglQueryDevicesEXT(EGLint max_devices,_EGLDevice ** devices,EGLint * num_devices)340*61046927SAndroid Build Coastguard Worker _eglQueryDevicesEXT(EGLint max_devices, _EGLDevice **devices,
341*61046927SAndroid Build Coastguard Worker EGLint *num_devices)
342*61046927SAndroid Build Coastguard Worker {
343*61046927SAndroid Build Coastguard Worker _EGLDevice *dev, *devs, *swrast;
344*61046927SAndroid Build Coastguard Worker int i = 0, num_devs;
345*61046927SAndroid Build Coastguard Worker
346*61046927SAndroid Build Coastguard Worker if ((devices && max_devices <= 0) || !num_devices)
347*61046927SAndroid Build Coastguard Worker return _eglError(EGL_BAD_PARAMETER, "eglQueryDevicesEXT");
348*61046927SAndroid Build Coastguard Worker
349*61046927SAndroid Build Coastguard Worker simple_mtx_lock(_eglGlobal.Mutex);
350*61046927SAndroid Build Coastguard Worker
351*61046927SAndroid Build Coastguard Worker num_devs = _eglDeviceRefreshList();
352*61046927SAndroid Build Coastguard Worker devs = _eglGlobal.DeviceList;
353*61046927SAndroid Build Coastguard Worker
354*61046927SAndroid Build Coastguard Worker #ifdef HAVE_SWRAST
355*61046927SAndroid Build Coastguard Worker swrast = devs;
356*61046927SAndroid Build Coastguard Worker #else
357*61046927SAndroid Build Coastguard Worker swrast = NULL;
358*61046927SAndroid Build Coastguard Worker num_devs--;
359*61046927SAndroid Build Coastguard Worker #endif
360*61046927SAndroid Build Coastguard Worker
361*61046927SAndroid Build Coastguard Worker /* The first device is swrast. Start with the non-swrast device. */
362*61046927SAndroid Build Coastguard Worker devs = devs->Next;
363*61046927SAndroid Build Coastguard Worker
364*61046927SAndroid Build Coastguard Worker /* bail early if we only care about the count */
365*61046927SAndroid Build Coastguard Worker if (!devices) {
366*61046927SAndroid Build Coastguard Worker *num_devices = num_devs;
367*61046927SAndroid Build Coastguard Worker goto out;
368*61046927SAndroid Build Coastguard Worker }
369*61046927SAndroid Build Coastguard Worker
370*61046927SAndroid Build Coastguard Worker *num_devices = MIN2(num_devs, max_devices);
371*61046927SAndroid Build Coastguard Worker
372*61046927SAndroid Build Coastguard Worker /* Add non-swrast devices first and add swrast last.
373*61046927SAndroid Build Coastguard Worker *
374*61046927SAndroid Build Coastguard Worker * By default, the user is likely to pick the first device so having the
375*61046927SAndroid Build Coastguard Worker * software (aka least performant) one is not a good idea.
376*61046927SAndroid Build Coastguard Worker */
377*61046927SAndroid Build Coastguard Worker for (i = 0, dev = devs; dev && i < max_devices; i++) {
378*61046927SAndroid Build Coastguard Worker devices[i] = dev;
379*61046927SAndroid Build Coastguard Worker dev = dev->Next;
380*61046927SAndroid Build Coastguard Worker }
381*61046927SAndroid Build Coastguard Worker
382*61046927SAndroid Build Coastguard Worker /* User requested the full device list, add the software device. */
383*61046927SAndroid Build Coastguard Worker if (max_devices >= num_devs && swrast) {
384*61046927SAndroid Build Coastguard Worker assert(_eglDeviceSupports(swrast, _EGL_DEVICE_SOFTWARE));
385*61046927SAndroid Build Coastguard Worker devices[num_devs - 1] = swrast;
386*61046927SAndroid Build Coastguard Worker }
387*61046927SAndroid Build Coastguard Worker
388*61046927SAndroid Build Coastguard Worker out:
389*61046927SAndroid Build Coastguard Worker simple_mtx_unlock(_eglGlobal.Mutex);
390*61046927SAndroid Build Coastguard Worker
391*61046927SAndroid Build Coastguard Worker return EGL_TRUE;
392*61046927SAndroid Build Coastguard Worker }
393