egl_dri2: Hookup gbm as drm platform
authorBenjamin Franzke <benjaminfranzke@googlemail.com>
Mon, 30 May 2011 08:50:52 +0000 (10:50 +0200)
committerBenjamin Franzke <benjaminfranzke@googlemail.com>
Thu, 23 Jun 2011 19:07:17 +0000 (21:07 +0200)
configure.ac
src/egl/drivers/dri2/Makefile
src/egl/drivers/dri2/egl_dri2.c
src/egl/drivers/dri2/egl_dri2.h
src/egl/drivers/dri2/platform_drm.c
src/egl/main/Makefile

index dbf8fe5caca3b210dba5528fe9e235ff1e3260c5..c94c5fadd4c0145c1e3903ac7850ca4374f1ae8c 100644 (file)
@@ -1653,6 +1653,9 @@ yes)
                WAYLAND_EGL_LIB_DEPS="$WAYLAND_LIBS $LIBDRM_LIBS"
                 GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/wayland"
        fi
+        if test "$plat" = "drm" && test "x$enable_gbm" = no; then
+                AC_MSG_ERROR([EGL platform drm needs gbm])
+        fi
     done
     EGL_PLATFORMS="$egl_platforms"
     ;;
index f8ff82b49c27ff5f4c140d772e219e58345addbc..65d35b36206312ad7a94c2b16c8a37d483f46111 100644 (file)
@@ -10,6 +10,8 @@ EGL_INCLUDES = \
        -I$(TOP)/include \
        -I$(TOP)/src/egl/main \
        -I$(TOP)/src/mapi \
+       -I$(TOP)/src/gbm/main \
+       -I$(TOP)/src/gbm/backends/dri \
        -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \
        $(LIBUDEV_CFLAGS) \
        $(LIBDRM_CFLAGS)
index d430145d09c4b232672b8f4656bdaf9d1400f320..cad1737f4bff5c852b066720b3139daea1921015 100644 (file)
@@ -244,7 +244,7 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
    return conf;
 }
 
-static __DRIimage *
+__DRIimage *
 dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data)
 {
    _EGLDisplay *disp = data;
@@ -433,42 +433,12 @@ dri2_load_driver_swrast(_EGLDisplay *disp)
    return EGL_TRUE;
 }
 
-EGLBoolean
-dri2_create_screen(_EGLDisplay *disp)
+void
+dri2_setup_screen(_EGLDisplay *disp)
 {
-   const __DRIextension **extensions;
-   struct dri2_egl_display *dri2_dpy;
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
    unsigned int api_mask;
 
-   dri2_dpy = disp->DriverData;
-
-   if (dri2_dpy->dri2) {
-      dri2_dpy->dri_screen =
-         dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions,
-                                        &dri2_dpy->driver_configs, disp);
-   } else {
-      assert(dri2_dpy->swrast);
-      dri2_dpy->dri_screen =
-         dri2_dpy->swrast->createNewScreen(0, dri2_dpy->extensions,
-                                           &dri2_dpy->driver_configs, disp);
-   }
-
-   if (dri2_dpy->dri_screen == NULL) {
-      _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen");
-      return EGL_FALSE;
-   }
-
-   extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen);
-   
-   if (dri2_dpy->dri2) {
-      if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions))
-         goto cleanup_dri_screen;
-   } else {
-      assert(dri2_dpy->swrast);
-      if (!dri2_bind_extensions(dri2_dpy, swrast_core_extensions, extensions))
-         goto cleanup_dri_screen;
-   }
-
    if (dri2_dpy->dri2) {
       if (dri2_dpy->dri2->base.version >= 2)
          api_mask = dri2_dpy->dri2->getAPIMask(dri2_dpy->dri_screen);
@@ -510,6 +480,44 @@ dri2_create_screen(_EGLDisplay *disp)
       disp->Extensions.KHR_image_base = EGL_TRUE;
       disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
    }
+}
+
+EGLBoolean
+dri2_create_screen(_EGLDisplay *disp)
+{
+   const __DRIextension **extensions;
+   struct dri2_egl_display *dri2_dpy;
+
+   dri2_dpy = disp->DriverData;
+
+   if (dri2_dpy->dri2) {
+      dri2_dpy->dri_screen =
+         dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions,
+                                        &dri2_dpy->driver_configs, disp);
+   } else {
+      assert(dri2_dpy->swrast);
+      dri2_dpy->dri_screen =
+         dri2_dpy->swrast->createNewScreen(0, dri2_dpy->extensions,
+                                           &dri2_dpy->driver_configs, disp);
+   }
+
+   if (dri2_dpy->dri_screen == NULL) {
+      _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen");
+      return EGL_FALSE;
+   }
+
+   extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen);
+   
+   if (dri2_dpy->dri2) {
+      if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions))
+         goto cleanup_dri_screen;
+   } else {
+      assert(dri2_dpy->swrast);
+      if (!dri2_bind_extensions(dri2_dpy, swrast_core_extensions, extensions))
+         goto cleanup_dri_screen;
+   }
+
+   dri2_setup_screen(disp);
 
    return EGL_TRUE;
 
index 1844b6c7a3a68339fc3df77d568d6af1bec13e71..cd52d421ddf07b0854f5c25c748f02eb5faa6384 100644 (file)
@@ -44,6 +44,8 @@
 #include <GL/gl.h>
 #include <GL/internal/dri_interface.h>
 
+#include <gbm_driint.h>
+
 #include "eglconfig.h"
 #include "eglcontext.h"
 #include "egldisplay.h"
@@ -79,6 +81,8 @@ struct dri2_egl_display
    __DRIimageExtension      *image;
    int                       fd;
 
+   struct gbm_dri_device    *gbm_dri;
+
    char                     *device_name;
    char                     *driver_name;
 
@@ -185,12 +189,19 @@ extern const __DRIuseInvalidateExtension use_invalidate;
 EGLBoolean
 dri2_load_driver(_EGLDisplay *disp);
 
+/* Helper for platforms not using dri2_create_screen */
+void
+dri2_setup_screen(_EGLDisplay *disp);
+
 EGLBoolean
 dri2_load_driver_swrast(_EGLDisplay *disp);
 
 EGLBoolean
 dri2_create_screen(_EGLDisplay *disp);
 
+__DRIimage *
+dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data);
+
 struct dri2_egl_config *
 dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
                int depth, EGLint surface_type, const EGLint *attr_list);
index 27846de39d28f0fb5be1258007837a67f922aace..579baf9f9d26239f7c69156ee637aedc5dd215fc 100644 (file)
 
 #include "egl_dri2.h"
 
+static _EGLImage *
+dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
+                            EGLClientBuffer buffer, const EGLint *attr_list)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+   struct gbm_dri_bo *dri_bo = gbm_dri_bo((struct gbm_bo *) buffer);
+   struct dri2_egl_image *dri2_img;
+
+   dri2_img = malloc(sizeof *dri2_img);
+   if (!dri2_img) {
+      _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap");
+      return NULL;
+   }
+
+   if (!_eglInitImage(&dri2_img->base, disp)) {
+      free(dri2_img);
+      return NULL;
+   }
+
+   dri2_img->dri_image = dri2_dpy->image->dupImage(dri_bo->image, dri2_img);
+   if (dri2_img->dri_image == NULL) {
+      free(dri2_img);
+      _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap");
+      return NULL;
+   }
+
+   return &dri2_img->base;
+}
+
+static _EGLImage *
+dri2_drm_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
+                          _EGLContext *ctx, EGLenum target,
+                          EGLClientBuffer buffer, const EGLint *attr_list)
+{
+   (void) drv;
+
+   switch (target) {
+   case EGL_NATIVE_PIXMAP_KHR:
+      return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
+   default:
+      return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
+   }
+}
+
 static int
 dri2_drm_authenticate(_EGLDisplay *disp, uint32_t id)
 {
@@ -45,57 +89,58 @@ EGLBoolean
 dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
 {
    struct dri2_egl_display *dri2_dpy;
+   struct gbm_device *gbm;
    int i;
 
    dri2_dpy = malloc(sizeof *dri2_dpy);
    if (!dri2_dpy)
       return _eglError(EGL_BAD_ALLOC, "eglInitialize");
-   
+
    memset(dri2_dpy, 0, sizeof *dri2_dpy);
 
    disp->DriverData = (void *) dri2_dpy;
-   dri2_dpy->fd = (int) (intptr_t) disp->PlatformDisplay;
 
-   dri2_dpy->driver_name = dri2_get_driver_for_fd(dri2_dpy->fd);
-   if (dri2_dpy->driver_name == NULL)
-      return _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name");
+   gbm = (struct gbm_device *) disp->PlatformDisplay;
+   if (strcmp(gbm_device_get_backend_name(gbm), "drm") != 0) {
+      free(dri2_dpy);
+      return EGL_FALSE;
+   }
 
-   dri2_dpy->device_name = dri2_get_device_name_for_fd(dri2_dpy->fd);
-   if (dri2_dpy->device_name == NULL) {
-      _eglError(EGL_BAD_ALLOC, "DRI2: failed to get device name");
-      goto cleanup_driver_name;
+   dri2_dpy->gbm_dri = gbm_dri_device(gbm);
+   if (dri2_dpy->gbm_dri->base.type != GBM_DRM_DRIVER_TYPE_DRI) {
+      free(dri2_dpy);
+      return EGL_FALSE;
    }
 
-   if (!dri2_load_driver(disp))
-      goto cleanup_device_name;
+   dri2_dpy->fd = gbm_device_get_fd(gbm);
+   dri2_dpy->device_name = dri2_get_device_name_for_fd(dri2_dpy->fd);
+   dri2_dpy->driver_name = dri2_dpy->gbm_dri->base.driver_name;
+
+   dri2_dpy->dri_screen = dri2_dpy->gbm_dri->screen;
+   dri2_dpy->core = dri2_dpy->gbm_dri->core;
+   dri2_dpy->dri2 = dri2_dpy->gbm_dri->dri2;
+   dri2_dpy->image = dri2_dpy->gbm_dri->image;
+   dri2_dpy->driver_configs = dri2_dpy->gbm_dri->driver_configs;
 
-   dri2_dpy->extensions[0] = &image_lookup_extension.base;
-   dri2_dpy->extensions[1] = &use_invalidate.base;
-   dri2_dpy->extensions[2] = NULL;
+   dri2_dpy->gbm_dri->lookup_image = dri2_lookup_egl_image;
+   dri2_dpy->gbm_dri->lookup_user_data = disp;
 
-   if (!dri2_create_screen(disp))
-      goto cleanup_driver;
+   dri2_setup_screen(disp);
 
    for (i = 0; dri2_dpy->driver_configs[i]; i++)
-      dri2_add_config(disp, dri2_dpy->driver_configs[i], i + 1, 0, 0, NULL);
+      dri2_add_config(disp, dri2_dpy->driver_configs[i],
+                      i + 1, 0, 0, NULL);
+
+   drv->API.CreateImageKHR = dri2_drm_create_image_khr;
 
 #ifdef HAVE_WAYLAND_PLATFORM
    disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
 #endif
    dri2_dpy->authenticate = dri2_drm_authenticate;
-   
+
    /* we're supporting EGL 1.4 */
    disp->VersionMajor = 1;
    disp->VersionMinor = 4;
 
    return EGL_TRUE;
-
- cleanup_driver:
-   dlclose(dri2_dpy->driver);
- cleanup_device_name:
-   free(dri2_dpy->device_name);
- cleanup_driver_name:
-   free(dri2_dpy->driver_name);
-
-   return EGL_FALSE;
 }
index 6c4a392760ffad605cecd6b18f92c85f86433b60..775fbbe178b670a4f9cc8e86a50d9ac8a4dbd118 100644 (file)
@@ -61,9 +61,13 @@ LOCAL_LIBS += $(TOP)/src/egl/drivers/dri2/libegl_dri2.a
 ifneq ($(findstring x11, $(EGL_PLATFORMS)),)
 EGL_LIB_DEPS += $(XCB_DRI2_LIBS)
 endif
+ifneq ($(findstring drm, $(EGL_PLATFORMS)),)
+EGL_LIB_DEPS += -lgbm
+endif
 EGL_LIB_DEPS += $(LIBUDEV_LIBS) $(DLOPEN_LIBS) $(LIBDRM_LIB) $(WAYLAND_LIBS)
 endif
 
+
 ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)
 LOCAL_LIBS += $(TOP)/src/egl/wayland/wayland-drm/libwayland-drm.a
 endif