Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 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 
26
 */
27
 
28
#include 
29
#include 
30
#include 
31
#include 
32
#include 
33
#include 
34
#include 
35
#include 
36
#include 
37
#include 
38
 
39
#include "egl_dri2.h"
40
#include "egl_dri2_fallbacks.h"
41
#include "loader.h"
42
 
43
static struct gbm_bo *
44
lock_front_buffer(struct gbm_surface *_surf)
45
{
46
   struct gbm_dri_surface *surf = (struct gbm_dri_surface *) _surf;
47
   struct dri2_egl_surface *dri2_surf = surf->dri_private;
48
   struct gbm_dri_device *device = (struct gbm_dri_device *) _surf->gbm;
49
   struct gbm_bo *bo;
50
 
51
   if (dri2_surf->current == NULL) {
52
      _eglError(EGL_BAD_SURFACE, "no front buffer");
53
      return NULL;
54
   }
55
 
56
   bo = dri2_surf->current->bo;
57
 
58
   if (device->dri2) {
59
      dri2_surf->current->locked = 1;
60
      dri2_surf->current = NULL;
61
   }
62
 
63
   return bo;
64
}
65
 
66
static void
67
release_buffer(struct gbm_surface *_surf, struct gbm_bo *bo)
68
{
69
   struct gbm_dri_surface *surf = (struct gbm_dri_surface *) _surf;
70
   struct dri2_egl_surface *dri2_surf = surf->dri_private;
71
   int i;
72
 
73
   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
74
      if (dri2_surf->color_buffers[i].bo == bo) {
75
	 dri2_surf->color_buffers[i].locked = 0;
76
      }
77
   }
78
}
79
 
80
static int
81
has_free_buffers(struct gbm_surface *_surf)
82
{
83
   struct gbm_dri_surface *surf = (struct gbm_dri_surface *) _surf;
84
   struct dri2_egl_surface *dri2_surf = surf->dri_private;
85
   int i;
86
 
87
   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
88
      if (!dri2_surf->color_buffers[i].locked)
89
	 return 1;
90
 
91
   return 0;
92
}
93
 
94
static _EGLSurface *
95
dri2_drm_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
96
                        _EGLConfig *conf, void *native_window,
97
                        const EGLint *attrib_list)
98
{
99
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
100
   struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
101
   struct dri2_egl_surface *dri2_surf;
102
   struct gbm_surface *window = native_window;
103
   struct gbm_dri_surface *surf;
104
 
105
   (void) drv;
106
 
107
   dri2_surf = calloc(1, sizeof *dri2_surf);
108
   if (!dri2_surf) {
109
      _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
110
      return NULL;
111
   }
112
 
113
   if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
114
      goto cleanup_surf;
115
 
116
   switch (type) {
117
   case EGL_WINDOW_BIT:
118
      if (!window)
119
         return NULL;
120
      surf = gbm_dri_surface(window);
121
      dri2_surf->gbm_surf = surf;
122
      dri2_surf->base.Width =  surf->base.width;
123
      dri2_surf->base.Height = surf->base.height;
124
      surf->dri_private = dri2_surf;
125
      break;
126
   default:
127
      goto cleanup_surf;
128
   }
129
 
130
   if (dri2_dpy->dri2) {
131
      dri2_surf->dri_drawable =
132
         (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
133
                                               dri2_conf->dri_double_config,
134
                                               dri2_surf->gbm_surf);
135
 
136
   } else {
137
      assert(dri2_dpy->swrast != NULL);
138
      dri2_surf->dri_drawable =
139
         (*dri2_dpy->swrast->createNewDrawable) (dri2_dpy->dri_screen,
140
                                                 dri2_conf->dri_double_config,
141
                                                 dri2_surf->gbm_surf);
142
 
143
   }
144
   if (dri2_surf->dri_drawable == NULL) {
145
      _eglError(EGL_BAD_ALLOC, "createNewDrawable()");
146
      goto cleanup_surf;
147
   }
148
 
149
   return &dri2_surf->base;
150
 
151
 cleanup_surf:
152
   free(dri2_surf);
153
 
154
   return NULL;
155
}
156
 
157
static _EGLSurface *
158
dri2_drm_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
159
                               _EGLConfig *conf, void *native_window,
160
                               const EGLint *attrib_list)
161
{
162
   return dri2_drm_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
163
                                  native_window, attrib_list);
164
}
165
 
166
static _EGLSurface *
167
dri2_drm_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp,
168
                               _EGLConfig *conf, void *native_window,
169
                               const EGLint *attrib_list)
170
{
171
   /* From the EGL_MESA_platform_gbm spec, version 5:
172
    *
173
    *  It is not valid to call eglCreatePlatformPixmapSurfaceEXT with a 
174
    *  that belongs to the GBM platform. Any such call fails and generates
175
    *  EGL_BAD_PARAMETER.
176
    */
177
   _eglError(EGL_BAD_PARAMETER, "cannot create EGL pixmap surfaces on GBM");
178
   return NULL;
179
}
180
 
181
static EGLBoolean
182
dri2_drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
183
{
184
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
185
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
186
   int i;
187
 
188
   if (!_eglPutSurface(surf))
189
      return EGL_TRUE;
190
 
191
   (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
192
 
193
   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
194
      if (dri2_surf->color_buffers[i].bo)
195
	 gbm_bo_destroy(dri2_surf->color_buffers[i].bo);
196
   }
197
 
198
   for (i = 0; i < __DRI_BUFFER_COUNT; i++) {
199
      if (dri2_surf->dri_buffers[i])
200
         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
201
                                       dri2_surf->dri_buffers[i]);
202
   }
203
 
204
   free(surf);
205
 
206
   return EGL_TRUE;
207
}
208
 
209
static int
210
get_back_bo(struct dri2_egl_surface *dri2_surf)
211
{
212
   struct dri2_egl_display *dri2_dpy =
213
      dri2_egl_display(dri2_surf->base.Resource.Display);
214
   struct gbm_dri_surface *surf = dri2_surf->gbm_surf;
215
   int i;
216
 
217
   if (dri2_surf->back == NULL) {
218
      for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
219
	 if (!dri2_surf->color_buffers[i].locked) {
220
	    dri2_surf->back = &dri2_surf->color_buffers[i];
221
	    break;
222
	 }
223
      }
224
   }
225
 
226
   if (dri2_surf->back == NULL)
227
      return -1;
228
   if (dri2_surf->back->bo == NULL)
229
      dri2_surf->back->bo = gbm_bo_create(&dri2_dpy->gbm_dri->base.base,
230
					  surf->base.width, surf->base.height,
231
					  surf->base.format, surf->base.flags);
232
   if (dri2_surf->back->bo == NULL)
233
      return -1;
234
 
235
   return 0;
236
}
237
 
238
static int
239
get_swrast_front_bo(struct dri2_egl_surface *dri2_surf)
240
{
241
   struct dri2_egl_display *dri2_dpy =
242
      dri2_egl_display(dri2_surf->base.Resource.Display);
243
   struct gbm_dri_surface *surf = dri2_surf->gbm_surf;
244
 
245
   if (dri2_surf->current == NULL) {
246
      assert(!dri2_surf->color_buffers[0].locked);
247
      dri2_surf->current = &dri2_surf->color_buffers[0];
248
   }
249
 
250
   if (dri2_surf->current->bo == NULL)
251
      dri2_surf->current->bo = gbm_bo_create(&dri2_dpy->gbm_dri->base.base,
252
                                             surf->base.width, surf->base.height,
253
                                             surf->base.format, surf->base.flags);
254
   if (dri2_surf->current->bo == NULL)
255
      return -1;
256
 
257
   return 0;
258
}
259
 
260
static void
261
back_bo_to_dri_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
262
{
263
   struct dri2_egl_display *dri2_dpy =
264
      dri2_egl_display(dri2_surf->base.Resource.Display);
265
   struct gbm_dri_bo *bo;
266
   int name, pitch;
267
 
268
   bo = (struct gbm_dri_bo *) dri2_surf->back->bo;
269
 
270
   dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_NAME, &name);
271
   dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, &pitch);
272
 
273
   buffer->attachment = __DRI_BUFFER_BACK_LEFT;
274
   buffer->name = name;
275
   buffer->pitch = pitch;
276
   buffer->cpp = 4;
277
   buffer->flags = 0;
278
}
279
 
280
static int
281
get_aux_bo(struct dri2_egl_surface *dri2_surf,
282
	   unsigned int attachment, unsigned int format, __DRIbuffer *buffer)
283
{
284
   struct dri2_egl_display *dri2_dpy =
285
      dri2_egl_display(dri2_surf->base.Resource.Display);
286
   __DRIbuffer *b = dri2_surf->dri_buffers[attachment];
287
 
288
   if (b == NULL) {
289
      b = dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
290
					 attachment, format,
291
					 dri2_surf->base.Width,
292
					 dri2_surf->base.Height);
293
      dri2_surf->dri_buffers[attachment] = b;
294
   }
295
   if (b == NULL)
296
      return -1;
297
 
298
   memcpy(buffer, b, sizeof *buffer);
299
 
300
   return 0;
301
}
302
 
303
static __DRIbuffer *
304
dri2_drm_get_buffers_with_format(__DRIdrawable *driDrawable,
305
			     int *width, int *height,
306
			     unsigned int *attachments, int count,
307
			     int *out_count, void *loaderPrivate)
308
{
309
   struct dri2_egl_surface *dri2_surf = loaderPrivate;
310
   int i, j;
311
 
312
   dri2_surf->buffer_count = 0;
313
   for (i = 0, j = 0; i < 2 * count; i += 2, j++) {
314
      assert(attachments[i] < __DRI_BUFFER_COUNT);
315
      assert(dri2_surf->buffer_count < 5);
316
 
317
      switch (attachments[i]) {
318
      case __DRI_BUFFER_BACK_LEFT:
319
	 if (get_back_bo(dri2_surf) < 0) {
320
	    _eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
321
	    return NULL;
322
	 }
323
         back_bo_to_dri_buffer(dri2_surf, &dri2_surf->buffers[j]);
324
	 break;
325
      default:
326
	 if (get_aux_bo(dri2_surf, attachments[i], attachments[i + 1],
327
			&dri2_surf->buffers[j]) < 0) {
328
	    _eglError(EGL_BAD_ALLOC, "failed to allocate aux buffer");
329
	    return NULL;
330
	 }
331
	 break;
332
      }
333
   }
334
 
335
   *out_count = j;
336
   if (j == 0)
337
      return NULL;
338
 
339
   *width = dri2_surf->base.Width;
340
   *height = dri2_surf->base.Height;
341
 
342
   return dri2_surf->buffers;
343
}
344
 
345
static __DRIbuffer *
346
dri2_drm_get_buffers(__DRIdrawable * driDrawable,
347
                     int *width, int *height,
348
                     unsigned int *attachments, int count,
349
                     int *out_count, void *loaderPrivate)
350
{
351
   unsigned int *attachments_with_format;
352
   __DRIbuffer *buffer;
353
   const unsigned int format = 32;
354
   int i;
355
 
356
   attachments_with_format = calloc(count, 2 * sizeof(unsigned int));
357
   if (!attachments_with_format) {
358
      *out_count = 0;
359
      return NULL;
360
   }
361
 
362
   for (i = 0; i < count; ++i) {
363
      attachments_with_format[2*i] = attachments[i];
364
      attachments_with_format[2*i + 1] = format;
365
   }
366
 
367
   buffer =
368
      dri2_drm_get_buffers_with_format(driDrawable,
369
                                       width, height,
370
                                       attachments_with_format, count,
371
                                       out_count, loaderPrivate);
372
 
373
   free(attachments_with_format);
374
 
375
   return buffer;
376
}
377
 
378
static int
379
dri2_drm_image_get_buffers(__DRIdrawable *driDrawable,
380
                           unsigned int format,
381
                           uint32_t *stamp,
382
                           void *loaderPrivate,
383
                           uint32_t buffer_mask,
384
                           struct __DRIimageList *buffers)
385
{
386
   struct dri2_egl_surface *dri2_surf = loaderPrivate;
387
   struct gbm_dri_bo *bo;
388
 
389
   if (get_back_bo(dri2_surf) < 0)
390
      return 0;
391
 
392
   bo = (struct gbm_dri_bo *) dri2_surf->back->bo;
393
   buffers->image_mask = __DRI_IMAGE_BUFFER_BACK;
394
   buffers->back = bo->image;
395
 
396
   return 1;
397
}
398
 
399
static void
400
dri2_drm_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
401
{
402
   (void) driDrawable;
403
   (void) loaderPrivate;
404
}
405
 
406
static EGLBoolean
407
dri2_drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
408
{
409
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
410
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
411
   int i;
412
 
413
   if (dri2_dpy->swrast) {
414
      (*dri2_dpy->core->swapBuffers)(dri2_surf->dri_drawable);
415
   } else {
416
      if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
417
         if (dri2_surf->current)
418
            _eglError(EGL_BAD_SURFACE, "dri2_swap_buffers");
419
         for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
420
            if (dri2_surf->color_buffers[i].age > 0)
421
               dri2_surf->color_buffers[i].age++;
422
 
423
         /* Make sure we have a back buffer in case we're swapping without
424
          * ever rendering. */
425
         if (get_back_bo(dri2_surf) < 0) {
426
            _eglError(EGL_BAD_ALLOC, "dri2_swap_buffers");
427
            return EGL_FALSE;
428
         }
429
 
430
         dri2_surf->current = dri2_surf->back;
431
         dri2_surf->current->age = 1;
432
         dri2_surf->back = NULL;
433
      }
434
 
435
      dri2_flush_drawable_for_swapbuffers(disp, draw);
436
      (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
437
   }
438
 
439
   return EGL_TRUE;
440
}
441
 
442
static EGLint
443
dri2_drm_query_buffer_age(_EGLDriver *drv,
444
                          _EGLDisplay *disp, _EGLSurface *surface)
445
{
446
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);
447
 
448
   if (get_back_bo(dri2_surf) < 0) {
449
      _eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age");
450
      return 0;
451
   }
452
 
453
   return dri2_surf->back->age;
454
}
455
 
456
static _EGLImage *
457
dri2_drm_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
458
                                 EGLClientBuffer buffer, const EGLint *attr_list)
459
{
460
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
461
   struct gbm_dri_bo *dri_bo = gbm_dri_bo((struct gbm_bo *) buffer);
462
   struct dri2_egl_image *dri2_img;
463
 
464
   dri2_img = malloc(sizeof *dri2_img);
465
   if (!dri2_img) {
466
      _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap");
467
      return NULL;
468
   }
469
 
470
   if (!_eglInitImage(&dri2_img->base, disp)) {
471
      free(dri2_img);
472
      return NULL;
473
   }
474
 
475
   dri2_img->dri_image = dri2_dpy->image->dupImage(dri_bo->image, dri2_img);
476
   if (dri2_img->dri_image == NULL) {
477
      free(dri2_img);
478
      _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap");
479
      return NULL;
480
   }
481
 
482
   return &dri2_img->base;
483
}
484
 
485
static _EGLImage *
486
dri2_drm_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
487
                          _EGLContext *ctx, EGLenum target,
488
                          EGLClientBuffer buffer, const EGLint *attr_list)
489
{
490
   (void) drv;
491
 
492
   switch (target) {
493
   case EGL_NATIVE_PIXMAP_KHR:
494
      return dri2_drm_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
495
   default:
496
      return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
497
   }
498
}
499
 
500
#if 0
501
static int
502
dri2_drm_authenticate(_EGLDisplay *disp, uint32_t id)
503
{
504
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
505
 
506
   return drmAuthMagic(dri2_dpy->fd, id);
507
}
508
#endif
509
 
510
static void
511
swrast_put_image2(__DRIdrawable *driDrawable,
512
                  int            op,
513
                  int            x,
514
                  int            y,
515
                  int            width,
516
                  int            height,
517
                  int            stride,
518
                  char          *data,
519
                  void          *loaderPrivate)
520
{
521
   struct dri2_egl_surface *dri2_surf = loaderPrivate;
522
   int internal_stride, i;
523
   struct gbm_dri_bo *bo;
524
 
525
   if (op != __DRI_SWRAST_IMAGE_OP_DRAW &&
526
       op != __DRI_SWRAST_IMAGE_OP_SWAP)
527
      return;
528
 
529
   if (get_swrast_front_bo(dri2_surf) < 0)
530
      return;
531
 
532
   bo = gbm_dri_bo(dri2_surf->current->bo);
533
   if (gbm_dri_bo_map(bo) == NULL)
534
      return;
535
 
536
   internal_stride = bo->base.base.stride;
537
 
538
   for (i = 0; i < height; i++) {
539
      memcpy(bo->map + (x + i) * internal_stride + y,
540
             data + i * stride, stride);
541
   }
542
 
543
   gbm_dri_bo_unmap(bo);
544
}
545
 
546
static void
547
swrast_get_image(__DRIdrawable *driDrawable,
548
                 int            x,
549
                 int            y,
550
                 int            width,
551
                 int            height,
552
                 char          *data,
553
                 void          *loaderPrivate)
554
{
555
   struct dri2_egl_surface *dri2_surf = loaderPrivate;
556
   int internal_stride, stride, i;
557
   struct gbm_dri_bo *bo;
558
 
559
   if (get_swrast_front_bo(dri2_surf) < 0)
560
      return;
561
 
562
   bo = gbm_dri_bo(dri2_surf->current->bo);
563
   if (gbm_dri_bo_map(bo) == NULL)
564
      return;
565
 
566
   internal_stride = bo->base.base.stride;
567
   stride = width * 4;
568
 
569
   for (i = 0; i < height; i++) {
570
      memcpy(data + i * stride,
571
             bo->map + (x + i) * internal_stride + y, stride);
572
   }
573
 
574
   gbm_dri_bo_unmap(bo);
575
}
576
 
577
static struct dri2_egl_display_vtbl dri2_drm_display_vtbl = {
578
   .authenticate = dri2_drm_authenticate,
579
   .create_window_surface = dri2_drm_create_window_surface,
580
   .create_pixmap_surface = dri2_drm_create_pixmap_surface,
581
   .create_pbuffer_surface = dri2_fallback_create_pbuffer_surface,
582
   .destroy_surface = dri2_drm_destroy_surface,
583
   .create_image = dri2_drm_create_image_khr,
584
   .swap_interval = dri2_fallback_swap_interval,
585
   .swap_buffers = dri2_drm_swap_buffers,
586
   .swap_buffers_with_damage = dri2_fallback_swap_buffers_with_damage,
587
   .swap_buffers_region = dri2_fallback_swap_buffers_region,
588
   .post_sub_buffer = dri2_fallback_post_sub_buffer,
589
   .copy_buffers = dri2_fallback_copy_buffers,
590
   .query_buffer_age = dri2_drm_query_buffer_age,
591
   .create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image,
592
   .get_sync_values = dri2_fallback_get_sync_values,
593
};
594
 
595
EGLBoolean
596
dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
597
{
598
   struct dri2_egl_display *dri2_dpy;
599
   struct gbm_device *gbm;
600
   void *lib;
601
 
602
   int fd = -1;
603
   int i;
604
 
605
   loader_set_logger(_eglLog);
606
 
607
   dri2_dpy = calloc(1, sizeof *dri2_dpy);
608
   if (!dri2_dpy)
609
      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
610
 
611
   disp->DriverData = (void *) dri2_dpy;
612
 
613
   gbm = disp->PlatformDisplay;
614
   if (gbm == NULL) {
615
      fd = get_service("DISPLAY");
616
      dri2_dpy->own_device = 1;
617
      gbm = gbm_create_device(fd);
618
      if (gbm == NULL)
619
         return EGL_FALSE;
620
   }
621
 
622
   if (strcmp(gbm_device_get_backend_name(gbm), "drm") != 0) {
623
      free(dri2_dpy);
624
      return EGL_FALSE;
625
   }
626
 
627
   dri2_dpy->gbm_dri = gbm_dri_device(gbm);
628
   if (dri2_dpy->gbm_dri->base.type != GBM_DRM_DRIVER_TYPE_DRI) {
629
      free(dri2_dpy);
630
      return EGL_FALSE;
631
   }
632
 
633
   if (fd < 0) {
634
      fd = dup(gbm_device_get_fd(gbm));
635
      if (fd < 0) {
636
         free(dri2_dpy);
637
         return EGL_FALSE;
638
      }
639
   }
640
 
641
   dri2_dpy->fd = fd;
642
   dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd);
643
   dri2_dpy->driver_name = strdup(dri2_dpy->gbm_dri->base.driver_name);
644
 
645
   dri2_dpy->dri_screen = dri2_dpy->gbm_dri->screen;
646
   dri2_dpy->core = dri2_dpy->gbm_dri->core;
647
   dri2_dpy->dri2 = dri2_dpy->gbm_dri->dri2;
648
   dri2_dpy->image = dri2_dpy->gbm_dri->image;
649
   dri2_dpy->flush = dri2_dpy->gbm_dri->flush;
650
   dri2_dpy->swrast = dri2_dpy->gbm_dri->swrast;
651
   dri2_dpy->driver_configs = dri2_dpy->gbm_dri->driver_configs;
652
 
653
   dri2_dpy->gbm_dri->lookup_image = dri2_lookup_egl_image;
654
   dri2_dpy->gbm_dri->lookup_user_data = disp;
655
 
656
   dri2_dpy->gbm_dri->get_buffers = dri2_drm_get_buffers;
657
   dri2_dpy->gbm_dri->flush_front_buffer = dri2_drm_flush_front_buffer;
658
   dri2_dpy->gbm_dri->get_buffers_with_format = dri2_drm_get_buffers_with_format;
659
   dri2_dpy->gbm_dri->image_get_buffers = dri2_drm_image_get_buffers;
660
   dri2_dpy->gbm_dri->swrast_put_image2 = swrast_put_image2;
661
   dri2_dpy->gbm_dri->swrast_get_image = swrast_get_image;
662
 
663
   dri2_dpy->gbm_dri->base.base.surface_lock_front_buffer = lock_front_buffer;
664
   dri2_dpy->gbm_dri->base.base.surface_release_buffer = release_buffer;
665
   dri2_dpy->gbm_dri->base.base.surface_has_free_buffers = has_free_buffers;
666
 
667
   dri2_setup_screen(disp);
668
 
669
   for (i = 0; dri2_dpy->driver_configs[i]; i++) {
670
      EGLint format, attr_list[3];
671
      unsigned int red, alpha;
672
 
673
      dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
674
                                       __DRI_ATTRIB_RED_MASK, &red);
675
      dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
676
                                       __DRI_ATTRIB_ALPHA_MASK, &alpha);
677
      if (red == 0x3ff00000 && alpha == 0x00000000)
678
         format = GBM_FORMAT_XRGB2101010;
679
      else if (red == 0x3ff00000 && alpha == 0xc0000000)
680
         format = GBM_FORMAT_ARGB2101010;
681
      else if (red == 0x00ff0000 && alpha == 0x00000000)
682
         format = GBM_FORMAT_XRGB8888;
683
      else if (red == 0x00ff0000 && alpha == 0xff000000)
684
         format = GBM_FORMAT_ARGB8888;
685
      else if (red == 0xf800)
686
         format = GBM_FORMAT_RGB565;
687
      else
688
         continue;
689
 
690
      attr_list[0] = EGL_NATIVE_VISUAL_ID;
691
      attr_list[1] = format;
692
      attr_list[2] = EGL_NONE;
693
 
694
      dri2_add_config(disp, dri2_dpy->driver_configs[i],
695
                      i + 1, EGL_WINDOW_BIT, attr_list, NULL);
696
   }
697
 
698
   disp->Extensions.KHR_image_pixmap = EGL_TRUE;
699
   if (dri2_dpy->dri2)
700
      disp->Extensions.EXT_buffer_age = EGL_TRUE;
701
 
702
#ifdef HAVE_WAYLAND_PLATFORM
703
   if (dri2_dpy->image) {
704
       if (dri2_dpy->image->base.version >= 10 &&
705
           dri2_dpy->image->getCapabilities != NULL) {
706
           int capabilities;
707
 
708
           capabilities =
709
               dri2_dpy->image->getCapabilities(dri2_dpy->dri_screen);
710
           disp->Extensions.WL_bind_wayland_display =
711
               (capabilities & __DRI_IMAGE_CAP_GLOBAL_NAMES) != 0;
712
       } else
713
           disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
714
   }
715
#endif
716
 
717
   /* we're supporting EGL 1.4 */
718
   disp->VersionMajor = 1;
719
   disp->VersionMinor = 4;
720
 
721
   /* Fill vtbl last to prevent accidentally calling virtual function during
722
    * initialization.
723
    */
724
   dri2_dpy->vtbl = &dri2_drm_display_vtbl;
725
 
726
   return EGL_TRUE;
727
}