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 #include <sys/stat.h>
45 #include <dirent.h>
46 #include <errno.h>
47 
48 #define KMSDRM_DRI_PATH "/dev/dri/"
49 
50 static int
51 check_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) {
61  if (SDL_KMSDRM_LoadSymbols()) {
62  drmModeRes *resources = KMSDRM_drmModeGetResources(drm_fd);
63  if (resources != NULL) {
64  available = SDL_TRUE;
65  KMSDRM_drmModeFreeResources(resources);
66  }
68  }
69  close(drm_fd);
70  }
71 
72  return available;
73 }
74 
75 static int get_dricount(void)
76 {
77  int devcount = 0;
78  struct dirent *res;
79  struct stat sb;
80  DIR *folder;
81 
82  if (!(stat(KMSDRM_DRI_PATH, &sb) == 0
83  && S_ISDIR(sb.st_mode))) {
84  printf("The path %s cannot be opened or is not available\n",
85  KMSDRM_DRI_PATH);
86  return 0;
87  }
88 
89  if (access(KMSDRM_DRI_PATH, F_OK) == -1) {
90  printf("The path %s cannot be opened\n",
91  KMSDRM_DRI_PATH);
92  return 0;
93  }
94 
95  folder = opendir(KMSDRM_DRI_PATH);
96  if (folder) {
97  while ((res = readdir(folder))) {
98  if (res->d_type == DT_CHR) {
99  devcount++;
100  }
101  }
102  closedir(folder);
103  }
104 
105  return devcount;
106 }
107 
108 static int
109 get_driindex(void)
110 {
111  const int devcount = get_dricount();
112  int i;
113 
114  for (i = 0; i < devcount; i++) {
115  if (check_modestting(i)) {
116  return i;
117  }
118  }
119 
120  return -ENOENT;
121 }
122 
123 static int
124 KMSDRM_Available(void)
125 {
126  int ret = -ENOENT;
127 
128  ret = get_driindex();
129  if (ret >= 0)
130  return 1;
131 
132  return ret;
133 }
134 
135 static void
136 KMSDRM_Destroy(SDL_VideoDevice * device)
137 {
138  if (device->driverdata != NULL) {
139  SDL_free(device->driverdata);
140  device->driverdata = NULL;
141  }
142 
143  SDL_free(device);
145 }
146 
147 static SDL_VideoDevice *
148 KMSDRM_Create(int devindex)
149 {
151  SDL_VideoData *vdata;
152 
153  if (!devindex || (devindex > 99)) {
154  devindex = get_driindex();
155  }
156 
157  if (devindex < 0) {
158  SDL_SetError("devindex (%d) must be between 0 and 99.\n", devindex);
159  return NULL;
160  }
161 
162  if (!SDL_KMSDRM_LoadSymbols()) {
163  return NULL;
164  }
165 
166  /* Initialize SDL_VideoDevice structure */
167  device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
168  if (device == NULL) {
169  SDL_OutOfMemory();
170  return NULL;
171  }
172 
173  /* Initialize internal data */
174  vdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
175  if (vdata == NULL) {
176  SDL_OutOfMemory();
177  goto cleanup;
178  }
179  vdata->devindex = devindex;
180  vdata->drm_fd = -1;
181 
182  device->driverdata = vdata;
183 
184  /* Setup amount of available displays and current display */
185  device->num_displays = 0;
186 
187  /* Set device free function */
188  device->free = KMSDRM_Destroy;
189 
190  /* Setup all functions which we can handle */
191  device->VideoInit = KMSDRM_VideoInit;
192  device->VideoQuit = KMSDRM_VideoQuit;
201  device->ShowWindow = KMSDRM_ShowWindow;
202  device->HideWindow = KMSDRM_HideWindow;
210 #if SDL_VIDEO_OPENGL_EGL
220 #endif
221 
222  device->PumpEvents = KMSDRM_PumpEvents;
223 
224  return device;
225 
226 cleanup:
227  if (device != NULL)
228  SDL_free(device);
229  if (vdata != NULL)
230  SDL_free(vdata);
231  return NULL;
232 }
233 
235  "KMSDRM",
236  "KMS/DRM Video Driver",
237  KMSDRM_Available,
238  KMSDRM_Create
239 };
240 
241 
242 static void
243 KMSDRM_FBDestroyCallback(struct gbm_bo *bo, void *data)
244 {
245  KMSDRM_FBInfo *fb_info = (KMSDRM_FBInfo *)data;
246 
247  if (fb_info && fb_info->drm_fd > 0 && fb_info->fb_id != 0) {
248  KMSDRM_drmModeRmFB(fb_info->drm_fd, fb_info->fb_id);
249  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Delete DRM FB %u", fb_info->fb_id);
250  }
251 
252  free(fb_info);
253 }
254 
256 KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
257 {
258  uint32_t w, h, stride, handle;
259  int ret;
261  KMSDRM_FBInfo *fb_info;
262 
263  fb_info = (KMSDRM_FBInfo *)KMSDRM_gbm_bo_get_user_data(bo);
264  if (fb_info != NULL) {
265  /* Have a previously used framebuffer, return it */
266  return fb_info;
267  }
268 
269  /* Here a new DRM FB must be created */
270  fb_info = (KMSDRM_FBInfo *)SDL_calloc(1, sizeof(KMSDRM_FBInfo));
271  if (fb_info == NULL) {
272  SDL_OutOfMemory();
273  return NULL;
274  }
275  fb_info->drm_fd = vdata->drm_fd;
276 
277  w = KMSDRM_gbm_bo_get_width(bo);
278  h = KMSDRM_gbm_bo_get_height(bo);
279  stride = KMSDRM_gbm_bo_get_stride(bo);
280  handle = KMSDRM_gbm_bo_get_handle(bo).u32;
281 
282  ret = KMSDRM_drmModeAddFB(vdata->drm_fd, w, h, 24, 32, stride, handle, &fb_info->fb_id);
283  if (ret < 0) {
284  free(fb_info);
285  return NULL;
286  }
287  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);
288 
289  /* Associate our DRM framebuffer with this buffer object */
290  KMSDRM_gbm_bo_set_user_data(bo, fb_info, KMSDRM_FBDestroyCallback);
291  return fb_info;
292 }
293 
294 SDL_bool
297 
298  while (wdata->waiting_for_flip) {
299  vdata->drm_pollfd.revents = 0;
300  if (poll(&vdata->drm_pollfd, 1, timeout) < 0) {
301  SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll error");
302  return SDL_FALSE;
303  }
304 
305  if (vdata->drm_pollfd.revents & (POLLHUP | POLLERR)) {
306  SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll hup or error");
307  return SDL_FALSE;
308  }
309 
310  if (vdata->drm_pollfd.revents & POLLIN) {
311  /* Page flip? If so, drmHandleEvent will unset wdata->waiting_for_flip */
312  KMSDRM_drmHandleEvent(vdata->drm_fd, &vdata->drm_evctx);
313  } else {
314  /* Timed out and page flip didn't happen */
315  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Dropping frame while waiting_for_flip");
316  return SDL_FALSE;
317  }
318  }
319  return SDL_TRUE;
320 }
321 
322 static void
323 KMSDRM_FlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
324 {
325  *((SDL_bool *) data) = SDL_FALSE;
326 }
327 
328 
329 /*****************************************************************************/
330 /* SDL Video and Display initialization/handling functions */
331 /* _this is a SDL_VideoDevice * */
332 /*****************************************************************************/
333 int
335 {
336  int i;
337  int ret = 0;
338  char *devname;
340  drmModeRes *resources = NULL;
341  drmModeConnector *connector = NULL;
342  drmModeEncoder *encoder = NULL;
343  SDL_DisplayMode current_mode;
344  SDL_VideoDisplay display;
345 
346  /* Allocate display internal data */
348  if (data == NULL) {
349  return SDL_OutOfMemory();
350  }
351 
352  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoInit()");
353 
354  /* Open /dev/dri/cardNN */
355  devname = (char *) SDL_calloc(1, 16);
356  if (devname == NULL) {
357  ret = SDL_OutOfMemory();
358  goto cleanup;
359  }
360  SDL_snprintf(devname, 16, "/dev/dri/card%d", vdata->devindex);
361  vdata->drm_fd = open(devname, O_RDWR | O_CLOEXEC);
362  SDL_free(devname);
363 
364  if (vdata->drm_fd < 0) {
365  ret = SDL_SetError("Could not open /dev/dri/card%d.", vdata->devindex);
366  goto cleanup;
367  }
368  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", vdata->drm_fd);
369 
370  vdata->gbm = KMSDRM_gbm_create_device(vdata->drm_fd);
371  if (vdata->gbm == NULL) {
372  ret = SDL_SetError("Couldn't create gbm device.");
373  goto cleanup;
374  }
375 
376  /* Find the first available connector with modes */
377  resources = KMSDRM_drmModeGetResources(vdata->drm_fd);
378  if (!resources) {
379  ret = SDL_SetError("drmModeGetResources(%d) failed", vdata->drm_fd);
380  goto cleanup;
381  }
382 
383  for (i = 0; i < resources->count_connectors; i++) {
384  connector = KMSDRM_drmModeGetConnector(vdata->drm_fd, resources->connectors[i]);
385  if (connector == NULL)
386  continue;
387 
388  if (connector->connection == DRM_MODE_CONNECTED &&
389  connector->count_modes > 0) {
390  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found connector %d with %d modes.",
391  connector->connector_id, connector->count_modes);
392  vdata->saved_conn_id = connector->connector_id;
393  break;
394  }
395 
396  KMSDRM_drmModeFreeConnector(connector);
397  connector = NULL;
398  }
399 
400  if (i == resources->count_connectors) {
401  ret = SDL_SetError("No currently active connector found.");
402  goto cleanup;
403  }
404 
405  for (i = 0; i < resources->count_encoders; i++) {
406  encoder = KMSDRM_drmModeGetEncoder(vdata->drm_fd, resources->encoders[i]);
407 
408  if (encoder == NULL)
409  continue;
410 
411  if (encoder->encoder_id == connector->encoder_id) {
412  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", encoder->encoder_id);
413  data->encoder_id = encoder->encoder_id;
414  break;
415  }
416 
417  KMSDRM_drmModeFreeEncoder(encoder);
418  encoder = NULL;
419  }
420 
421  if (i == resources->count_encoders) {
422  ret = SDL_SetError("No connected encoder found.");
423  goto cleanup;
424  }
425 
426  vdata->saved_crtc = KMSDRM_drmModeGetCrtc(vdata->drm_fd, encoder->crtc_id);
427  if (vdata->saved_crtc == NULL) {
428  ret = SDL_SetError("No CRTC found.");
429  goto cleanup;
430  }
431  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Saved crtc_id %u, fb_id %u, (%u,%u), %ux%u",
432  vdata->saved_crtc->crtc_id, vdata->saved_crtc->buffer_id, vdata->saved_crtc->x,
433  vdata->saved_crtc->y, vdata->saved_crtc->width, vdata->saved_crtc->height);
434  data->crtc_id = encoder->crtc_id;
435  data->cur_mode = vdata->saved_crtc->mode;
436  vdata->crtc_id = encoder->crtc_id;
437 
438  SDL_zero(current_mode);
439 
440  current_mode.w = vdata->saved_crtc->mode.hdisplay;
441  current_mode.h = vdata->saved_crtc->mode.vdisplay;
442  current_mode.refresh_rate = vdata->saved_crtc->mode.vrefresh;
443 
444  /* FIXME ?
445  drmModeFB *fb = drmModeGetFB(vdata->drm_fd, vdata->saved_crtc->buffer_id);
446  current_mode.format = drmToSDLPixelFormat(fb->bpp, fb->depth);
447  drmModeFreeFB(fb);
448  */
449  current_mode.format = SDL_PIXELFORMAT_ARGB8888;
450 
451  current_mode.driverdata = NULL;
452 
453  SDL_zero(display);
454  display.desktop_mode = current_mode;
455  display.current_mode = current_mode;
456 
457  display.driverdata = data;
458  /* SDL_VideoQuit will later SDL_free(display.driverdata) */
459  SDL_AddVideoDisplay(&display);
460 
461  /* Setup page flip handler */
462  vdata->drm_pollfd.fd = vdata->drm_fd;
463  vdata->drm_pollfd.events = POLLIN;
464  vdata->drm_evctx.version = DRM_EVENT_CONTEXT_VERSION;
465  vdata->drm_evctx.page_flip_handler = KMSDRM_FlipHandler;
466 
467 #ifdef SDL_INPUT_LINUXEV
468  SDL_EVDEV_Init();
469 #endif
470 
472 
473 cleanup:
474  if (encoder != NULL)
475  KMSDRM_drmModeFreeEncoder(encoder);
476  if (connector != NULL)
477  KMSDRM_drmModeFreeConnector(connector);
478  if (resources != NULL)
479  KMSDRM_drmModeFreeResources(resources);
480 
481  if (ret != 0) {
482  /* Error (complete) cleanup */
483  SDL_free(data);
484  if(vdata->saved_crtc != NULL) {
485  KMSDRM_drmModeFreeCrtc(vdata->saved_crtc);
486  vdata->saved_crtc = NULL;
487  }
488  if (vdata->gbm != NULL) {
489  KMSDRM_gbm_device_destroy(vdata->gbm);
490  vdata->gbm = NULL;
491  }
492  if (vdata->drm_fd >= 0) {
493  close(vdata->drm_fd);
494  vdata->drm_fd = -1;
495  }
496  }
497  return ret;
498 }
499 
500 void
502 {
504 
505  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoQuit()");
506 
509  }
510 
511  if(vdata->saved_crtc != NULL) {
512  if(vdata->drm_fd > 0 && vdata->saved_conn_id > 0) {
513  /* Restore saved CRTC settings */
514  drmModeCrtc *crtc = vdata->saved_crtc;
515  if(KMSDRM_drmModeSetCrtc(vdata->drm_fd, crtc->crtc_id, crtc->buffer_id,
516  crtc->x, crtc->y, &vdata->saved_conn_id, 1,
517  &crtc->mode) != 0) {
518  SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not restore original CRTC mode");
519  }
520  }
521  KMSDRM_drmModeFreeCrtc(vdata->saved_crtc);
522  vdata->saved_crtc = NULL;
523  }
524  if (vdata->gbm != NULL) {
525  KMSDRM_gbm_device_destroy(vdata->gbm);
526  vdata->gbm = NULL;
527  }
528  if (vdata->drm_fd >= 0) {
529  close(vdata->drm_fd);
530  SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Closed DRM FD %d", vdata->drm_fd);
531  vdata->drm_fd = -1;
532  }
533 #ifdef SDL_INPUT_LINUXEV
534  SDL_EVDEV_Quit();
535 #endif
536 }
537 
538 void
540 {
541  /* Only one display mode available, the current one */
542  SDL_AddDisplayMode(display, &display->current_mode);
543 }
544 
545 int
547 {
548  return 0;
549 }
550 
551 int
553 {
554  SDL_WindowData *wdata;
555  SDL_VideoDisplay *display;
557  Uint32 surface_fmt, surface_flags;
558 
559  /* Allocate window internal data */
560  wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
561  if (wdata == NULL) {
562  SDL_OutOfMemory();
563  goto error;
564  }
565 
566  wdata->waiting_for_flip = SDL_FALSE;
567  display = SDL_GetDisplayForWindow(window);
568 
569  /* Windows have one size for now */
570  window->w = display->desktop_mode.w;
571  window->h = display->desktop_mode.h;
572 
573  /* Maybe you didn't ask for a fullscreen OpenGL window, but that's what you get */
575 
576  surface_fmt = GBM_FORMAT_XRGB8888;
577  surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
578 
579  if (!KMSDRM_gbm_device_is_format_supported(vdata->gbm, surface_fmt, surface_flags)) {
580  SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "GBM surface format not supported. Trying anyway.");
581  }
582  wdata->gs = KMSDRM_gbm_surface_create(vdata->gbm, window->w, window->h, surface_fmt, surface_flags);
583 
584 #if SDL_VIDEO_OPENGL_EGL
585  if (!_this->egl_data) {
586  if (SDL_GL_LoadLibrary(NULL) < 0) {
587  goto error;
588  }
589  }
590  wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wdata->gs);
591 
592  if (wdata->egl_surface == EGL_NO_SURFACE) {
593  SDL_SetError("Could not create EGL window surface");
594  goto error;
595  }
596 #endif /* SDL_VIDEO_OPENGL_EGL */
597 
598  /* In case we want low-latency, double-buffer video, we take note here */
599  wdata->double_buffer = SDL_FALSE;
601  wdata->double_buffer = SDL_TRUE;
602  }
603 
604  /* Window is created, but we have yet to set up CRTC to one of the GBM buffers if we want
605  drmModePageFlip to work, and we can't do it until EGL is completely setup, because we
606  need to do eglSwapBuffers so we can get a valid GBM buffer object to call
607  drmModeSetCrtc on it. */
608  wdata->crtc_ready = SDL_FALSE;
609 
610  /* Setup driver data for this window */
611  window->driverdata = wdata;
612 
613  /* One window, it always has focus */
614  SDL_SetMouseFocus(window);
615  SDL_SetKeyboardFocus(window);
616 
617  /* Window has been successfully created */
618  return 0;
619 
620 error:
621  if (wdata != NULL) {
622 #if SDL_VIDEO_OPENGL_EGL
623  if (wdata->egl_surface != EGL_NO_SURFACE)
624  SDL_EGL_DestroySurface(_this, wdata->egl_surface);
625 #endif /* SDL_VIDEO_OPENGL_EGL */
626  if (wdata->gs != NULL)
627  KMSDRM_gbm_surface_destroy(wdata->gs);
628  SDL_free(wdata);
629  }
630  return -1;
631 }
632 
633 void
635 {
636  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
637  if(data) {
638  /* Wait for any pending page flips and unlock buffer */
639  KMSDRM_WaitPageFlip(_this, data, -1);
640  if (data->crtc_bo != NULL) {
641  KMSDRM_gbm_surface_release_buffer(data->gs, data->crtc_bo);
642  data->crtc_bo = NULL;
643  }
644  if (data->next_bo != NULL) {
645  KMSDRM_gbm_surface_release_buffer(data->gs, data->next_bo);
646  data->next_bo = NULL;
647  }
648  if (data->current_bo != NULL) {
649  KMSDRM_gbm_surface_release_buffer(data->gs, data->current_bo);
650  data->current_bo = NULL;
651  }
652 #if SDL_VIDEO_OPENGL_EGL
653  SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, EGL_NO_CONTEXT);
654  if (data->egl_surface != EGL_NO_SURFACE) {
655  SDL_EGL_DestroySurface(_this, data->egl_surface);
656  }
657 #endif /* SDL_VIDEO_OPENGL_EGL */
658  if (data->gs != NULL) {
659  KMSDRM_gbm_surface_destroy(data->gs);
660  data->gs = NULL;
661  }
662  SDL_free(data);
663  window->driverdata = NULL;
664  }
665 }
666 
667 int
668 KMSDRM_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
669 {
670  return -1;
671 }
672 
673 void
675 {
676 }
677 void
679 {
680 }
681 void
683 {
684 }
685 void
687 {
688 }
689 void
691 {
692 }
693 void
695 {
696 }
697 void
699 {
700 }
701 void
703 {
704 }
705 void
707 {
708 }
709 void
711 {
712 }
713 void
714 KMSDRM_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
715 {
716 
717 }
718 
719 /*****************************************************************************/
720 /* SDL Window Manager function */
721 /*****************************************************************************/
722 SDL_bool
723 KMSDRM_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
724 {
725  if (info->version.major <= SDL_MAJOR_VERSION) {
726  return SDL_TRUE;
727  } else {
728  SDL_SetError("application not compiled with SDL %d.%d\n",
730  return SDL_FALSE;
731  }
732 
733  /* Failed to get window manager information */
734  return SDL_FALSE;
735 }
736 
737 #endif /* SDL_VIDEO_DRIVER_KMSDRM */
738 
739 /* 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:228
void * KMSDRM_GLES_GetProcAddress(_THIS, const char *proc)
SDL_bool waiting_for_flip
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:630
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 local 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
#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:394
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:261
void(* ShowWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:223
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:216
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:177
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:255
GLuint GLint GLboolean GLint GLenum access
GLuint res
int(* SetDisplayMode)(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
Definition: SDL_sysvideo.h:205
#define SDL_GetHintBoolean
#define SDL_LogError
struct SDL_VideoDevice::@33 gl_config
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:224
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:225
#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:248
SDL_GLContext(* GL_CreateContext)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:258
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:259
#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:235
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
void(* SetWindowIcon)(_THIS, SDL_Window *window, SDL_Surface *icon)
Definition: SDL_sysvideo.h:214
drmEventContext drm_evctx
void KMSDRM_RestoreWindow(_THIS, SDL_Window *window)
SDL_bool crtc_ready
struct gbm_bo * crtc_bo
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:257
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:197
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:211
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_bool
Definition: SDL_stdinc.h:161
SDL_DisplayMode desktop_mode
Definition: SDL_sysvideo.h:131
unsigned int uint32_t
void(* VideoQuit)(_THIS)
Definition: SDL_sysvideo.h:167
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:1092
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:215
int(* GL_SwapWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:263
#define SDL_HINT_VIDEO_DOUBLE_BUFFER
Tell the video driver that we only want a double buffer.
Definition: SDL_hints.h:974
struct gbm_surface * gs
The type used to identify a window.
Definition: SDL_sysvideo.h:73
GLbitfield GLuint64 timeout
uint32_t Uint32
Definition: SDL_stdinc.h:203
void(* MinimizeWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:227
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:754
struct gbm_bo * next_bo
int(* VideoInit)(_THIS)
Definition: SDL_sysvideo.h:161
#define SDL_snprintf
int(* CreateSDLWindowFrom)(_THIS, SDL_Window *window, const void *data)
Definition: SDL_sysvideo.h:212
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:264
Uint32 format
Definition: SDL_video.h:55
void(* SetWindowTitle)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:213
#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:262
void(* MaximizeWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:226
Uint32 flags
Definition: SDL_sysvideo.h:83
drmModeCrtc * saved_crtc
void KMSDRM_VideoQuit(_THIS)
uint32_t saved_conn_id
void(* SetWindowGrab)(_THIS, SDL_Window *window, SDL_bool grabbed)
Definition: SDL_sysvideo.h:234
void *(* GL_GetProcAddress)(_THIS, const char *proc)
Definition: SDL_sysvideo.h:256
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:281