Subversion Repositories Kolibri OS

Rev

Rev 4401 | Go to most recent revision | 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 vsync, 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.    struct gbm_bo       *bo;
  111.    _EGLImage           *img;
  112.    EGLint attr[10];
  113.  
  114.    (void) drv;
  115.  
  116.    dri2_surf = calloc(1, sizeof *dri2_surf);
  117.    if (!dri2_surf) {
  118.       _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
  119.       return NULL;
  120.    }
  121.  
  122.    if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
  123.       goto cleanup_surf;
  124.  
  125.    switch (type) {
  126.    case EGL_WINDOW_BIT:
  127.       if (!window)
  128.          return NULL;
  129.       surf = gbm_dri_surface((struct gbm_surface *) window);
  130.       dri2_surf->gbm_surf = surf;
  131.       dri2_surf->base.Width =  surf->base.width;
  132.       dri2_surf->base.Height = surf->base.height;
  133.       surf->dri_private = dri2_surf;
  134.       break;
  135.    default:
  136.       goto cleanup_surf;
  137.    }
  138.  
  139.    attr[0] = EGL_WIDTH;
  140.    attr[1] = surf->base.width;
  141.    attr[2] = EGL_HEIGHT;
  142.    attr[3] = surf->base.height;
  143.    attr[4] = EGL_DRM_BUFFER_FORMAT_MESA;
  144.    attr[5] = EGL_DRM_BUFFER_FORMAT_ARGB32_MESA;
  145.    attr[6] = EGL_DRM_BUFFER_USE_MESA;
  146.    attr[7] = EGL_DRM_BUFFER_USE_SHARE_MESA;
  147.    attr[8] = EGL_NONE;
  148.  
  149.    img = drv->API.CreateDRMImageMESA(drv, disp, attr);
  150.    dri2_surf->egl_front = img;
  151.    dri2_surf->khr_front = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
  152.  
  153.    bo = gbm_bo_import(&dri2_dpy->gbm_dri->base.base,
  154.                       GBM_BO_IMPORT_EGL_IMAGE, dri2_surf->khr_front, 0);
  155.    if( bo == NULL){
  156.       _eglError(EGL_BAD_ALLOC, "gbm_bo_create front buffer");
  157.       goto cleanup_surf;
  158.    }
  159.    dri2_surf->color_buffers[1].bo = bo;
  160.  
  161.    img = drv->API.CreateDRMImageMESA(drv, disp, attr);
  162.    dri2_surf->egl_back = img;
  163.    dri2_surf->khr_back = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
  164.  
  165.    bo = gbm_bo_import(&dri2_dpy->gbm_dri->base.base,
  166.                       GBM_BO_IMPORT_EGL_IMAGE, dri2_surf->khr_back, 0);
  167.    if( bo == NULL){
  168.       _eglError(EGL_BAD_ALLOC, "gbm_bo_create back buffer");
  169.       goto cleanup_surf;
  170.    }
  171.    dri2_surf->color_buffers[2].bo = bo;
  172.  
  173.  
  174.    dri2_surf->dri_drawable =
  175.       (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
  176.                                             dri2_conf->dri_double_config,
  177.                                             dri2_surf->gbm_surf);
  178.  
  179.    if (dri2_surf->dri_drawable == NULL) {
  180.       _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
  181.       goto cleanup_surf;
  182.    }
  183.  
  184.    return &dri2_surf->base;
  185.  
  186.  cleanup_surf:
  187.    free(dri2_surf);
  188.  
  189.    return NULL;
  190. }
  191.  
  192. static EGLImageKHR
  193. dri2_get_fb_image(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw, EGLint type)
  194. {
  195.    struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
  196.  
  197.    return (type == EGL_DRM_BUFFER_FRONT) ? dri2_surf->khr_front:dri2_surf->khr_back;
  198. }
  199.  
  200.  
  201. static _EGLSurface *
  202. dri2_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
  203.                            _EGLConfig *conf, EGLNativeWindowType window,
  204.                            const EGLint *attrib_list)
  205. {
  206.    return dri2_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
  207.                               window, attrib_list);
  208. }
  209.  
  210. static EGLBoolean
  211. dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
  212. {
  213.    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  214.    struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
  215.    int i;
  216.  
  217.    if (!_eglPutSurface(surf))
  218.       return EGL_TRUE;
  219.  
  220.    (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
  221.  
  222.    for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
  223.       if (dri2_surf->color_buffers[i].bo)
  224.          gbm_bo_destroy(dri2_surf->color_buffers[i].bo);
  225.    }
  226.  
  227.    for (i = 0; i < __DRI_BUFFER_COUNT; i++) {
  228.       if (dri2_surf->dri_buffers[i])
  229.          dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
  230.                                        dri2_surf->dri_buffers[i]);
  231.    }
  232.  
  233.    free(surf);
  234.  
  235.    return EGL_TRUE;
  236. }
  237.  
  238. static int
  239. get_back_bo(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
  240. {
  241.    struct dri2_egl_display *dri2_dpy =
  242.       dri2_egl_display(dri2_surf->base.Resource.Display);
  243.    struct gbm_dri_bo *bo;
  244.    struct gbm_dri_surface *surf = dri2_surf->gbm_surf;
  245.    int i, name, pitch;
  246.  
  247.    if (dri2_surf->back == NULL)
  248.    {
  249.       for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
  250.       {
  251.         if(dri2_surf->color_buffers[i].locked)
  252.         {
  253.             dri2_surf->color_buffers[i].locked = 0;
  254.             continue;
  255.         }
  256.         dri2_surf->back = &dri2_surf->color_buffers[i];
  257.       }
  258.    }
  259.  
  260.     if (dri2_surf->back == NULL)
  261.         return -1;
  262.     if (dri2_surf->back->bo == NULL)
  263.         dri2_surf->back->bo = gbm_bo_create(&dri2_dpy->gbm_dri->base.base,
  264.                                           surf->base.width, surf->base.height,
  265.                                           surf->base.format, surf->base.flags);
  266.     if (dri2_surf->back->bo == NULL)
  267.         return -1;
  268.  
  269.     bo = (struct gbm_dri_bo *) dri2_surf->back->bo;
  270.  
  271.     dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_NAME, &name);
  272.     dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, &pitch);
  273.  
  274.     buffer->attachment = __DRI_BUFFER_BACK_LEFT;
  275.     buffer->name = name;
  276.     buffer->pitch = pitch;
  277.     buffer->cpp = 4;
  278.     buffer->flags = 0;
  279.  
  280.     dri2_surf->back->locked = 1;
  281.  
  282.     return 0;
  283. }
  284.  
  285. static int
  286. get_aux_bo(struct dri2_egl_surface *dri2_surf,
  287.            unsigned int attachment, unsigned int format, __DRIbuffer *buffer)
  288. {
  289.    struct dri2_egl_display *dri2_dpy =
  290.       dri2_egl_display(dri2_surf->base.Resource.Display);
  291.    __DRIbuffer *b = dri2_surf->dri_buffers[attachment];
  292.  
  293.    if (b == NULL) {
  294.       b = dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
  295.                                          attachment, format,
  296.                                          dri2_surf->base.Width,
  297.                                          dri2_surf->base.Height);
  298.       dri2_surf->dri_buffers[attachment] = b;
  299.    }
  300.    if (b == NULL)
  301.       return -1;
  302.  
  303.    memcpy(buffer, b, sizeof *buffer);
  304.  
  305.    return 0;
  306. }
  307.  
  308. static __DRIbuffer *
  309. dri2_get_buffers_with_format(__DRIdrawable *driDrawable,
  310.                              int *width, int *height,
  311.                              unsigned int *attachments, int count,
  312.                              int *out_count, void *loaderPrivate)
  313. {
  314.    struct dri2_egl_surface *dri2_surf = loaderPrivate;
  315.    int i, j;
  316.  
  317.    dri2_surf->buffer_count = 0;
  318.    for (i = 0, j = 0; i < 2 * count; i += 2, j++) {
  319.       assert(attachments[i] < __DRI_BUFFER_COUNT);
  320.       assert(dri2_surf->buffer_count < 5);
  321.  
  322.       switch (attachments[i]) {
  323.       case __DRI_BUFFER_BACK_LEFT:
  324.         if (get_back_bo(dri2_surf, &dri2_surf->buffers[j]) < 0) {
  325.             _eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
  326.             return NULL;
  327.         }
  328.         break;
  329.       default:
  330.         if (get_aux_bo(dri2_surf, attachments[i], attachments[i + 1],
  331.                         &dri2_surf->buffers[j]) < 0) {
  332.             _eglError(EGL_BAD_ALLOC, "failed to allocate aux buffer");
  333.             return NULL;
  334.         }
  335.         break;
  336.       }
  337.    }
  338.  
  339.    *out_count = j;
  340.    if (j == 0)
  341.       return NULL;
  342.  
  343.    *width = dri2_surf->base.Width;
  344.    *height = dri2_surf->base.Height;
  345.  
  346.    return dri2_surf->buffers;
  347. }
  348.  
  349. static __DRIbuffer *
  350. dri2_get_buffers(__DRIdrawable * driDrawable,
  351.                  int *width, int *height,
  352.                  unsigned int *attachments, int count,
  353.                  int *out_count, void *loaderPrivate)
  354. {
  355.    unsigned int *attachments_with_format;
  356.    __DRIbuffer *buffer;
  357.    const unsigned int format = 32;
  358.    int i;
  359.  
  360.    attachments_with_format = calloc(count * 2, sizeof(unsigned int));
  361.    if (!attachments_with_format) {
  362.       *out_count = 0;
  363.       return NULL;
  364.    }
  365.  
  366.    for (i = 0; i < count; ++i) {
  367.       attachments_with_format[2*i] = attachments[i];
  368.       attachments_with_format[2*i + 1] = format;
  369.    }
  370.  
  371.    buffer =
  372.       dri2_get_buffers_with_format(driDrawable,
  373.                                    width, height,
  374.                                    attachments_with_format, count,
  375.                                    out_count, loaderPrivate);
  376.  
  377.    free(attachments_with_format);
  378.  
  379.    return buffer;
  380. }
  381.  
  382. static void
  383. dri2_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
  384. {
  385.    (void) driDrawable;
  386.    (void) loaderPrivate;
  387. }
  388.  
  389. static EGLBoolean
  390. dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
  391. {
  392.    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  393.    struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
  394.    __DRIbuffer buffer;
  395.    static bitmap_t bm;
  396.  
  397.    int i;
  398.  
  399.    if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
  400.       if (dri2_surf->current)
  401.         _eglError(EGL_BAD_SURFACE, "dri2_swap_buffers");
  402.       for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
  403.          if (dri2_surf->color_buffers[i].age > 0)
  404.             dri2_surf->color_buffers[i].age++;
  405.  
  406. #if 1
  407.  
  408.       if ( (dri2_surf->back != NULL) &&
  409.            (dri2_surf->back->bo != NULL))
  410.       {
  411.         struct gbm_dri_bo *bo;
  412.         bo = (struct gbm_dri_bo *)dri2_surf->back->bo;
  413.  
  414.         if(bm.width == 0)
  415.         {
  416. //            printf("%s bo: %p handle: %d width: %d height: %d pitch %d format %x\n",
  417. //                __FUNCTION__, bo, bo->base.base.handle.s32, bo->base.base.width,
  418.  //                             bo->base.base.height, (int)bo->base.base.stride,
  419. //                              bo->base.base.format);
  420.  
  421.             bm.width      = bo->base.base.width;
  422.             bm.height     = bo->base.base.height;
  423.             bm.pitch      = (int)bo->base.base.stride;
  424.             bm.max_width  = bo->base.base.width;
  425.             bm.max_height = bo->base.base.height;
  426.             bm.flags      = HW_TEX_BLIT;
  427.  
  428.             if( blit_bitmap_from_handle(&bm, bo->base.base.handle.s32))
  429.             {
  430.                 printf("sna_bitmap_from_handle failed\n");
  431.             }
  432.         }
  433.         if( bm.handle != 0)
  434.         {
  435. //           printf("%s bo: %p handle: %d width: %d height: %d pitch %d format %x\n",
  436. //                __FUNCTION__, bo, bo->base.base.handle.s32, bo->base.base.width,
  437. //                              bo->base.base.height, (int)bo->base.base.stride,
  438. //                              bo->base.base.format);
  439.  
  440.             blit_set_bo_handle(&bm, bo->base.base.handle.s32);
  441.             blit_blit_tex(&bm, 0, 0, 5, 20, bm.width, bm.height, 0, 0);
  442.         }
  443.       }
  444. #endif
  445.  
  446.       dri2_surf->current = dri2_surf->back;
  447.       dri2_surf->current->age = 1;
  448.       dri2_surf->back = NULL;
  449.    }
  450.  
  451.    (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
  452.    (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
  453.  
  454.    return EGL_TRUE;
  455. }
  456.  
  457. static EGLint
  458. dri2_query_buffer_age(_EGLDriver *drv,
  459.                       _EGLDisplay *disp, _EGLSurface *surface)
  460. {
  461.    struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);
  462.    __DRIbuffer buffer;
  463.  
  464.    if (get_back_bo(dri2_surf, &buffer) < 0) {
  465.       _eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age");
  466.       return 0;
  467.    }
  468.  
  469.    return dri2_surf->back->age;
  470. }
  471.  
  472. static _EGLImage *
  473. dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
  474.                              EGLClientBuffer buffer, const EGLint *attr_list)
  475. {
  476.    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  477.    struct gbm_dri_bo *dri_bo = gbm_dri_bo((struct gbm_bo *) buffer);
  478.    struct dri2_egl_image *dri2_img;
  479.  
  480.    dri2_img = malloc(sizeof *dri2_img);
  481.    if (!dri2_img) {
  482.       _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap");
  483.       return NULL;
  484.    }
  485.  
  486.    if (!_eglInitImage(&dri2_img->base, disp)) {
  487.       free(dri2_img);
  488.       return NULL;
  489.    }
  490.  
  491.    dri2_img->dri_image = dri2_dpy->image->dupImage(dri_bo->image, dri2_img);
  492.    if (dri2_img->dri_image == NULL) {
  493.       free(dri2_img);
  494.       _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap");
  495.       return NULL;
  496.    }
  497.  
  498.    return &dri2_img->base;
  499. }
  500.  
  501. static _EGLImage *
  502. dri2_drm_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
  503.                           _EGLContext *ctx, EGLenum target,
  504.                           EGLClientBuffer buffer, const EGLint *attr_list)
  505. {
  506.    (void) drv;
  507.  
  508.    switch (target) {
  509.    case EGL_NATIVE_PIXMAP_KHR:
  510.       return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
  511.    default:
  512.       return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
  513.    }
  514. }
  515.  
  516. #if 0
  517. static int
  518. dri2_drm_authenticate(_EGLDisplay *disp, uint32_t id)
  519. {
  520.    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
  521.  
  522.    return drmAuthMagic(dri2_dpy->fd, id);
  523. }
  524. #endif
  525.  
  526. EGLBoolean
  527. dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
  528. {
  529.    struct dri2_egl_display *dri2_dpy;
  530.    struct gbm_device *gbm;
  531.    void *lib;
  532.  
  533.    int fd = -1;
  534.    int i;
  535.  
  536.    dri2_dpy = calloc(1, sizeof *dri2_dpy);
  537.    if (!dri2_dpy)
  538.       return _eglError(EGL_BAD_ALLOC, "eglInitialize");
  539.  
  540.    disp->DriverData = (void *) dri2_dpy;
  541.  
  542.    gbm = disp->PlatformDisplay;
  543.    if (gbm == NULL) {
  544.       fd = get_service("DISPLAY");
  545.       dri2_dpy->own_device = 1;
  546.       gbm = gbm_create_device(fd);
  547.       if (gbm == NULL)
  548.          return EGL_FALSE;
  549.    }
  550.  
  551.    if (strcmp(gbm_device_get_backend_name(gbm), "drm") != 0) {
  552.       free(dri2_dpy);
  553.       return EGL_FALSE;
  554.    }
  555.  
  556.    dri2_dpy->gbm_dri = gbm_dri_device(gbm);
  557.    if (dri2_dpy->gbm_dri->base.type != GBM_DRM_DRIVER_TYPE_DRI) {
  558.       free(dri2_dpy);
  559.       return EGL_FALSE;
  560.    }
  561.  
  562.  
  563.    lib = load_library("intel-sna.drv");
  564.    if(lib)
  565.    {
  566.        blit_bitmap_from_handle = get_proc_address(lib,"sna_bitmap_from_handle");
  567.        blit_set_bo_handle = get_proc_address(lib,"sna_set_bo_handle");
  568.        blit_blit_tex = get_proc_address(lib,"sna_blit_tex");
  569.    }
  570.    else
  571.    {
  572.        lib = load_library("intel-uxa.drv");
  573.        if(lib)
  574.        {
  575.            blit_bitmap_from_handle = get_proc_address(lib,"uxa_bitmap_from_handle");
  576.            blit_set_bo_handle = get_proc_address(lib,"uxa_set_bo_handle");
  577.            blit_blit_tex = get_proc_address(lib,"uxa_blit_tex");
  578.        }
  579.        else return EGL_FALSE;
  580.    }
  581.  
  582.    dri2_dpy->fd = fd;
  583.    dri2_dpy->device_name = strdup("drm device"); //dri2_get_device_name_for_fd(dri2_dpy->fd);
  584.    dri2_dpy->driver_name = dri2_dpy->gbm_dri->base.driver_name;
  585.  
  586.    dri2_dpy->dri_screen = dri2_dpy->gbm_dri->screen;
  587.    dri2_dpy->core = dri2_dpy->gbm_dri->core;
  588.    dri2_dpy->dri2 = dri2_dpy->gbm_dri->dri2;
  589.    dri2_dpy->image = dri2_dpy->gbm_dri->image;
  590.    dri2_dpy->flush = dri2_dpy->gbm_dri->flush;
  591.    dri2_dpy->driver_configs = dri2_dpy->gbm_dri->driver_configs;
  592.  
  593.    dri2_dpy->gbm_dri->lookup_image = dri2_lookup_egl_image;
  594.    dri2_dpy->gbm_dri->lookup_user_data = disp;
  595.  
  596.    dri2_dpy->gbm_dri->get_buffers = dri2_get_buffers;
  597.    dri2_dpy->gbm_dri->flush_front_buffer = dri2_flush_front_buffer;
  598.    dri2_dpy->gbm_dri->get_buffers_with_format = dri2_get_buffers_with_format;
  599.  
  600.    dri2_dpy->gbm_dri->base.base.surface_lock_front_buffer = lock_front_buffer;
  601.    dri2_dpy->gbm_dri->base.base.surface_release_buffer = release_buffer;
  602.    dri2_dpy->gbm_dri->base.base.surface_has_free_buffers = has_free_buffers;
  603.  
  604.    dri2_setup_screen(disp);
  605.  
  606.    for (i = 0; dri2_dpy->driver_configs[i]; i++)
  607.       dri2_add_config(disp, dri2_dpy->driver_configs[i],
  608.                       i + 1, 0, EGL_WINDOW_BIT, NULL, NULL);
  609.  
  610.    drv->API.CreateWindowSurface = dri2_create_window_surface;
  611.    drv->API.DestroySurface = dri2_destroy_surface;
  612.    drv->API.SwapBuffers = dri2_swap_buffers;
  613.    drv->API.CreateImageKHR = dri2_drm_create_image_khr;
  614.    drv->API.QueryBufferAge = dri2_query_buffer_age;
  615.    drv->API.GetImageFB = dri2_get_fb_image;
  616.  
  617.    disp->Extensions.EXT_buffer_age = EGL_TRUE;
  618.  
  619. #ifdef HAVE_WAYLAND_PLATFORM
  620.    disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
  621. #endif
  622. //   dri2_dpy->authenticate = dri2_drm_authenticate;
  623.  
  624.    /* we're supporting EGL 1.4 */
  625.    disp->VersionMajor = 1;
  626.    disp->VersionMinor = 4;
  627.  
  628.    return EGL_TRUE;
  629. }
  630.