SDL  2.0
SDL_kmsdrmvideo.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 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_events_c.h"
32 #include "../../events/SDL_mouse_c.h"
33 #include "../../events/SDL_keyboard_c.h"
34 
35 #ifdef SDL_INPUT_LINUXEV
36 #include "../../core/linux/SDL_evdev.h"
37 #endif
38 
39 /* KMS/DRM declarations */
40 #include "SDL_kmsdrmvideo.h"
41 #include "SDL_kmsdrmevents.h"
42 #include "SDL_kmsdrmopengles.h"
43 #include "SDL_kmsdrmmouse.h"
44 #include "SDL_kmsdrmdyn.h"
45 #include <sys/stat.h>
46 #include <dirent.h>
47 #include <errno.h>
48 #include <poll.h>
49 
50 #define KMSDRM_DRI_PATH "/dev/dri/"
51 
52 static int
53 check_modestting(int devindex)
54 {
56  char device[512];
57  int drm_fd;
58 
59  SDL_snprintf(device, sizeof (device), "%scard%d", KMSDRM_DRI_PATH, devindex);
60 
61  drm_fd = open(device, O_RDWR | O_CLOEXEC);
62  if (drm_fd >= 0) {
63  if (SDL_KMSDRM_LoadSymbols()) {
64  drmModeRes *resources = KMSDRM_drmModeGetResources(drm_fd);
65  if (resources) {
66  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "%scard%d connector, encoder and CRTC counts are: %d %d %d",
67  KMSDRM_DRI_PATH, devindex,
68  resources->count_connectors, resources->count_encoders, resources->count_crtcs);
69 
70  if (resources->count_connectors > 0 && resources->count_encoders > 0 && resources->count_crtcs > 0) {
72  }
73  KMSDRM_drmModeFreeResources(resources);
74  }
76  }
77  close(drm_fd);
78  }
79 
80  return available;
81 }
82 
83 static int get_dricount(void)
84 {
85  int devcount = 0;
86  struct dirent *res;
87  struct stat sb;
88  DIR *folder;
89 
90  if (!(stat(KMSDRM_DRI_PATH, &sb) == 0
91  && S_ISDIR(sb.st_mode))) {
92  printf("The path %s cannot be opened or is not available\n",
93  KMSDRM_DRI_PATH);
94  return 0;
95  }
96 
97  if (access(KMSDRM_DRI_PATH, F_OK) == -1) {
98  printf("The path %s cannot be opened\n",
99  KMSDRM_DRI_PATH);
100  return 0;
101  }
102 
103  folder = opendir(KMSDRM_DRI_PATH);
104  if (folder) {
105  while ((res = readdir(folder))) {
106  int len = SDL_strlen(res->d_name);
107  if (len > 4 && SDL_strncmp(res->d_name, "card", 4) == 0) {
108  devcount++;
109  }
110  }
111  closedir(folder);
112  }
113 
114  return devcount;
115 }
116 
117 static int
118 get_driindex(void)
119 {
120  const int devcount = get_dricount();
121  int i;
122 
123  for (i = 0; i < devcount; i++) {
124  if (check_modestting(i)) {
125  return i;
126  }
127  }
128 
129  return -ENOENT;
130 }
131 
132 static int
133 KMSDRM_Available(void)
134 {
135  int ret = -ENOENT;
136 
137  ret = get_driindex();
138  if (ret >= 0)
139  return 1;
140 
141  return ret;
142 }
143 
144 static void
145 KMSDRM_DeleteDevice(SDL_VideoDevice * device)
146 {
147  if (device->driverdata) {
148  SDL_free(device->driverdata);
149  device->driverdata = NULL;
150  }
151 
152  SDL_free(device);
153 
155 }
156 
157 static SDL_VideoDevice *
158 KMSDRM_CreateDevice(int devindex)
159 {
161  SDL_VideoData *viddata;
162 
163  if (!devindex || (devindex > 99)) {
164  devindex = get_driindex();
165  }
166 
167  if (devindex < 0) {
168  SDL_SetError("devindex (%d) must be between 0 and 99.\n", devindex);
169  return NULL;
170  }
171 
172  if (!SDL_KMSDRM_LoadSymbols()) {
173  return NULL;
174  }
175 
177  if (!device) {
178  SDL_OutOfMemory();
179  return NULL;
180  }
181 
182  viddata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
183  if (!viddata) {
184  SDL_OutOfMemory();
185  goto cleanup;
186  }
187  viddata->devindex = devindex;
188  viddata->drm_fd = -1;
189 
190  device->driverdata = viddata;
191 
192  /* Setup all functions which we can handle */
193  device->VideoInit = KMSDRM_VideoInit;
194  device->VideoQuit = KMSDRM_VideoQuit;
195  device->GetDisplayModes = KMSDRM_GetDisplayModes;
196  device->SetDisplayMode = KMSDRM_SetDisplayMode;
197  device->CreateSDLWindow = KMSDRM_CreateWindow;
198  device->CreateSDLWindowFrom = KMSDRM_CreateWindowFrom;
199  device->SetWindowTitle = KMSDRM_SetWindowTitle;
200  device->SetWindowIcon = KMSDRM_SetWindowIcon;
201  device->SetWindowPosition = KMSDRM_SetWindowPosition;
202  device->SetWindowSize = KMSDRM_SetWindowSize;
203  device->ShowWindow = KMSDRM_ShowWindow;
204  device->HideWindow = KMSDRM_HideWindow;
205  device->RaiseWindow = KMSDRM_RaiseWindow;
206  device->MaximizeWindow = KMSDRM_MaximizeWindow;
207  device->MinimizeWindow = KMSDRM_MinimizeWindow;
208  device->RestoreWindow = KMSDRM_RestoreWindow;
209  device->SetWindowGrab = KMSDRM_SetWindowGrab;
210  device->DestroyWindow = KMSDRM_DestroyWindow;
211  device->GetWindowWMInfo = KMSDRM_GetWindowWMInfo;
212 #if SDL_VIDEO_OPENGL_EGL
213  device->GL_LoadLibrary = KMSDRM_GLES_LoadLibrary;
214  device->GL_GetProcAddress = KMSDRM_GLES_GetProcAddress;
215  device->GL_UnloadLibrary = KMSDRM_GLES_UnloadLibrary;
216  device->GL_CreateContext = KMSDRM_GLES_CreateContext;
217  device->GL_MakeCurrent = KMSDRM_GLES_MakeCurrent;
218  device->GL_SetSwapInterval = KMSDRM_GLES_SetSwapInterval;
219  device->GL_GetSwapInterval = KMSDRM_GLES_GetSwapInterval;
220  device->GL_SwapWindow = KMSDRM_GLES_SwapWindow;
221  device->GL_DeleteContext = KMSDRM_GLES_DeleteContext;
222 #endif
223  device->PumpEvents = KMSDRM_PumpEvents;
224  device->free = KMSDRM_DeleteDevice;
225 
226  return device;
227 
228 cleanup:
229  if (device)
230  SDL_free(device);
231  if (viddata)
232  SDL_free(viddata);
233  return NULL;
234 }
235 
237  "KMSDRM",
238  "KMS/DRM Video Driver",
239  KMSDRM_Available,
240  KMSDRM_CreateDevice
241 };
242 
243 
244 static void
245 KMSDRM_FBDestroyCallback(struct gbm_bo *bo, void *data)
246 {
247  KMSDRM_FBInfo *fb_info = (KMSDRM_FBInfo *)data;
248 
249  if (fb_info && fb_info->drm_fd >= 0 && fb_info->fb_id != 0) {
250  KMSDRM_drmModeRmFB(fb_info->drm_fd, fb_info->fb_id);
251  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Delete DRM FB %u", fb_info->fb_id);
252  }
253 
254  SDL_free(fb_info);
255 }
256 
258 KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
259 {
260  SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
261  unsigned w,h;
262  int ret;
264 
265  /* Check for an existing framebuffer */
266  KMSDRM_FBInfo *fb_info = (KMSDRM_FBInfo *)KMSDRM_gbm_bo_get_user_data(bo);
267 
268  if (fb_info) {
269  return fb_info;
270  }
271 
272  /* Create a structure that contains enough info to remove the framebuffer
273  when the backing buffer is destroyed */
274  fb_info = (KMSDRM_FBInfo *)SDL_calloc(1, sizeof(KMSDRM_FBInfo));
275 
276  if (!fb_info) {
277  SDL_OutOfMemory();
278  return NULL;
279  }
280 
281  fb_info->drm_fd = viddata->drm_fd;
282 
283  /* Create framebuffer object for the buffer */
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  ret = KMSDRM_drmModeAddFB(viddata->drm_fd, w, h, 24, 32, stride, handle,
289  &fb_info->fb_id);
290  if (ret) {
291  SDL_free(fb_info);
292  return NULL;
293  }
294 
295  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "New DRM FB (%u): %ux%u, stride %u from BO %p",
296  fb_info->fb_id, w, h, stride, (void *)bo);
297 
298  /* Associate our DRM framebuffer with this buffer object */
299  KMSDRM_gbm_bo_set_user_data(bo, fb_info, KMSDRM_FBDestroyCallback);
300 
301  return fb_info;
302 }
303 
304 static void
305 KMSDRM_FlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
306 {
307  *((SDL_bool *) data) = SDL_FALSE;
308 }
309 
310 SDL_bool
312  SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
313  drmEventContext ev = {0};
314  struct pollfd pfd = {0};
315 
316  ev.version = DRM_EVENT_CONTEXT_VERSION;
317  ev.page_flip_handler = KMSDRM_FlipHandler;
318 
319  pfd.fd = viddata->drm_fd;
320  pfd.events = POLLIN;
321 
322  while (windata->waiting_for_flip) {
323  pfd.revents = 0;
324 
325  if (poll(&pfd, 1, timeout) < 0) {
326  SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll error");
327  return SDL_FALSE;
328  }
329 
330  if (pfd.revents & (POLLHUP | POLLERR)) {
331  SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll hup or error");
332  return SDL_FALSE;
333  }
334 
335  if (pfd.revents & POLLIN) {
336  /* Page flip? If so, drmHandleEvent will unset windata->waiting_for_flip */
337  KMSDRM_drmHandleEvent(viddata->drm_fd, &ev);
338  } else {
339  /* Timed out and page flip didn't happen */
340  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Dropping frame while waiting_for_flip");
341  return SDL_FALSE;
342  }
343  }
344 
345  return SDL_TRUE;
346 }
347 
348 /*****************************************************************************/
349 /* SDL Video and Display initialization/handling functions */
350 /* _this is a SDL_VideoDevice * */
351 /*****************************************************************************/
352 static void
353 KMSDRM_DestroySurfaces(_THIS, SDL_Window * window)
354 {
355  SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
356 
357  KMSDRM_WaitPageFlip(_this, windata, -1);
358 
359  if (windata->curr_bo) {
360  KMSDRM_gbm_surface_release_buffer(windata->gs, windata->curr_bo);
361  windata->curr_bo = NULL;
362  }
363 
364  if (windata->next_bo) {
365  KMSDRM_gbm_surface_release_buffer(windata->gs, windata->next_bo);
366  windata->next_bo = NULL;
367  }
368 
369 #if SDL_VIDEO_OPENGL_EGL
370  SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, EGL_NO_CONTEXT);
371 
372  if (windata->egl_surface != EGL_NO_SURFACE) {
373  SDL_EGL_DestroySurface(_this, windata->egl_surface);
374  windata->egl_surface = EGL_NO_SURFACE;
375  }
376 #endif
377 
378  if (windata->gs) {
379  KMSDRM_gbm_surface_destroy(windata->gs);
380  windata->gs = NULL;
381  }
382 }
383 
384 int
386 {
387  SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
388  SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
390  Uint32 width = dispdata->mode.hdisplay;
391  Uint32 height = dispdata->mode.vdisplay;
392  Uint32 surface_fmt = GBM_FORMAT_XRGB8888;
393  Uint32 surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
394  EGLContext egl_context;
395 
396  if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm, surface_fmt, surface_flags)) {
397  SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "GBM surface format not supported. Trying anyway.");
398  }
399 
400 #if SDL_VIDEO_OPENGL_EGL
401  SDL_EGL_SetRequiredVisualId(_this, surface_fmt);
402  egl_context = (EGLContext)SDL_GL_GetCurrentContext();
403 #endif
404 
405  KMSDRM_DestroySurfaces(_this, window);
406 
407  windata->gs = KMSDRM_gbm_surface_create(viddata->gbm, width, height, surface_fmt, surface_flags);
408 
409  if (!windata->gs) {
410  return SDL_SetError("Could not create GBM surface");
411  }
412 
413 #if SDL_VIDEO_OPENGL_EGL
414  windata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)windata->gs);
415 
416  if (windata->egl_surface == EGL_NO_SURFACE) {
417  return SDL_SetError("Could not create EGL window surface");
418  }
419 
420  SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context);
421 
422  windata->egl_surface_dirty = 0;
423 #endif
424 
425  return 0;
426 }
427 
428 int
430 {
431  int ret = 0;
432  SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
433  SDL_DisplayData *dispdata = NULL;
434  drmModeRes *resources = NULL;
435  drmModeEncoder *encoder = NULL;
436  char devname[32];
437  SDL_VideoDisplay display = {0};
438 
439  dispdata = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
440 
441  if (!dispdata) {
442  return SDL_OutOfMemory();
443  }
444 
445  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoInit()");
446 
447  /* Open /dev/dri/cardNN */
448  SDL_snprintf(devname, sizeof(devname), "/dev/dri/card%d", viddata->devindex);
449 
450  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opening device %s", devname);
451  viddata->drm_fd = open(devname, O_RDWR | O_CLOEXEC);
452 
453  if (viddata->drm_fd < 0) {
454  ret = SDL_SetError("Could not open %s", devname);
455  goto cleanup;
456  }
457 
458  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", viddata->drm_fd);
459 
460  viddata->gbm = KMSDRM_gbm_create_device(viddata->drm_fd);
461  if (!viddata->gbm) {
462  ret = SDL_SetError("Couldn't create gbm device.");
463  goto cleanup;
464  }
465 
466  /* Get all of the available connectors / devices / crtcs */
467  resources = KMSDRM_drmModeGetResources(viddata->drm_fd);
468  if (!resources) {
469  ret = SDL_SetError("drmModeGetResources(%d) failed", viddata->drm_fd);
470  goto cleanup;
471  }
472 
473  for (int i = 0; i < resources->count_connectors; i++) {
474  drmModeConnector *conn = KMSDRM_drmModeGetConnector(viddata->drm_fd, resources->connectors[i]);
475 
476  if (!conn) {
477  continue;
478  }
479 
480  if (conn->connection == DRM_MODE_CONNECTED && conn->count_modes) {
481  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found connector %d with %d modes.",
482  conn->connector_id, conn->count_modes);
483  dispdata->conn = conn;
484  break;
485  }
486 
487  KMSDRM_drmModeFreeConnector(conn);
488  }
489 
490  if (!dispdata->conn) {
491  ret = SDL_SetError("No currently active connector found.");
492  goto cleanup;
493  }
494 
495  /* Try to find the connector's current encoder */
496  for (int i = 0; i < resources->count_encoders; i++) {
497  encoder = KMSDRM_drmModeGetEncoder(viddata->drm_fd, resources->encoders[i]);
498 
499  if (!encoder) {
500  continue;
501  }
502 
503  if (encoder->encoder_id == dispdata->conn->encoder_id) {
504  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", encoder->encoder_id);
505  break;
506  }
507 
508  KMSDRM_drmModeFreeEncoder(encoder);
509  encoder = NULL;
510  }
511 
512  if (!encoder) {
513  /* No encoder was connected, find the first supported one */
514  for (int i = 0, j; i < resources->count_encoders; i++) {
515  encoder = KMSDRM_drmModeGetEncoder(viddata->drm_fd, resources->encoders[i]);
516 
517  if (!encoder) {
518  continue;
519  }
520 
521  for (j = 0; j < dispdata->conn->count_encoders; j++) {
522  if (dispdata->conn->encoders[j] == encoder->encoder_id) {
523  break;
524  }
525  }
526 
527  if (j != dispdata->conn->count_encoders) {
528  break;
529  }
530 
531  KMSDRM_drmModeFreeEncoder(encoder);
532  encoder = NULL;
533  }
534  }
535 
536  if (!encoder) {
537  ret = SDL_SetError("No connected encoder found.");
538  goto cleanup;
539  }
540 
541  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", encoder->encoder_id);
542 
543  /* Try to find a CRTC connected to this encoder */
544  dispdata->saved_crtc = KMSDRM_drmModeGetCrtc(viddata->drm_fd, encoder->crtc_id);
545 
546  if (!dispdata->saved_crtc) {
547  /* No CRTC was connected, find the first CRTC that can be connected */
548  for (int i = 0; i < resources->count_crtcs; i++) {
549  if (encoder->possible_crtcs & (1 << i)) {
550  encoder->crtc_id = resources->crtcs[i];
551  dispdata->saved_crtc = KMSDRM_drmModeGetCrtc(viddata->drm_fd, encoder->crtc_id);
552  break;
553  }
554  }
555  }
556 
557  if (!dispdata->saved_crtc) {
558  ret = SDL_SetError("No CRTC found.");
559  goto cleanup;
560  }
561 
562  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Saved crtc_id %u, fb_id %u, (%u,%u), %ux%u",
563  dispdata->saved_crtc->crtc_id, dispdata->saved_crtc->buffer_id, dispdata->saved_crtc->x,
564  dispdata->saved_crtc->y, dispdata->saved_crtc->width, dispdata->saved_crtc->height);
565 
566  dispdata->crtc_id = encoder->crtc_id;
567 
568  /* Figure out the default mode to be set. If the current CRTC's mode isn't
569  valid, select the first mode supported by the connector
570 
571  FIXME find first mode that specifies DRM_MODE_TYPE_PREFERRED */
572  dispdata->mode = dispdata->saved_crtc->mode;
573 
574  if (dispdata->saved_crtc->mode_valid == 0) {
576  "Current mode is invalid, selecting connector's mode #0.");
577  dispdata->mode = dispdata->conn->modes[0];
578  }
579 
580  /* Setup the single display that's available */
581 
582  display.desktop_mode.w = dispdata->mode.hdisplay;
583  display.desktop_mode.h = dispdata->mode.vdisplay;
584  display.desktop_mode.refresh_rate = dispdata->mode.vrefresh;
585 #if 1
587 #else
588  /* FIXME */
589  drmModeFB *fb = drmModeGetFB(viddata->drm_fd, dispdata->saved_crtc->buffer_id);
590  display.desktop_mode.format = drmToSDLPixelFormat(fb->bpp, fb->depth);
591  drmModeFreeFB(fb);
592 #endif
593  display.current_mode = display.desktop_mode;
594  display.driverdata = dispdata;
595  SDL_AddVideoDisplay(&display);
596 
597 #ifdef SDL_INPUT_LINUXEV
598  SDL_EVDEV_Init();
599 #endif
600 
602 
603  return ret;
604 
605 cleanup:
606  if (encoder)
607  KMSDRM_drmModeFreeEncoder(encoder);
608  if (resources)
609  KMSDRM_drmModeFreeResources(resources);
610 
611  if (ret != 0) {
612  /* Error (complete) cleanup */
613  if (dispdata->conn) {
614  KMSDRM_drmModeFreeConnector(dispdata->conn);
615  dispdata->conn = NULL;
616  }
617  if (dispdata->saved_crtc) {
618  KMSDRM_drmModeFreeCrtc(dispdata->saved_crtc);
619  dispdata->saved_crtc = NULL;
620  }
621  if (viddata->gbm) {
622  KMSDRM_gbm_device_destroy(viddata->gbm);
623  viddata->gbm = NULL;
624  }
625  if (viddata->drm_fd >= 0) {
626  close(viddata->drm_fd);
627  viddata->drm_fd = -1;
628  }
629  SDL_free(dispdata);
630  }
631  return ret;
632 }
633 
634 void
636 {
637  SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
639 
640  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoQuit()");
641 
644  }
645 
646  /* Clear out the window list */
647  SDL_free(viddata->windows);
648  viddata->windows = NULL;
649  viddata->max_windows = 0;
650  viddata->num_windows = 0;
651 
652  /* Restore saved CRTC settings */
653  if (viddata->drm_fd >= 0 && dispdata && dispdata->conn && dispdata->saved_crtc) {
654  drmModeConnector *conn = dispdata->conn;
655  drmModeCrtc *crtc = dispdata->saved_crtc;
656 
657  int ret = KMSDRM_drmModeSetCrtc(viddata->drm_fd, crtc->crtc_id, crtc->buffer_id,
658  crtc->x, crtc->y, &conn->connector_id, 1, &crtc->mode);
659 
660  if (ret != 0) {
661  SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not restore original CRTC mode");
662  }
663  }
664  if (dispdata && dispdata->conn) {
665  KMSDRM_drmModeFreeConnector(dispdata->conn);
666  dispdata->conn = NULL;
667  }
668  if (dispdata && dispdata->saved_crtc) {
669  KMSDRM_drmModeFreeCrtc(dispdata->saved_crtc);
670  dispdata->saved_crtc = NULL;
671  }
672  if (viddata->gbm) {
673  KMSDRM_gbm_device_destroy(viddata->gbm);
674  viddata->gbm = NULL;
675  }
676  if (viddata->drm_fd >= 0) {
677  close(viddata->drm_fd);
678  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Closed DRM FD %d", viddata->drm_fd);
679  viddata->drm_fd = -1;
680  }
681 #ifdef SDL_INPUT_LINUXEV
682  SDL_EVDEV_Quit();
683 #endif
684 }
685 
686 void
688 {
689  SDL_DisplayData *dispdata = display->driverdata;
690  drmModeConnector *conn = dispdata->conn;
692 
693  for (int i = 0; i < conn->count_modes; i++) {
694  SDL_DisplayModeData *modedata = SDL_calloc(1, sizeof(SDL_DisplayModeData));
695 
696  if (modedata) {
697  modedata->mode_index = i;
698  }
699 
700  mode.w = conn->modes[i].hdisplay;
701  mode.h = conn->modes[i].vdisplay;
702  mode.refresh_rate = conn->modes[i].vrefresh;
704  mode.driverdata = modedata;
705 
706  if (!SDL_AddDisplayMode(display, &mode)) {
707  SDL_free(modedata);
708  }
709  }
710 }
711 
712 int
714 {
716  SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata;
717  SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
718  drmModeConnector *conn = dispdata->conn;
719 
720  if (!modedata) {
721  return SDL_SetError("Mode doesn't have an associated index");
722  }
723 
724  dispdata->mode = conn->modes[modedata->mode_index];
725 
726  for (int i = 0; i < viddata->num_windows; i++) {
727  SDL_Window *window = viddata->windows[i];
728  SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
729 
731  /* Can't recreate EGL surfaces right now, need to wait until SwapWindow
732  so the correct thread-local surface and context state are available */
733  windata->egl_surface_dirty = 1;
734 #else
736  return -1;
737  }
738 #endif
739 
740  /* Tell app about the resize */
742  }
743 
744  return 0;
745 }
746 
747 int
749 {
751  SDL_WindowData *windata;
752  SDL_VideoDisplay *display;
753 
755  if (!_this->egl_data) {
756  if (SDL_GL_LoadLibrary(NULL) < 0) {
757  goto error;
758  }
759  }
760 #endif
761 
762  /* Allocate window internal data */
763  windata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData));
764 
765  if (!windata) {
766  SDL_OutOfMemory();
767  goto error;
768  }
769 
770  /* Windows have one size for now */
771  display = SDL_GetDisplayForWindow(window);
772  window->w = display->desktop_mode.w;
773  window->h = display->desktop_mode.h;
774 
775  /* Maybe you didn't ask for a fullscreen OpenGL window, but that's what you get */
777 
778  /* In case we want low-latency, double-buffer video, we take note here */
779  windata->double_buffer = SDL_FALSE;
780 
782  windata->double_buffer = SDL_TRUE;
783  }
784 
785  /* Setup driver data for this window */
786  window->driverdata = windata;
787 
789  goto error;
790  }
791 
792  /* Add window to the internal list of tracked windows. Note, while it may
793  seem odd to support multiple fullscreen windows, some apps create an
794  extra window as a dummy surface when working with multiple contexts */
795  windata->viddata = viddata;
796 
797  if (viddata->num_windows >= viddata->max_windows) {
798  int new_max_windows = viddata->max_windows + 1;
799  viddata->windows = (SDL_Window **)SDL_realloc(viddata->windows,
800  new_max_windows * sizeof(SDL_Window *));
801  viddata->max_windows = new_max_windows;
802 
803  if (!viddata->windows) {
804  SDL_OutOfMemory();
805  goto error;
806  }
807  }
808 
809  viddata->windows[viddata->num_windows++] = window;
810 
811  /* Focus on the newly created window */
814 
815  return 0;
816 
817 error:
819 
820  return -1;
821 }
822 
823 void
825 {
826  SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
827  SDL_VideoData *viddata;
828  if (!windata) {
829  return;
830  }
831 
832  /* Remove from the internal window list */
833  viddata = windata->viddata;
834 
835  for (int i = 0; i < viddata->num_windows; i++) {
836  if (viddata->windows[i] == window) {
837  viddata->num_windows--;
838 
839  for (int j = i; j < viddata->num_windows; j++) {
840  viddata->windows[j] = viddata->windows[j + 1];
841  }
842 
843  break;
844  }
845  }
846 
847  KMSDRM_DestroySurfaces(_this, window);
848 
849  window->driverdata = NULL;
850 
851  SDL_free(windata);
852 }
853 
854 int
856 {
857  return -1;
858 }
859 
860 void
862 {
863 }
864 void
866 {
867 }
868 void
870 {
871 }
872 void
874 {
875 }
876 void
878 {
879 }
880 void
882 {
883 }
884 void
886 {
887 }
888 void
890 {
891 }
892 void
894 {
895 }
896 void
898 {
899 }
900 void
902 {
903 
904 }
905 
906 /*****************************************************************************/
907 /* SDL Window Manager function */
908 /*****************************************************************************/
909 SDL_bool
911 {
912  if (info->version.major <= SDL_MAJOR_VERSION) {
913  return SDL_TRUE;
914  } else {
915  SDL_SetError("application not compiled with SDL %d.%d\n",
917  return SDL_FALSE;
918  }
919 
920  /* Failed to get window manager information */
921  return SDL_FALSE;
922 }
923 
924 #endif /* SDL_VIDEO_DRIVER_KMSDRM */
925 
926 /* vi: set ts=4 sw=4 expandtab: */
SDL_VIDEO_OPENGL_EGL
#define SDL_VIDEO_OPENGL_EGL
Definition: SDL_config.h:382
KMSDRM_GLES_GetProcAddress
void * KMSDRM_GLES_GetProcAddress(_THIS, const char *proc)
KMSDRM_DestroyWindow
void KMSDRM_DestroyWindow(_THIS, SDL_Window *window)
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
EGLContext
void * EGLContext
Definition: egl.h:60
SDL_DisplayMode::format
Uint32 format
Definition: SDL_video.h:55
SDL_VideoDevice::driverdata
void * driverdata
Definition: SDL_sysvideo.h:389
KMSDRM_SetDisplayMode
int KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
SDL_Surface
A collection of pixels used in software blitting.
Definition: SDL_surface.h:70
if
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
Definition: pixman-arm-neon-asm.h:469
KMSDRM_SetWindowSize
void KMSDRM_SetWindowSize(_THIS, SDL_Window *window)
SDL_kmsdrmvideo.h
NULL
#define NULL
Definition: begin_code.h:167
handle
EGLImageKHR EGLint EGLint * handle
Definition: eglext.h:937
width
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
KMSDRM_FBInfo
Definition: SDL_kmsdrmvideo.h:80
timeout
GLbitfield GLuint64 timeout
Definition: SDL_opengl_glext.h:1486
SDL_VideoData::num_windows
int num_windows
Definition: SDL_kmsdrmvideo.h:46
access
GLuint GLint GLboolean GLint GLenum access
Definition: SDL_opengl_glext.h:2165
mode
GLenum mode
Definition: SDL_opengl_glext.h:1125
SDL_WindowData::next_bo
struct gbm_bo * next_bo
Definition: SDL_kmsdrmvideo.h:70
NativeWindowType
EGLNativeWindowType NativeWindowType
Definition: eglplatform.h:112
SDL_DisplayModeData::mode_index
int mode_index
Definition: SDL_kmsdrmvideo.h:52
SDL_SysWMinfo
Definition: SDL_syswm.h:201
SDL_log.h
SDL_WindowData
Definition: SDL_androidwindow.h:38
SDL_GetDisplayForWindow
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1110
SDL_WINDOW_FULLSCREEN
@ SDL_WINDOW_FULLSCREEN
Definition: SDL_video.h:99
SDL_WindowData::curr_bo
struct gbm_bo * curr_bo
Definition: SDL_kmsdrmvideo.h:69
SDL_WINDOW_OPENGL
@ SDL_WINDOW_OPENGL
Definition: SDL_video.h:100
SDL_realloc
#define SDL_realloc
Definition: SDL_dynapi_overrides.h:376
SDL_WINDOWEVENT_RESIZED
@ SDL_WINDOWEVENT_RESIZED
Definition: SDL_video.h:154
KMSDRM_MaximizeWindow
void KMSDRM_MaximizeWindow(_THIS, SDL_Window *window)
KMSDRM_GLES_LoadLibrary
int KMSDRM_GLES_LoadLibrary(_THIS, const char *path)
KMSDRM_GLES_SetSwapInterval
int KMSDRM_GLES_SetSwapInterval(_THIS, int interval)
KMSDRM_InitMouse
void KMSDRM_InitMouse(_THIS)
SDL_GL_LoadLibrary
#define SDL_GL_LoadLibrary
Definition: SDL_dynapi_overrides.h:553
SDL_SetKeyboardFocus
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:630
KMSDRM_CreateWindowFrom
int KMSDRM_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
SDL_DisplayData::mode
drmModeModeInfo mode
Definition: SDL_kmsdrmvideo.h:60
SDL_VideoDisplay::desktop_mode
SDL_DisplayMode desktop_mode
Definition: SDL_sysvideo.h:132
SDL_strncmp
#define SDL_strncmp
Definition: SDL_dynapi_overrides.h:418
KMSDRM_CreateWindow
int KMSDRM_CreateWindow(_THIS, SDL_Window *window)
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1949
KMSDRM_CreateSurfaces
int KMSDRM_CreateSurfaces(_THIS, SDL_Window *window)
SDL_kmsdrmmouse.h
SDL_GetDisplayDriverData
void * SDL_GetDisplayDriverData(int displayIndex)
Definition: SDL_video.c:660
SDL_SetMouseFocus
void SDL_SetMouseFocus(SDL_Window *window)
Definition: SDL_mouse.c:203
SDL_LogError
#define SDL_LogError
Definition: SDL_dynapi_overrides.h:36
SDL_DisplayMode::h
int h
Definition: SDL_video.h:57
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
EGL_NO_CONTEXT
#define EGL_NO_CONTEXT
Definition: egl.h:98
KMSDRM_GLES_UnloadLibrary
void KMSDRM_GLES_UnloadLibrary(_THIS)
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:74
SDL_DisplayData::conn
drmModeConnector * conn
Definition: SDL_kmsdrmvideo.h:59
SDL_DisplayMode
The structure that defines a display mode.
Definition: SDL_video.h:53
SDL_AddDisplayMode
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
Definition: SDL_video.c:772
SDL_GL_UnloadLibrary
#define SDL_GL_UnloadLibrary
Definition: SDL_dynapi_overrides.h:555
KMSDRM_GLES_CreateContext
SDL_GLContext KMSDRM_GLES_CreateContext(_THIS, SDL_Window *window)
SDL_WindowData::gs
struct gbm_surface * gs
Definition: SDL_kmsdrmvideo.h:68
SDL_VideoDevice::gl_config
struct SDL_VideoDevice::@255 gl_config
len
GLenum GLsizei len
Definition: SDL_opengl_glext.h:2929
SDL_GetHintBoolean
#define SDL_GetHintBoolean
Definition: SDL_dynapi_overrides.h:608
SDL_KMSDRM_UnloadSymbols
void SDL_KMSDRM_UnloadSymbols(void)
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_VideoData::gbm
struct gbm_device * gbm
Definition: SDL_kmsdrmvideo.h:42
_this
static SDL_VideoDevice * _this
Definition: SDL_video.c:121
KMSDRM_PumpEvents
void KMSDRM_PumpEvents(_THIS)
SDL_kmsdrmevents.h
SDL_MINOR_VERSION
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
window
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
EGL_NO_SURFACE
#define EGL_NO_SURFACE
Definition: egl.h:100
KMSDRM_bootstrap
VideoBootStrap KMSDRM_bootstrap
KMSDRM_WaitPageFlip
SDL_bool KMSDRM_WaitPageFlip(_THIS, SDL_WindowData *windata, int timeout)
KMSDRM_SetWindowGrab
void KMSDRM_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
height
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
SDL_VideoDevice::driver_loaded
int driver_loaded
Definition: SDL_sysvideo.h:361
SDL_DisplayMode::refresh_rate
int refresh_rate
Definition: SDL_video.h:58
SDL_LogDebug
#define SDL_LogDebug
Definition: SDL_dynapi_overrides.h:33
frame
int frame
Definition: teststreaming.c:60
KMSDRM_VideoInit
int KMSDRM_VideoInit(_THIS)
KMSDRM_FBInfo::drm_fd
int drm_fd
Definition: SDL_kmsdrmvideo.h:82
SDL_kmsdrmopengles.h
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
cleanup
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld cleanup[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld_src SRC pixld MASK if DST_R else pixld DST_R endif if src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head if pixblock_size cache_preload_simple endif process_pixblock_tail pixinterleave dst_w_basereg irp if pixblock_size chunk_size tst beq if DST_W else pixst DST_W else mov ORIG_W endif add lsl if lsl endif if lsl endif lsl endif lsl endif lsl endif subs mov DST_W if regs_shortage str endif bge start_of_loop_label endm macro generate_composite_function
Definition: pixman-arm-neon-asm.h:625
KMSDRM_GLES_MakeCurrent
int KMSDRM_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
SDL_PIXELFORMAT_ARGB8888
@ SDL_PIXELFORMAT_ARGB8888
Definition: SDL_pixels.h:251
SDL_DisplayData::saved_crtc
drmModeCrtc * saved_crtc
Definition: SDL_kmsdrmvideo.h:61
SDL_DisplayMode::w
int w
Definition: SDL_video.h:56
SDL_AddVideoDisplay
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
Definition: SDL_video.c:606
SDL_GL_GetCurrentContext
#define SDL_GL_GetCurrentContext
Definition: SDL_dynapi_overrides.h:562
SDL_VideoDisplay::driverdata
void * driverdata
Definition: SDL_sysvideo.h:140
SDL_DisplayData
Definition: SDL_cocoamodes.h:26
SDL_VideoDevice
Definition: SDL_sysvideo.h:149
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_VideoData::drm_fd
int drm_fd
Definition: SDL_kmsdrmvideo.h:41
KMSDRM_RestoreWindow
void KMSDRM_RestoreWindow(_THIS, SDL_Window *window)
KMSDRM_SetWindowPosition
void KMSDRM_SetWindowPosition(_THIS, SDL_Window *window)
available
static int available()
Definition: video.c:356
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
KMSDRM_RaiseWindow
void KMSDRM_RaiseWindow(_THIS, SDL_Window *window)
KMSDRM_SetWindowIcon
void KMSDRM_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
KMSDRM_HideWindow
void KMSDRM_HideWindow(_THIS, SDL_Window *window)
SDL_WindowData::double_buffer
SDL_bool double_buffer
Definition: SDL_kmsdrmvideo.h:73
SDL_WindowData::waiting_for_flip
SDL_bool waiting_for_flip
Definition: SDL_kmsdrmvideo.h:72
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
KMSDRM_GetWindowWMInfo
SDL_bool KMSDRM_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
SDL_SysWMinfo::version
SDL_version version
Definition: SDL_syswm.h:203
SDL_VideoDisplay
Definition: SDL_sysvideo.h:126
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_snprintf
#define SDL_snprintf
Definition: SDL_dynapi_overrides.h:40
SDL_kmsdrmdyn.h
SDL_hints.h
SDL_WindowData::viddata
SDL_VideoData * viddata
Definition: SDL_kmsdrmvideo.h:67
KMSDRM_GLES_DeleteContext
void KMSDRM_GLES_DeleteContext(_THIS, SDL_GLContext context)
SDL_HINT_VIDEO_DOUBLE_BUFFER
#define SDL_HINT_VIDEO_DOUBLE_BUFFER
Tell the video driver that we only want a double buffer.
Definition: SDL_hints.h:1077
SDL_SendWindowEvent
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
Definition: SDL_windowevents.c:74
KMSDRM_FBFromBO
KMSDRM_FBInfo * KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
SDL_strlen
#define SDL_strlen
Definition: SDL_dynapi_overrides.h:393
stride
GLsizei stride
Definition: SDL_opengl_glext.h:381
KMSDRM_ShowWindow
void KMSDRM_ShowWindow(_THIS, SDL_Window *window)
KMSDRM_GLES_SwapWindow
int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window *window)
KMSDRM_MinimizeWindow
void KMSDRM_MinimizeWindow(_THIS, SDL_Window *window)
KMSDRM_SetWindowTitle
void KMSDRM_SetWindowTitle(_THIS, SDL_Window *window)
KMSDRM_GetDisplayModes
void KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
j
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
SDL_DisplayData::crtc_id
uint32_t crtc_id
Definition: SDL_kmsdrmvideo.h:58
SDL_KMSDRM_LoadSymbols
int SDL_KMSDRM_LoadSymbols(void)
SDL_VideoData::max_windows
int max_windows
Definition: SDL_kmsdrmvideo.h:45
SDL_VideoDisplay::current_mode
SDL_DisplayMode current_mode
Definition: SDL_sysvideo.h:133
SDL_DisplayModeData
Definition: SDL_cocoamodes.h:31
fd
GLuint64 GLenum GLint fd
Definition: gl2ext.h:1508
SDL_version::major
Uint8 major
Definition: SDL_version.h:53
res
GLuint res
Definition: SDL_opengl_glext.h:7940
VideoBootStrap
Definition: SDL_sysvideo.h:405
SDL_MAJOR_VERSION
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
device
static SDL_AudioDeviceID device
Definition: loopwave.c:37
SDL_LogWarn
#define SDL_LogWarn
Definition: SDL_dynapi_overrides.h:35
SDL_VideoData::windows
SDL_Window ** windows
Definition: SDL_kmsdrmvideo.h:44
SDL_WindowData::egl_surface
EGLSurface egl_surface
Definition: SDL_androidwindow.h:40
SDL_VideoData::devindex
int devindex
Definition: SDL_kmsdrmvideo.h:40
i
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
KMSDRM_VideoQuit
void KMSDRM_VideoQuit(_THIS)
KMSDRM_GLES_GetSwapInterval
int KMSDRM_GLES_GetSwapInterval(_THIS)
SDL_VideoData
Definition: SDL_androidvideo.h:36
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:161
SDL_syswm.h
SDL_LOG_CATEGORY_VIDEO
@ SDL_LOG_CATEGORY_VIDEO
Definition: SDL_log.h:71
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:734
KMSDRM_FBInfo::fb_id
uint32_t fb_id
Definition: SDL_kmsdrmvideo.h:83