SDL  2.0
SDL_kmsdrmvideo.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 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 
45 #define KMSDRM_DRI_CARD_0 "/dev/dri/card0"
46 
47 static int
48 KMSDRM_Available(void)
49 {
50  int available = 0;
51 
52  int drm_fd = open(KMSDRM_DRI_CARD_0, O_RDWR | O_CLOEXEC);
53  if (drm_fd >= 0) {
54  if (SDL_KMSDRM_LoadSymbols()) {
55  drmModeRes *resources = KMSDRM_drmModeGetResources(drm_fd);
56  if (resources != NULL) {
57  available = 1;
58  KMSDRM_drmModeFreeResources(resources);
59  }
61  }
62  close(drm_fd);
63  }
64 
65  return available;
66 }
67 
68 static void
69 KMSDRM_Destroy(SDL_VideoDevice * device)
70 {
71  if (device->driverdata != NULL) {
72  SDL_free(device->driverdata);
73  device->driverdata = NULL;
74  }
75 
76  SDL_free(device);
78 }
79 
80 static SDL_VideoDevice *
81 KMSDRM_Create(int devindex)
82 {
84  SDL_VideoData *vdata;
85 
86  if (devindex < 0 || devindex > 99) {
87  SDL_SetError("devindex (%d) must be between 0 and 99.\n", devindex);
88  return NULL;
89  }
90 
91  if (!SDL_KMSDRM_LoadSymbols()) {
92  return NULL;
93  }
94 
95  /* Initialize SDL_VideoDevice structure */
96  device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
97  if (device == NULL) {
99  return NULL;
100  }
101 
102  /* Initialize internal data */
103  vdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
104  if (vdata == NULL) {
105  SDL_OutOfMemory();
106  goto cleanup;
107  }
108  vdata->devindex = devindex;
109  vdata->drm_fd = -1;
110 
111  device->driverdata = vdata;
112 
113  /* Setup amount of available displays and current display */
114  device->num_displays = 0;
115 
116  /* Set device free function */
117  device->free = KMSDRM_Destroy;
118 
119  /* Setup all functions which we can handle */
120  device->VideoInit = KMSDRM_VideoInit;
121  device->VideoQuit = KMSDRM_VideoQuit;
130  device->ShowWindow = KMSDRM_ShowWindow;
131  device->HideWindow = KMSDRM_HideWindow;
139 #if SDL_VIDEO_OPENGL_EGL
149 #endif
150 
151  device->PumpEvents = KMSDRM_PumpEvents;
152 
153  return device;
154 
155 cleanup:
156  if (device != NULL)
157  SDL_free(device);
158  if (vdata != NULL)
159  SDL_free(vdata);
160  return NULL;
161 }
162 
164  "KMSDRM",
165  "KMS/DRM Video Driver",
166  KMSDRM_Available,
167  KMSDRM_Create
168 };
169 
170 
171 static void
172 KMSDRM_FBDestroyCallback(struct gbm_bo *bo, void *data)
173 {
174  KMSDRM_FBInfo *fb_info = (KMSDRM_FBInfo *)data;
175 
176  if (fb_info && fb_info->drm_fd > 0 && fb_info->fb_id != 0) {
177  KMSDRM_drmModeRmFB(fb_info->drm_fd, fb_info->fb_id);
178  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Delete DRM FB %u", fb_info->fb_id);
179  }
180 
181  free(fb_info);
182 }
183 
185 KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
186 {
187  uint32_t w, h, stride, handle;
188  int ret;
190  KMSDRM_FBInfo *fb_info;
191 
192  fb_info = (KMSDRM_FBInfo *)KMSDRM_gbm_bo_get_user_data(bo);
193  if (fb_info != NULL) {
194  /* Have a previously used framebuffer, return it */
195  return fb_info;
196  }
197 
198  /* Here a new DRM FB must be created */
199  fb_info = (KMSDRM_FBInfo *)SDL_calloc(1, sizeof(KMSDRM_FBInfo));
200  if (fb_info == NULL) {
201  SDL_OutOfMemory();
202  return NULL;
203  }
204  fb_info->drm_fd = vdata->drm_fd;
205 
206  w = KMSDRM_gbm_bo_get_width(bo);
207  h = KMSDRM_gbm_bo_get_height(bo);
208  stride = KMSDRM_gbm_bo_get_stride(bo);
209  handle = KMSDRM_gbm_bo_get_handle(bo).u32;
210 
211  ret = KMSDRM_drmModeAddFB(vdata->drm_fd, w, h, 24, 32, stride, handle, &fb_info->fb_id);
212  if (ret < 0) {
213  free(fb_info);
214  return NULL;
215  }
216  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);
217 
218  /* Associate our DRM framebuffer with this buffer object */
219  KMSDRM_gbm_bo_set_user_data(bo, fb_info, KMSDRM_FBDestroyCallback);
220  return fb_info;
221 }
222 
223 SDL_bool
226 
227  while (wdata->waiting_for_flip) {
228  vdata->drm_pollfd.revents = 0;
229  if (poll(&vdata->drm_pollfd, 1, timeout) < 0) {
230  SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll error");
231  return SDL_FALSE;
232  }
233 
234  if (vdata->drm_pollfd.revents & (POLLHUP | POLLERR)) {
235  SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll hup or error");
236  return SDL_FALSE;
237  }
238 
239  if (vdata->drm_pollfd.revents & POLLIN) {
240  /* Page flip? If so, drmHandleEvent will unset wdata->waiting_for_flip */
241  KMSDRM_drmHandleEvent(vdata->drm_fd, &vdata->drm_evctx);
242  } else {
243  /* Timed out and page flip didn't happen */
244  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Dropping frame while waiting_for_flip");
245  return SDL_FALSE;
246  }
247  }
248  return SDL_TRUE;
249 }
250 
251 static void
252 KMSDRM_FlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
253 {
254  *((SDL_bool *) data) = SDL_FALSE;
255 }
256 
257 
258 /*****************************************************************************/
259 /* SDL Video and Display initialization/handling functions */
260 /* _this is a SDL_VideoDevice * */
261 /*****************************************************************************/
262 int
264 {
265  int i;
266  int ret = 0;
267  char *devname;
269  drmModeRes *resources = NULL;
270  drmModeConnector *connector = NULL;
271  drmModeEncoder *encoder = NULL;
272  SDL_DisplayMode current_mode;
273  SDL_VideoDisplay display;
274 
275  /* Allocate display internal data */
277  if (data == NULL) {
278  return SDL_OutOfMemory();
279  }
280 
281  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoInit()");
282 
283  /* Open /dev/dri/cardNN */
284  devname = (char *) SDL_calloc(1, 16);
285  if (devname == NULL) {
286  ret = SDL_OutOfMemory();
287  goto cleanup;
288  }
289  SDL_snprintf(devname, 16, "/dev/dri/card%d", vdata->devindex);
290  vdata->drm_fd = open(devname, O_RDWR | O_CLOEXEC);
291  SDL_free(devname);
292 
293  if (vdata->drm_fd < 0) {
294  ret = SDL_SetError("Could not open /dev/dri/card%d.", vdata->devindex);
295  goto cleanup;
296  }
297  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", vdata->drm_fd);
298 
299  vdata->gbm = KMSDRM_gbm_create_device(vdata->drm_fd);
300  if (vdata->gbm == NULL) {
301  ret = SDL_SetError("Couldn't create gbm device.");
302  goto cleanup;
303  }
304 
305  /* Find the first available connector with modes */
306  resources = KMSDRM_drmModeGetResources(vdata->drm_fd);
307  if (!resources) {
308  ret = SDL_SetError("drmModeGetResources(%d) failed", vdata->drm_fd);
309  goto cleanup;
310  }
311 
312  for (i = 0; i < resources->count_connectors; i++) {
313  connector = KMSDRM_drmModeGetConnector(vdata->drm_fd, resources->connectors[i]);
314  if (connector == NULL)
315  continue;
316 
317  if (connector->connection == DRM_MODE_CONNECTED &&
318  connector->count_modes > 0) {
319  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found connector %d with %d modes.",
320  connector->connector_id, connector->count_modes);
321  vdata->saved_conn_id = connector->connector_id;
322  break;
323  }
324 
325  KMSDRM_drmModeFreeConnector(connector);
326  connector = NULL;
327  }
328 
329  if (i == resources->count_connectors) {
330  ret = SDL_SetError("No currently active connector found.");
331  goto cleanup;
332  }
333 
334  for (i = 0; i < resources->count_encoders; i++) {
335  encoder = KMSDRM_drmModeGetEncoder(vdata->drm_fd, resources->encoders[i]);
336 
337  if (encoder == NULL)
338  continue;
339 
340  if (encoder->encoder_id == connector->encoder_id) {
341  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", encoder->encoder_id);
342  data->encoder_id = encoder->encoder_id;
343  break;
344  }
345 
346  KMSDRM_drmModeFreeEncoder(encoder);
347  encoder = NULL;
348  }
349 
350  if (i == resources->count_encoders) {
351  ret = SDL_SetError("No connected encoder found.");
352  goto cleanup;
353  }
354 
355  vdata->saved_crtc = KMSDRM_drmModeGetCrtc(vdata->drm_fd, encoder->crtc_id);
356  if (vdata->saved_crtc == NULL) {
357  ret = SDL_SetError("No CRTC found.");
358  goto cleanup;
359  }
360  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Saved crtc_id %u, fb_id %u, (%u,%u), %ux%u",
361  vdata->saved_crtc->crtc_id, vdata->saved_crtc->buffer_id, vdata->saved_crtc->x,
362  vdata->saved_crtc->y, vdata->saved_crtc->width, vdata->saved_crtc->height);
363  data->crtc_id = encoder->crtc_id;
364  data->cur_mode = vdata->saved_crtc->mode;
365  vdata->crtc_id = encoder->crtc_id;
366 
367  SDL_zero(current_mode);
368 
369  current_mode.w = vdata->saved_crtc->mode.hdisplay;
370  current_mode.h = vdata->saved_crtc->mode.vdisplay;
371  current_mode.refresh_rate = vdata->saved_crtc->mode.vrefresh;
372 
373  /* FIXME ?
374  drmModeFB *fb = drmModeGetFB(vdata->drm_fd, vdata->saved_crtc->buffer_id);
375  current_mode.format = drmToSDLPixelFormat(fb->bpp, fb->depth);
376  drmModeFreeFB(fb);
377  */
378  current_mode.format = SDL_PIXELFORMAT_ARGB8888;
379 
380  current_mode.driverdata = NULL;
381 
382  SDL_zero(display);
383  display.desktop_mode = current_mode;
384  display.current_mode = current_mode;
385 
386  display.driverdata = data;
387  /* SDL_VideoQuit will later SDL_free(display.driverdata) */
388  SDL_AddVideoDisplay(&display);
389 
390  /* Setup page flip handler */
391  vdata->drm_pollfd.fd = vdata->drm_fd;
392  vdata->drm_pollfd.events = POLLIN;
393  vdata->drm_evctx.version = DRM_EVENT_CONTEXT_VERSION;
394  vdata->drm_evctx.page_flip_handler = KMSDRM_FlipHandler;
395 
396 #ifdef SDL_INPUT_LINUXEV
397  SDL_EVDEV_Init();
398 #endif
399 
401 
402 cleanup:
403  if (encoder != NULL)
404  KMSDRM_drmModeFreeEncoder(encoder);
405  if (connector != NULL)
406  KMSDRM_drmModeFreeConnector(connector);
407  if (resources != NULL)
408  KMSDRM_drmModeFreeResources(resources);
409 
410  if (ret != 0) {
411  /* Error (complete) cleanup */
412  SDL_free(data);
413  if(vdata->saved_crtc != NULL) {
414  KMSDRM_drmModeFreeCrtc(vdata->saved_crtc);
415  vdata->saved_crtc = NULL;
416  }
417  if (vdata->gbm != NULL) {
418  KMSDRM_gbm_device_destroy(vdata->gbm);
419  vdata->gbm = NULL;
420  }
421  if (vdata->drm_fd >= 0) {
422  close(vdata->drm_fd);
423  vdata->drm_fd = -1;
424  }
425  }
426  return ret;
427 }
428 
429 void
431 {
433 
434  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoQuit()");
435 
438  }
439 
440  if(vdata->saved_crtc != NULL) {
441  if(vdata->drm_fd > 0 && vdata->saved_conn_id > 0) {
442  /* Restore saved CRTC settings */
443  drmModeCrtc *crtc = vdata->saved_crtc;
444  if(KMSDRM_drmModeSetCrtc(vdata->drm_fd, crtc->crtc_id, crtc->buffer_id,
445  crtc->x, crtc->y, &vdata->saved_conn_id, 1,
446  &crtc->mode) != 0) {
447  SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not restore original CRTC mode");
448  }
449  }
450  KMSDRM_drmModeFreeCrtc(vdata->saved_crtc);
451  vdata->saved_crtc = NULL;
452  }
453  if (vdata->gbm != NULL) {
454  KMSDRM_gbm_device_destroy(vdata->gbm);
455  vdata->gbm = NULL;
456  }
457  if (vdata->drm_fd >= 0) {
458  close(vdata->drm_fd);
459  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Closed DRM FD %d", vdata->drm_fd);
460  vdata->drm_fd = -1;
461  }
462 #ifdef SDL_INPUT_LINUXEV
463  SDL_EVDEV_Quit();
464 #endif
465 }
466 
467 void
469 {
470  /* Only one display mode available, the current one */
471  SDL_AddDisplayMode(display, &display->current_mode);
472 }
473 
474 int
476 {
477  return 0;
478 }
479 
480 int
482 {
483  SDL_WindowData *wdata;
484  SDL_VideoDisplay *display;
486  Uint32 surface_fmt, surface_flags;
487 
488  /* Allocate window internal data */
489  wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
490  if (wdata == NULL) {
491  SDL_OutOfMemory();
492  goto error;
493  }
494 
495  wdata->waiting_for_flip = SDL_FALSE;
496  display = SDL_GetDisplayForWindow(window);
497 
498  /* Windows have one size for now */
499  window->w = display->desktop_mode.w;
500  window->h = display->desktop_mode.h;
501 
502  /* Maybe you didn't ask for a fullscreen OpenGL window, but that's what you get */
504 
505  surface_fmt = GBM_FORMAT_XRGB8888;
506  surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
507 
508  if (!KMSDRM_gbm_device_is_format_supported(vdata->gbm, surface_fmt, surface_flags)) {
509  SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "GBM surface format not supported. Trying anyway.");
510  }
511  wdata->gs = KMSDRM_gbm_surface_create(vdata->gbm, window->w, window->h, surface_fmt, surface_flags);
512 
513 #if SDL_VIDEO_OPENGL_EGL
514  if (!_this->egl_data) {
515  if (SDL_GL_LoadLibrary(NULL) < 0) {
516  goto error;
517  }
518  }
519  wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wdata->gs);
520 
521  if (wdata->egl_surface == EGL_NO_SURFACE) {
522  SDL_SetError("Could not create EGL window surface");
523  goto error;
524  }
525 #endif /* SDL_VIDEO_OPENGL_EGL */
526 
527  /* In case we want low-latency, double-buffer video, we take note here */
528  wdata->double_buffer = SDL_FALSE;
530  wdata->double_buffer = SDL_TRUE;
531  }
532 
533  /* Window is created, but we have yet to set up CRTC to one of the GBM buffers if we want
534  drmModePageFlip to work, and we can't do it until EGL is completely setup, because we
535  need to do eglSwapBuffers so we can get a valid GBM buffer object to call
536  drmModeSetCrtc on it. */
537  wdata->crtc_ready = SDL_FALSE;
538 
539  /* Setup driver data for this window */
540  window->driverdata = wdata;
541 
542  /* One window, it always has focus */
543  SDL_SetMouseFocus(window);
544  SDL_SetKeyboardFocus(window);
545 
546  /* Window has been successfully created */
547  return 0;
548 
549 error:
550  if (wdata != NULL) {
551 #if SDL_VIDEO_OPENGL_EGL
552  if (wdata->egl_surface != EGL_NO_SURFACE)
553  SDL_EGL_DestroySurface(_this, wdata->egl_surface);
554 #endif /* SDL_VIDEO_OPENGL_EGL */
555  if (wdata->gs != NULL)
556  KMSDRM_gbm_surface_destroy(wdata->gs);
557  SDL_free(wdata);
558  }
559  return -1;
560 }
561 
562 void
564 {
565  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
566  if(data) {
567  /* Wait for any pending page flips and unlock buffer */
568  KMSDRM_WaitPageFlip(_this, data, -1);
569  if (data->next_bo != NULL) {
570  KMSDRM_gbm_surface_release_buffer(data->gs, data->next_bo);
571  data->next_bo = NULL;
572  }
573  if (data->current_bo != NULL) {
574  KMSDRM_gbm_surface_release_buffer(data->gs, data->current_bo);
575  data->current_bo = NULL;
576  }
577 #if SDL_VIDEO_OPENGL_EGL
578  SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, EGL_NO_CONTEXT);
579  if (data->egl_surface != EGL_NO_SURFACE) {
580  SDL_EGL_DestroySurface(_this, data->egl_surface);
581  }
582 #endif /* SDL_VIDEO_OPENGL_EGL */
583  if (data->gs != NULL) {
584  KMSDRM_gbm_surface_destroy(data->gs);
585  data->gs = NULL;
586  }
587  SDL_free(data);
588  window->driverdata = NULL;
589  }
590 }
591 
592 int
593 KMSDRM_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
594 {
595  return -1;
596 }
597 
598 void
600 {
601 }
602 void
604 {
605 }
606 void
608 {
609 }
610 void
612 {
613 }
614 void
616 {
617 }
618 void
620 {
621 }
622 void
624 {
625 }
626 void
628 {
629 }
630 void
632 {
633 }
634 void
636 {
637 }
638 void
639 KMSDRM_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
640 {
641 
642 }
643 
644 /*****************************************************************************/
645 /* SDL Window Manager function */
646 /*****************************************************************************/
647 SDL_bool
648 KMSDRM_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
649 {
650  if (info->version.major <= SDL_MAJOR_VERSION) {
651  return SDL_TRUE;
652  } else {
653  SDL_SetError("application not compiled with SDL %d.%d\n",
655  return SDL_FALSE;
656  }
657 
658  /* Failed to get window manager information */
659  return SDL_FALSE;
660 }
661 
662 #endif /* SDL_VIDEO_DRIVER_KMSDRM */
663 
664 /* vi: set ts=4 sw=4 expandtab: */
int KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
int KMSDRM_GLES_GetSwapInterval(_THIS)
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
SDL_bool double_buffer
GLsizei stride
void SDL_KMSDRM_UnloadSymbols(void)
drmModeModeInfo cur_mode
void KMSDRM_SetWindowSize(_THIS, SDL_Window *window)
void(* RestoreWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:227
void * KMSDRM_GLES_GetProcAddress(_THIS, const char *proc)
SDL_bool waiting_for_flip
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:630
#define EGL_NO_SURFACE
Definition: egl.h:100
struct pollfd drm_pollfd
VideoBootStrap KMSDRM_bootstrap
struct gbm_bo * current_bo
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
void KMSDRM_InitMouse(_THIS)
void KMSDRM_MaximizeWindow(_THIS, SDL_Window *window)
static int available()
Definition: video.c:356
void(* free)(_THIS)
Definition: SDL_sysvideo.h:390
GLfloat GLfloat GLfloat GLfloat h
SDL_EventEntry * free
Definition: SDL_events.c:84
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
int(* GL_SetSwapInterval)(_THIS, int interval)
Definition: SDL_sysvideo.h:260
void(* ShowWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:222
The structure that defines a display mode.
Definition: SDL_video.h:53
int KMSDRM_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
SDL_version version
Definition: SDL_syswm.h:196
Uint8 major
Definition: SDL_version.h:53
int SDL_KMSDRM_LoadSymbols(void)
void(* SetWindowSize)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:215
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
int KMSDRM_GLES_SetSwapInterval(_THIS, int interval)
int KMSDRM_GLES_LoadLibrary(_THIS, const char *path)
void SDL_SetMouseFocus(SDL_Window *window)
Definition: SDL_mouse.c:151
uint32_t Uint32
Definition: SDL_stdinc.h:181
void KMSDRM_GLES_UnloadLibrary(_THIS)
#define SDL_GL_LoadLibrary
SDL_GLContext KMSDRM_GLES_CreateContext(_THIS, SDL_Window *window)
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
Definition: SDL_video.c:606
int KMSDRM_CreateWindow(_THIS, SDL_Window *window)
int(* GL_LoadLibrary)(_THIS, const char *path)
Definition: SDL_sysvideo.h:254
int(* SetDisplayMode)(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
Definition: SDL_sysvideo.h:204
#define SDL_GetHintBoolean
#define SDL_LogError
static SDL_VideoDevice * _this
Definition: SDL_video.c:121
EGLNativeWindowType NativeWindowType
Definition: eglplatform.h:112
void(* HideWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:223
static SDL_AudioDeviceID device
Definition: loopwave.c:37
#define SDL_GL_UnloadLibrary
void KMSDRM_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
void(* RaiseWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:224
#define SDL_LogDebug
#define EGL_NO_CONTEXT
Definition: egl.h:98
SDL_bool(* GetWindowWMInfo)(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
Definition: SDL_sysvideo.h:247
SDL_GLContext(* GL_CreateContext)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:257
EGLImageKHR EGLint EGLint * handle
Definition: eglext.h:937
void KMSDRM_PumpEvents(_THIS)
int KMSDRM_VideoInit(_THIS)
#define _THIS
int(* GL_MakeCurrent)(_THIS, SDL_Window *window, SDL_GLContext context)
Definition: SDL_sysvideo.h:258
#define SDL_free
int frame
Definition: teststreaming.c:60
void * driverdata
Definition: SDL_video.h:59
int KMSDRM_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
SDL_DisplayMode current_mode
Definition: SDL_sysvideo.h:132
GLenum mode
GLubyte GLubyte GLubyte GLubyte w
void(* DestroyWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:234
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
void(* SetWindowIcon)(_THIS, SDL_Window *window, SDL_Surface *icon)
Definition: SDL_sysvideo.h:213
drmEventContext drm_evctx
void KMSDRM_RestoreWindow(_THIS, SDL_Window *window)
SDL_bool crtc_ready
void KMSDRM_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
void KMSDRM_HideWindow(_THIS, SDL_Window *window)
void(* GL_UnloadLibrary)(_THIS)
Definition: SDL_sysvideo.h:256
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
struct gbm_device * gbm
void(* GetDisplayModes)(_THIS, SDL_VideoDisplay *display)
Definition: SDL_sysvideo.h:196
SDL_bool KMSDRM_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
SDL_bool KMSDRM_WaitPageFlip(_THIS, SDL_WindowData *wdata, int timeout)
#define NULL
Definition: begin_code.h:164
int(* CreateSDLWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:210
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_bool
Definition: SDL_stdinc.h:139
SDL_DisplayMode desktop_mode
Definition: SDL_sysvideo.h:131
unsigned int uint32_t
void(* VideoQuit)(_THIS)
Definition: SDL_sysvideo.h:166
void KMSDRM_SetWindowPosition(_THIS, SDL_Window *window)
uint32_t crtc_id
#define SDL_SetError
#define SDL_calloc
void KMSDRM_RaiseWindow(_THIS, SDL_Window *window)
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1073
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
void KMSDRM_GLES_DeleteContext(_THIS, SDL_GLContext context)
void(* SetWindowPosition)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:214
int(* GL_SwapWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:262
#define SDL_HINT_VIDEO_DOUBLE_BUFFER
Tell the video driver that we only want a double buffer.
Definition: SDL_hints.h:861
struct gbm_surface * gs
The type used to identify a window.
Definition: SDL_sysvideo.h:73
GLbitfield GLuint64 timeout
void(* MinimizeWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:226
void KMSDRM_MinimizeWindow(_THIS, SDL_Window *window)
void KMSDRM_SetWindowTitle(_THIS, SDL_Window *window)
void KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
Definition: SDL_video.c:743
struct gbm_bo * next_bo
int(* VideoInit)(_THIS)
Definition: SDL_sysvideo.h:160
#define SDL_snprintf
int(* CreateSDLWindowFrom)(_THIS, SDL_Window *window, const void *data)
Definition: SDL_sysvideo.h:211
struct SDL_VideoDevice::@34 gl_config
KMSDRM_FBInfo * KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
void * driverdata
Definition: SDL_sysvideo.h:111
void(* GL_DeleteContext)(_THIS, SDL_GLContext context)
Definition: SDL_sysvideo.h:263
Uint32 format
Definition: SDL_video.h:55
void(* SetWindowTitle)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:212
#define SDL_LogWarn
int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window *window)
void KMSDRM_ShowWindow(_THIS, SDL_Window *window)
int(* GL_GetSwapInterval)(_THIS)
Definition: SDL_sysvideo.h:261
void(* MaximizeWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:225
Uint32 flags
Definition: SDL_sysvideo.h:83
drmModeCrtc * saved_crtc
void KMSDRM_VideoQuit(_THIS)
static void cleanup(void)
Definition: testfile.c:44
uint32_t saved_conn_id
void(* SetWindowGrab)(_THIS, SDL_Window *window, SDL_bool grabbed)
Definition: SDL_sysvideo.h:233
void *(* GL_GetProcAddress)(_THIS, const char *proc)
Definition: SDL_sysvideo.h:255
GLuint64 GLenum GLint fd
Definition: gl2ext.h:1508
EGLSurface egl_surface
void KMSDRM_DestroyWindow(_THIS, SDL_Window *window)
void(* PumpEvents)(_THIS)
Definition: SDL_sysvideo.h:280