Go to the documentation of this file.
22 #include "../../SDL_internal.h"
24 #if SDL_VIDEO_DRIVER_KMSDRM
27 #include "../SDL_sysvideo.h"
31 #include "../../events/SDL_mouse_c.h"
32 #include "../../events/SDL_keyboard_c.h"
34 #ifdef SDL_INPUT_LINUXEV
35 #include "../../core/linux/SDL_evdev.h"
48 #define KMSDRM_DRI_PATH "/dev/dri/"
51 check_modestting(
int devindex)
59 drm_fd = open(
device, O_RDWR | O_CLOEXEC);
62 drmModeRes *resources = KMSDRM_drmModeGetResources(drm_fd);
63 if (resources !=
NULL) {
65 KMSDRM_drmModeFreeResources(resources);
75 static int get_dricount(
void)
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",
89 if (
access(KMSDRM_DRI_PATH, F_OK) == -1) {
90 printf(
"The path %s cannot be opened\n",
95 folder = opendir(KMSDRM_DRI_PATH);
97 while ((
res = readdir(folder))) {
98 if (
res->d_type == DT_CHR) {
111 const int devcount = get_dricount();
114 for (
i = 0;
i < devcount;
i++) {
115 if (check_modestting(
i)) {
124 KMSDRM_Available(
void)
128 ret = get_driindex();
148 KMSDRM_Create(
int devindex)
153 if (!devindex || (devindex > 99)) {
154 devindex = get_driindex();
158 SDL_SetError(
"devindex (%d) must be between 0 and 99.\n", devindex);
182 device->driverdata = vdata;
188 device->free = KMSDRM_Destroy;
210 #if SDL_VIDEO_OPENGL_EGL
236 "KMS/DRM Video Driver",
243 KMSDRM_FBDestroyCallback(
struct gbm_bo *bo,
void *
data)
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);
264 if (fb_info !=
NULL) {
271 if (fb_info ==
NULL) {
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;
290 KMSDRM_gbm_bo_set_user_data(bo, fb_info, KMSDRM_FBDestroyCallback);
305 if (vdata->
drm_pollfd.revents & (POLLHUP | POLLERR)) {
323 KMSDRM_FlipHandler(
int fd,
unsigned int frame,
unsigned int sec,
unsigned int usec,
void *
data)
340 drmModeRes *resources =
NULL;
341 drmModeConnector *connector =
NULL;
342 drmModeEncoder *encoder =
NULL;
356 if (devname ==
NULL) {
361 vdata->
drm_fd = open(devname, O_RDWR | O_CLOEXEC);
370 vdata->
gbm = KMSDRM_gbm_create_device(vdata->
drm_fd);
377 resources = KMSDRM_drmModeGetResources(vdata->
drm_fd);
383 for (
i = 0;
i < resources->count_connectors;
i++) {
384 connector = KMSDRM_drmModeGetConnector(vdata->
drm_fd, resources->connectors[
i]);
385 if (connector ==
NULL)
388 if (connector->connection == DRM_MODE_CONNECTED &&
389 connector->count_modes > 0) {
391 connector->connector_id, connector->count_modes);
396 KMSDRM_drmModeFreeConnector(connector);
400 if (
i == resources->count_connectors) {
401 ret =
SDL_SetError(
"No currently active connector found.");
405 for (
i = 0;
i < resources->count_encoders;
i++) {
406 encoder = KMSDRM_drmModeGetEncoder(vdata->
drm_fd, resources->encoders[
i]);
411 if (encoder->encoder_id == connector->encoder_id) {
413 data->encoder_id = encoder->encoder_id;
417 KMSDRM_drmModeFreeEncoder(encoder);
421 if (
i == resources->count_encoders) {
434 data->crtc_id = encoder->crtc_id;
436 vdata->
crtc_id = encoder->crtc_id;
464 vdata->
drm_evctx.version = DRM_EVENT_CONTEXT_VERSION;
465 vdata->
drm_evctx.page_flip_handler = KMSDRM_FlipHandler;
467 #ifdef SDL_INPUT_LINUXEV
475 KMSDRM_drmModeFreeEncoder(encoder);
476 if (connector !=
NULL)
477 KMSDRM_drmModeFreeConnector(connector);
478 if (resources !=
NULL)
479 KMSDRM_drmModeFreeResources(resources);
489 KMSDRM_gbm_device_destroy(vdata->
gbm);
515 if(KMSDRM_drmModeSetCrtc(vdata->
drm_fd, crtc->crtc_id, crtc->buffer_id,
525 KMSDRM_gbm_device_destroy(vdata->
gbm);
533 #ifdef SDL_INPUT_LINUXEV
557 Uint32 surface_fmt, surface_flags;
576 surface_fmt = GBM_FORMAT_XRGB8888;
577 surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
579 if (!KMSDRM_gbm_device_is_format_supported(vdata->
gbm, surface_fmt, surface_flags)) {
582 wdata->
gs = KMSDRM_gbm_surface_create(vdata->
gbm,
window->w,
window->h, surface_fmt, surface_flags);
584 #if SDL_VIDEO_OPENGL_EGL
585 if (!
_this->egl_data) {
611 window->driverdata = wdata;
622 #if SDL_VIDEO_OPENGL_EGL
627 KMSDRM_gbm_surface_destroy(wdata->
gs);
641 KMSDRM_gbm_surface_release_buffer(
data->gs,
data->crtc_bo);
645 KMSDRM_gbm_surface_release_buffer(
data->gs,
data->next_bo);
649 KMSDRM_gbm_surface_release_buffer(
data->gs,
data->current_bo);
652 #if SDL_VIDEO_OPENGL_EGL
655 SDL_EGL_DestroySurface(
_this,
data->egl_surface);
659 KMSDRM_gbm_surface_destroy(
data->gs);
728 SDL_SetError(
"application not compiled with SDL %d.%d\n",
@ SDL_PIXELFORMAT_ARGB8888
void * KMSDRM_GLES_GetProcAddress(_THIS, const char *proc)
void KMSDRM_DestroyWindow(_THIS, SDL_Window *window)
int KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
A collection of pixels used in software blitting.
void KMSDRM_SetWindowSize(_THIS, SDL_Window *window)
EGLImageKHR EGLint EGLint * handle
GLbitfield GLuint64 timeout
GLuint GLint GLboolean GLint GLenum access
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
void KMSDRM_MaximizeWindow(_THIS, SDL_Window *window)
int KMSDRM_GLES_LoadLibrary(_THIS, const char *path)
int KMSDRM_GLES_SetSwapInterval(_THIS, int interval)
void KMSDRM_InitMouse(_THIS)
#define SDL_GL_LoadLibrary
void SDL_SetKeyboardFocus(SDL_Window *window)
int KMSDRM_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
SDL_DisplayMode desktop_mode
int KMSDRM_CreateWindow(_THIS, SDL_Window *window)
GLfloat GLfloat GLfloat GLfloat h
void SDL_SetMouseFocus(SDL_Window *window)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
void KMSDRM_GLES_UnloadLibrary(_THIS)
The type used to identify a window.
The structure that defines a display mode.
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
#define SDL_GL_UnloadLibrary
SDL_GLContext KMSDRM_GLES_CreateContext(_THIS, SDL_Window *window)
static void cleanup(void)
#define SDL_GetHintBoolean
void SDL_KMSDRM_UnloadSymbols(void)
static SDL_VideoDevice * _this
void KMSDRM_PumpEvents(_THIS)
#define SDL_MINOR_VERSION
EGLSurface EGLNativeWindowType * window
VideoBootStrap KMSDRM_bootstrap
void KMSDRM_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
int KMSDRM_VideoInit(_THIS)
int KMSDRM_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
SDL_bool KMSDRM_WaitPageFlip(_THIS, SDL_WindowData *wdata, int timeout)
#define SDL_OutOfMemory()
void KMSDRM_RestoreWindow(_THIS, SDL_Window *window)
void KMSDRM_SetWindowPosition(_THIS, SDL_Window *window)
void KMSDRM_RaiseWindow(_THIS, SDL_Window *window)
void KMSDRM_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
void KMSDRM_HideWindow(_THIS, SDL_Window *window)
SDL_bool waiting_for_flip
SDL_bool KMSDRM_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
drmEventContext drm_evctx
void KMSDRM_GLES_DeleteContext(_THIS, SDL_GLContext context)
#define SDL_HINT_VIDEO_DOUBLE_BUFFER
Tell the video driver that we only want a double buffer.
KMSDRM_FBInfo * KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
void KMSDRM_ShowWindow(_THIS, SDL_Window *window)
int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window *window)
void KMSDRM_MinimizeWindow(_THIS, SDL_Window *window)
void KMSDRM_SetWindowTitle(_THIS, SDL_Window *window)
void KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
int SDL_KMSDRM_LoadSymbols(void)
SDL_DisplayMode current_mode
#define SDL_MAJOR_VERSION
static SDL_AudioDeviceID device
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)
void KMSDRM_VideoQuit(_THIS)
int KMSDRM_GLES_GetSwapInterval(_THIS)
struct SDL_VideoDevice::@33 gl_config
GLubyte GLubyte GLubyte GLubyte w