OSDN Git Service

gallium: Convert state trackers to drm driver interface
[android-x86/external-mesa.git] / src / gallium / state_trackers / egl / kms / native_kms.c
1 /*
2  * Mesa 3-D graphics library
3  * Version:  7.8
4  *
5  * Copyright (C) 2010 Chia-I Wu <olv@0xlab.org>
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23  * DEALINGS IN THE SOFTWARE.
24  */
25
26 #include "pipe/p_screen.h"
27 #include "pipe/p_context.h"
28 #include "util/u_debug.h"
29 #include "util/u_memory.h"
30 #include "util/u_inlines.h"
31 #include "util/u_pointer.h"
32 #include "util/u_string.h"
33 #include "egllog.h"
34
35 #include "native_kms.h"
36 #include "state_tracker/drm_driver.h"
37
38 static boolean
39 kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
40                      unsigned int *seq_num, struct pipe_resource **textures,
41                      int *width, int *height)
42 {
43    struct kms_surface *ksurf = kms_surface(nsurf);
44
45    if (!resource_surface_add_resources(ksurf->rsurf, attachment_mask))
46       return FALSE;
47    if (textures)
48       resource_surface_get_resources(ksurf->rsurf, textures, attachment_mask);
49
50    if (seq_num)
51       *seq_num = ksurf->sequence_number;
52    if (width)
53       *width = ksurf->width;
54    if (height)
55       *height = ksurf->height;
56
57    return TRUE;
58 }
59
60 /**
61  * Add textures as DRM framebuffers.
62  */
63 static boolean
64 kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
65 {
66    struct kms_surface *ksurf = kms_surface(nsurf);
67    struct kms_display *kdpy = ksurf->kdpy;
68    int num_framebuffers = (need_back) ? 2 : 1;
69    int i, err;
70
71    for (i = 0; i < num_framebuffers; i++) {
72       struct kms_framebuffer *fb;
73       enum native_attachment natt;
74       struct winsys_handle whandle;
75       uint block_bits;
76
77       if (i == 0) {
78          fb = &ksurf->front_fb;
79          natt = NATIVE_ATTACHMENT_FRONT_LEFT;
80       }
81       else {
82          fb = &ksurf->back_fb;
83          natt = NATIVE_ATTACHMENT_BACK_LEFT;
84       }
85
86       if (!fb->texture) {
87          /* make sure the texture has been allocated */
88          resource_surface_add_resources(ksurf->rsurf, 1 << natt);
89          fb->texture =
90             resource_surface_get_single_resource(ksurf->rsurf, natt);
91          if (!fb->texture)
92             return FALSE;
93       }
94
95       /* already initialized */
96       if (fb->buffer_id)
97          continue;
98
99       /* TODO detect the real value */
100       fb->is_passive = TRUE;
101
102       memset(&whandle, 0, sizeof(whandle));
103       whandle.type = DRM_API_HANDLE_TYPE_KMS;
104
105       if (!kdpy->base.screen->resource_get_handle(kdpy->base.screen,
106                fb->texture, &whandle))
107          return FALSE;
108
109       block_bits = util_format_get_blocksizebits(ksurf->color_format);
110       err = drmModeAddFB(kdpy->fd, ksurf->width, ksurf->height,
111             block_bits, block_bits, whandle.stride, whandle.handle,
112             &fb->buffer_id);
113       if (err) {
114          fb->buffer_id = 0;
115          return FALSE;
116       }
117    }
118
119    return TRUE;
120 }
121
122 static boolean
123 kms_surface_flush_frontbuffer(struct native_surface *nsurf)
124 {
125 #ifdef DRM_MODE_FEATURE_DIRTYFB
126    struct kms_surface *ksurf = kms_surface(nsurf);
127    struct kms_display *kdpy = ksurf->kdpy;
128
129    if (ksurf->front_fb.is_passive)
130       drmModeDirtyFB(kdpy->fd, ksurf->front_fb.buffer_id, NULL, 0);
131 #endif
132
133    return TRUE;
134 }
135
136 static boolean
137 kms_surface_swap_buffers(struct native_surface *nsurf)
138 {
139    struct kms_surface *ksurf = kms_surface(nsurf);
140    struct kms_crtc *kcrtc = &ksurf->current_crtc;
141    struct kms_display *kdpy = ksurf->kdpy;
142    struct kms_framebuffer tmp_fb;
143    int err;
144
145    if (!ksurf->back_fb.buffer_id) {
146       if (!kms_surface_init_framebuffers(&ksurf->base, TRUE))
147          return FALSE;
148    }
149
150    if (ksurf->is_shown && kcrtc->crtc) {
151       err = drmModeSetCrtc(kdpy->fd, kcrtc->crtc->crtc_id,
152             ksurf->back_fb.buffer_id, kcrtc->crtc->x, kcrtc->crtc->y,
153             kcrtc->connectors, kcrtc->num_connectors, &kcrtc->crtc->mode);
154       if (err)
155          return FALSE;
156    }
157
158    /* swap the buffers */
159    tmp_fb = ksurf->front_fb;
160    ksurf->front_fb = ksurf->back_fb;
161    ksurf->back_fb = tmp_fb;
162
163    resource_surface_swap_buffers(ksurf->rsurf,
164          NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, FALSE);
165    /* the front/back textures are swapped */
166    ksurf->sequence_number++;
167    kdpy->event_handler->invalid_surface(&kdpy->base,
168          &ksurf->base, ksurf->sequence_number);
169
170    return TRUE;
171 }
172
173 static void
174 kms_surface_wait(struct native_surface *nsurf)
175 {
176    /* no-op */
177 }
178
179 static void
180 kms_surface_destroy(struct native_surface *nsurf)
181 {
182    struct kms_surface *ksurf = kms_surface(nsurf);
183
184    if (ksurf->current_crtc.crtc)
185          drmModeFreeCrtc(ksurf->current_crtc.crtc);
186
187    if (ksurf->front_fb.buffer_id)
188       drmModeRmFB(ksurf->kdpy->fd, ksurf->front_fb.buffer_id);
189    pipe_resource_reference(&ksurf->front_fb.texture, NULL);
190
191    if (ksurf->back_fb.buffer_id)
192       drmModeRmFB(ksurf->kdpy->fd, ksurf->back_fb.buffer_id);
193    pipe_resource_reference(&ksurf->back_fb.texture, NULL);
194
195    resource_surface_destroy(ksurf->rsurf);
196    FREE(ksurf);
197 }
198
199 static struct kms_surface *
200 kms_display_create_surface(struct native_display *ndpy,
201                            const struct native_config *nconf,
202                            uint width, uint height)
203 {
204    struct kms_display *kdpy = kms_display(ndpy);
205    struct kms_config *kconf = kms_config(nconf);
206    struct kms_surface *ksurf;
207
208    ksurf = CALLOC_STRUCT(kms_surface);
209    if (!ksurf)
210       return NULL;
211
212    ksurf->kdpy = kdpy;
213    ksurf->color_format = kconf->base.color_format;
214    ksurf->width = width;
215    ksurf->height = height;
216
217    ksurf->rsurf = resource_surface_create(kdpy->base.screen,
218          ksurf->color_format,
219          PIPE_BIND_RENDER_TARGET |
220          PIPE_BIND_SAMPLER_VIEW |
221          PIPE_BIND_DISPLAY_TARGET |
222          PIPE_BIND_SCANOUT);
223    if (!ksurf->rsurf) {
224       FREE(ksurf);
225       return NULL;
226    }
227
228    resource_surface_set_size(ksurf->rsurf, ksurf->width, ksurf->height);
229
230    ksurf->base.destroy = kms_surface_destroy;
231    ksurf->base.swap_buffers = kms_surface_swap_buffers;
232    ksurf->base.flush_frontbuffer = kms_surface_flush_frontbuffer;
233    ksurf->base.validate = kms_surface_validate;
234    ksurf->base.wait = kms_surface_wait;
235
236    return ksurf;
237 }
238
239 /**
240  * Choose a CRTC that supports all given connectors.
241  */
242 static uint32_t
243 kms_display_choose_crtc(struct native_display *ndpy,
244                         uint32_t *connectors, int num_connectors)
245 {
246    struct kms_display *kdpy = kms_display(ndpy);
247    int idx;
248
249    for (idx = 0; idx < kdpy->resources->count_crtcs; idx++) {
250       boolean found_crtc = TRUE;
251       int i, j;
252
253       for (i = 0; i < num_connectors; i++) {
254          drmModeConnectorPtr connector;
255          int encoder_idx = -1;
256
257          connector = drmModeGetConnector(kdpy->fd, connectors[i]);
258          if (!connector) {
259             found_crtc = FALSE;
260             break;
261          }
262
263          /* find an encoder the CRTC supports */
264          for (j = 0; j < connector->count_encoders; j++) {
265             drmModeEncoderPtr encoder =
266                drmModeGetEncoder(kdpy->fd, connector->encoders[j]);
267             if (encoder->possible_crtcs & (1 << idx)) {
268                encoder_idx = j;
269                break;
270             }
271             drmModeFreeEncoder(encoder);
272          }
273
274          drmModeFreeConnector(connector);
275          if (encoder_idx < 0) {
276             found_crtc = FALSE;
277             break;
278          }
279       }
280
281       if (found_crtc)
282          break;
283    }
284
285    if (idx >= kdpy->resources->count_crtcs) {
286       _eglLog(_EGL_WARNING,
287             "failed to find a CRTC that supports the given %d connectors",
288             num_connectors);
289       return 0;
290    }
291
292    return kdpy->resources->crtcs[idx];
293 }
294
295 /**
296  * Remember the original CRTC status and set the CRTC
297  */
298 static boolean
299 kms_display_set_crtc(struct native_display *ndpy, int crtc_idx,
300                      uint32_t buffer_id, uint32_t x, uint32_t y,
301                      uint32_t *connectors, int num_connectors,
302                      drmModeModeInfoPtr mode)
303 {
304    struct kms_display *kdpy = kms_display(ndpy);
305    struct kms_crtc *kcrtc = &kdpy->saved_crtcs[crtc_idx];
306    uint32_t crtc_id;
307    int err;
308
309    if (kcrtc->crtc) {
310       crtc_id = kcrtc->crtc->crtc_id;
311    }
312    else {
313       int count = 0, i;
314
315       /*
316        * Choose the CRTC once.  It could be more dynamic, but let's keep it
317        * simple for now.
318        */
319       crtc_id = kms_display_choose_crtc(&kdpy->base,
320             connectors, num_connectors);
321
322       /* save the original CRTC status */
323       kcrtc->crtc = drmModeGetCrtc(kdpy->fd, crtc_id);
324       if (!kcrtc->crtc)
325          return FALSE;
326
327       for (i = 0; i < kdpy->num_connectors; i++) {
328          struct kms_connector *kconn = &kdpy->connectors[i];
329          drmModeConnectorPtr connector = kconn->connector;
330          drmModeEncoderPtr encoder;
331
332          encoder = drmModeGetEncoder(kdpy->fd, connector->encoder_id);
333          if (encoder) {
334             if (encoder->crtc_id == crtc_id) {
335                kcrtc->connectors[count++] = connector->connector_id;
336                if (count >= Elements(kcrtc->connectors))
337                   break;
338             }
339             drmModeFreeEncoder(encoder);
340          }
341       }
342
343       kcrtc->num_connectors = count;
344    }
345
346    err = drmModeSetCrtc(kdpy->fd, crtc_id, buffer_id, x, y,
347          connectors, num_connectors, mode);
348    if (err) {
349       drmModeFreeCrtc(kcrtc->crtc);
350       kcrtc->crtc = NULL;
351       kcrtc->num_connectors = 0;
352
353       return FALSE;
354    }
355
356    return TRUE;
357 }
358
359 static boolean
360 kms_display_program(struct native_display *ndpy, int crtc_idx,
361                     struct native_surface *nsurf, uint x, uint y,
362                     const struct native_connector **nconns, int num_nconns,
363                     const struct native_mode *nmode)
364 {
365    struct kms_display *kdpy = kms_display(ndpy);
366    struct kms_surface *ksurf = kms_surface(nsurf);
367    const struct kms_mode *kmode = kms_mode(nmode);
368    uint32_t connector_ids[32];
369    uint32_t buffer_id;
370    drmModeModeInfo mode_tmp, *mode;
371    int i;
372
373    if (num_nconns > Elements(connector_ids)) {
374       _eglLog(_EGL_WARNING, "too many connectors (%d)", num_nconns);
375       num_nconns = Elements(connector_ids);
376    }
377
378    if (ksurf) {
379       if (!kms_surface_init_framebuffers(&ksurf->base, FALSE))
380          return FALSE;
381
382       buffer_id = ksurf->front_fb.buffer_id;
383       /* the mode argument of drmModeSetCrtc is not constified */
384       mode_tmp = kmode->mode;
385       mode = &mode_tmp;
386    }
387    else {
388       /* disable the CRTC */
389       buffer_id = 0;
390       mode = NULL;
391       num_nconns = 0;
392    }
393
394    for (i = 0; i < num_nconns; i++) {
395       struct kms_connector *kconn = kms_connector(nconns[i]);
396       connector_ids[i] = kconn->connector->connector_id;
397    }
398
399    if (!kms_display_set_crtc(&kdpy->base, crtc_idx, buffer_id, x, y,
400             connector_ids, num_nconns, mode)) {
401       _eglLog(_EGL_WARNING, "failed to set CRTC %d", crtc_idx);
402
403       return FALSE;
404    }
405
406    if (kdpy->shown_surfaces[crtc_idx])
407       kdpy->shown_surfaces[crtc_idx]->is_shown = FALSE;
408    kdpy->shown_surfaces[crtc_idx] = ksurf;
409
410    /* remember the settings for buffer swapping */
411    if (ksurf) {
412       uint32_t crtc_id = kdpy->saved_crtcs[crtc_idx].crtc->crtc_id;
413       struct kms_crtc *kcrtc = &ksurf->current_crtc;
414
415       if (kcrtc->crtc)
416          drmModeFreeCrtc(kcrtc->crtc);
417       kcrtc->crtc = drmModeGetCrtc(kdpy->fd, crtc_id);
418
419       assert(num_nconns < Elements(kcrtc->connectors));
420       memcpy(kcrtc->connectors, connector_ids,
421             sizeof(*connector_ids) * num_nconns);
422       kcrtc->num_connectors = num_nconns;
423
424       ksurf->is_shown = TRUE;
425    }
426
427    return TRUE;
428 }
429
430 static const struct native_mode **
431 kms_display_get_modes(struct native_display *ndpy,
432                       const struct native_connector *nconn,
433                       int *num_modes)
434 {
435    struct kms_display *kdpy = kms_display(ndpy);
436    struct kms_connector *kconn = kms_connector(nconn);
437    const struct native_mode **nmodes_return;
438    int count, i;
439
440    /* delete old data */
441    if (kconn->connector) {
442       drmModeFreeConnector(kconn->connector);
443       FREE(kconn->kms_modes);
444
445       kconn->connector = NULL;
446       kconn->kms_modes = NULL;
447       kconn->num_modes = 0;
448    }
449
450    /* detect again */
451    kconn->connector = drmModeGetConnector(kdpy->fd, kconn->connector_id);
452    if (!kconn->connector)
453       return NULL;
454
455    count = kconn->connector->count_modes;
456    kconn->kms_modes = CALLOC(count, sizeof(*kconn->kms_modes));
457    if (!kconn->kms_modes) {
458       drmModeFreeConnector(kconn->connector);
459       kconn->connector = NULL;
460
461       return NULL;
462    }
463
464    for (i = 0; i < count; i++) {
465       struct kms_mode *kmode = &kconn->kms_modes[i];
466       drmModeModeInfoPtr mode = &kconn->connector->modes[i];
467
468       kmode->mode = *mode;
469
470       kmode->base.desc = kmode->mode.name;
471       kmode->base.width = kmode->mode.hdisplay;
472       kmode->base.height = kmode->mode.vdisplay;
473       kmode->base.refresh_rate = kmode->mode.vrefresh;
474       /* not all kernels have vrefresh = refresh_rate * 1000 */
475       if (kmode->base.refresh_rate > 1000)
476          kmode->base.refresh_rate = (kmode->base.refresh_rate + 500) / 1000;
477    }
478
479    nmodes_return = MALLOC(count * sizeof(*nmodes_return));
480    if (nmodes_return) {
481       for (i = 0; i < count; i++)
482          nmodes_return[i] = &kconn->kms_modes[i].base;
483       if (num_modes)
484          *num_modes = count;
485    }
486
487    return nmodes_return;
488 }
489
490 static const struct native_connector **
491 kms_display_get_connectors(struct native_display *ndpy, int *num_connectors,
492                            int *num_crtc)
493 {
494    struct kms_display *kdpy = kms_display(ndpy);
495    const struct native_connector **connectors;
496    int i;
497
498    if (!kdpy->connectors) {
499       kdpy->connectors =
500          CALLOC(kdpy->resources->count_connectors, sizeof(*kdpy->connectors));
501       if (!kdpy->connectors)
502          return NULL;
503
504       for (i = 0; i < kdpy->resources->count_connectors; i++) {
505          struct kms_connector *kconn = &kdpy->connectors[i];
506
507          kconn->connector_id = kdpy->resources->connectors[i];
508          /* kconn->connector is allocated when the modes are asked */
509       }
510
511       kdpy->num_connectors = kdpy->resources->count_connectors;
512    }
513
514    connectors = MALLOC(kdpy->num_connectors * sizeof(*connectors));
515    if (connectors) {
516       for (i = 0; i < kdpy->num_connectors; i++)
517          connectors[i] = &kdpy->connectors[i].base;
518       if (num_connectors)
519          *num_connectors = kdpy->num_connectors;
520    }
521
522    if (num_crtc)
523       *num_crtc = kdpy->resources->count_crtcs;
524
525    return connectors;
526 }
527
528 static struct native_surface *
529 kms_display_create_scanout_surface(struct native_display *ndpy,
530                                    const struct native_config *nconf,
531                                    uint width, uint height)
532 {
533    struct kms_surface *ksurf;
534
535    ksurf = kms_display_create_surface(ndpy, nconf, width, height);
536    return &ksurf->base;
537 }
538
539 static boolean
540 kms_display_is_format_supported(struct native_display *ndpy,
541                                 enum pipe_format fmt, boolean is_color)
542 {
543    return ndpy->screen->is_format_supported(ndpy->screen,
544          fmt, PIPE_TEXTURE_2D, 0,
545          (is_color) ? PIPE_BIND_RENDER_TARGET :
546          PIPE_BIND_DEPTH_STENCIL, 0);
547 }
548
549 static const struct native_config **
550 kms_display_get_configs(struct native_display *ndpy, int *num_configs)
551 {
552    struct kms_display *kdpy = kms_display(ndpy);
553    const struct native_config **configs;
554
555    /* first time */
556    if (!kdpy->config) {
557       struct native_config *nconf;
558       enum pipe_format format;
559
560       kdpy->config = CALLOC(1, sizeof(*kdpy->config));
561       if (!kdpy->config)
562          return NULL;
563
564       nconf = &kdpy->config->base;
565
566       nconf->buffer_mask =
567          (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
568          (1 << NATIVE_ATTACHMENT_BACK_LEFT);
569
570       format = PIPE_FORMAT_B8G8R8A8_UNORM;
571       if (!kms_display_is_format_supported(&kdpy->base, format, TRUE)) {
572          format = PIPE_FORMAT_A8R8G8B8_UNORM;
573          if (!kms_display_is_format_supported(&kdpy->base, format, TRUE))
574             format = PIPE_FORMAT_NONE;
575       }
576       if (format == PIPE_FORMAT_NONE) {
577          FREE(kdpy->config);
578          kdpy->config = NULL;
579          return NULL;
580       }
581
582       nconf->color_format = format;
583
584       nconf->scanout_bit = TRUE;
585    }
586
587    configs = MALLOC(sizeof(*configs));
588    if (configs) {
589       configs[0] = &kdpy->config->base;
590       if (num_configs)
591          *num_configs = 1;
592    }
593
594    return configs;
595 }
596
597 static int
598 kms_display_get_param(struct native_display *ndpy,
599                       enum native_param_type param)
600 {
601    int val;
602
603    switch (param) {
604    default:
605       val = 0;
606       break;
607    }
608
609    return val;
610 }
611
612 static void
613 kms_display_destroy(struct native_display *ndpy)
614 {
615    struct kms_display *kdpy = kms_display(ndpy);
616    int i;
617
618    if (kdpy->config)
619       FREE(kdpy->config);
620
621    if (kdpy->connectors) {
622       for (i = 0; i < kdpy->num_connectors; i++) {
623          struct kms_connector *kconn = &kdpy->connectors[i];
624          if (kconn->connector) {
625             drmModeFreeConnector(kconn->connector);
626             FREE(kconn->kms_modes);
627          }
628       }
629       FREE(kdpy->connectors);
630    }
631
632    if (kdpy->shown_surfaces)
633       FREE(kdpy->shown_surfaces);
634
635    if (kdpy->saved_crtcs) {
636       for (i = 0; i < kdpy->resources->count_crtcs; i++) {
637          struct kms_crtc *kcrtc = &kdpy->saved_crtcs[i];
638
639          if (kcrtc->crtc) {
640             /* restore crtc */
641             drmModeSetCrtc(kdpy->fd, kcrtc->crtc->crtc_id,
642                   kcrtc->crtc->buffer_id, kcrtc->crtc->x, kcrtc->crtc->y,
643                   kcrtc->connectors, kcrtc->num_connectors,
644                   &kcrtc->crtc->mode);
645
646             drmModeFreeCrtc(kcrtc->crtc);
647          }
648       }
649       FREE(kdpy->saved_crtcs);
650    }
651
652    if (kdpy->resources)
653       drmModeFreeResources(kdpy->resources);
654
655    if (kdpy->base.screen)
656       kdpy->base.screen->destroy(kdpy->base.screen);
657
658    if (kdpy->fd >= 0)
659       drmClose(kdpy->fd);
660
661    FREE(kdpy);
662 }
663
664 /**
665  * Initialize KMS and pipe screen.
666  */
667 static boolean
668 kms_display_init_screen(struct native_display *ndpy)
669 {
670    struct kms_display *kdpy = kms_display(ndpy);
671    int fd;
672
673    fd = kdpy->fd;
674    if (fd >= 0) {
675       drmVersionPtr version = drmGetVersion(fd);
676       if (!version || strcmp(version->name, driver_descriptor.driver_name)) {
677          if (version) {
678             _eglLog(_EGL_WARNING, "unknown driver name %s", version->name);
679             drmFreeVersion(version);
680          }
681          else {
682             _eglLog(_EGL_WARNING, "invalid fd %d", fd);
683          }
684
685          return FALSE;
686       }
687
688       drmFreeVersion(version);
689    }
690    else {
691       fd = drmOpen(driver_descriptor.driver_name, NULL);
692    }
693
694    if (fd < 0) {
695       _eglLog(_EGL_WARNING, "failed to open DRM device");
696       return FALSE;
697    }
698
699 #if 0
700    if (drmSetMaster(fd)) {
701       _eglLog(_EGL_WARNING, "failed to become DRM master");
702       return FALSE;
703    }
704 #endif
705
706    kdpy->base.screen = driver_descriptor.create_screen(fd);
707    if (!kdpy->base.screen) {
708       _eglLog(_EGL_WARNING, "failed to create DRM screen");
709       drmClose(fd);
710       return FALSE;
711    }
712
713    kdpy->fd = fd;
714
715    return TRUE;
716 }
717
718 static struct native_display_modeset kms_display_modeset = {
719    .get_connectors = kms_display_get_connectors,
720    .get_modes = kms_display_get_modes,
721    .create_scanout_surface = kms_display_create_scanout_surface,
722    .program = kms_display_program
723 };
724
725 static struct native_display *
726 kms_create_display(int fd, struct native_event_handler *event_handler)
727 {
728    struct kms_display *kdpy;
729
730    kdpy = CALLOC_STRUCT(kms_display);
731    if (!kdpy)
732       return NULL;
733
734    kdpy->event_handler = event_handler;
735    kdpy->fd = fd;
736    if (!kms_display_init_screen(&kdpy->base)) {
737       kms_display_destroy(&kdpy->base);
738       return NULL;
739    }
740
741    /* resources are fixed, unlike crtc, connector, or encoder */
742    kdpy->resources = drmModeGetResources(kdpy->fd);
743    if (!kdpy->resources) {
744       kms_display_destroy(&kdpy->base);
745       return NULL;
746    }
747
748    kdpy->saved_crtcs =
749       CALLOC(kdpy->resources->count_crtcs, sizeof(*kdpy->saved_crtcs));
750    if (!kdpy->saved_crtcs) {
751       kms_display_destroy(&kdpy->base);
752       return NULL;
753    }
754
755    kdpy->shown_surfaces =
756       CALLOC(kdpy->resources->count_crtcs, sizeof(*kdpy->shown_surfaces));
757    if (!kdpy->shown_surfaces) {
758       kms_display_destroy(&kdpy->base);
759       return NULL;
760    }
761
762    kdpy->base.destroy = kms_display_destroy;
763    kdpy->base.get_param = kms_display_get_param;
764    kdpy->base.get_configs = kms_display_get_configs;
765
766    kdpy->base.modeset = &kms_display_modeset;
767
768    return &kdpy->base;
769 }
770
771 struct native_probe *
772 native_create_probe(EGLNativeDisplayType dpy)
773 {
774    return NULL;
775 }
776
777 enum native_probe_result
778 native_get_probe_result(struct native_probe *nprobe)
779 {
780    return NATIVE_PROBE_UNKNOWN;
781 }
782
783 const char *
784 native_get_name(void)
785 {
786    static char kms_name[32];
787
788
789    util_snprintf(kms_name, sizeof(kms_name), "KMS/%s", driver_descriptor.name);
790
791    return kms_name;
792 }
793
794 struct native_display *
795 native_create_display(EGLNativeDisplayType dpy,
796                       struct native_event_handler *event_handler)
797 {
798    struct native_display *ndpy = NULL;
799    int fd;
800
801    fd = (dpy != EGL_DEFAULT_DISPLAY) ? (int) pointer_to_intptr((void *) dpy) : -1;
802    ndpy = kms_create_display(fd, event_handler);
803
804    return ndpy;
805 }