{ HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 0, 2, __DRI_IMAGE_FOURCC_NV12 },
{ HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 0, 1, __DRI_IMAGE_FOURCC_YUV420 },
{ HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 1, 1, __DRI_IMAGE_FOURCC_YVU420 },
+ { HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 1, 1, __DRI_IMAGE_FOURCC_AYUV },
+ { HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 1, 1, __DRI_IMAGE_FOURCC_XYUV8888 },
};
static int
}
static EGLBoolean
-droid_swap_interval(_EGLDriver *drv, _EGLDisplay *dpy,
+droid_swap_interval(_EGLDriver *drv, _EGLDisplay *disp,
_EGLSurface *surf, EGLint interval)
{
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
-
- if (dri2_surf->base.Type != EGL_WINDOW_BIT)
- return EGL_TRUE;
-
const bool has_mutable_rb = _eglSurfaceHasMutableRenderBuffer(draw);
/* From the EGL_KHR_mutable_render_buffer spec (v12):
#endif /* HAVE_DRM_GRALLOC */
static EGLBoolean
-droid_query_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
+droid_query_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
EGLint attribute, EGLint *value)
{
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
default:
break;
}
- return _eglQuerySurface(drv, dpy, surf, attribute, value);
+ return _eglQuerySurface(drv, disp, surf, attribute, value);
}
static _EGLImage *
}
static EGLBoolean
-droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
+droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp)
{
- struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
static const struct {
int format;
unsigned int rgba_masks[4];
};
struct dri2_egl_config *dri2_conf =
- dri2_add_config(dpy, dri2_dpy->driver_configs[j],
+ dri2_add_config(disp, dri2_dpy->driver_configs[j],
config_count + 1, surface_type, config_attrs,
visuals[i].rgba_masks);
if (dri2_conf) {
return (config_count != 0);
}
+static EGLBoolean
+droid_probe_device(_EGLDisplay *disp);
+
#ifdef HAVE_DRM_GRALLOC
-static int
-droid_open_device_drm_gralloc(struct dri2_egl_display *dri2_dpy)
+static EGLBoolean
+droid_open_device_drm_gralloc(_EGLDisplay *disp)
{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
int fd = -1, err = -EINVAL;
if (dri2_dpy->gralloc->perform)
&fd);
if (err || fd < 0) {
_eglLog(_EGL_WARNING, "fail to get drm fd");
- fd = -1;
+ return EGL_FALSE;
}
- return (fd >= 0) ? fcntl(fd, F_DUPFD_CLOEXEC, 3) : -1;
+ dri2_dpy->fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
+ if (dri2_dpy->fd < 0)
+ return EGL_FALSE;
+
+ return droid_probe_device(disp);
}
#endif /* HAVE_DRM_GRALLOC */
NULL,
};
-EGLBoolean
+static EGLBoolean
droid_load_driver(_EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy = disp->DriverData;
dri2_dpy->is_render_node = drmGetNodeTypeFromFd(dri2_dpy->fd) == DRM_NODE_RENDER;
if (!dri2_dpy->is_render_node) {
- #ifdef HAVE_DRM_GRALLOC
+#ifdef HAVE_DRM_GRALLOC
/* Handle control nodes using __DRI_DRI2_LOADER extension and GEM names
* for backwards compatibility with drm_gralloc. (Do not use on new
* systems.) */
err = "DRI2: failed to load driver";
goto error;
}
- #else
+#else
err = "DRI2: handle is not for a render node";
goto error;
- #endif
+#endif
} else {
dri2_dpy->loader_extensions = droid_image_loader_extensions;
if (!dri2_load_driver_dri3(disp)) {
return false;
}
-static bool
-droid_probe_driver(int fd)
+static void
+droid_unload_driver(_EGLDisplay *disp)
{
- char *driver_name;
-
- driver_name = loader_get_driver_for_fd(fd);
- if (driver_name == NULL)
- return false;
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- free(driver_name);
- return true;
+ dlclose(dri2_dpy->driver);
+ dri2_dpy->driver = NULL;
+ free(dri2_dpy->driver_name);
+ dri2_dpy->driver_name = NULL;
}
-typedef enum {
- probe_fail = -1,
- probe_success = 0,
- probe_filtered_out = 1,
-} probe_ret_t;
-
-static probe_ret_t
-droid_probe_device(_EGLDisplay *disp, int fd, const char *vendor)
+static int
+droid_filter_device(_EGLDisplay *disp, int fd, const char *vendor)
{
- int ret;
-
drmVersionPtr ver = drmGetVersion(fd);
if (!ver)
- return probe_fail;
-
- if (!ver->name) {
- ret = probe_fail;
- goto cleanup;
- }
+ return -1;
- if (vendor && strcmp(vendor, ver->name) != 0) {
- ret = probe_filtered_out;
- goto cleanup;
+ if (strcmp(vendor, ver->name) != 0) {
+ drmFreeVersion(ver);
+ return -1;
}
- if (!droid_probe_driver(fd)) {
- ret = probe_fail;
- goto cleanup;
- }
+ drmFreeVersion(ver);
+ return 0;
+}
- ret = probe_success;
+static EGLBoolean
+droid_probe_device(_EGLDisplay *disp)
+{
+ /* Check that the device is supported, by attempting to:
+ * - load the dri module
+ * - and, create a screen
+ */
+ if (!droid_load_driver(disp))
+ return EGL_FALSE;
-cleanup:
- drmFreeVersion(ver);
- return ret;
+ if (!dri2_create_screen(disp)) {
+ _eglLog(_EGL_WARNING, "DRI2: failed to create screen");
+ droid_unload_driver(disp);
+ return EGL_FALSE;
+ }
+ return EGL_TRUE;
}
-static int
+static EGLBoolean
droid_open_device(_EGLDisplay *disp)
{
-#define MAX_DRM_DEVICES 32
+#define MAX_DRM_DEVICES 64
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
drmDevicePtr device, devices[MAX_DRM_DEVICES] = { NULL };
- int prop_set, num_devices;
- int fd = -1, fallback_fd = -1;
+ int num_devices;
char *vendor_name = NULL;
char vendor_buf[PROPERTY_VALUE_MAX];
num_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
if (num_devices < 0)
- return num_devices;
+ return EGL_FALSE;
for (int i = 0; i < num_devices; i++) {
device = devices[i];
if (!(device->available_nodes & (1 << DRM_NODE_RENDER)))
continue;
- fd = loader_open_device(device->nodes[DRM_NODE_RENDER]);
- if (fd < 0) {
+ dri2_dpy->fd = loader_open_device(device->nodes[DRM_NODE_RENDER]);
+ if (dri2_dpy->fd < 0) {
_eglLog(_EGL_WARNING, "%s() Failed to open DRM device %s",
__func__, device->nodes[DRM_NODE_RENDER]);
continue;
}
- int ret = droid_probe_device(disp, fd, vendor_name);
- switch (ret) {
- case probe_success:
- goto success;
- case probe_filtered_out:
- /* Set as fallback */
- if (fallback_fd == -1)
- fallback_fd = fd;
- break;
- case probe_fail:
+ /* If a vendor is explicitly provided, we use only that.
+ * Otherwise we fall-back the first device that is supported.
+ */
+ if (vendor_name) {
+ if (droid_filter_device(disp, dri2_dpy->fd, vendor_name)) {
+ /* Device does not match - try next device */
+ close(dri2_dpy->fd);
+ dri2_dpy->fd = -1;
+ continue;
+ }
+ /* If the requested device matches - use it. Regardless if
+ * init fails, do not fall-back to any other device.
+ */
+ if (!droid_probe_device(disp)) {
+ close(dri2_dpy->fd);
+ dri2_dpy->fd = -1;
+ }
+
break;
}
+ if (droid_probe_device(disp))
+ break;
- if (fallback_fd != fd)
- close(fd);
- fd = -1;
+ /* No explicit request - attempt the next device */
+ close(dri2_dpy->fd);
+ dri2_dpy->fd = -1;
}
-
-success:
drmFreeDevices(devices, num_devices);
- if (fallback_fd < 0 && fd < 0) {
- _eglLog(_EGL_WARNING, "Failed to open any DRM device");
- return -1;
- }
-
- if (fd < 0) {
- _eglLog(_EGL_WARNING, "Failed to open desired DRM device, using fallback");
- return fallback_fd;
+ if (dri2_dpy->fd < 0) {
+ _eglLog(_EGL_WARNING, "Failed to open %s DRM device",
+ vendor_name ? "desired": "any");
+ return EGL_FALSE;
}
- close(fallback_fd);
- return fd;
+ return EGL_TRUE;
#undef MAX_DRM_DEVICES
}
EGLBoolean
dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp)
{
+ _EGLDevice *dev;
struct dri2_egl_display *dri2_dpy;
const char *err;
int ret;
if (disp->Options.ForceSoftware)
return EGL_FALSE;
- loader_set_logger(_eglLog);
-
dri2_dpy = calloc(1, sizeof(*dri2_dpy));
if (!dri2_dpy)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
disp->DriverData = (void *) dri2_dpy;
#ifdef HAVE_DRM_GRALLOC
- dri2_dpy->fd = droid_open_device_drm_gralloc(dri2_dpy);
+ if (!droid_open_device_drm_gralloc(disp)) {
#else
- dri2_dpy->fd = droid_open_device(disp);
+ if (!droid_open_device(disp)) {
#endif
- if (dri2_dpy->fd < 0) {
err = "DRI2: failed to open device";
goto cleanup;
}
- if (!droid_load_driver(disp)) {
- err = "DRI2: failed to load driver";
+ dev = _eglAddDevice(dri2_dpy->fd, false);
+ if (!dev) {
+ err = "DRI2: failed to find EGLDevice";
goto cleanup;
}
- if (!dri2_create_screen(disp)) {
- err = "DRI2: failed to create screen";
- goto cleanup;
- }
+ disp->Device = dev;
if (!dri2_setup_extensions(disp)) {
err = "DRI2: failed to setup extensions";