/*
 * Copyright © 2011 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Authors:
 *    Kristian Høgsberg <krh@bitplanet.net>
 */

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <xf86drm.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include "util/os_file.h"

#include "egl_dri2.h"
#include "loader.h"

static struct gbm_bo *
lock_front_buffer(struct gbm_surface *_surf)
{
   struct gbm_dri_surface *surf = gbm_dri_surface(_surf);
   struct dri2_egl_surface *dri2_surf = surf->dri_private;
   struct gbm_dri_device *device = gbm_dri_device(_surf->gbm);
   struct gbm_bo *bo;

   if (dri2_surf->current == NULL) {
      _eglError(EGL_BAD_SURFACE, "no front buffer");
      return NULL;
   }

   bo = dri2_surf->current->bo;

   if (device->dri2) {
      dri2_surf->current->locked = true;
      dri2_surf->current = NULL;
   }

   return bo;
}

static void
release_buffer(struct gbm_surface *_surf, struct gbm_bo *bo)
{
   struct gbm_dri_surface *surf = gbm_dri_surface(_surf);
   struct dri2_egl_surface *dri2_surf = surf->dri_private;

   for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
      if (dri2_surf->color_buffers[i].bo == bo) {
	 dri2_surf->color_buffers[i].locked = false;
	 break;
      }
   }
}

static int
has_free_buffers(struct gbm_surface *_surf)
{
   struct gbm_dri_surface *surf = gbm_dri_surface(_surf);
   struct dri2_egl_surface *dri2_surf = surf->dri_private;

   for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
      if (!dri2_surf->color_buffers[i].locked)
	 return 1;

   return 0;
}

static bool
dri2_drm_config_is_compatible(struct dri2_egl_display *dri2_dpy,
                              const __DRIconfig *config,
                              struct gbm_surface *surface)
{
   const struct gbm_dri_visual *visual = NULL;
   int shifts[4];
   unsigned int sizes[4];
   bool is_float;
   int i;

   /* Check that the EGLConfig being used to render to the surface is
    * compatible with the surface format. Since mixing ARGB and XRGB of
    * otherwise-compatible formats is relatively common, explicitly allow
    * this.
    */
   dri2_get_shifts_and_sizes(dri2_dpy->core, config, shifts, sizes);

   dri2_get_render_type_float(dri2_dpy->core, config, &is_float);

   for (i = 0; i < dri2_dpy->gbm_dri->num_visuals; i++) {
      visual = &dri2_dpy->gbm_dri->visual_table[i];
      if (visual->gbm_format == surface->format)
         break;
   }

   if (i == dri2_dpy->gbm_dri->num_visuals)
      return false;

   if (shifts[0] != visual->rgba_shifts.red ||
       shifts[1] != visual->rgba_shifts.green ||
       shifts[2] != visual->rgba_shifts.blue ||
       (shifts[3] > -1 && visual->rgba_shifts.alpha > -1 &&
        shifts[3] != visual->rgba_shifts.alpha) ||
       sizes[0] != visual->rgba_sizes.red ||
       sizes[1] != visual->rgba_sizes.green ||
       sizes[2] != visual->rgba_sizes.blue ||
       (sizes[3] > 0 && visual->rgba_sizes.alpha > 0 &&
        sizes[3] != visual->rgba_sizes.alpha) ||
       is_float != visual->is_float) {
      return false;
   }

   return true;
}

static _EGLSurface *
dri2_drm_create_window_surface(const _EGLDriver *drv, _EGLDisplay *disp,
                               _EGLConfig *conf, void *native_surface,
                               const EGLint *attrib_list)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
   struct dri2_egl_surface *dri2_surf;
   struct gbm_surface *surface = native_surface;
   struct gbm_dri_surface *surf;
   const __DRIconfig *config;

   (void) drv;

   dri2_surf = calloc(1, sizeof *dri2_surf);
   if (!dri2_surf) {
      _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
      return NULL;
   }

   if (!dri2_init_surface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf,
                          attrib_list, false, native_surface))
      goto cleanup_surf;

   config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
                                dri2_surf->base.GLColorspace);

   if (!config) {
      _eglError(EGL_BAD_MATCH, "Unsupported surfacetype/colorspace configuration");
      goto cleanup_surf;
   }

   if (!dri2_drm_config_is_compatible(dri2_dpy, config, surface)) {
      _eglError(EGL_BAD_MATCH, "EGL config not compatible with GBM format");
      goto cleanup_surf;
   }

   surf = gbm_dri_surface(surface);
   dri2_surf->gbm_surf = surf;
   dri2_surf->base.Width =  surf->base.width;
   dri2_surf->base.Height = surf->base.height;
   surf->dri_private = dri2_surf;

   if (!dri2_create_drawable(dri2_dpy, config, dri2_surf, dri2_surf->gbm_surf))
      goto cleanup_surf;

   return &dri2_surf->base;

 cleanup_surf:
   free(dri2_surf);

   return NULL;
}

static _EGLSurface *
dri2_drm_create_pixmap_surface(const _EGLDriver *drv, _EGLDisplay *disp,
                               _EGLConfig *conf, void *native_window,
                               const EGLint *attrib_list)
{
   /* From the EGL_MESA_platform_gbm spec, version 5:
    *
    *  It is not valid to call eglCreatePlatformPixmapSurfaceEXT with a <dpy>
    *  that belongs to the GBM platform. Any such call fails and generates
    *  EGL_BAD_PARAMETER.
    */
   _eglError(EGL_BAD_PARAMETER, "cannot create EGL pixmap surfaces on GBM");
   return NULL;
}

static EGLBoolean
dri2_drm_destroy_surface(const _EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);

   dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);

   for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
      if (dri2_surf->color_buffers[i].bo)
	 gbm_bo_destroy(dri2_surf->color_buffers[i].bo);
   }

   dri2_egl_surface_free_local_buffers(dri2_surf);

   dri2_fini_surface(surf);
   free(surf);

   return EGL_TRUE;
}

static int
get_back_bo(struct dri2_egl_surface *dri2_surf)
{
   struct dri2_egl_display *dri2_dpy =
      dri2_egl_display(dri2_surf->base.Resource.Display);
   struct gbm_dri_surface *surf = dri2_surf->gbm_surf;
   int age = 0;

   if (dri2_surf->back == NULL) {
      for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
	 if (!dri2_surf->color_buffers[i].locked &&
	      dri2_surf->color_buffers[i].age >= age) {
	    dri2_surf->back = &dri2_surf->color_buffers[i];
	    age = dri2_surf->color_buffers[i].age;
	 }
      }
   }

   if (dri2_surf->back == NULL)
      return -1;
   if (dri2_surf->back->bo == NULL) {
      if (surf->base.modifiers)
         dri2_surf->back->bo = gbm_bo_create_with_modifiers(&dri2_dpy->gbm_dri->base,
                                                            surf->base.width,
                                                            surf->base.height,
                                                            surf->base.format,
                                                            surf->base.modifiers,
                                                            surf->base.count);
      else
         dri2_surf->back->bo = gbm_bo_create(&dri2_dpy->gbm_dri->base,
                                             surf->base.width,
                                             surf->base.height,
                                             surf->base.format,
                                             surf->base.flags);

   }
   if (dri2_surf->back->bo == NULL)
      return -1;

   return 0;
}

static int
get_swrast_front_bo(struct dri2_egl_surface *dri2_surf)
{
   struct dri2_egl_display *dri2_dpy =
      dri2_egl_display(dri2_surf->base.Resource.Display);
   struct gbm_dri_surface *surf = dri2_surf->gbm_surf;

   if (dri2_surf->current == NULL) {
      assert(!dri2_surf->color_buffers[0].locked);
      dri2_surf->current = &dri2_surf->color_buffers[0];
   }

   if (dri2_surf->current->bo == NULL)
      dri2_surf->current->bo = gbm_bo_create(&dri2_dpy->gbm_dri->base,
                                             surf->base.width, surf->base.height,
                                             surf->base.format, surf->base.flags);
   if (dri2_surf->current->bo == NULL)
      return -1;

   return 0;
}

static void
back_bo_to_dri_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
{
   struct dri2_egl_display *dri2_dpy =
      dri2_egl_display(dri2_surf->base.Resource.Display);
   struct gbm_dri_bo *bo;
   int name, pitch;

   bo = gbm_dri_bo(dri2_surf->back->bo);

   dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_NAME, &name);
   dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, &pitch);

   buffer->attachment = __DRI_BUFFER_BACK_LEFT;
   buffer->name = name;
   buffer->pitch = pitch;
   buffer->cpp = 4;
   buffer->flags = 0;
}

static __DRIbuffer *
dri2_drm_get_buffers_with_format(__DRIdrawable *driDrawable,
                                 int *width, int *height,
                                 unsigned int *attachments, int count,
                                 int *out_count, void *loaderPrivate)
{
   struct dri2_egl_surface *dri2_surf = loaderPrivate;
   int i, j;

   for (i = 0, j = 0; i < 2 * count; i += 2, j++) {
      __DRIbuffer *local;

      assert(attachments[i] < __DRI_BUFFER_COUNT);
      assert(j < ARRAY_SIZE(dri2_surf->buffers));

      switch (attachments[i]) {
      case __DRI_BUFFER_BACK_LEFT:
	 if (get_back_bo(dri2_surf) < 0) {
	    _eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
	    return NULL;
	 }
         back_bo_to_dri_buffer(dri2_surf, &dri2_surf->buffers[j]);
	 break;
      default:
	 local = dri2_egl_surface_alloc_local_buffer(dri2_surf, attachments[i],
                                                     attachments[i + 1]);

	 if (!local) {
	    _eglError(EGL_BAD_ALLOC, "failed to allocate local buffer");
	    return NULL;
	 }
	 dri2_surf->buffers[j] = *local;
	 break;
      }
   }

   *out_count = j;
   if (j == 0)
      return NULL;

   *width = dri2_surf->base.Width;
   *height = dri2_surf->base.Height;

   return dri2_surf->buffers;
}

static __DRIbuffer *
dri2_drm_get_buffers(__DRIdrawable * driDrawable,
                     int *width, int *height,
                     unsigned int *attachments, int count,
                     int *out_count, void *loaderPrivate)
{
   unsigned int *attachments_with_format;
   __DRIbuffer *buffer;
   const unsigned int format = 32;

   attachments_with_format = calloc(count, 2 * sizeof(unsigned int));
   if (!attachments_with_format) {
      *out_count = 0;
      return NULL;
   }

   for (int i = 0; i < count; ++i) {
      attachments_with_format[2*i] = attachments[i];
      attachments_with_format[2*i + 1] = format;
   }

   buffer =
      dri2_drm_get_buffers_with_format(driDrawable,
                                       width, height,
                                       attachments_with_format, count,
                                       out_count, loaderPrivate);

   free(attachments_with_format);

   return buffer;
}

static int
dri2_drm_image_get_buffers(__DRIdrawable *driDrawable,
                           unsigned int format,
                           uint32_t *stamp,
                           void *loaderPrivate,
                           uint32_t buffer_mask,
                           struct __DRIimageList *buffers)
{
   struct dri2_egl_surface *dri2_surf = loaderPrivate;
   struct gbm_dri_bo *bo;

   if (get_back_bo(dri2_surf) < 0)
      return 0;

   bo = gbm_dri_bo(dri2_surf->back->bo);
   buffers->image_mask = __DRI_IMAGE_BUFFER_BACK;
   buffers->back = bo->image;

   return 1;
}

static void
dri2_drm_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
{
   (void) driDrawable;
   (void) loaderPrivate;
}

static EGLBoolean
dri2_drm_swap_buffers(const _EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);

   if (!dri2_dpy->flush) {
      dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable);
      return EGL_TRUE;
   }

   if (dri2_surf->current)
      _eglError(EGL_BAD_SURFACE, "dri2_swap_buffers");
   for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
      if (dri2_surf->color_buffers[i].age > 0)
         dri2_surf->color_buffers[i].age++;

   /* Make sure we have a back buffer in case we're swapping without
    * ever rendering. */
   if (get_back_bo(dri2_surf) < 0)
      return _eglError(EGL_BAD_ALLOC, "dri2_swap_buffers");

   dri2_surf->current = dri2_surf->back;
   dri2_surf->current->age = 1;
   dri2_surf->back = NULL;

   dri2_flush_drawable_for_swapbuffers(disp, draw);
   dri2_dpy->flush->invalidate(dri2_surf->dri_drawable);

   return EGL_TRUE;
}

static EGLint
dri2_drm_query_buffer_age(const _EGLDriver *drv,
                          _EGLDisplay *disp, _EGLSurface *surface)
{
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);

   if (get_back_bo(dri2_surf) < 0) {
      _eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age");
      return -1;
   }

   return dri2_surf->back->age;
}

static _EGLImage *
dri2_drm_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;
   }

   _eglInitImage(&dri2_img->base, disp);

   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(const _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_drm_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)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);

   return drmAuthMagic(dri2_dpy->fd, id);
}

static void
swrast_put_image2(__DRIdrawable *driDrawable,
                  int            op,
                  int            x,
                  int            y,
                  int            width,
                  int            height,
                  int            stride,
                  char          *data,
                  void          *loaderPrivate)
{
   struct dri2_egl_surface *dri2_surf = loaderPrivate;
   int internal_stride;
   struct gbm_dri_bo *bo;
   uint32_t bpp;
   int x_bytes, width_bytes;
   char *src, *dst;

   if (op != __DRI_SWRAST_IMAGE_OP_DRAW &&
       op != __DRI_SWRAST_IMAGE_OP_SWAP)
      return;

   if (get_swrast_front_bo(dri2_surf) < 0)
      return;

   bo = gbm_dri_bo(dri2_surf->current->bo);

   bpp = gbm_bo_get_bpp(&bo->base);
   if (bpp == 0)
      return;

   x_bytes = x * (bpp >> 3);
   width_bytes = width * (bpp >> 3);

   if (gbm_dri_bo_map_dumb(bo) == NULL)
      return;

   internal_stride = bo->base.stride;

   dst = bo->map + x_bytes + (y * internal_stride);
   src = data;

   for (int i = 0; i < height; i++) {
      memcpy(dst, src, width_bytes);
      dst += internal_stride;
      src += stride;
   }

   gbm_dri_bo_unmap_dumb(bo);
}

static void
swrast_get_image(__DRIdrawable *driDrawable,
                 int            x,
                 int            y,
                 int            width,
                 int            height,
                 char          *data,
                 void          *loaderPrivate)
{
   struct dri2_egl_surface *dri2_surf = loaderPrivate;
   int internal_stride, stride;
   struct gbm_dri_bo *bo;
   uint32_t bpp;
   int x_bytes, width_bytes;
   char *src, *dst;

   if (get_swrast_front_bo(dri2_surf) < 0)
      return;

   bo = gbm_dri_bo(dri2_surf->current->bo);

   bpp = gbm_bo_get_bpp(&bo->base);
   if (bpp == 0)
      return;

   x_bytes = x * (bpp >> 3);
   width_bytes = width * (bpp >> 3);

   internal_stride = bo->base.stride;
   stride = width_bytes;

   if (gbm_dri_bo_map_dumb(bo) == NULL)
      return;

   dst = data;
   src = bo->map + x_bytes + (y * internal_stride);

   for (int i = 0; i < height; i++) {
      memcpy(dst, src, width_bytes);
      dst += stride;
      src += internal_stride;
   }

   gbm_dri_bo_unmap_dumb(bo);
}

static EGLBoolean
drm_add_configs_for_visuals(const _EGLDriver *drv, _EGLDisplay *disp)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   const struct gbm_dri_visual *visuals = dri2_dpy->gbm_dri->visual_table;
   int num_visuals = dri2_dpy->gbm_dri->num_visuals;
   unsigned int format_count[num_visuals];
   unsigned int config_count = 0;

   memset(format_count, 0, num_visuals * sizeof(unsigned int));

   for (unsigned i = 0; dri2_dpy->driver_configs[i]; i++) {
      const __DRIconfig *config = dri2_dpy->driver_configs[i];
      int shifts[4];
      unsigned int sizes[4];
      bool is_float;

      dri2_get_shifts_and_sizes(dri2_dpy->core, config, shifts, sizes);

      dri2_get_render_type_float(dri2_dpy->core, config, &is_float);

      for (unsigned j = 0; j < num_visuals; j++) {
         struct dri2_egl_config *dri2_conf;

         if (visuals[j].rgba_shifts.red != shifts[0] ||
             visuals[j].rgba_shifts.green != shifts[1] ||
             visuals[j].rgba_shifts.blue != shifts[2] ||
             visuals[j].rgba_shifts.alpha != shifts[3] ||
             visuals[j].rgba_sizes.red != sizes[0] ||
             visuals[j].rgba_sizes.green != sizes[1] ||
             visuals[j].rgba_sizes.blue != sizes[2] ||
             visuals[j].rgba_sizes.alpha != sizes[3] ||
             visuals[j].is_float != is_float)
            continue;

         const EGLint attr_list[] = {
            EGL_NATIVE_VISUAL_ID, visuals[j].gbm_format,
            EGL_NONE,
         };

         dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
               config_count + 1, EGL_WINDOW_BIT, attr_list, NULL, NULL);
         if (dri2_conf) {
            if (dri2_conf->base.ConfigID == config_count + 1)
               config_count++;
            format_count[j]++;
         }
      }
   }

   for (unsigned i = 0; i < ARRAY_SIZE(format_count); i++) {
      if (!format_count[i]) {
         struct gbm_format_name_desc desc;
         _eglLog(_EGL_DEBUG, "No DRI config supports native format %s",
                 gbm_format_get_name(visuals[i].gbm_format, &desc));
      }
   }

   return (config_count != 0);
}

static const struct dri2_egl_display_vtbl dri2_drm_display_vtbl = {
   .authenticate = dri2_drm_authenticate,
   .create_window_surface = dri2_drm_create_window_surface,
   .create_pixmap_surface = dri2_drm_create_pixmap_surface,
   .destroy_surface = dri2_drm_destroy_surface,
   .create_image = dri2_drm_create_image_khr,
   .swap_buffers = dri2_drm_swap_buffers,
   .query_buffer_age = dri2_drm_query_buffer_age,
   .get_dri_drawable = dri2_surface_get_dri_drawable,
};

EGLBoolean
dri2_initialize_drm(const _EGLDriver *drv, _EGLDisplay *disp)
{
   _EGLDevice *dev;
   struct dri2_egl_display *dri2_dpy;
   struct gbm_device *gbm;
   const char *err;

   dri2_dpy = calloc(1, sizeof *dri2_dpy);
   if (!dri2_dpy)
      return _eglError(EGL_BAD_ALLOC, "eglInitialize");

   dri2_dpy->fd = -1;
   disp->DriverData = (void *) dri2_dpy;

   gbm = disp->PlatformDisplay;
   if (gbm == NULL) {
      char buf[64];
      int n = snprintf(buf, sizeof(buf), DRM_DEV_NAME, DRM_DIR_NAME, 0);
      if (n != -1 && n < sizeof(buf))
         dri2_dpy->fd = loader_open_device(buf);
      gbm = gbm_create_device(dri2_dpy->fd);
      if (gbm == NULL) {
         err = "DRI2: failed to create gbm device";
         goto cleanup;
      }
      dri2_dpy->own_device = true;
   } else {
      dri2_dpy->fd = os_dupfd_cloexec(gbm_device_get_fd(gbm));
      if (dri2_dpy->fd < 0) {
         err = "DRI2: failed to fcntl() existing gbm device";
         goto cleanup;
      }
   }
   dri2_dpy->gbm_dri = gbm_dri_device(gbm);

   if (strcmp(gbm_device_get_backend_name(gbm), "drm") != 0) {
      err = "DRI2: gbm device using incorrect/incompatible backend";
      goto cleanup;
   }

   dev = _eglAddDevice(dri2_dpy->fd, disp->Options.ForceSoftware);
   if (!dev) {
      err = "DRI2: failed to find EGLDevice";
      goto cleanup;
   }

   disp->Device = dev;

   dri2_dpy->driver_name = strdup(dri2_dpy->gbm_dri->driver_name);
   dri2_dpy->is_render_node = drmGetNodeTypeFromFd(dri2_dpy->fd) == DRM_NODE_RENDER;

   /* render nodes cannot use Gem names, and thus do not support
    * the __DRI_DRI2_LOADER extension */
   if (!dri2_dpy->is_render_node) {
      if (!dri2_load_driver(disp)) {
         err = "DRI2: failed to load driver";
         goto cleanup;
      }
   } else {
      if (!dri2_load_driver_dri3(disp)) {
         err = "DRI3: failed to load driver";
         goto cleanup;
      }
   }

   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->swrast = dri2_dpy->gbm_dri->swrast;
   dri2_dpy->driver_configs = dri2_dpy->gbm_dri->driver_configs;

   dri2_dpy->gbm_dri->lookup_image = dri2_lookup_egl_image;
   dri2_dpy->gbm_dri->lookup_user_data = disp;

   dri2_dpy->gbm_dri->get_buffers = dri2_drm_get_buffers;
   dri2_dpy->gbm_dri->flush_front_buffer = dri2_drm_flush_front_buffer;
   dri2_dpy->gbm_dri->get_buffers_with_format = dri2_drm_get_buffers_with_format;
   dri2_dpy->gbm_dri->image_get_buffers = dri2_drm_image_get_buffers;
   dri2_dpy->gbm_dri->swrast_put_image2 = swrast_put_image2;
   dri2_dpy->gbm_dri->swrast_get_image = swrast_get_image;

   dri2_dpy->gbm_dri->base.surface_lock_front_buffer = lock_front_buffer;
   dri2_dpy->gbm_dri->base.surface_release_buffer = release_buffer;
   dri2_dpy->gbm_dri->base.surface_has_free_buffers = has_free_buffers;

   if (!dri2_setup_extensions(disp)) {
      err = "DRI2: failed to find required DRI extensions";
      goto cleanup;
   }

   dri2_setup_screen(disp);

   if (!drm_add_configs_for_visuals(drv, disp)) {
      err = "DRI2: failed to add configs";
      goto cleanup;
   }

   disp->Extensions.KHR_image_pixmap = EGL_TRUE;
   if (dri2_dpy->dri2)
      disp->Extensions.EXT_buffer_age = EGL_TRUE;

#ifdef HAVE_WAYLAND_PLATFORM
   dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd);
#endif
   dri2_set_WL_bind_wayland_display(drv, disp);

   /* Fill vtbl last to prevent accidentally calling virtual function during
    * initialization.
    */
   dri2_dpy->vtbl = &dri2_drm_display_vtbl;

   return EGL_TRUE;

cleanup:
   dri2_display_destroy(disp);
   return _eglError(EGL_NOT_INITIALIZED, err);
}

void
dri2_teardown_drm(struct dri2_egl_display *dri2_dpy)
{
   if (dri2_dpy->own_device)
      gbm_device_destroy(&dri2_dpy->gbm_dri->base);
}
