egl: add EGL_platform_device support

This new 'platform' is added by default with no guards.

It is effectively a copy of the surfaceless one, with updated function
names and brand new probe function.

Due to the reuse, some of the ifdef HAVE_SURFACELESS_PLATFORM guards
have been dropped.

A worthy mention are the changes in _egFindDisplay, since the original
and dup'd fd are required, we make use of the plat_opt argument.

Note that no hacks for eglGetDisplay are added - the API works only with
the eglGetPlatformDisplay* API.

v2:
 - s/_eglCompareDeviceDisplay/_eglSameDeviceDisplay/ (Eric)
 - let ^^ return bool (Eric)
 - fixup meson build, move files() further up (Eric)
 - copy from plat. surfaceless w/o the visual cleanups
 - close and free when destroying the dpy
 - sprinkle a few _eglDeviceSupports
 - split fd handling into separate function
 - use directly the render node if no FD is given (Mathias)

v3:
 - s/dpy/disp/g
 - drop swap_buffers* callbacks
 - drop loader_set_logger()
 - drop local define
 - re-introduce _eglGetDRMDeviceRenderNode()
 - EGL_WARN on ForceSoftware with HW device - continue using the HW device
 - bail out for "EGL_MESA_device_software" until it's fixed
 - wire-up the Android build

v4:
 - use new style _eglFindDisplay()
 - split hw vs sw code paths
 - don't close the internal fd (already handled in FiniDisplay())
 - make swrast work (bit hacky bit will do for now)
 - Android for real, drop autotools
 - Correct HW + LIBGL_ALWAYS_SOFTWARE check
 - use the dri2_create_drawable() helper

v5:
 - enhance comment around fd checks (Mathias)
 - rebase for dri2_init_surface() changes

Cc: Mathias Fröhlich <Mathias.Froehlich@gmx.net>
Acked-by: Marek Olšák <marek.olsak@amd.com> (v4)
Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
Signed-off-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
Emil Velikov
2019-05-16 18:01:40 +01:00
committed by Marek Olšák
parent 2f11957532
commit d6edccee8d
12 changed files with 550 additions and 12 deletions

View File

@@ -35,12 +35,14 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include "c11/threads.h"
#include "util/u_atomic.h"
#include "eglcontext.h"
#include "eglcurrent.h"
#include "eglsurface.h"
#include "egldevice.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
@@ -202,6 +204,13 @@ _eglFiniDisplay(void)
}
}
/* The fcntl() code in _eglGetDeviceDisplay() ensures that valid fd >= 3,
* and invalid one is 0.
*/
if (disp->Options.fd)
close(disp->Options.fd);
free(disp->Options.Attribs);
free(disp);
}
@@ -557,3 +566,61 @@ _eglGetSurfacelessDisplay(void *native_display,
attrib_list);
}
#endif /* HAVE_SURFACELESS_PLATFORM */
_EGLDisplay*
_eglGetDeviceDisplay(void *native_display,
const EGLAttrib *attrib_list)
{
_EGLDevice *dev;
_EGLDisplay *display;
int fd = -1;
dev = _eglLookupDevice(native_display);
if (!dev) {
_eglError(EGL_BAD_PARAMETER, "eglGetPlatformDisplay");
return NULL;
}
if (attrib_list) {
for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
EGLAttrib attrib = attrib_list[i];
EGLAttrib value = attrib_list[i + 1];
/* EGL_EXT_platform_device does not recognize any attributes,
* EGL_EXT_device_drm adds the optional EGL_DRM_MASTER_FD_EXT.
*/
if (!_eglDeviceSupports(dev, _EGL_DEVICE_DRM) ||
attrib != EGL_DRM_MASTER_FD_EXT) {
_eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
return NULL;
}
fd = (int) value;
}
}
display = _eglFindDisplay(_EGL_PLATFORM_DEVICE, native_display, attrib_list);
if (!display) {
_eglError(EGL_BAD_ALLOC, "eglGetPlatformDisplay");
return NULL;
}
/* If the fd is explicitly provided and we did not dup() it yet, do so.
* The spec mandates that we do so, since we'll need it past the
* eglGetPlatformDispay call.
*
* The new fd is guaranteed to be 3 or greater.
*/
if (fd != -1 && display->Options.fd == 0) {
display->Options.fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
if (display->Options.fd == -1) {
/* Do not (really) need to teardown the display */
_eglError(EGL_BAD_ALLOC, "eglGetPlatformDisplay");
return NULL;
}
}
return display;
}