2 * Mesa 3-D graphics library
5 * Copyright (C) 2010 Chia-I Wu <olv@0xlab.org>
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #include "pipe/p_screen.h"
29 #include "pipe/p_context.h"
30 #include "util/u_debug.h"
31 #include "util/u_memory.h"
32 #include "util/u_inlines.h"
35 #include "native_kms.h"
38 kms_surface_validate(struct native_surface
*nsurf
, uint attachment_mask
,
39 unsigned int *seq_num
, struct pipe_texture
**textures
,
40 int *width
, int *height
)
42 struct kms_surface
*ksurf
= kms_surface(nsurf
);
43 struct kms_display
*kdpy
= ksurf
->kdpy
;
44 struct pipe_screen
*screen
= kdpy
->base
.screen
;
45 struct pipe_texture templ
, *ptex
;
48 if (attachment_mask
) {
49 memset(&templ
, 0, sizeof(templ
));
50 templ
.target
= PIPE_TEXTURE_2D
;
52 templ
.width0
= ksurf
->width
;
53 templ
.height0
= ksurf
->height
;
55 templ
.format
= ksurf
->color_format
;
56 templ
.tex_usage
= PIPE_TEXTURE_USAGE_RENDER_TARGET
;
57 if (ksurf
->type
== KMS_SURFACE_TYPE_SCANOUT
)
58 templ
.tex_usage
|= PIPE_TEXTURE_USAGE_SCANOUT
;
62 for (att
= 0; att
< NUM_NATIVE_ATTACHMENTS
; att
++) {
63 /* delay the allocation */
64 if (!native_attachment_mask_test(attachment_mask
, att
))
67 ptex
= ksurf
->textures
[att
];
69 ptex
= screen
->texture_create(screen
, &templ
);
70 ksurf
->textures
[att
] = ptex
;
75 pipe_texture_reference(&textures
[att
], ptex
);
80 *seq_num
= ksurf
->sequence_number
;
82 *width
= ksurf
->width
;
84 *height
= ksurf
->height
;
90 * Add textures as DRM framebuffers.
93 kms_surface_init_framebuffers(struct native_surface
*nsurf
, boolean need_back
)
95 struct kms_surface
*ksurf
= kms_surface(nsurf
);
96 struct kms_display
*kdpy
= ksurf
->kdpy
;
97 int num_framebuffers
= (need_back
) ? 2 : 1;
100 for (i
= 0; i
< num_framebuffers
; i
++) {
101 struct kms_framebuffer
*fb
;
102 enum native_attachment natt
;
103 struct winsys_handle whandle
;
107 fb
= &ksurf
->front_fb
;
108 natt
= NATIVE_ATTACHMENT_FRONT_LEFT
;
111 fb
= &ksurf
->back_fb
;
112 natt
= NATIVE_ATTACHMENT_BACK_LEFT
;
116 /* make sure the texture has been allocated */
117 kms_surface_validate(&ksurf
->base
, 1 << natt
, NULL
, NULL
, NULL
, NULL
);
118 if (!ksurf
->textures
[natt
])
121 pipe_texture_reference(&fb
->texture
, ksurf
->textures
[natt
]);
124 /* already initialized */
128 /* TODO detect the real value */
129 fb
->is_passive
= TRUE
;
131 memset(&whandle
, 0, sizeof(whandle
));
132 whandle
.type
= DRM_API_HANDLE_TYPE_KMS
;
134 if (!kdpy
->base
.screen
->texture_get_handle(kdpy
->base
.screen
,
135 fb
->texture
, &whandle
))
138 block_bits
= util_format_get_blocksizebits(ksurf
->color_format
);
139 err
= drmModeAddFB(kdpy
->fd
, ksurf
->width
, ksurf
->height
,
140 block_bits
, block_bits
, whandle
.stride
, whandle
.handle
,
152 kms_surface_flush_frontbuffer(struct native_surface
*nsurf
)
154 #ifdef DRM_MODE_FEATURE_DIRTYFB
155 struct kms_surface
*ksurf
= kms_surface(nsurf
);
156 struct kms_display
*kdpy
= ksurf
->kdpy
;
158 /* pbuffer is private */
159 if (ksurf
->type
== KMS_SURFACE_TYPE_PBUFFER
)
162 if (ksurf
->front_fb
.is_passive
)
163 drmModeDirtyFB(kdpy
->fd
, ksurf
->front_fb
.buffer_id
, NULL
, 0);
170 kms_surface_swap_buffers(struct native_surface
*nsurf
)
172 struct kms_surface
*ksurf
= kms_surface(nsurf
);
173 struct kms_crtc
*kcrtc
= &ksurf
->current_crtc
;
174 struct kms_display
*kdpy
= ksurf
->kdpy
;
175 struct kms_framebuffer tmp_fb
;
176 struct pipe_texture
*tmp_texture
;
179 /* pbuffer is private */
180 if (ksurf
->type
== KMS_SURFACE_TYPE_PBUFFER
)
183 if (!ksurf
->back_fb
.buffer_id
) {
184 if (!kms_surface_init_framebuffers(&ksurf
->base
, TRUE
))
188 if (ksurf
->is_shown
&& kcrtc
->crtc
) {
189 err
= drmModeSetCrtc(kdpy
->fd
, kcrtc
->crtc
->crtc_id
,
190 ksurf
->back_fb
.buffer_id
, kcrtc
->crtc
->x
, kcrtc
->crtc
->y
,
191 kcrtc
->connectors
, kcrtc
->num_connectors
, &kcrtc
->crtc
->mode
);
196 /* swap the buffers */
197 tmp_fb
= ksurf
->front_fb
;
198 ksurf
->front_fb
= ksurf
->back_fb
;
199 ksurf
->back_fb
= tmp_fb
;
201 tmp_texture
= ksurf
->textures
[NATIVE_ATTACHMENT_FRONT_LEFT
];
202 ksurf
->textures
[NATIVE_ATTACHMENT_FRONT_LEFT
] =
203 ksurf
->textures
[NATIVE_ATTACHMENT_BACK_LEFT
];
204 ksurf
->textures
[NATIVE_ATTACHMENT_BACK_LEFT
] = tmp_texture
;
206 /* the front/back textures are swapped */
207 ksurf
->sequence_number
++;
208 kdpy
->event_handler
->invalid_surface(&kdpy
->base
,
209 &ksurf
->base
, ksurf
->sequence_number
);
215 kms_surface_wait(struct native_surface
*nsurf
)
221 kms_surface_destroy(struct native_surface
*nsurf
)
223 struct kms_surface
*ksurf
= kms_surface(nsurf
);
226 if (ksurf
->current_crtc
.crtc
)
227 drmModeFreeCrtc(ksurf
->current_crtc
.crtc
);
229 if (ksurf
->front_fb
.buffer_id
)
230 drmModeRmFB(ksurf
->kdpy
->fd
, ksurf
->front_fb
.buffer_id
);
231 pipe_texture_reference(&ksurf
->front_fb
.texture
, NULL
);
233 if (ksurf
->back_fb
.buffer_id
)
234 drmModeRmFB(ksurf
->kdpy
->fd
, ksurf
->back_fb
.buffer_id
);
235 pipe_texture_reference(&ksurf
->back_fb
.texture
, NULL
);
237 for (i
= 0; i
< NUM_NATIVE_ATTACHMENTS
; i
++) {
238 struct pipe_texture
*ptex
= ksurf
->textures
[i
];
239 pipe_texture_reference(&ptex
, NULL
);
245 static struct kms_surface
*
246 kms_display_create_surface(struct native_display
*ndpy
,
247 enum kms_surface_type type
,
248 const struct native_config
*nconf
,
249 uint width
, uint height
)
251 struct kms_display
*kdpy
= kms_display(ndpy
);
252 struct kms_config
*kconf
= kms_config(nconf
);
253 struct kms_surface
*ksurf
;
255 ksurf
= CALLOC_STRUCT(kms_surface
);
261 ksurf
->color_format
= kconf
->base
.color_format
;
262 ksurf
->width
= width
;
263 ksurf
->height
= height
;
265 ksurf
->base
.destroy
= kms_surface_destroy
;
266 ksurf
->base
.swap_buffers
= kms_surface_swap_buffers
;
267 ksurf
->base
.flush_frontbuffer
= kms_surface_flush_frontbuffer
;
268 ksurf
->base
.validate
= kms_surface_validate
;
269 ksurf
->base
.wait
= kms_surface_wait
;
275 * Choose a CRTC that supports all given connectors.
278 kms_display_choose_crtc(struct native_display
*ndpy
,
279 uint32_t *connectors
, int num_connectors
)
281 struct kms_display
*kdpy
= kms_display(ndpy
);
284 for (idx
= 0; idx
< kdpy
->resources
->count_crtcs
; idx
++) {
285 boolean found_crtc
= TRUE
;
288 for (i
= 0; i
< num_connectors
; i
++) {
289 drmModeConnectorPtr connector
;
290 int encoder_idx
= -1;
292 connector
= drmModeGetConnector(kdpy
->fd
, connectors
[i
]);
298 /* find an encoder the CRTC supports */
299 for (j
= 0; j
< connector
->count_encoders
; j
++) {
300 drmModeEncoderPtr encoder
=
301 drmModeGetEncoder(kdpy
->fd
, connector
->encoders
[j
]);
302 if (encoder
->possible_crtcs
& (1 << idx
)) {
306 drmModeFreeEncoder(encoder
);
309 drmModeFreeConnector(connector
);
310 if (encoder_idx
< 0) {
320 if (idx
>= kdpy
->resources
->count_crtcs
) {
321 _eglLog(_EGL_WARNING
,
322 "failed to find a CRTC that supports the given %d connectors",
327 return kdpy
->resources
->crtcs
[idx
];
331 * Remember the original CRTC status and set the CRTC
334 kms_display_set_crtc(struct native_display
*ndpy
, int crtc_idx
,
335 uint32_t buffer_id
, uint32_t x
, uint32_t y
,
336 uint32_t *connectors
, int num_connectors
,
337 drmModeModeInfoPtr mode
)
339 struct kms_display
*kdpy
= kms_display(ndpy
);
340 struct kms_crtc
*kcrtc
= &kdpy
->saved_crtcs
[crtc_idx
];
345 crtc_id
= kcrtc
->crtc
->crtc_id
;
351 * Choose the CRTC once. It could be more dynamic, but let's keep it
354 crtc_id
= kms_display_choose_crtc(&kdpy
->base
,
355 connectors
, num_connectors
);
357 /* save the original CRTC status */
358 kcrtc
->crtc
= drmModeGetCrtc(kdpy
->fd
, crtc_id
);
362 for (i
= 0; i
< kdpy
->num_connectors
; i
++) {
363 struct kms_connector
*kconn
= &kdpy
->connectors
[i
];
364 drmModeConnectorPtr connector
= kconn
->connector
;
365 drmModeEncoderPtr encoder
;
367 encoder
= drmModeGetEncoder(kdpy
->fd
, connector
->encoder_id
);
369 if (encoder
->crtc_id
== crtc_id
) {
370 kcrtc
->connectors
[count
++] = connector
->connector_id
;
371 if (count
>= Elements(kcrtc
->connectors
))
374 drmModeFreeEncoder(encoder
);
378 kcrtc
->num_connectors
= count
;
381 err
= drmModeSetCrtc(kdpy
->fd
, crtc_id
, buffer_id
, x
, y
,
382 connectors
, num_connectors
, mode
);
384 drmModeFreeCrtc(kcrtc
->crtc
);
386 kcrtc
->num_connectors
= 0;
395 kms_display_program(struct native_display
*ndpy
, int crtc_idx
,
396 struct native_surface
*nsurf
, uint x
, uint y
,
397 const struct native_connector
**nconns
, int num_nconns
,
398 const struct native_mode
*nmode
)
400 struct kms_display
*kdpy
= kms_display(ndpy
);
401 struct kms_surface
*ksurf
= kms_surface(nsurf
);
402 const struct kms_mode
*kmode
= kms_mode(nmode
);
403 uint32_t connector_ids
[32];
405 drmModeModeInfo mode_tmp
, *mode
;
408 if (num_nconns
> Elements(connector_ids
)) {
409 _eglLog(_EGL_WARNING
, "too many connectors (%d)", num_nconns
);
410 num_nconns
= Elements(connector_ids
);
414 if (!kms_surface_init_framebuffers(&ksurf
->base
, FALSE
))
417 buffer_id
= ksurf
->front_fb
.buffer_id
;
418 /* the mode argument of drmModeSetCrtc is not constified */
419 mode_tmp
= kmode
->mode
;
423 /* disable the CRTC */
429 for (i
= 0; i
< num_nconns
; i
++) {
430 struct kms_connector
*kconn
= kms_connector(nconns
[i
]);
431 connector_ids
[i
] = kconn
->connector
->connector_id
;
434 if (!kms_display_set_crtc(&kdpy
->base
, crtc_idx
, buffer_id
, x
, y
,
435 connector_ids
, num_nconns
, mode
)) {
436 _eglLog(_EGL_WARNING
, "failed to set CRTC %d", crtc_idx
);
441 if (kdpy
->shown_surfaces
[crtc_idx
])
442 kdpy
->shown_surfaces
[crtc_idx
]->is_shown
= FALSE
;
443 kdpy
->shown_surfaces
[crtc_idx
] = ksurf
;
445 /* remember the settings for buffer swapping */
447 uint32_t crtc_id
= kdpy
->saved_crtcs
[crtc_idx
].crtc
->crtc_id
;
448 struct kms_crtc
*kcrtc
= &ksurf
->current_crtc
;
451 drmModeFreeCrtc(kcrtc
->crtc
);
452 kcrtc
->crtc
= drmModeGetCrtc(kdpy
->fd
, crtc_id
);
454 assert(num_nconns
< Elements(kcrtc
->connectors
));
455 memcpy(kcrtc
->connectors
, connector_ids
,
456 sizeof(*connector_ids
) * num_nconns
);
457 kcrtc
->num_connectors
= num_nconns
;
459 ksurf
->is_shown
= TRUE
;
465 static const struct native_mode
**
466 kms_display_get_modes(struct native_display
*ndpy
,
467 const struct native_connector
*nconn
,
470 struct kms_display
*kdpy
= kms_display(ndpy
);
471 struct kms_connector
*kconn
= kms_connector(nconn
);
472 const struct native_mode
**nmodes_return
;
475 /* delete old data */
476 if (kconn
->connector
) {
477 drmModeFreeConnector(kconn
->connector
);
478 free(kconn
->kms_modes
);
480 kconn
->connector
= NULL
;
481 kconn
->kms_modes
= NULL
;
482 kconn
->num_modes
= 0;
486 kconn
->connector
= drmModeGetConnector(kdpy
->fd
, kconn
->connector_id
);
487 if (!kconn
->connector
)
490 count
= kconn
->connector
->count_modes
;
491 kconn
->kms_modes
= calloc(count
, sizeof(*kconn
->kms_modes
));
492 if (!kconn
->kms_modes
) {
493 drmModeFreeConnector(kconn
->connector
);
494 kconn
->connector
= NULL
;
499 for (i
= 0; i
< count
; i
++) {
500 struct kms_mode
*kmode
= &kconn
->kms_modes
[i
];
501 drmModeModeInfoPtr mode
= &kconn
->connector
->modes
[i
];
505 kmode
->base
.desc
= kmode
->mode
.name
;
506 kmode
->base
.width
= kmode
->mode
.hdisplay
;
507 kmode
->base
.height
= kmode
->mode
.vdisplay
;
508 kmode
->base
.refresh_rate
= kmode
->mode
.vrefresh
;
509 /* not all kernels have vrefresh = refresh_rate * 1000 */
510 if (kmode
->base
.refresh_rate
> 1000)
511 kmode
->base
.refresh_rate
= (kmode
->base
.refresh_rate
+ 500) / 1000;
514 nmodes_return
= malloc(count
* sizeof(*nmodes_return
));
516 for (i
= 0; i
< count
; i
++)
517 nmodes_return
[i
] = &kconn
->kms_modes
[i
].base
;
522 return nmodes_return
;
525 static const struct native_connector
**
526 kms_display_get_connectors(struct native_display
*ndpy
, int *num_connectors
,
529 struct kms_display
*kdpy
= kms_display(ndpy
);
530 const struct native_connector
**connectors
;
533 if (!kdpy
->connectors
) {
535 calloc(kdpy
->resources
->count_connectors
, sizeof(*kdpy
->connectors
));
536 if (!kdpy
->connectors
)
539 for (i
= 0; i
< kdpy
->resources
->count_connectors
; i
++) {
540 struct kms_connector
*kconn
= &kdpy
->connectors
[i
];
542 kconn
->connector_id
= kdpy
->resources
->connectors
[i
];
543 /* kconn->connector is allocated when the modes are asked */
546 kdpy
->num_connectors
= kdpy
->resources
->count_connectors
;
549 connectors
= malloc(kdpy
->num_connectors
* sizeof(*connectors
));
551 for (i
= 0; i
< kdpy
->num_connectors
; i
++)
552 connectors
[i
] = &kdpy
->connectors
[i
].base
;
554 *num_connectors
= kdpy
->num_connectors
;
558 *num_crtc
= kdpy
->resources
->count_crtcs
;
563 static struct native_surface
*
564 kms_display_create_scanout_surface(struct native_display
*ndpy
,
565 const struct native_config
*nconf
,
566 uint width
, uint height
)
568 struct kms_surface
*ksurf
;
570 ksurf
= kms_display_create_surface(ndpy
,
571 KMS_SURFACE_TYPE_SCANOUT
, nconf
, width
, height
);
575 static struct native_surface
*
576 kms_display_create_pbuffer_surface(struct native_display
*ndpy
,
577 const struct native_config
*nconf
,
578 uint width
, uint height
)
580 struct kms_surface
*ksurf
;
582 ksurf
= kms_display_create_surface(ndpy
,
583 KMS_SURFACE_TYPE_PBUFFER
, nconf
, width
, height
);
589 kms_display_is_format_supported(struct native_display
*ndpy
,
590 enum pipe_format fmt
, boolean is_color
)
592 return ndpy
->screen
->is_format_supported(ndpy
->screen
,
593 fmt
, PIPE_TEXTURE_2D
,
594 (is_color
) ? PIPE_TEXTURE_USAGE_RENDER_TARGET
:
595 PIPE_TEXTURE_USAGE_DEPTH_STENCIL
, 0);
598 static const struct native_config
**
599 kms_display_get_configs(struct native_display
*ndpy
, int *num_configs
)
601 struct kms_display
*kdpy
= kms_display(ndpy
);
602 const struct native_config
**configs
;
606 struct native_config
*nconf
;
607 enum pipe_format format
;
609 kdpy
->config
= calloc(1, sizeof(*kdpy
->config
));
613 nconf
= &kdpy
->config
->base
;
615 /* always double-buffered */
616 nconf
->mode
.doubleBufferMode
= TRUE
;
618 format
= PIPE_FORMAT_B8G8R8A8_UNORM
;
619 if (!kms_display_is_format_supported(&kdpy
->base
, format
, TRUE
)) {
620 format
= PIPE_FORMAT_A8R8G8B8_UNORM
;
621 if (!kms_display_is_format_supported(&kdpy
->base
, format
, TRUE
))
622 format
= PIPE_FORMAT_NONE
;
624 if (format
== PIPE_FORMAT_NONE
)
627 nconf
->color_format
= format
;
628 nconf
->mode
.redBits
= 8;
629 nconf
->mode
.greenBits
= 8;
630 nconf
->mode
.blueBits
= 8;
631 nconf
->mode
.alphaBits
= 8;
632 nconf
->mode
.rgbBits
= 32;
634 format
= PIPE_FORMAT_Z24S8_UNORM
;
635 if (!kms_display_is_format_supported(&kdpy
->base
, format
, FALSE
)) {
636 format
= PIPE_FORMAT_S8Z24_UNORM
;
637 if (!kms_display_is_format_supported(&kdpy
->base
, format
, FALSE
))
638 format
= PIPE_FORMAT_NONE
;
640 if (format
!= PIPE_FORMAT_NONE
) {
641 nconf
->depth_format
= format
;
642 nconf
->stencil_format
= format
;
644 nconf
->mode
.depthBits
= 24;
645 nconf
->mode
.stencilBits
= 8;
646 nconf
->mode
.haveDepthBuffer
= TRUE
;
647 nconf
->mode
.haveStencilBuffer
= TRUE
;
650 nconf
->scanout_bit
= TRUE
;
651 nconf
->mode
.drawableType
= GLX_PBUFFER_BIT
;
652 nconf
->mode
.swapMethod
= GLX_SWAP_EXCHANGE_OML
;
654 nconf
->mode
.visualID
= 0;
655 nconf
->mode
.visualType
= EGL_NONE
;
657 nconf
->mode
.renderType
= GLX_RGBA_BIT
;
658 nconf
->mode
.rgbMode
= TRUE
;
659 nconf
->mode
.xRenderable
= FALSE
;
662 configs
= malloc(sizeof(*configs
));
664 configs
[0] = &kdpy
->config
->base
;
673 kms_display_get_param(struct native_display
*ndpy
,
674 enum native_param_type param
)
688 kms_display_destroy(struct native_display
*ndpy
)
690 struct kms_display
*kdpy
= kms_display(ndpy
);
696 if (kdpy
->connectors
) {
697 for (i
= 0; i
< kdpy
->num_connectors
; i
++) {
698 struct kms_connector
*kconn
= &kdpy
->connectors
[i
];
699 if (kconn
->connector
) {
700 drmModeFreeConnector(kconn
->connector
);
701 free(kconn
->kms_modes
);
704 free(kdpy
->connectors
);
707 if (kdpy
->shown_surfaces
)
708 free(kdpy
->shown_surfaces
);
710 if (kdpy
->saved_crtcs
) {
711 for (i
= 0; i
< kdpy
->resources
->count_crtcs
; i
++) {
712 struct kms_crtc
*kcrtc
= &kdpy
->saved_crtcs
[i
];
716 drmModeSetCrtc(kdpy
->fd
, kcrtc
->crtc
->crtc_id
,
717 kcrtc
->crtc
->buffer_id
, kcrtc
->crtc
->x
, kcrtc
->crtc
->y
,
718 kcrtc
->connectors
, kcrtc
->num_connectors
,
721 drmModeFreeCrtc(kcrtc
->crtc
);
724 free(kdpy
->saved_crtcs
);
728 drmModeFreeResources(kdpy
->resources
);
730 if (kdpy
->base
.screen
)
731 kdpy
->base
.screen
->destroy(kdpy
->base
.screen
);
737 kdpy
->api
->destroy(kdpy
->api
);
742 * Initialize KMS and pipe screen.
745 kms_display_init_screen(struct native_display
*ndpy
)
747 struct kms_display
*kdpy
= kms_display(ndpy
);
748 struct drm_create_screen_arg arg
;
751 fd
= drmOpen(kdpy
->api
->name
, NULL
);
753 _eglLog(_EGL_WARNING
, "failed to open DRM device");
758 if (drmSetMaster(fd
)) {
759 _eglLog(_EGL_WARNING
, "failed to become DRM master");
764 memset(&arg
, 0, sizeof(arg
));
765 arg
.mode
= DRM_CREATE_NORMAL
;
766 kdpy
->base
.screen
= kdpy
->api
->create_screen(kdpy
->api
, fd
, &arg
);
767 if (!kdpy
->base
.screen
) {
768 _eglLog(_EGL_WARNING
, "failed to create DRM screen");
778 static struct native_display_modeset kms_display_modeset
= {
779 .get_connectors
= kms_display_get_connectors
,
780 .get_modes
= kms_display_get_modes
,
781 .create_scanout_surface
= kms_display_create_scanout_surface
,
782 .program
= kms_display_program
785 static struct native_display
*
786 kms_create_display(EGLNativeDisplayType dpy
,
787 struct native_event_handler
*event_handler
,
790 struct kms_display
*kdpy
;
792 kdpy
= CALLOC_STRUCT(kms_display
);
796 kdpy
->event_handler
= event_handler
;
800 _eglLog(_EGL_WARNING
, "failed to create DRM API");
806 if (!kms_display_init_screen(&kdpy
->base
)) {
807 kms_display_destroy(&kdpy
->base
);
811 /* resources are fixed, unlike crtc, connector, or encoder */
812 kdpy
->resources
= drmModeGetResources(kdpy
->fd
);
813 if (!kdpy
->resources
) {
814 kms_display_destroy(&kdpy
->base
);
819 calloc(kdpy
->resources
->count_crtcs
, sizeof(*kdpy
->saved_crtcs
));
820 if (!kdpy
->saved_crtcs
) {
821 kms_display_destroy(&kdpy
->base
);
825 kdpy
->shown_surfaces
=
826 calloc(kdpy
->resources
->count_crtcs
, sizeof(*kdpy
->shown_surfaces
));
827 if (!kdpy
->shown_surfaces
) {
828 kms_display_destroy(&kdpy
->base
);
832 kdpy
->base
.destroy
= kms_display_destroy
;
833 kdpy
->base
.get_param
= kms_display_get_param
;
834 kdpy
->base
.get_configs
= kms_display_get_configs
;
835 kdpy
->base
.create_pbuffer_surface
= kms_display_create_pbuffer_surface
;
837 kdpy
->base
.modeset
= &kms_display_modeset
;
842 struct native_probe
*
843 native_create_probe(EGLNativeDisplayType dpy
)
848 enum native_probe_result
849 native_get_probe_result(struct native_probe
*nprobe
)
851 return NATIVE_PROBE_UNKNOWN
;
854 /* the api is destroyed with the native display */
855 static struct drm_api
*drm_api
;
858 native_get_name(void)
860 static char kms_name
[32];
863 drm_api
= drm_api_create();
866 snprintf(kms_name
, sizeof(kms_name
), "KMS/%s", drm_api
->name
);
868 snprintf(kms_name
, sizeof(kms_name
), "KMS");
873 struct native_display
*
874 native_create_display(EGLNativeDisplayType dpy
,
875 struct native_event_handler
*event_handler
)
877 struct native_display
*ndpy
= NULL
;
880 drm_api
= drm_api_create();
883 ndpy
= kms_create_display(dpy
, event_handler
, drm_api
);