Subversion Repositories Kolibri OS

Rev

Rev 4358 | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2011 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18.  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  19.  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  20.  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors:
  25.  *    Kristian Høgsberg <krh@bitplanet.net>
  26.  */
  27.  
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <xf86drm.h>
  32. //#include <dlfcn.h>
  33. #include <sys/types.h>
  34. #include <sys/stat.h>
  35. #include <fcntl.h>
  36. #include <unistd.h>
  37. #include <kos32sys.h>
  38. #include <pixlib2.h>
  39.  
  40. #define EGL_EGLEXT_PROTOTYPES
  41. #include <EGL/egl.h>
  42. #include <EGL/eglext.h>
  43.  
  44. #include "egl_dri2.h"
  45.  
  46. void* load_library(const char *name);
  47. void *get_proc_address(void *module, char *proc_name);
  48.  
  49. int (*blit_bitmap_from_handle)(bitmap_t *bitmap, uint32_t handle);
  50. void (*blit_set_bo_handle)(bitmap_t *bitmap, int handle);
  51. int (*blit_blit_tex)(bitmap_t *bitmap, int scale, int dst_x, int dst_y,
  52.                   int w, int h, int src_x, int src_y);
  53.  
  54. static struct gbm_bo *
  55. lock_front_buffer(struct gbm_surface *_surf)
  56. {
  57.    struct gbm_dri_surface *surf = (struct gbm_dri_surface *) _surf;
  58.    struct dri2_egl_surface *dri2_surf = surf->dri_private;
  59.    struct gbm_bo *bo;
  60.  
  61.    if (dri2_surf->current == NULL) {
  62.       _eglError(EGL_BAD_SURFACE, "no front buffer");
  63.       return NULL;
  64.    }
  65.  
  66.    bo = dri2_surf->current->bo;
  67.    dri2_surf->current->locked = 1;
  68.    dri2_surf->current = NULL;
  69.  
  70.    return bo;
  71. }
  72.  
  73. static void
  74. release_buffer(struct gbm_surface *_surf, struct gbm_bo *bo)
  75. {
  76.    struct gbm_dri_surface *surf = (struct gbm_dri_surface *) _surf;
  77.    struct dri2_egl_surface *dri2_surf = surf->dri_private;
  78.    int i;
  79.  
  80.    for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
  81.       if (dri2_surf->color_buffers[i].bo == bo) {
  82.          dri2_surf->color_buffers[i].locked = 0;
  83.       }
  84.    }
  85. }
  86.  
  87. static int
  88. has_free_buffers(struct gbm_surface *_surf)
  89. {
  90.    struct gbm_dri_surface *surf = (struct gbm_dri_surface *) _surf;
  91.    struct dri2_egl_surface *dri2_surf = surf->dri_private;
  92.    int i;
  93.  
  94.    for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
  95.       if (!dri2_surf->color_buffers[i].locked)
  96.          return 1;
  97.  
  98.    return 0;
  99. }
  100.  
  101. static _EGLSurface *
  102. dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
  103.                     _EGLConfig *conf, EGLNativeWindowType window,
  104.                     const EGLint *attrib_list)
  105. {
  106.    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  107.    struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
  108.    struct dri2_egl_surface *dri2_surf;
  109.    struct gbm_dri_surface *surf;
  110.  
  111.    (void) drv;
  112.  
  113.    dri2_surf = calloc(1, sizeof *dri2_surf);
  114.    if (!dri2_surf) {
  115.       _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
  116.       return NULL;
  117.    }
  118.  
  119.    if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
  120.       goto cleanup_surf;
  121.  
  122.    switch (type) {
  123.    case EGL_WINDOW_BIT:
  124.       if (!window)
  125.          return NULL;
  126.       surf = gbm_dri_surface((struct gbm_surface *) window);
  127.       dri2_surf->gbm_surf = surf;
  128.       dri2_surf->base.Width =  surf->base.width;
  129.       dri2_surf->base.Height = surf->base.height;
  130.       surf->dri_private = dri2_surf;
  131.       break;
  132.    default:
  133.       goto cleanup_surf;
  134.    }
  135.  
  136.    dri2_surf->dri_drawable =
  137.       (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
  138.                                             dri2_conf->dri_double_config,
  139.                                             dri2_surf->gbm_surf);
  140.  
  141.    if (dri2_surf->dri_drawable == NULL) {
  142.       _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
  143.       goto cleanup_surf;
  144.    }
  145.  
  146.    return &dri2_surf->base;
  147.  
  148.  cleanup_surf:
  149.    free(dri2_surf);
  150.  
  151.    return NULL;
  152. }
  153.  
  154. static _EGLSurface *
  155. dri2_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
  156.                            _EGLConfig *conf, EGLNativeWindowType window,
  157.                            const EGLint *attrib_list)
  158. {
  159.    return dri2_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
  160.                               window, attrib_list);
  161. }
  162.  
  163. static EGLBoolean
  164. dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
  165. {
  166.    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  167.    struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
  168.    int i;
  169.  
  170.    if (!_eglPutSurface(surf))
  171.       return EGL_TRUE;
  172.  
  173.    (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
  174.  
  175.    for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
  176.       if (dri2_surf->color_buffers[i].bo)
  177.          gbm_bo_destroy(dri2_surf->color_buffers[i].bo);
  178.    }
  179.  
  180.    for (i = 0; i < __DRI_BUFFER_COUNT; i++) {
  181.       if (dri2_surf->dri_buffers[i])
  182.          dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
  183.                                        dri2_surf->dri_buffers[i]);
  184.    }
  185.  
  186.    free(surf);
  187.  
  188.    return EGL_TRUE;
  189. }
  190.  
  191. static int
  192. get_back_bo(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
  193. {
  194.    struct dri2_egl_display *dri2_dpy =
  195.       dri2_egl_display(dri2_surf->base.Resource.Display);
  196.    struct gbm_dri_bo *bo;
  197.    struct gbm_dri_surface *surf = dri2_surf->gbm_surf;
  198.    int i, name, pitch;
  199.  
  200.    if (dri2_surf->back == NULL)
  201.    {
  202.       for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
  203.       {
  204.         if(dri2_surf->color_buffers[i].locked)
  205.         {
  206.             dri2_surf->color_buffers[i].locked = 0;
  207.             continue;
  208.         }
  209.         dri2_surf->back = &dri2_surf->color_buffers[i];
  210.       }
  211.    }
  212.  
  213.     if (dri2_surf->back == NULL)
  214.         return -1;
  215.     if (dri2_surf->back->bo == NULL)
  216.         dri2_surf->back->bo = gbm_bo_create(&dri2_dpy->gbm_dri->base.base,
  217.                                           surf->base.width, surf->base.height,
  218.                                           surf->base.format, surf->base.flags);
  219.     if (dri2_surf->back->bo == NULL)
  220.         return -1;
  221.  
  222.     bo = (struct gbm_dri_bo *) dri2_surf->back->bo;
  223.  
  224.     dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_NAME, &name);
  225.     dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, &pitch);
  226.  
  227.     buffer->attachment = __DRI_BUFFER_BACK_LEFT;
  228.     buffer->name = name;
  229.     buffer->pitch = pitch;
  230.     buffer->cpp = 4;
  231.     buffer->flags = 0;
  232.  
  233.     dri2_surf->back->locked = 1;
  234.  
  235.     return 0;
  236. }
  237.  
  238. static int
  239. get_aux_bo(struct dri2_egl_surface *dri2_surf,
  240.            unsigned int attachment, unsigned int format, __DRIbuffer *buffer)
  241. {
  242.    struct dri2_egl_display *dri2_dpy =
  243.       dri2_egl_display(dri2_surf->base.Resource.Display);
  244.    __DRIbuffer *b = dri2_surf->dri_buffers[attachment];
  245.  
  246.    if (b == NULL) {
  247.       b = dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
  248.                                          attachment, format,
  249.                                          dri2_surf->base.Width,
  250.                                          dri2_surf->base.Height);
  251.       dri2_surf->dri_buffers[attachment] = b;
  252.    }
  253.    if (b == NULL)
  254.       return -1;
  255.  
  256.    memcpy(buffer, b, sizeof *buffer);
  257.  
  258.    return 0;
  259. }
  260.  
  261. static __DRIbuffer *
  262. dri2_get_buffers_with_format(__DRIdrawable *driDrawable,
  263.                              int *width, int *height,
  264.                              unsigned int *attachments, int count,
  265.                              int *out_count, void *loaderPrivate)
  266. {
  267.    struct dri2_egl_surface *dri2_surf = loaderPrivate;
  268.    int i, j;
  269.  
  270. //   printf("dri2_get_buffers_with_format count %d\n", count);
  271.  
  272.    dri2_surf->buffer_count = 0;
  273.    for (i = 0, j = 0; i < 2 * count; i += 2, j++) {
  274.       assert(attachments[i] < __DRI_BUFFER_COUNT);
  275.       assert(dri2_surf->buffer_count < 5);
  276.  
  277. //      printf("attachments %d\n",attachments[i]);
  278.  
  279.       switch (attachments[i]) {
  280.       case __DRI_BUFFER_BACK_LEFT:
  281.         if (get_back_bo(dri2_surf, &dri2_surf->buffers[j]) < 0) {
  282.             _eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
  283.             return NULL;
  284.         }
  285.         break;
  286.       default:
  287.         if (get_aux_bo(dri2_surf, attachments[i], attachments[i + 1],
  288.                         &dri2_surf->buffers[j]) < 0) {
  289.             _eglError(EGL_BAD_ALLOC, "failed to allocate aux buffer");
  290.             return NULL;
  291.         }
  292.         break;
  293.       }
  294.    }
  295.  
  296.    *out_count = j;
  297.    if (j == 0)
  298.       return NULL;
  299.  
  300.    *width = dri2_surf->base.Width;
  301.    *height = dri2_surf->base.Height;
  302.  
  303.    return dri2_surf->buffers;
  304. }
  305.  
  306. static __DRIbuffer *
  307. dri2_get_buffers(__DRIdrawable * driDrawable,
  308.                  int *width, int *height,
  309.                  unsigned int *attachments, int count,
  310.                  int *out_count, void *loaderPrivate)
  311. {
  312.    unsigned int *attachments_with_format;
  313.    __DRIbuffer *buffer;
  314.    const unsigned int format = 32;
  315.    int i;
  316.  
  317.    attachments_with_format = calloc(count * 2, sizeof(unsigned int));
  318.    if (!attachments_with_format) {
  319.       *out_count = 0;
  320.       return NULL;
  321.    }
  322.  
  323.    for (i = 0; i < count; ++i) {
  324.       attachments_with_format[2*i] = attachments[i];
  325.       attachments_with_format[2*i + 1] = format;
  326.    }
  327.  
  328.    buffer =
  329.       dri2_get_buffers_with_format(driDrawable,
  330.                                    width, height,
  331.                                    attachments_with_format, count,
  332.                                    out_count, loaderPrivate);
  333.  
  334.    free(attachments_with_format);
  335.  
  336.    return buffer;
  337. }
  338.  
  339. static void
  340. dri2_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
  341. {
  342.    (void) driDrawable;
  343.    (void) loaderPrivate;
  344. }
  345.  
  346. static EGLBoolean
  347. dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
  348. {
  349.    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  350.    struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
  351.    __DRIbuffer buffer;
  352.    static bitmap_t bm;
  353.  
  354.    int i;
  355.  
  356.    if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
  357.       if (dri2_surf->current)
  358.         _eglError(EGL_BAD_SURFACE, "dri2_swap_buffers");
  359.       for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
  360.          if (dri2_surf->color_buffers[i].age > 0)
  361.             dri2_surf->color_buffers[i].age++;
  362.  
  363. #if 1
  364.  
  365.       if ( (dri2_surf->back != NULL) &&
  366.            (dri2_surf->back->bo != NULL))
  367.       {
  368.         struct gbm_dri_bo *bo;
  369.         bo = (struct gbm_dri_bo *)dri2_surf->back->bo;
  370.  
  371.         if(bm.width == 0)
  372.         {
  373. //            printf("%s bo: %p handle: %d width: %d height: %d pitch %d format %x\n",
  374. //                __FUNCTION__, bo, bo->base.base.handle.s32, bo->base.base.width,
  375.  //                             bo->base.base.height, (int)bo->base.base.stride,
  376. //                              bo->base.base.format);
  377.  
  378.             bm.width      = bo->base.base.width;
  379.             bm.height     = bo->base.base.height;
  380.             bm.pitch      = (int)bo->base.base.stride;
  381.             bm.max_width  = bo->base.base.width;
  382.             bm.max_height = bo->base.base.height;
  383.             bm.flags      = HW_TEX_BLIT;
  384.  
  385.             if( blit_bitmap_from_handle(&bm, bo->base.base.handle.s32))
  386.             {
  387.                 printf("sna_bitmap_from_handle failed\n");
  388.             }
  389.         }
  390.         if( bm.handle != 0)
  391.         {
  392. //           printf("%s bo: %p handle: %d width: %d height: %d pitch %d format %x\n",
  393. //                __FUNCTION__, bo, bo->base.base.handle.s32, bo->base.base.width,
  394. //                              bo->base.base.height, (int)bo->base.base.stride,
  395. //                              bo->base.base.format);
  396.  
  397.             blit_set_bo_handle(&bm, bo->base.base.handle.s32);
  398.             blit_blit_tex(&bm, 0, 5, 20, bm.width, bm.height, 0, 0);
  399.         }
  400.       }
  401. #endif
  402.  
  403.       dri2_surf->current = dri2_surf->back;
  404.       dri2_surf->current->age = 1;
  405.       dri2_surf->back = NULL;
  406.    }
  407.  
  408.    (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
  409.    (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
  410.  
  411.    return EGL_TRUE;
  412. }
  413.  
  414. static EGLint
  415. dri2_query_buffer_age(_EGLDriver *drv,
  416.                       _EGLDisplay *disp, _EGLSurface *surface)
  417. {
  418.    struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);
  419.    __DRIbuffer buffer;
  420.  
  421.    if (get_back_bo(dri2_surf, &buffer) < 0) {
  422.       _eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age");
  423.       return 0;
  424.    }
  425.  
  426.    return dri2_surf->back->age;
  427. }
  428.  
  429. static _EGLImage *
  430. dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
  431.                              EGLClientBuffer buffer, const EGLint *attr_list)
  432. {
  433.    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  434.    struct gbm_dri_bo *dri_bo = gbm_dri_bo((struct gbm_bo *) buffer);
  435.    struct dri2_egl_image *dri2_img;
  436.  
  437.    dri2_img = malloc(sizeof *dri2_img);
  438.    if (!dri2_img) {
  439.       _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap");
  440.       return NULL;
  441.    }
  442.  
  443.    if (!_eglInitImage(&dri2_img->base, disp)) {
  444.       free(dri2_img);
  445.       return NULL;
  446.    }
  447.  
  448.    dri2_img->dri_image = dri2_dpy->image->dupImage(dri_bo->image, dri2_img);
  449.    if (dri2_img->dri_image == NULL) {
  450.       free(dri2_img);
  451.       _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap");
  452.       return NULL;
  453.    }
  454.  
  455.    return &dri2_img->base;
  456. }
  457.  
  458. static _EGLImage *
  459. dri2_drm_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
  460.                           _EGLContext *ctx, EGLenum target,
  461.                           EGLClientBuffer buffer, const EGLint *attr_list)
  462. {
  463.    (void) drv;
  464.  
  465.    switch (target) {
  466.    case EGL_NATIVE_PIXMAP_KHR:
  467.       return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
  468.    default:
  469.       return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
  470.    }
  471. }
  472.  
  473. #if 0
  474. static int
  475. dri2_drm_authenticate(_EGLDisplay *disp, uint32_t id)
  476. {
  477.    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  478.  
  479.    return drmAuthMagic(dri2_dpy->fd, id);
  480. }
  481. #endif
  482.  
  483. EGLBoolean
  484. dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
  485. {
  486.    struct dri2_egl_display *dri2_dpy;
  487.    struct gbm_device *gbm;
  488.    void *lib;
  489.  
  490.    int fd = -1;
  491.    int i;
  492.  
  493.    dri2_dpy = calloc(1, sizeof *dri2_dpy);
  494.    if (!dri2_dpy)
  495.       return _eglError(EGL_BAD_ALLOC, "eglInitialize");
  496.  
  497.    disp->DriverData = (void *) dri2_dpy;
  498.  
  499.    gbm = disp->PlatformDisplay;
  500.    if (gbm == NULL) {
  501.       fd = get_service("DISPLAY");
  502.       dri2_dpy->own_device = 1;
  503.       gbm = gbm_create_device(fd);
  504.       if (gbm == NULL)
  505.          return EGL_FALSE;
  506.    }
  507.  
  508.    if (strcmp(gbm_device_get_backend_name(gbm), "drm") != 0) {
  509.       free(dri2_dpy);
  510.       return EGL_FALSE;
  511.    }
  512.  
  513.    dri2_dpy->gbm_dri = gbm_dri_device(gbm);
  514.    if (dri2_dpy->gbm_dri->base.type != GBM_DRM_DRIVER_TYPE_DRI) {
  515.       free(dri2_dpy);
  516.       return EGL_FALSE;
  517.    }
  518.  
  519.  
  520.    lib = load_library("intel-sna.drv");
  521.    if(lib)
  522.    {
  523.        blit_bitmap_from_handle = get_proc_address(lib,"sna_bitmap_from_handle");
  524.        blit_set_bo_handle = get_proc_address(lib,"sna_set_bo_handle");
  525.        blit_blit_tex = get_proc_address(lib,"sna_blit_tex");
  526.    }
  527.    else
  528.    {
  529.        lib = load_library("intel-uxa.drv");
  530.        if(lib)
  531.        {
  532.            blit_bitmap_from_handle = get_proc_address(lib,"uxa_bitmap_from_handle");
  533.            blit_set_bo_handle = get_proc_address(lib,"uxa_set_bo_handle");
  534.            blit_blit_tex = get_proc_address(lib,"uxa_blit_tex");
  535.        }
  536.        else return EGL_FALSE;
  537.    }
  538.  
  539.    dri2_dpy->fd = fd;
  540.    dri2_dpy->device_name = strdup("drm device"); //dri2_get_device_name_for_fd(dri2_dpy->fd);
  541.    dri2_dpy->driver_name = dri2_dpy->gbm_dri->base.driver_name;
  542.  
  543.    dri2_dpy->dri_screen = dri2_dpy->gbm_dri->screen;
  544.    dri2_dpy->core = dri2_dpy->gbm_dri->core;
  545.    dri2_dpy->dri2 = dri2_dpy->gbm_dri->dri2;
  546.    dri2_dpy->image = dri2_dpy->gbm_dri->image;
  547.    dri2_dpy->flush = dri2_dpy->gbm_dri->flush;
  548.    dri2_dpy->driver_configs = dri2_dpy->gbm_dri->driver_configs;
  549.  
  550.    dri2_dpy->gbm_dri->lookup_image = dri2_lookup_egl_image;
  551.    dri2_dpy->gbm_dri->lookup_user_data = disp;
  552.  
  553.    dri2_dpy->gbm_dri->get_buffers = dri2_get_buffers;
  554.    dri2_dpy->gbm_dri->flush_front_buffer = dri2_flush_front_buffer;
  555.    dri2_dpy->gbm_dri->get_buffers_with_format = dri2_get_buffers_with_format;
  556.  
  557.    dri2_dpy->gbm_dri->base.base.surface_lock_front_buffer = lock_front_buffer;
  558.    dri2_dpy->gbm_dri->base.base.surface_release_buffer = release_buffer;
  559.    dri2_dpy->gbm_dri->base.base.surface_has_free_buffers = has_free_buffers;
  560.  
  561.    dri2_setup_screen(disp);
  562.  
  563.    for (i = 0; dri2_dpy->driver_configs[i]; i++)
  564.       dri2_add_config(disp, dri2_dpy->driver_configs[i],
  565.                       i + 1, 0, EGL_WINDOW_BIT, NULL, NULL);
  566.  
  567.    drv->API.CreateWindowSurface = dri2_create_window_surface;
  568.    drv->API.DestroySurface = dri2_destroy_surface;
  569.    drv->API.SwapBuffers = dri2_swap_buffers;
  570.    drv->API.CreateImageKHR = dri2_drm_create_image_khr;
  571.    drv->API.QueryBufferAge = dri2_query_buffer_age;
  572.  
  573.    disp->Extensions.EXT_buffer_age = EGL_TRUE;
  574.  
  575. #ifdef HAVE_WAYLAND_PLATFORM
  576.    disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
  577. #endif
  578. //   dri2_dpy->authenticate = dri2_drm_authenticate;
  579.  
  580.    /* we're supporting EGL 1.4 */
  581.    disp->VersionMajor = 1;
  582.    disp->VersionMinor = 4;
  583.  
  584.    return EGL_TRUE;
  585. }
  586.