SDL_kmsdrmvideo.c
Go to the documentation of this file.
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_KMSDRM
/* SDL internals */
#include "../SDL_sysvideo.h"
#include "SDL_syswm.h"
#include "SDL_log.h"
#include "SDL_hints.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_keyboard_c.h"
#ifdef SDL_INPUT_LINUXEV
#include "../../core/linux/SDL_evdev.h"
#endif
/* KMS/DRM declarations */
#include "SDL_kmsdrmvideo.h"
#include "SDL_kmsdrmevents.h"
#include "SDL_kmsdrmopengles.h"
#include "SDL_kmsdrmmouse.h"
#include "SDL_kmsdrmdyn.h"
#define KMSDRM_DRI_CARD_0 "/dev/dri/card0"
static int
KMSDRM_Available(void)
{
int available = 0;
int drm_fd = open(KMSDRM_DRI_CARD_0, O_RDWR | O_CLOEXEC);
if (drm_fd >= 0) {
if (SDL_KMSDRM_LoadSymbols()) {
drmModeRes *resources = KMSDRM_drmModeGetResources(drm_fd);
if (resources != NULL) {
available = 1;
KMSDRM_drmModeFreeResources(resources);
}
SDL_KMSDRM_UnloadSymbols();
}
close(drm_fd);
}
return available;
}
static void
KMSDRM_Destroy(SDL_VideoDevice * device)
{
if (device->driverdata != NULL) {
SDL_free(device->driverdata);
device->driverdata = NULL;
}
SDL_free(device);
SDL_KMSDRM_UnloadSymbols();
}
static SDL_VideoDevice *
KMSDRM_Create(int devindex)
{
SDL_VideoDevice *device;
SDL_VideoData *vdata;
if (devindex < 0 || devindex > 99) {
SDL_SetError("devindex (%d) must be between 0 and 99.\n", devindex);
return NULL;
}
if (!SDL_KMSDRM_LoadSymbols()) {
return NULL;
}
/* Initialize SDL_VideoDevice structure */
device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
if (device == NULL) {
SDL_OutOfMemory();
return NULL;
}
/* Initialize internal data */
vdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
if (vdata == NULL) {
SDL_OutOfMemory();
goto cleanup;
}
vdata->devindex = devindex;
vdata->drm_fd = -1;
device->driverdata = vdata;
/* Setup amount of available displays and current display */
device->num_displays = 0;
/* Set device free function */
device->free = KMSDRM_Destroy;
/* Setup all functions which we can handle */
device->VideoInit = KMSDRM_VideoInit;
device->VideoQuit = KMSDRM_VideoQuit;
device->GetDisplayModes = KMSDRM_GetDisplayModes;
device->SetDisplayMode = KMSDRM_SetDisplayMode;
device->CreateSDLWindow = KMSDRM_CreateWindow;
device->CreateSDLWindowFrom = KMSDRM_CreateWindowFrom;
device->SetWindowTitle = KMSDRM_SetWindowTitle;
device->SetWindowIcon = KMSDRM_SetWindowIcon;
device->SetWindowPosition = KMSDRM_SetWindowPosition;
device->SetWindowSize = KMSDRM_SetWindowSize;
device->ShowWindow = KMSDRM_ShowWindow;
device->HideWindow = KMSDRM_HideWindow;
device->RaiseWindow = KMSDRM_RaiseWindow;
device->MaximizeWindow = KMSDRM_MaximizeWindow;
device->MinimizeWindow = KMSDRM_MinimizeWindow;
device->RestoreWindow = KMSDRM_RestoreWindow;
device->SetWindowGrab = KMSDRM_SetWindowGrab;
device->DestroyWindow = KMSDRM_DestroyWindow;
device->GetWindowWMInfo = KMSDRM_GetWindowWMInfo;
#if SDL_VIDEO_OPENGL_EGL
device->GL_LoadLibrary = KMSDRM_GLES_LoadLibrary;
device->GL_GetProcAddress = KMSDRM_GLES_GetProcAddress;
device->GL_UnloadLibrary = KMSDRM_GLES_UnloadLibrary;
device->GL_CreateContext = KMSDRM_GLES_CreateContext;
device->GL_MakeCurrent = KMSDRM_GLES_MakeCurrent;
device->GL_SetSwapInterval = KMSDRM_GLES_SetSwapInterval;
device->GL_GetSwapInterval = KMSDRM_GLES_GetSwapInterval;
device->GL_SwapWindow = KMSDRM_GLES_SwapWindow;
device->GL_DeleteContext = KMSDRM_GLES_DeleteContext;
#endif
device->PumpEvents = KMSDRM_PumpEvents;
return device;
cleanup:
if (device != NULL)
SDL_free(device);
if (vdata != NULL)
SDL_free(vdata);
return NULL;
}
VideoBootStrap KMSDRM_bootstrap = {
"KMSDRM",
"KMS/DRM Video Driver",
KMSDRM_Available,
KMSDRM_Create
};
static void
KMSDRM_FBDestroyCallback(struct gbm_bo *bo, void *data)
{
KMSDRM_FBInfo *fb_info = (KMSDRM_FBInfo *)data;
if (fb_info && fb_info->drm_fd > 0 && fb_info->fb_id != 0) {
KMSDRM_drmModeRmFB(fb_info->drm_fd, fb_info->fb_id);
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Delete DRM FB %u", fb_info->fb_id);
}
free(fb_info);
}
KMSDRM_FBInfo *
KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
{
uint32_t w, h, stride, handle;
int ret;
SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
KMSDRM_FBInfo *fb_info;
fb_info = (KMSDRM_FBInfo *)KMSDRM_gbm_bo_get_user_data(bo);
if (fb_info != NULL) {
/* Have a previously used framebuffer, return it */
return fb_info;
}
/* Here a new DRM FB must be created */
fb_info = (KMSDRM_FBInfo *)SDL_calloc(1, sizeof(KMSDRM_FBInfo));
if (fb_info == NULL) {
SDL_OutOfMemory();
return NULL;
}
fb_info->drm_fd = vdata->drm_fd;
w = KMSDRM_gbm_bo_get_width(bo);
h = KMSDRM_gbm_bo_get_height(bo);
stride = KMSDRM_gbm_bo_get_stride(bo);
handle = KMSDRM_gbm_bo_get_handle(bo).u32;
ret = KMSDRM_drmModeAddFB(vdata->drm_fd, w, h, 24, 32, stride, handle, &fb_info->fb_id);
if (ret < 0) {
free(fb_info);
return NULL;
}
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);
/* Associate our DRM framebuffer with this buffer object */
KMSDRM_gbm_bo_set_user_data(bo, fb_info, KMSDRM_FBDestroyCallback);
return fb_info;
}
SDL_bool
KMSDRM_WaitPageFlip(_THIS, SDL_WindowData *wdata, int timeout) {
SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
while (wdata->waiting_for_flip) {
vdata->drm_pollfd.revents = 0;
if (poll(&vdata->drm_pollfd, 1, timeout) < 0) {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll error");
return SDL_FALSE;
}
if (vdata->drm_pollfd.revents & (POLLHUP | POLLERR)) {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll hup or error");
return SDL_FALSE;
}
if (vdata->drm_pollfd.revents & POLLIN) {
/* Page flip? If so, drmHandleEvent will unset wdata->waiting_for_flip */
KMSDRM_drmHandleEvent(vdata->drm_fd, &vdata->drm_evctx);
} else {
/* Timed out and page flip didn't happen */
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Dropping frame while waiting_for_flip");
return SDL_FALSE;
}
}
return SDL_TRUE;
}
static void
KMSDRM_FlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
{
*((SDL_bool *) data) = SDL_FALSE;
}
/*****************************************************************************/
/* SDL Video and Display initialization/handling functions */
/* _this is a SDL_VideoDevice * */
/*****************************************************************************/
int
KMSDRM_VideoInit(_THIS)
{
int i;
int ret = 0;
char *devname;
SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
drmModeRes *resources = NULL;
drmModeConnector *connector = NULL;
drmModeEncoder *encoder = NULL;
SDL_DisplayMode current_mode;
SDL_VideoDisplay display;
/* Allocate display internal data */
SDL_DisplayData *data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
if (data == NULL) {
return SDL_OutOfMemory();
}
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoInit()");
/* Open /dev/dri/cardNN */
devname = (char *) SDL_calloc(1, 16);
if (devname == NULL) {
ret = SDL_OutOfMemory();
goto cleanup;
}
SDL_snprintf(devname, 16, "/dev/dri/card%d", vdata->devindex);
vdata->drm_fd = open(devname, O_RDWR | O_CLOEXEC);
SDL_free(devname);
if (vdata->drm_fd < 0) {
ret = SDL_SetError("Could not open /dev/dri/card%d.", vdata->devindex);
goto cleanup;
}
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", vdata->drm_fd);
vdata->gbm = KMSDRM_gbm_create_device(vdata->drm_fd);
if (vdata->gbm == NULL) {
ret = SDL_SetError("Couldn't create gbm device.");
goto cleanup;
}
/* Find the first available connector with modes */
resources = KMSDRM_drmModeGetResources(vdata->drm_fd);
if (!resources) {
ret = SDL_SetError("drmModeGetResources(%d) failed", vdata->drm_fd);
goto cleanup;
}
for (i = 0; i < resources->count_connectors; i++) {
connector = KMSDRM_drmModeGetConnector(vdata->drm_fd, resources->connectors[i]);
if (connector == NULL)
continue;
if (connector->connection == DRM_MODE_CONNECTED &&
connector->count_modes > 0) {
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found connector %d with %d modes.",
connector->connector_id, connector->count_modes);
vdata->saved_conn_id = connector->connector_id;
break;
}
KMSDRM_drmModeFreeConnector(connector);
connector = NULL;
}
if (i == resources->count_connectors) {
ret = SDL_SetError("No currently active connector found.");
goto cleanup;
}
for (i = 0; i < resources->count_encoders; i++) {
encoder = KMSDRM_drmModeGetEncoder(vdata->drm_fd, resources->encoders[i]);
if (encoder == NULL)
continue;
if (encoder->encoder_id == connector->encoder_id) {
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", encoder->encoder_id);
data->encoder_id = encoder->encoder_id;
break;
}
KMSDRM_drmModeFreeEncoder(encoder);
encoder = NULL;
}
if (i == resources->count_encoders) {
ret = SDL_SetError("No connected encoder found.");
goto cleanup;
}
vdata->saved_crtc = KMSDRM_drmModeGetCrtc(vdata->drm_fd, encoder->crtc_id);
if (vdata->saved_crtc == NULL) {
ret = SDL_SetError("No CRTC found.");
goto cleanup;
}
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Saved crtc_id %u, fb_id %u, (%u,%u), %ux%u",
vdata->saved_crtc->crtc_id, vdata->saved_crtc->buffer_id, vdata->saved_crtc->x,
vdata->saved_crtc->y, vdata->saved_crtc->width, vdata->saved_crtc->height);
data->crtc_id = encoder->crtc_id;
data->cur_mode = vdata->saved_crtc->mode;
vdata->crtc_id = encoder->crtc_id;
SDL_zero(current_mode);
current_mode.w = vdata->saved_crtc->mode.hdisplay;
current_mode.h = vdata->saved_crtc->mode.vdisplay;
current_mode.refresh_rate = vdata->saved_crtc->mode.vrefresh;
/* FIXME ?
drmModeFB *fb = drmModeGetFB(vdata->drm_fd, vdata->saved_crtc->buffer_id);
current_mode.format = drmToSDLPixelFormat(fb->bpp, fb->depth);
drmModeFreeFB(fb);
*/
current_mode.format = SDL_PIXELFORMAT_ARGB8888;
current_mode.driverdata = NULL;
SDL_zero(display);
display.desktop_mode = current_mode;
display.current_mode = current_mode;
display.driverdata = data;
/* SDL_VideoQuit will later SDL_free(display.driverdata) */
SDL_AddVideoDisplay(&display);
/* Setup page flip handler */
vdata->drm_pollfd.fd = vdata->drm_fd;
vdata->drm_pollfd.events = POLLIN;
vdata->drm_evctx.version = DRM_EVENT_CONTEXT_VERSION;
vdata->drm_evctx.page_flip_handler = KMSDRM_FlipHandler;
#ifdef SDL_INPUT_LINUXEV
SDL_EVDEV_Init();
#endif
KMSDRM_InitMouse(_this);
cleanup:
if (encoder != NULL)
KMSDRM_drmModeFreeEncoder(encoder);
if (connector != NULL)
KMSDRM_drmModeFreeConnector(connector);
if (resources != NULL)
KMSDRM_drmModeFreeResources(resources);
if (ret != 0) {
/* Error (complete) cleanup */
SDL_free(data);
if(vdata->saved_crtc != NULL) {
KMSDRM_drmModeFreeCrtc(vdata->saved_crtc);
vdata->saved_crtc = NULL;
}
if (vdata->gbm != NULL) {
KMSDRM_gbm_device_destroy(vdata->gbm);
vdata->gbm = NULL;
}
if (vdata->drm_fd >= 0) {
close(vdata->drm_fd);
vdata->drm_fd = -1;
}
}
return ret;
}
void
KMSDRM_VideoQuit(_THIS)
{
SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoQuit()");
if (_this->gl_config.driver_loaded) {
SDL_GL_UnloadLibrary();
}
if(vdata->saved_crtc != NULL) {
if(vdata->drm_fd > 0 && vdata->saved_conn_id > 0) {
/* Restore saved CRTC settings */
drmModeCrtc *crtc = vdata->saved_crtc;
if(KMSDRM_drmModeSetCrtc(vdata->drm_fd, crtc->crtc_id, crtc->buffer_id,
crtc->x, crtc->y, &vdata->saved_conn_id, 1,
&crtc->mode) != 0) {
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not restore original CRTC mode");
}
}
KMSDRM_drmModeFreeCrtc(vdata->saved_crtc);
vdata->saved_crtc = NULL;
}
if (vdata->gbm != NULL) {
KMSDRM_gbm_device_destroy(vdata->gbm);
vdata->gbm = NULL;
}
if (vdata->drm_fd >= 0) {
close(vdata->drm_fd);
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Closed DRM FD %d", vdata->drm_fd);
vdata->drm_fd = -1;
}
#ifdef SDL_INPUT_LINUXEV
SDL_EVDEV_Quit();
#endif
}
void
KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
{
/* Only one display mode available, the current one */
SDL_AddDisplayMode(display, &display->current_mode);
}
int
KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
{
return 0;
}
int
KMSDRM_CreateWindow(_THIS, SDL_Window * window)
{
SDL_WindowData *wdata;
SDL_VideoDisplay *display;
SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
Uint32 surface_fmt, surface_flags;
/* Allocate window internal data */
wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
if (wdata == NULL) {
SDL_OutOfMemory();
goto error;
}
wdata->waiting_for_flip = SDL_FALSE;
display = SDL_GetDisplayForWindow(window);
/* Windows have one size for now */
window->w = display->desktop_mode.w;
window->h = display->desktop_mode.h;
/* Maybe you didn't ask for a fullscreen OpenGL window, but that's what you get */
window->flags |= (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);
surface_fmt = GBM_FORMAT_XRGB8888;
surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
if (!KMSDRM_gbm_device_is_format_supported(vdata->gbm, surface_fmt, surface_flags)) {
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "GBM surface format not supported. Trying anyway.");
}
wdata->gs = KMSDRM_gbm_surface_create(vdata->gbm, window->w, window->h, surface_fmt, surface_flags);
#if SDL_VIDEO_OPENGL_EGL
if (!_this->egl_data) {
if (SDL_GL_LoadLibrary(NULL) < 0) {
goto error;
}
}
wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wdata->gs);
if (wdata->egl_surface == EGL_NO_SURFACE) {
SDL_SetError("Could not create EGL window surface");
goto error;
}
#endif /* SDL_VIDEO_OPENGL_EGL */
/* In case we want low-latency, double-buffer video, we take note here */
wdata->double_buffer = SDL_FALSE;
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) {
wdata->double_buffer = SDL_TRUE;
}
/* Window is created, but we have yet to set up CRTC to one of the GBM buffers if we want
drmModePageFlip to work, and we can't do it until EGL is completely setup, because we
need to do eglSwapBuffers so we can get a valid GBM buffer object to call
drmModeSetCrtc on it. */
wdata->crtc_ready = SDL_FALSE;
/* Setup driver data for this window */
window->driverdata = wdata;
/* One window, it always has focus */
SDL_SetMouseFocus(window);
SDL_SetKeyboardFocus(window);
/* Window has been successfully created */
return 0;
error:
if (wdata != NULL) {
#if SDL_VIDEO_OPENGL_EGL
if (wdata->egl_surface != EGL_NO_SURFACE)
SDL_EGL_DestroySurface(_this, wdata->egl_surface);
#endif /* SDL_VIDEO_OPENGL_EGL */
if (wdata->gs != NULL)
KMSDRM_gbm_surface_destroy(wdata->gs);
SDL_free(wdata);
}
return -1;
}
void
KMSDRM_DestroyWindow(_THIS, SDL_Window * window)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
if(data) {
/* Wait for any pending page flips and unlock buffer */
KMSDRM_WaitPageFlip(_this, data, -1);
if (data->next_bo != NULL) {
KMSDRM_gbm_surface_release_buffer(data->gs, data->next_bo);
data->next_bo = NULL;
}
if (data->current_bo != NULL) {
KMSDRM_gbm_surface_release_buffer(data->gs, data->current_bo);
data->current_bo = NULL;
}
#if SDL_VIDEO_OPENGL_EGL
SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (data->egl_surface != EGL_NO_SURFACE) {
SDL_EGL_DestroySurface(_this, data->egl_surface);
}
#endif /* SDL_VIDEO_OPENGL_EGL */
if (data->gs != NULL) {
KMSDRM_gbm_surface_destroy(data->gs);
data->gs = NULL;
}
SDL_free(data);
window->driverdata = NULL;
}
}
int
KMSDRM_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
{
return -1;
}
void
KMSDRM_SetWindowTitle(_THIS, SDL_Window * window)
{
}
void
KMSDRM_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
{
}
void
KMSDRM_SetWindowPosition(_THIS, SDL_Window * window)
{
}
void
KMSDRM_SetWindowSize(_THIS, SDL_Window * window)
{
}
void
KMSDRM_ShowWindow(_THIS, SDL_Window * window)
{
}
void
KMSDRM_HideWindow(_THIS, SDL_Window * window)
{
}
void
KMSDRM_RaiseWindow(_THIS, SDL_Window * window)
{
}
void
KMSDRM_MaximizeWindow(_THIS, SDL_Window * window)
{
}
void
KMSDRM_MinimizeWindow(_THIS, SDL_Window * window)
{
}
void
KMSDRM_RestoreWindow(_THIS, SDL_Window * window)
{
}
void
KMSDRM_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
{
}
/*****************************************************************************/
/* SDL Window Manager function */
/*****************************************************************************/
SDL_bool
KMSDRM_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
{
if (info->version.major <= SDL_MAJOR_VERSION) {
return SDL_TRUE;
} else {
SDL_SetError("application not compiled with SDL %d.%d\n",
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
return SDL_FALSE;
}
/* Failed to get window manager information */
return SDL_FALSE;
}
#endif /* SDL_VIDEO_DRIVER_KMSDRM */
/* vi: set ts=4 sw=4 expandtab: */
KMSDRM_SetDisplayMode
int KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
KMSDRM_GLES_GetSwapInterval
int KMSDRM_GLES_GetSwapInterval(_THIS)
SDL_PIXELFORMAT_ARGB8888
Definition: SDL_pixels.h:248
SDL_MINOR_VERSION
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
SDL_WindowData::double_buffer
SDL_bool double_buffer
Definition: SDL_kmsdrmvideo.h:67
SDL_VideoData::drm_fd
int drm_fd
Definition: SDL_kmsdrmvideo.h:42
stride
GLsizei stride
Definition: SDL_opengl_glext.h:378
SDL_KMSDRM_UnloadSymbols
void SDL_KMSDRM_UnloadSymbols(void)
SDL_LOG_CATEGORY_VIDEO
Definition: SDL_log.h:71
SDL_DisplayData::cur_mode
drmModeModeInfo cur_mode
Definition: SDL_kmsdrmvideo.h:56
KMSDRM_SetWindowSize
void KMSDRM_SetWindowSize(_THIS, SDL_Window *window)
SDL_VideoDevice::RestoreWindow
void(* RestoreWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:227
KMSDRM_GLES_GetProcAddress
void * KMSDRM_GLES_GetProcAddress(_THIS, const char *proc)
SDL_WindowData::waiting_for_flip
SDL_bool waiting_for_flip
Definition: SDL_kmsdrmvideo.h:65
SDL_TRUE
Definition: SDL_stdinc.h:142
SDL_SetKeyboardFocus
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:630
SDL_log.h
SDL_Window::w
int w
Definition: SDL_sysvideo.h:80
EGL_NO_SURFACE
#define EGL_NO_SURFACE
Definition: egl.h:100
SDL_DisplayMode::w
int w
Definition: SDL_video.h:56
SDL_VideoData::drm_pollfd
struct pollfd drm_pollfd
Definition: SDL_kmsdrmvideo.h:45
KMSDRM_bootstrap
VideoBootStrap KMSDRM_bootstrap
SDL_WindowData::current_bo
struct gbm_bo * current_bo
Definition: SDL_kmsdrmvideo.h:63
SDL_MAJOR_VERSION
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
KMSDRM_InitMouse
void KMSDRM_InitMouse(_THIS)
KMSDRM_MaximizeWindow
void KMSDRM_MaximizeWindow(_THIS, SDL_Window *window)
available
static int available()
Definition: video.c:356
SDL_VideoDevice::free
void(* free)(_THIS)
Definition: SDL_sysvideo.h:390
SDL_FALSE
Definition: SDL_stdinc.h:141
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1946
SDL_kmsdrmopengles.h
free
SDL_EventEntry * free
Definition: SDL_events.c:84
SDL_Surface
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
SDL_VideoDevice::driverdata
void * driverdata
Definition: SDL_sysvideo.h:377
SDL_VideoDevice::GL_SetSwapInterval
int(* GL_SetSwapInterval)(_THIS, int interval)
Definition: SDL_sysvideo.h:260
SDL_VideoDevice::ShowWindow
void(* ShowWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:222
SDL_DisplayMode
The structure that defines a display mode.
Definition: SDL_video.h:53
KMSDRM_CreateWindowFrom
int KMSDRM_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
SDL_SysWMinfo::version
SDL_version version
Definition: SDL_syswm.h:196
SDL_version::major
Uint8 major
Definition: SDL_version.h:53
SDL_KMSDRM_LoadSymbols
int SDL_KMSDRM_LoadSymbols(void)
SDL_VideoDevice::SetWindowSize
void(* SetWindowSize)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:215
SDL_DisplayMode::refresh_rate
int refresh_rate
Definition: SDL_video.h:58
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
KMSDRM_GLES_SetSwapInterval
int KMSDRM_GLES_SetSwapInterval(_THIS, int interval)
KMSDRM_GLES_LoadLibrary
int KMSDRM_GLES_LoadLibrary(_THIS, const char *path)
SDL_SetMouseFocus
void SDL_SetMouseFocus(SDL_Window *window)
Definition: SDL_mouse.c:151
SDL_DisplayData::crtc_id
uint32_t crtc_id
Definition: SDL_kmsdrmvideo.h:55
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:181
KMSDRM_GLES_UnloadLibrary
void KMSDRM_GLES_UnloadLibrary(_THIS)
SDL_GL_LoadLibrary
#define SDL_GL_LoadLibrary
Definition: SDL_dynapi_overrides.h:553
KMSDRM_GLES_CreateContext
SDL_GLContext KMSDRM_GLES_CreateContext(_THIS, SDL_Window *window)
SDL_AddVideoDisplay
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
Definition: SDL_video.c:606
KMSDRM_CreateWindow
int KMSDRM_CreateWindow(_THIS, SDL_Window *window)
SDL_VideoDevice::GL_LoadLibrary
int(* GL_LoadLibrary)(_THIS, const char *path)
Definition: SDL_sysvideo.h:254
SDL_DisplayData
Definition: SDL_cocoamodes.h:26
SDL_VideoDevice::SetDisplayMode
int(* SetDisplayMode)(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
Definition: SDL_sysvideo.h:204
SDL_kmsdrmmouse.h
SDL_WindowData
Definition: SDL_androidwindow.h:35
SDL_GetHintBoolean
#define SDL_GetHintBoolean
Definition: SDL_dynapi_overrides.h:608
SDL_LogError
#define SDL_LogError
Definition: SDL_dynapi_overrides.h:36
_this
static SDL_VideoDevice * _this
Definition: SDL_video.c:121
NativeWindowType
EGLNativeWindowType NativeWindowType
Definition: eglplatform.h:112
SDL_VideoDevice::HideWindow
void(* HideWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:223
device
static SDL_AudioDeviceID device
Definition: loopwave.c:37
SDL_GL_UnloadLibrary
#define SDL_GL_UnloadLibrary
Definition: SDL_dynapi_overrides.h:555
KMSDRM_SetWindowGrab
void KMSDRM_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
SDL_VideoDevice::RaiseWindow
void(* RaiseWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:224
SDL_LogDebug
#define SDL_LogDebug
Definition: SDL_dynapi_overrides.h:33
EGL_NO_CONTEXT
#define EGL_NO_CONTEXT
Definition: egl.h:98
SDL_VideoDevice::GetWindowWMInfo
SDL_bool(* GetWindowWMInfo)(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
Definition: SDL_sysvideo.h:247
SDL_VideoDevice::GL_CreateContext
SDL_GLContext(* GL_CreateContext)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:257
handle
EGLImageKHR EGLint EGLint * handle
Definition: eglext.h:937
SDL_SysWMinfo
Definition: SDL_syswm.h:194
KMSDRM_PumpEvents
void KMSDRM_PumpEvents(_THIS)
KMSDRM_VideoInit
int KMSDRM_VideoInit(_THIS)
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
SDL_VideoDevice::GL_MakeCurrent
int(* GL_MakeCurrent)(_THIS, SDL_Window *window, SDL_GLContext context)
Definition: SDL_sysvideo.h:258
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
frame
int frame
Definition: teststreaming.c:60
SDL_DisplayMode::driverdata
void * driverdata
Definition: SDL_video.h:59
KMSDRM_GLES_MakeCurrent
int KMSDRM_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
SDL_VideoDevice::driver_loaded
int driver_loaded
Definition: SDL_sysvideo.h:349
VideoBootStrap
Definition: SDL_sysvideo.h:393
KMSDRM_FBInfo
Definition: SDL_kmsdrmvideo.h:73
SDL_VideoDevice::num_displays
int num_displays
Definition: SDL_sysvideo.h:311
SDL_VideoDisplay::current_mode
SDL_DisplayMode current_mode
Definition: SDL_sysvideo.h:132
mode
GLenum mode
Definition: SDL_opengl_glext.h:1122
SDL_hints.h
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:731
SDL_VideoDevice::DestroyWindow
void(* DestroyWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:234
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
SDL_DisplayMode::h
int h
Definition: SDL_video.h:57
SDL_VideoDevice::SetWindowIcon
void(* SetWindowIcon)(_THIS, SDL_Window *window, SDL_Surface *icon)
Definition: SDL_sysvideo.h:213
SDL_VideoData::drm_evctx
drmEventContext drm_evctx
Definition: SDL_kmsdrmvideo.h:44
SDL_kmsdrmvideo.h
KMSDRM_RestoreWindow
void KMSDRM_RestoreWindow(_THIS, SDL_Window *window)
SDL_WindowData::crtc_ready
SDL_bool crtc_ready
Definition: SDL_kmsdrmvideo.h:66
KMSDRM_SetWindowIcon
void KMSDRM_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
KMSDRM_HideWindow
void KMSDRM_HideWindow(_THIS, SDL_Window *window)
SDL_VideoDisplay
Definition: SDL_sysvideo.h:125
SDL_Window::h
int h
Definition: SDL_sysvideo.h:80
SDL_VideoDevice::GL_UnloadLibrary
void(* GL_UnloadLibrary)(_THIS)
Definition: SDL_sysvideo.h:256
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
SDL_VideoData::gbm
struct gbm_device * gbm
Definition: SDL_kmsdrmvideo.h:43
SDL_VideoDevice::GetDisplayModes
void(* GetDisplayModes)(_THIS, SDL_VideoDisplay *display)
Definition: SDL_sysvideo.h:196
SDL_VideoData::devindex
int devindex
Definition: SDL_kmsdrmvideo.h:41
KMSDRM_GetWindowWMInfo
SDL_bool KMSDRM_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
KMSDRM_WaitPageFlip
SDL_bool KMSDRM_WaitPageFlip(_THIS, SDL_WindowData *wdata, int timeout)
NULL
#define NULL
Definition: begin_code.h:164
SDL_VideoDevice::CreateSDLWindow
int(* CreateSDLWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:210
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:139
SDL_VideoDisplay::desktop_mode
SDL_DisplayMode desktop_mode
Definition: SDL_sysvideo.h:131
uint32_t
unsigned int uint32_t
Definition: SDL_config_windows.h:63
SDL_VideoDevice::VideoQuit
void(* VideoQuit)(_THIS)
Definition: SDL_sysvideo.h:166
KMSDRM_SetWindowPosition
void KMSDRM_SetWindowPosition(_THIS, SDL_Window *window)
SDL_VideoData::crtc_id
uint32_t crtc_id
Definition: SDL_kmsdrmvideo.h:48
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
KMSDRM_RaiseWindow
void KMSDRM_RaiseWindow(_THIS, SDL_Window *window)
SDL_GetDisplayForWindow
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1073
window
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
KMSDRM_GLES_DeleteContext
void KMSDRM_GLES_DeleteContext(_THIS, SDL_GLContext context)
SDL_VideoDevice::SetWindowPosition
void(* SetWindowPosition)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:214
SDL_VideoDevice::GL_SwapWindow
int(* GL_SwapWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:262
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:861
SDL_WindowData::gs
struct gbm_surface * gs
Definition: SDL_kmsdrmvideo.h:62
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:73
timeout
GLbitfield GLuint64 timeout
Definition: SDL_opengl_glext.h:1483
SDL_VideoDevice::MinimizeWindow
void(* MinimizeWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:226
KMSDRM_MinimizeWindow
void KMSDRM_MinimizeWindow(_THIS, SDL_Window *window)
KMSDRM_SetWindowTitle
void KMSDRM_SetWindowTitle(_THIS, SDL_Window *window)
SDL_WINDOW_FULLSCREEN
Definition: SDL_video.h:100
KMSDRM_GetDisplayModes
void KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
SDL_kmsdrmdyn.h
SDL_VideoDevice
Definition: SDL_sysvideo.h:147
SDL_VideoData
Definition: SDL_androidvideo.h:35
SDL_AddDisplayMode
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
Definition: SDL_video.c:743
SDL_WindowData::next_bo
struct gbm_bo * next_bo
Definition: SDL_kmsdrmvideo.h:64
SDL_VideoDevice::VideoInit
int(* VideoInit)(_THIS)
Definition: SDL_sysvideo.h:160
SDL_snprintf
#define SDL_snprintf
Definition: SDL_dynapi_overrides.h:40
SDL_VideoDevice::CreateSDLWindowFrom
int(* CreateSDLWindowFrom)(_THIS, SDL_Window *window, const void *data)
Definition: SDL_sysvideo.h:211
SDL_WINDOW_OPENGL
Definition: SDL_video.h:101
SDL_VideoDevice::gl_config
struct SDL_VideoDevice::@34 gl_config
KMSDRM_FBFromBO
KMSDRM_FBInfo * KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
SDL_Window::driverdata
void * driverdata
Definition: SDL_sysvideo.h:111
SDL_VideoDevice::GL_DeleteContext
void(* GL_DeleteContext)(_THIS, SDL_GLContext context)
Definition: SDL_sysvideo.h:263
SDL_DisplayMode::format
Uint32 format
Definition: SDL_video.h:55
SDL_VideoDevice::SetWindowTitle
void(* SetWindowTitle)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:212
SDL_DisplayData::encoder_id
uint32_t encoder_id
Definition: SDL_kmsdrmvideo.h:54
SDL_LogWarn
#define SDL_LogWarn
Definition: SDL_dynapi_overrides.h:35
KMSDRM_GLES_SwapWindow
int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window *window)
KMSDRM_ShowWindow
void KMSDRM_ShowWindow(_THIS, SDL_Window *window)
SDL_VideoDevice::GL_GetSwapInterval
int(* GL_GetSwapInterval)(_THIS)
Definition: SDL_sysvideo.h:261
SDL_VideoDevice::MaximizeWindow
void(* MaximizeWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:225
SDL_Window::flags
Uint32 flags
Definition: SDL_sysvideo.h:83
SDL_VideoData::saved_crtc
drmModeCrtc * saved_crtc
Definition: SDL_kmsdrmvideo.h:46
KMSDRM_VideoQuit
void KMSDRM_VideoQuit(_THIS)
cleanup
static void cleanup(void)
Definition: testfile.c:44
SDL_VideoData::saved_conn_id
uint32_t saved_conn_id
Definition: SDL_kmsdrmvideo.h:47
KMSDRM_FBInfo::drm_fd
int drm_fd
Definition: SDL_kmsdrmvideo.h:75
SDL_kmsdrmevents.h
SDL_VideoDevice::SetWindowGrab
void(* SetWindowGrab)(_THIS, SDL_Window *window, SDL_bool grabbed)
Definition: SDL_sysvideo.h:233
SDL_syswm.h
SDL_VideoDevice::GL_GetProcAddress
void *(* GL_GetProcAddress)(_THIS, const char *proc)
Definition: SDL_sysvideo.h:255
KMSDRM_FBInfo::fb_id
uint32_t fb_id
Definition: SDL_kmsdrmvideo.h:76
fd
GLuint64 GLenum GLint fd
Definition: gl2ext.h:1508
SDL_WindowData::egl_surface
EGLSurface egl_surface
Definition: SDL_androidwindow.h:37
SDL_VideoDisplay::driverdata
void * driverdata
Definition: SDL_sysvideo.h:138
KMSDRM_DestroyWindow
void KMSDRM_DestroyWindow(_THIS, SDL_Window *window)
SDL_VideoDevice::PumpEvents
void(* PumpEvents)(_THIS)
Definition: SDL_sysvideo.h:280