egl/gbm: Fix EGL_DEFAULT_DISPLAY
authorBenjamin Franzke <benjaminfranzke@googlemail.com>
Wed, 29 Jun 2011 06:49:39 +0000 (08:49 +0200)
committerBenjamin Franzke <benjaminfranzke@googlemail.com>
Thu, 4 Aug 2011 12:09:34 +0000 (14:09 +0200)
src/egl/drivers/dri2/egl_dri2.c
src/egl/drivers/dri2/egl_dri2.h
src/egl/drivers/dri2/platform_drm.c
src/gallium/state_trackers/egl/drm/native_drm.c
src/gallium/state_trackers/egl/drm/native_drm.h

index 0aca929e6aae7ef16d5e3840e684b9d097ae1d0d..9a37ea4bbfcafcbb0b8b790a7f358fe5594bb134 100644 (file)
@@ -591,6 +591,13 @@ dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
       case _EGL_PLATFORM_WAYLAND:
          wl_display_destroy(dri2_dpy->wl_dpy);
          break;
+#endif
+#ifdef HAVE_DRM_PLATFORM
+      case _EGL_PLATFORM_DRM:
+         if (dri2_dpy->own_gbm_device) {
+            gbm_device_destroy(&dri2_dpy->gbm_dri->base.base);
+         }
+         break;
 #endif
       default:
          break;
index 3854200bc694642ffd18e21a016214d1e0099626..a7297188af284f87133fbbe43930b8a096a56a39 100644 (file)
@@ -86,6 +86,7 @@ struct dri2_egl_display
 
 #ifdef HAVE_DRM_PLATFORM
    struct gbm_dri_device    *gbm_dri;
+   int                       own_gbm_device;
 #endif
 
    char                     *device_name;
index 579baf9f9d26239f7c69156ee637aedc5dd215fc..04b10e279ec6bb497c0f531e5dcb82c0822d9e28 100644 (file)
 #include <string.h>
 #include <xf86drm.h>
 #include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
 
 #include "egl_dri2.h"
 
@@ -90,6 +94,7 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
 {
    struct dri2_egl_display *dri2_dpy;
    struct gbm_device *gbm;
+   int fd = -1;
    int i;
 
    dri2_dpy = malloc(sizeof *dri2_dpy);
@@ -100,7 +105,15 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
 
    disp->DriverData = (void *) dri2_dpy;
 
-   gbm = (struct gbm_device *) disp->PlatformDisplay;
+   gbm = disp->PlatformDisplay;
+   if (gbm == NULL) {
+      fd = open("/dev/dri/card0", O_RDWR);
+      dri2_dpy->own_gbm_device = 1;
+      gbm = gbm_create_device(fd);
+      if (gbm == NULL)
+         return EGL_FALSE;
+   }
+
    if (strcmp(gbm_device_get_backend_name(gbm), "drm") != 0) {
       free(dri2_dpy);
       return EGL_FALSE;
@@ -112,7 +125,15 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
       return EGL_FALSE;
    }
 
-   dri2_dpy->fd = gbm_device_get_fd(gbm);
+   if (fd < 0) {
+      fd = dup(gbm_device_get_fd(gbm));
+      if (fd < 0) {
+         free(dri2_dpy);
+         return EGL_FALSE;
+      }
+   }
+
+   dri2_dpy->fd = fd;
    dri2_dpy->device_name = dri2_get_device_name_for_fd(dri2_dpy->fd);
    dri2_dpy->driver_name = dri2_dpy->gbm_dri->base.driver_name;
 
index 47910de8d3c4b138cbf8c65c9b8520737852467c..c013769e57d8b874f905d967dbd3c1e6803a667f 100644 (file)
@@ -134,8 +134,11 @@ drm_display_destroy(struct native_display *ndpy)
    if (drmdpy->device_name)
       FREE(drmdpy->device_name);
 
-   if (drmdpy->fd >= 0)
-      close(drmdpy->fd);
+   if (drmdpy->own_gbm) {
+      gbm_device_destroy(&drmdpy->gbmdrm->base.base);
+      if (drmdpy->fd >= 0)
+         close(drmdpy->fd);
+   }
 
    FREE(drmdpy);
 }
@@ -258,7 +261,7 @@ drm_display_init_screen(struct native_display *ndpy)
 }
 
 static struct native_display *
-drm_create_display(struct gbm_gallium_drm_device *gbmdrm,
+drm_create_display(struct gbm_gallium_drm_device *gbmdrm, int own_gbm,
                    const struct native_event_handler *event_handler)
 {
    struct drm_display *drmdpy;
@@ -267,6 +270,8 @@ drm_create_display(struct gbm_gallium_drm_device *gbmdrm,
    if (!drmdpy)
       return NULL;
 
+   drmdpy->gbmdrm = gbmdrm;
+   drmdpy->own_gbm = own_gbm;
    drmdpy->fd = gbmdrm->base.base.fd;
    drmdpy->device_name = drm_get_device_name(drmdpy->fd);
 
@@ -302,22 +307,30 @@ native_create_display(void *dpy, boolean use_sw)
 {
    struct gbm_gallium_drm_device *gbm;
    int fd;
+   int own_gbm = 0;
 
    gbm = dpy;
 
    if (gbm == NULL) {
       fd = open("/dev/dri/card0", O_RDWR);
+      /* FIXME: Use an internal constructor to create a gbm
+       * device with gallium backend directly, without setenv */
+      setenv("GBM_BACKEND", "gbm_gallium_drm.so", 1);
       gbm = gbm_gallium_drm_device(gbm_create_device(fd));
+      own_gbm = 1;
    }
 
    if (gbm == NULL)
       return NULL;
    
    if (strcmp(gbm_device_get_backend_name(&gbm->base.base), "drm") != 0 ||
-       gbm->base.type != GBM_DRM_DRIVER_TYPE_GALLIUM)
+       gbm->base.type != GBM_DRM_DRIVER_TYPE_GALLIUM) {
+      if (own_gbm)
+         gbm_device_destroy(&gbm->base.base);
       return NULL;
+   }
 
-   return drm_create_display(gbm, drm_event_handler);
+   return drm_create_display(gbm, own_gbm, drm_event_handler);
 }
 
 static const struct native_platform drm_platform = {
index 675a58a1922b37e8e4c88164dd20c0834a141aaa..18cebf4e276dfdf6729f45b08e31503152f8d94f 100644 (file)
@@ -41,6 +41,8 @@
 #include "common/native_wayland_drm_bufmgr_helper.h"
 #endif
 
+#include "gbm_gallium_drmint.h"
+
 struct drm_config;
 struct drm_crtc;
 struct drm_connector;
@@ -52,6 +54,8 @@ struct drm_display {
 
    const struct native_event_handler *event_handler;
 
+   struct gbm_gallium_drm_device *gbmdrm;
+   int own_gbm;
    int fd;
    char *device_name;
    struct drm_config *config;