SDL 2.0
SDL_kmsdrmvideo.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22#include "../../SDL_internal.h"
23
24#if SDL_VIDEO_DRIVER_KMSDRM
25
26/* SDL internals */
27#include "../SDL_sysvideo.h"
28#include "SDL_syswm.h"
29#include "SDL_log.h"
30#include "SDL_hints.h"
31#include "../../events/SDL_mouse_c.h"
32#include "../../events/SDL_keyboard_c.h"
33
34#ifdef SDL_INPUT_LINUXEV
35#include "../../core/linux/SDL_evdev.h"
36#endif
37
38/* KMS/DRM declarations */
39#include "SDL_kmsdrmvideo.h"
40#include "SDL_kmsdrmevents.h"
41#include "SDL_kmsdrmopengles.h"
42#include "SDL_kmsdrmmouse.h"
43#include "SDL_kmsdrmdyn.h"
44#include <sys/stat.h>
45#include <dirent.h>
46#include <errno.h>
47
48#define KMSDRM_DRI_PATH "/dev/dri/"
49
50static int
51check_modestting(int devindex)
52{
54 char device[512];
55 int drm_fd;
56
57 SDL_snprintf(device, sizeof (device), "%scard%d", KMSDRM_DRI_PATH, devindex);
58
59 drm_fd = open(device, O_RDWR | O_CLOEXEC);
60 if (drm_fd >= 0) {
62 drmModeRes *resources = KMSDRM_drmModeGetResources(drm_fd);
63 if (resources != NULL) {
64 SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "%scard%d connector, encoder and CRTC counts are: %d %d %d",
65 KMSDRM_DRI_PATH, devindex,
66 resources->count_connectors, resources->count_encoders, resources->count_crtcs);
67
68 if (resources->count_connectors > 0 && resources->count_encoders > 0 && resources->count_crtcs > 0) {
70 }
71 KMSDRM_drmModeFreeResources(resources);
72 }
74 }
75 close(drm_fd);
76 }
77
78 return available;
79}
80
81static int get_dricount(void)
82{
83 int devcount = 0;
84 struct dirent *res;
85 struct stat sb;
86 DIR *folder;
87
88 if (!(stat(KMSDRM_DRI_PATH, &sb) == 0
89 && S_ISDIR(sb.st_mode))) {
90 printf("The path %s cannot be opened or is not available\n",
91 KMSDRM_DRI_PATH);
92 return 0;
93 }
94
95 if (access(KMSDRM_DRI_PATH, F_OK) == -1) {
96 printf("The path %s cannot be opened\n",
97 KMSDRM_DRI_PATH);
98 return 0;
99 }
100
101 folder = opendir(KMSDRM_DRI_PATH);
102 if (folder) {
103 while ((res = readdir(folder))) {
104 int len = SDL_strlen(res->d_name);
105 if (len > 4 && SDL_strncmp(res->d_name, "card", 4) == 0) {
106 devcount++;
107 }
108 }
109 closedir(folder);
110 }
111
112 return devcount;
113}
114
115static int
116get_driindex(void)
117{
118 const int devcount = get_dricount();
119 int i;
120
121 for (i = 0; i < devcount; i++) {
122 if (check_modestting(i)) {
123 return i;
124 }
125 }
126
127 return -ENOENT;
128}
129
130static int
131KMSDRM_Available(void)
132{
133 int ret = -ENOENT;
134
135 ret = get_driindex();
136 if (ret >= 0)
137 return 1;
138
139 return ret;
140}
141
142static void
143KMSDRM_Destroy(SDL_VideoDevice * device)
144{
145 if (device->driverdata != NULL) {
146 SDL_free(device->driverdata);
147 device->driverdata = NULL;
148 }
149
152}
153
154static SDL_VideoDevice *
155KMSDRM_Create(int devindex)
156{
158 SDL_VideoData *vdata;
159
160 if (!devindex || (devindex > 99)) {
161 devindex = get_driindex();
162 }
163
164 if (devindex < 0) {
165 SDL_SetError("devindex (%d) must be between 0 and 99.\n", devindex);
166 return NULL;
167 }
168
169 if (!SDL_KMSDRM_LoadSymbols()) {
170 return NULL;
171 }
172
173 /* Initialize SDL_VideoDevice structure */
175 if (device == NULL) {
177 return NULL;
178 }
179
180 /* Initialize internal data */
181 vdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
182 if (vdata == NULL) {
184 goto cleanup;
185 }
186 vdata->devindex = devindex;
187 vdata->drm_fd = -1;
188
189 device->driverdata = vdata;
190
191 /* Setup amount of available displays and current display */
192 device->num_displays = 0;
193
194 /* Set device free function */
195 device->free = KMSDRM_Destroy;
196
197 /* Setup all functions which we can handle */
198 device->VideoInit = KMSDRM_VideoInit;
199 device->VideoQuit = KMSDRM_VideoQuit;
200 device->GetDisplayModes = KMSDRM_GetDisplayModes;
201 device->SetDisplayMode = KMSDRM_SetDisplayMode;
202 device->CreateSDLWindow = KMSDRM_CreateWindow;
203 device->CreateSDLWindowFrom = KMSDRM_CreateWindowFrom;
204 device->SetWindowTitle = KMSDRM_SetWindowTitle;
205 device->SetWindowIcon = KMSDRM_SetWindowIcon;
206 device->SetWindowPosition = KMSDRM_SetWindowPosition;
207 device->SetWindowSize = KMSDRM_SetWindowSize;
208 device->ShowWindow = KMSDRM_ShowWindow;
209 device->HideWindow = KMSDRM_HideWindow;
210 device->RaiseWindow = KMSDRM_RaiseWindow;
211 device->MaximizeWindow = KMSDRM_MaximizeWindow;
212 device->MinimizeWindow = KMSDRM_MinimizeWindow;
213 device->RestoreWindow = KMSDRM_RestoreWindow;
214 device->SetWindowGrab = KMSDRM_SetWindowGrab;
215 device->DestroyWindow = KMSDRM_DestroyWindow;
216 device->GetWindowWMInfo = KMSDRM_GetWindowWMInfo;
217#if SDL_VIDEO_OPENGL_EGL
218 device->GL_LoadLibrary = KMSDRM_GLES_LoadLibrary;
219 device->GL_GetProcAddress = KMSDRM_GLES_GetProcAddress;
220 device->GL_UnloadLibrary = KMSDRM_GLES_UnloadLibrary;
221 device->GL_CreateContext = KMSDRM_GLES_CreateContext;
222 device->GL_MakeCurrent = KMSDRM_GLES_MakeCurrent;
223 device->GL_SetSwapInterval = KMSDRM_GLES_SetSwapInterval;
224 device->GL_GetSwapInterval = KMSDRM_GLES_GetSwapInterval;
225 device->GL_SwapWindow = KMSDRM_GLES_SwapWindow;
226 device->GL_DeleteContext = KMSDRM_GLES_DeleteContext;
227#endif
228
229 device->PumpEvents = KMSDRM_PumpEvents;
230
231 return device;
232
233cleanup:
234 if (device != NULL)
236 if (vdata != NULL)
237 SDL_free(vdata);
238 return NULL;
239}
240
242 "KMSDRM",
243 "KMS/DRM Video Driver",
244 KMSDRM_Available,
245 KMSDRM_Create
246};
247
248
249static void
250KMSDRM_FBDestroyCallback(struct gbm_bo *bo, void *data)
251{
252 KMSDRM_FBInfo *fb_info = (KMSDRM_FBInfo *)data;
253
254 if (fb_info && fb_info->drm_fd >= 0 && fb_info->fb_id != 0) {
255 KMSDRM_drmModeRmFB(fb_info->drm_fd, fb_info->fb_id);
256 SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Delete DRM FB %u", fb_info->fb_id);
257 }
258
259 SDL_free(fb_info);
260}
261
263KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
264{
266 int ret;
268 KMSDRM_FBInfo *fb_info;
269
270 fb_info = (KMSDRM_FBInfo *)KMSDRM_gbm_bo_get_user_data(bo);
271 if (fb_info != NULL) {
272 /* Have a previously used framebuffer, return it */
273 return fb_info;
274 }
275
276 /* Here a new DRM FB must be created */
277 fb_info = (KMSDRM_FBInfo *)SDL_calloc(1, sizeof(KMSDRM_FBInfo));
278 if (fb_info == NULL) {
280 return NULL;
281 }
282 fb_info->drm_fd = vdata->drm_fd;
283
284 w = KMSDRM_gbm_bo_get_width(bo);
285 h = KMSDRM_gbm_bo_get_height(bo);
286 stride = KMSDRM_gbm_bo_get_stride(bo);
287 handle = KMSDRM_gbm_bo_get_handle(bo).u32;
288
289 ret = KMSDRM_drmModeAddFB(vdata->drm_fd, w, h, 24, 32, stride, handle, &fb_info->fb_id);
290 if (ret < 0) {
291 SDL_free(fb_info);
292 return NULL;
293 }
294 SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "New DRM FB (%u): %ux%u, stride %u from BO %p", fb_info->fb_id, w, h, stride, (void *)bo);
295
296 /* Associate our DRM framebuffer with this buffer object */
297 KMSDRM_gbm_bo_set_user_data(bo, fb_info, KMSDRM_FBDestroyCallback);
298 return fb_info;
299}
300
304
305 while (wdata->waiting_for_flip) {
306 vdata->drm_pollfd.revents = 0;
307 if (poll(&vdata->drm_pollfd, 1, timeout) < 0) {
308 SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll error");
309 return SDL_FALSE;
310 }
311
312 if (vdata->drm_pollfd.revents & (POLLHUP | POLLERR)) {
313 SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll hup or error");
314 return SDL_FALSE;
315 }
316
317 if (vdata->drm_pollfd.revents & POLLIN) {
318 /* Page flip? If so, drmHandleEvent will unset wdata->waiting_for_flip */
319 KMSDRM_drmHandleEvent(vdata->drm_fd, &vdata->drm_evctx);
320 } else {
321 /* Timed out and page flip didn't happen */
322 SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Dropping frame while waiting_for_flip");
323 return SDL_FALSE;
324 }
325 }
326 return SDL_TRUE;
327}
328
329static void
330KMSDRM_FlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
331{
332 *((SDL_bool *) data) = SDL_FALSE;
333}
334
335
336/*****************************************************************************/
337/* SDL Video and Display initialization/handling functions */
338/* _this is a SDL_VideoDevice * */
339/*****************************************************************************/
340int
342{
343 int i, j;
344 SDL_bool found;
345 int ret = 0;
346 char *devname;
348 drmModeRes *resources = NULL;
349 drmModeConnector *connector = NULL;
350 drmModeEncoder *encoder = NULL;
351 SDL_DisplayMode current_mode;
352 SDL_VideoDisplay display;
353
354 /* Allocate display internal data */
356 if (data == NULL) {
357 return SDL_OutOfMemory();
358 }
359
360 SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoInit()");
361
362 /* Open /dev/dri/cardNN */
363 devname = (char *) SDL_calloc(1, 16);
364 if (devname == NULL) {
365 ret = SDL_OutOfMemory();
366 goto cleanup;
367 }
368 SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opening device /dev/dri/card%d", vdata->devindex);
369 SDL_snprintf(devname, 16, "/dev/dri/card%d", vdata->devindex);
370 vdata->drm_fd = open(devname, O_RDWR | O_CLOEXEC);
371 SDL_free(devname);
372
373 if (vdata->drm_fd < 0) {
374 ret = SDL_SetError("Could not open /dev/dri/card%d.", vdata->devindex);
375 goto cleanup;
376 }
377 SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", vdata->drm_fd);
378
379 vdata->gbm = KMSDRM_gbm_create_device(vdata->drm_fd);
380 if (vdata->gbm == NULL) {
381 ret = SDL_SetError("Couldn't create gbm device.");
382 goto cleanup;
383 }
384
385 /* Find the first available connector with modes */
386 resources = KMSDRM_drmModeGetResources(vdata->drm_fd);
387 if (!resources) {
388 ret = SDL_SetError("drmModeGetResources(%d) failed", vdata->drm_fd);
389 goto cleanup;
390 }
391
392 for (i = 0; i < resources->count_connectors; i++) {
393 connector = KMSDRM_drmModeGetConnector(vdata->drm_fd, resources->connectors[i]);
394 if (connector == NULL)
395 continue;
396
397 if (connector->connection == DRM_MODE_CONNECTED &&
398 connector->count_modes > 0) {
399 SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found connector %d with %d modes.",
400 connector->connector_id, connector->count_modes);
401 vdata->saved_conn_id = connector->connector_id;
402 break;
403 }
404
405 KMSDRM_drmModeFreeConnector(connector);
406 connector = NULL;
407 }
408
409 if (i == resources->count_connectors) {
410 ret = SDL_SetError("No currently active connector found.");
411 goto cleanup;
412 }
413
414 found = SDL_FALSE;
415
416 for (i = 0; i < resources->count_encoders; i++) {
417 encoder = KMSDRM_drmModeGetEncoder(vdata->drm_fd, resources->encoders[i]);
418
419 if (encoder == NULL)
420 continue;
421
422 if (encoder->encoder_id == connector->encoder_id) {
423 data->encoder_id = encoder->encoder_id;
424 found = SDL_TRUE;
425 } else {
426 for (j = 0; j < connector->count_encoders; j++) {
427 if (connector->encoders[j] == encoder->encoder_id) {
428 data->encoder_id = encoder->encoder_id;
429 found = SDL_TRUE;
430 break;
431 }
432 }
433 }
434
435 if (found == SDL_TRUE) {
436 SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", data->encoder_id);
437 break;
438 }
439
440 KMSDRM_drmModeFreeEncoder(encoder);
441 encoder = NULL;
442 }
443
444 if (i == resources->count_encoders) {
445 ret = SDL_SetError("No connected encoder found.");
446 goto cleanup;
447 }
448
449 vdata->saved_crtc = KMSDRM_drmModeGetCrtc(vdata->drm_fd, encoder->crtc_id);
450
451 if (vdata->saved_crtc == NULL) {
452 for (i = 0; i < resources->count_crtcs; i++) {
453 if (encoder->possible_crtcs & (1 << i)) {
454 encoder->crtc_id = resources->crtcs[i];
455 SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Set encoder's CRTC to %d.", encoder->crtc_id);
456 vdata->saved_crtc = KMSDRM_drmModeGetCrtc(vdata->drm_fd, encoder->crtc_id);
457 break;
458 }
459 }
460 }
461
462 if (vdata->saved_crtc == NULL) {
463 ret = SDL_SetError("No CRTC found.");
464 goto cleanup;
465 }
466 SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Saved crtc_id %u, fb_id %u, (%u,%u), %ux%u",
467 vdata->saved_crtc->crtc_id, vdata->saved_crtc->buffer_id, vdata->saved_crtc->x,
468 vdata->saved_crtc->y, vdata->saved_crtc->width, vdata->saved_crtc->height);
469 data->crtc_id = encoder->crtc_id;
470 data->cur_mode = vdata->saved_crtc->mode;
471 vdata->crtc_id = encoder->crtc_id;
472
473 // select default mode if this one is not valid
474 if (vdata->saved_crtc->mode_valid == 0) {
476 "Current mode is invalid, selecting connector's mode #0.");
477 data->cur_mode = connector->modes[0];
478 }
479
480 SDL_zero(current_mode);
481
482 current_mode.w = data->cur_mode.hdisplay;
483 current_mode.h = data->cur_mode.vdisplay;
484 current_mode.refresh_rate = data->cur_mode.vrefresh;
485
486 /* FIXME ?
487 drmModeFB *fb = drmModeGetFB(vdata->drm_fd, vdata->saved_crtc->buffer_id);
488 current_mode.format = drmToSDLPixelFormat(fb->bpp, fb->depth);
489 drmModeFreeFB(fb);
490 */
491 current_mode.format = SDL_PIXELFORMAT_ARGB8888;
492
493 current_mode.driverdata = NULL;
494
495 SDL_zero(display);
496 display.desktop_mode = current_mode;
497 display.current_mode = current_mode;
498
499 display.driverdata = data;
500 /* SDL_VideoQuit will later SDL_free(display.driverdata) */
501 SDL_AddVideoDisplay(&display);
502
503 /* Setup page flip handler */
504 vdata->drm_pollfd.fd = vdata->drm_fd;
505 vdata->drm_pollfd.events = POLLIN;
506 vdata->drm_evctx.version = DRM_EVENT_CONTEXT_VERSION;
507 vdata->drm_evctx.page_flip_handler = KMSDRM_FlipHandler;
508
509#ifdef SDL_INPUT_LINUXEV
510 SDL_EVDEV_Init();
511#endif
512
514
515 return ret;
516
517cleanup:
518 if (encoder != NULL)
519 KMSDRM_drmModeFreeEncoder(encoder);
520 if (connector != NULL)
521 KMSDRM_drmModeFreeConnector(connector);
522 if (resources != NULL)
523 KMSDRM_drmModeFreeResources(resources);
524
525 if (ret != 0) {
526 /* Error (complete) cleanup */
527 SDL_free(data);
528 if(vdata->saved_crtc != NULL) {
529 KMSDRM_drmModeFreeCrtc(vdata->saved_crtc);
530 vdata->saved_crtc = NULL;
531 }
532 if (vdata->gbm != NULL) {
533 KMSDRM_gbm_device_destroy(vdata->gbm);
534 vdata->gbm = NULL;
535 }
536 if (vdata->drm_fd >= 0) {
537 close(vdata->drm_fd);
538 vdata->drm_fd = -1;
539 }
540 }
541 return ret;
542}
543
544void
546{
548
549 SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoQuit()");
550
553 }
554
555 if(vdata->saved_crtc != NULL) {
556 if(vdata->drm_fd >= 0 && vdata->saved_conn_id > 0) {
557 /* Restore saved CRTC settings */
558 drmModeCrtc *crtc = vdata->saved_crtc;
559 if(KMSDRM_drmModeSetCrtc(vdata->drm_fd, crtc->crtc_id, crtc->buffer_id,
560 crtc->x, crtc->y, &vdata->saved_conn_id, 1,
561 &crtc->mode) != 0) {
562 SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not restore original CRTC mode");
563 }
564 }
565 KMSDRM_drmModeFreeCrtc(vdata->saved_crtc);
566 vdata->saved_crtc = NULL;
567 }
568 if (vdata->gbm != NULL) {
569 KMSDRM_gbm_device_destroy(vdata->gbm);
570 vdata->gbm = NULL;
571 }
572 if (vdata->drm_fd >= 0) {
573 close(vdata->drm_fd);
574 SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Closed DRM FD %d", vdata->drm_fd);
575 vdata->drm_fd = -1;
576 }
577#ifdef SDL_INPUT_LINUXEV
578 SDL_EVDEV_Quit();
579#endif
580}
581
582void
584{
585 /* Only one display mode available, the current one */
586 SDL_AddDisplayMode(display, &display->current_mode);
587}
588
589int
591{
592 return 0;
593}
594
595int
597{
598 SDL_WindowData *wdata;
599 SDL_VideoDisplay *display;
601 Uint32 surface_fmt, surface_flags;
602
603 /* Allocate window internal data */
604 wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
605 if (wdata == NULL) {
607 goto error;
608 }
609
612
613 /* Windows have one size for now */
614 window->w = display->desktop_mode.w;
615 window->h = display->desktop_mode.h;
616
617 /* Maybe you didn't ask for a fullscreen OpenGL window, but that's what you get */
619
620 surface_fmt = GBM_FORMAT_XRGB8888;
621 surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
622
623 if (!KMSDRM_gbm_device_is_format_supported(vdata->gbm, surface_fmt, surface_flags)) {
624 SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "GBM surface format not supported. Trying anyway.");
625 }
626 wdata->gs = KMSDRM_gbm_surface_create(vdata->gbm, window->w, window->h, surface_fmt, surface_flags);
627
628#if SDL_VIDEO_OPENGL_EGL
629 if (!_this->egl_data) {
630 if (SDL_GL_LoadLibrary(NULL) < 0) {
631 goto error;
632 }
633 }
634 SDL_EGL_SetRequiredVisualId(_this, surface_fmt);
635 wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wdata->gs);
636
637 if (wdata->egl_surface == EGL_NO_SURFACE) {
638 SDL_SetError("Could not create EGL window surface");
639 goto error;
640 }
641#endif /* SDL_VIDEO_OPENGL_EGL */
642
643 /* In case we want low-latency, double-buffer video, we take note here */
644 wdata->double_buffer = SDL_FALSE;
646 wdata->double_buffer = SDL_TRUE;
647 }
648
649 /* Window is created, but we have yet to set up CRTC to one of the GBM buffers if we want
650 drmModePageFlip to work, and we can't do it until EGL is completely setup, because we
651 need to do eglSwapBuffers so we can get a valid GBM buffer object to call
652 drmModeSetCrtc on it. */
653 wdata->crtc_ready = SDL_FALSE;
654
655 /* Setup driver data for this window */
656 window->driverdata = wdata;
657
658 /* One window, it always has focus */
661
662 /* Window has been successfully created */
663 return 0;
664
665error:
666 if (wdata != NULL) {
667#if SDL_VIDEO_OPENGL_EGL
668 if (wdata->egl_surface != EGL_NO_SURFACE)
669 SDL_EGL_DestroySurface(_this, wdata->egl_surface);
670#endif /* SDL_VIDEO_OPENGL_EGL */
671 if (wdata->gs != NULL)
672 KMSDRM_gbm_surface_destroy(wdata->gs);
673 SDL_free(wdata);
674 }
675 return -1;
676}
677
678void
680{
681 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
682 if(data) {
683 /* Wait for any pending page flips and unlock buffer */
685 if (data->crtc_bo != NULL) {
686 KMSDRM_gbm_surface_release_buffer(data->gs, data->crtc_bo);
687 data->crtc_bo = NULL;
688 }
689 if (data->next_bo != NULL) {
690 KMSDRM_gbm_surface_release_buffer(data->gs, data->next_bo);
691 data->next_bo = NULL;
692 }
693 if (data->current_bo != NULL) {
694 KMSDRM_gbm_surface_release_buffer(data->gs, data->current_bo);
695 data->current_bo = NULL;
696 }
697#if SDL_VIDEO_OPENGL_EGL
698 SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, EGL_NO_CONTEXT);
699 if (data->egl_surface != EGL_NO_SURFACE) {
700 SDL_EGL_DestroySurface(_this, data->egl_surface);
701 }
702#endif /* SDL_VIDEO_OPENGL_EGL */
703 if (data->gs != NULL) {
704 KMSDRM_gbm_surface_destroy(data->gs);
705 data->gs = NULL;
706 }
707 SDL_free(data);
708 window->driverdata = NULL;
709 }
710}
711
712int
714{
715 return -1;
716}
717
718void
720{
721}
722void
724{
725}
726void
728{
729}
730void
732{
733}
734void
736{
737}
738void
740{
741}
742void
744{
745}
746void
748{
749}
750void
752{
753}
754void
756{
757}
758void
760{
761
762}
763
764/*****************************************************************************/
765/* SDL Window Manager function */
766/*****************************************************************************/
769{
770 if (info->version.major <= SDL_MAJOR_VERSION) {
771 return SDL_TRUE;
772 } else {
773 SDL_SetError("application not compiled with SDL %d.%d\n",
775 return SDL_FALSE;
776 }
777
778 /* Failed to get window manager information */
779 return SDL_FALSE;
780}
781
782#endif /* SDL_VIDEO_DRIVER_KMSDRM */
783
784/* vi: set ts=4 sw=4 expandtab: */
#define _THIS
unsigned int uint32_t
#define SDL_SetError
#define SDL_strncmp
#define SDL_GL_LoadLibrary
#define SDL_strlen
#define SDL_LogError
#define SDL_free
#define SDL_GetHintBoolean
#define SDL_GL_UnloadLibrary
#define SDL_LogDebug
#define SDL_LogWarn
#define SDL_snprintf
#define SDL_calloc
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_HINT_VIDEO_DOUBLE_BUFFER
Tell the video driver that we only want a double buffer.
Definition: SDL_hints.h:993
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:630
int SDL_KMSDRM_LoadSymbols(void)
void SDL_KMSDRM_UnloadSymbols(void)
void KMSDRM_PumpEvents(_THIS)
void KMSDRM_InitMouse(_THIS)
void KMSDRM_RaiseWindow(_THIS, SDL_Window *window)
int KMSDRM_GLES_SetSwapInterval(_THIS, int interval)
void KMSDRM_RestoreWindow(_THIS, SDL_Window *window)
SDL_bool KMSDRM_WaitPageFlip(_THIS, SDL_WindowData *wdata, int timeout)
int KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
void KMSDRM_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
void KMSDRM_ShowWindow(_THIS, SDL_Window *window)
int KMSDRM_GLES_LoadLibrary(_THIS, const char *path)
void KMSDRM_MaximizeWindow(_THIS, SDL_Window *window)
int KMSDRM_CreateWindow(_THIS, SDL_Window *window)
void KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
void KMSDRM_SetWindowSize(_THIS, SDL_Window *window)
void KMSDRM_SetWindowPosition(_THIS, SDL_Window *window)
void KMSDRM_GLES_DeleteContext(_THIS, SDL_GLContext context)
void KMSDRM_HideWindow(_THIS, SDL_Window *window)
void KMSDRM_MinimizeWindow(_THIS, SDL_Window *window)
void KMSDRM_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
void KMSDRM_VideoQuit(_THIS)
int KMSDRM_VideoInit(_THIS)
void KMSDRM_SetWindowTitle(_THIS, SDL_Window *window)
void * KMSDRM_GLES_GetProcAddress(_THIS, const char *proc)
SDL_bool KMSDRM_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
int KMSDRM_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
SDL_GLContext KMSDRM_GLES_CreateContext(_THIS, SDL_Window *window)
void KMSDRM_GLES_UnloadLibrary(_THIS)
int KMSDRM_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
KMSDRM_FBInfo * KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
int KMSDRM_GLES_GetSwapInterval(_THIS)
int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window *window)
void KMSDRM_DestroyWindow(_THIS, SDL_Window *window)
@ SDL_LOG_CATEGORY_VIDEO
Definition: SDL_log.h:71
void SDL_SetMouseFocus(SDL_Window *window)
Definition: SDL_mouse.c:211
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLsizei stride
GLuint res
GLenum mode
GLbitfield GLuint64 timeout
GLenum GLsizei len
GLuint GLint GLboolean GLint GLenum access
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
@ SDL_PIXELFORMAT_ARGB8888
Definition: SDL_pixels.h:248
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
@ SDL_FALSE
Definition: SDL_stdinc.h:163
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1089
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
Definition: SDL_video.c:603
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
Definition: SDL_video.c:751
VideoBootStrap KMSDRM_bootstrap
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
static SDL_VideoDevice * _this
Definition: SDL_video.c:118
@ SDL_WINDOW_OPENGL
Definition: SDL_video.h:101
@ SDL_WINDOW_FULLSCREEN
Definition: SDL_video.h:100
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
Definition: SDL_x11sym.h:50
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:167
#define EGL_NO_CONTEXT
Definition: egl.h:98
#define EGL_NO_SURFACE
Definition: egl.h:100
EGLImageKHR EGLint EGLint * handle
Definition: eglext.h:937
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
EGLNativeWindowType NativeWindowType
Definition: eglplatform.h:112
GLuint64 GLenum GLint fd
Definition: gl2ext.h:1508
static SDL_AudioDeviceID device
Definition: loopwave.c:37
The structure that defines a display mode.
Definition: SDL_video.h:54
void * driverdata
Definition: SDL_video.h:59
Uint32 format
Definition: SDL_video.h:55
A collection of pixels used in software blitting.
Definition: SDL_surface.h:71
SDL_version version
Definition: SDL_syswm.h:199
drmModeCrtc * saved_crtc
uint32_t saved_conn_id
uint32_t crtc_id
struct pollfd drm_pollfd
drmEventContext drm_evctx
struct gbm_device * gbm
struct SDL_VideoDevice::@262 gl_config
SDL_DisplayMode desktop_mode
Definition: SDL_sysvideo.h:131
SDL_DisplayMode current_mode
Definition: SDL_sysvideo.h:132
SDL_bool waiting_for_flip
SDL_bool double_buffer
SDL_bool crtc_ready
EGLSurface egl_surface
struct gbm_surface * gs
The type used to identify a window.
Definition: SDL_sysvideo.h:74
Uint8 major
Definition: SDL_version.h:53
static void cleanup(void)
Definition: testfile.c:44
int frame
Definition: teststreaming.c:60
static int available()
Definition: video.c:356