mirror of
https://github.com/Relintai/sdl2_frt.git
synced 2025-02-04 11:15:57 +01:00
262 lines
8.4 KiB
C
262 lines
8.4 KiB
C
/*
|
|
Simple DirectMedia Layer
|
|
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
|
Atomic KMSDRM backend by Manuel Alfayate Corchete <redwindwanderer@gmail.com>
|
|
|
|
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"
|
|
|
|
#ifndef __SDL_KMSDRMVIDEO_H__
|
|
#define __SDL_KMSDRMVIDEO_H__
|
|
|
|
#include "../SDL_sysvideo.h"
|
|
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <xf86drm.h>
|
|
#include <xf86drmMode.h>
|
|
|
|
#include <gbm.h>
|
|
#include <assert.h>
|
|
#if SDL_VIDEO_OPENGL_EGL
|
|
#include <EGL/egl.h>
|
|
#include <EGL/eglext.h>
|
|
#endif
|
|
|
|
/* Headers related to dumb buffer creation. */
|
|
#include <drm_fourcc.h>
|
|
#include <sys/mman.h>
|
|
|
|
/**********************/
|
|
/* DUMB BUFFER Block. */
|
|
/**********************/
|
|
|
|
typedef struct dumb_buffer {
|
|
|
|
/* The GEM handle for this buffer, returned by the creation ioctl. */
|
|
uint32_t gem_handles[4];
|
|
|
|
/* The framebuffer ID which is passed to KMS to display. */
|
|
uint32_t fb_id;
|
|
|
|
uint32_t format;
|
|
uint64_t modifier;
|
|
|
|
/* Parameters for our memory-mapped image. */
|
|
struct {
|
|
uint32_t *mem;
|
|
unsigned int size;
|
|
} dumb;
|
|
|
|
unsigned int width;
|
|
unsigned int height;
|
|
unsigned int pitches[4]; /* in bytes */
|
|
unsigned int offsets[4]; /* in bytes */
|
|
|
|
} dumb_buffer;
|
|
|
|
/***************************/
|
|
/* DUMB BUFFER Block ends. */
|
|
/***************************/
|
|
|
|
/****************************************************************************************/
|
|
/* Driverdata pointers are void struct* used to store backend-specific variables */
|
|
/* and info that supports the SDL-side structs like SDL Display Devices, SDL_Windows... */
|
|
/* which need to be "supported" with backend-side info and mechanisms to work. */
|
|
/****************************************************************************************/
|
|
|
|
typedef struct SDL_VideoData
|
|
{
|
|
int devindex; /* device index that was passed on creation */
|
|
int drm_fd; /* DRM file desc */
|
|
struct gbm_device *gbm_dev;
|
|
|
|
SDL_Window **windows;
|
|
unsigned int max_windows;
|
|
unsigned int num_windows;
|
|
} SDL_VideoData;
|
|
|
|
typedef struct plane {
|
|
drmModePlane *plane;
|
|
drmModeObjectProperties *props;
|
|
drmModePropertyRes **props_info;
|
|
} plane;
|
|
|
|
typedef struct crtc {
|
|
drmModeCrtc *crtc;
|
|
drmModeObjectProperties *props;
|
|
drmModePropertyRes **props_info;
|
|
} crtc;
|
|
|
|
typedef struct connector {
|
|
drmModeConnector *connector;
|
|
drmModeObjectProperties *props;
|
|
drmModePropertyRes **props_info;
|
|
} connector;
|
|
|
|
/* More general driverdata info that gives support and substance to the SDL_Display. */
|
|
typedef struct SDL_DisplayData
|
|
{
|
|
drmModeModeInfo mode;
|
|
uint32_t atomic_flags;
|
|
|
|
plane *display_plane;
|
|
plane *cursor_plane;
|
|
crtc *crtc;
|
|
connector *connector;
|
|
|
|
/* Central atomic request list, used for the prop
|
|
changeset related to pageflip in SwapWindow. */
|
|
drmModeAtomicReq *atomic_req;
|
|
|
|
int kms_in_fence_fd;
|
|
int kms_out_fence_fd;
|
|
|
|
EGLSyncKHR kms_fence;
|
|
EGLSyncKHR gpu_fence;
|
|
|
|
#if SDL_VIDEO_OPENGL_EGL
|
|
EGLSurface old_egl_surface;
|
|
#endif
|
|
|
|
dumb_buffer *dumb_buffer;
|
|
|
|
SDL_bool modeset_pending;
|
|
|
|
} SDL_DisplayData;
|
|
|
|
/* Driverdata info that gives KMSDRM-side support and substance to the SDL_Window. */
|
|
typedef struct SDL_WindowData
|
|
{
|
|
SDL_VideoData *viddata;
|
|
/* SDL internals expect EGL surface to be here, and in KMSDRM the GBM surface is
|
|
what supports the EGL surface on the driver side, so all these surfaces and buffers
|
|
are expected to be here, in the struct pointed by SDL_Window driverdata pointer:
|
|
this one. So don't try to move these to dispdata! */
|
|
struct gbm_surface *gs;
|
|
struct gbm_bo *bo;
|
|
struct gbm_bo *next_bo;
|
|
|
|
#if SDL_VIDEO_OPENGL_EGL
|
|
EGLSurface egl_surface;
|
|
#endif
|
|
|
|
/* For scaling and AR correction. */
|
|
int32_t src_w;
|
|
int32_t src_h;
|
|
int32_t output_w;
|
|
int32_t output_h;
|
|
int32_t output_x;
|
|
|
|
/* This is for deferred eglMakeCurrent() call: we can't call it until
|
|
the EGL context is available, but we need the EGL surface sooner. */
|
|
SDL_bool egl_context_pending;
|
|
|
|
/* This dictates what approach we'll use for SwapBuffers. */
|
|
int (*swap_window)(_THIS, SDL_Window * window);
|
|
} SDL_WindowData;
|
|
|
|
typedef struct SDL_DisplayModeData
|
|
{
|
|
int mode_index;
|
|
} SDL_DisplayModeData;
|
|
|
|
typedef struct KMSDRM_FBInfo
|
|
{
|
|
int drm_fd; /* DRM file desc */
|
|
uint32_t fb_id; /* DRM framebuffer ID */
|
|
} KMSDRM_FBInfo;
|
|
|
|
typedef struct KMSDRM_PlaneInfo
|
|
{
|
|
struct plane *plane;
|
|
uint32_t fb_id;
|
|
uint32_t crtc_id;
|
|
int32_t src_x;
|
|
int32_t src_y;
|
|
int32_t src_w;
|
|
int32_t src_h;
|
|
int32_t crtc_x;
|
|
int32_t crtc_y;
|
|
int32_t crtc_w;
|
|
int32_t crtc_h;
|
|
} KMSDRM_PlaneInfo;
|
|
|
|
/* Helper functions */
|
|
int KMSDRM_CreateEGLSurface(_THIS, SDL_Window * window);
|
|
KMSDRM_FBInfo *KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo);
|
|
|
|
/* Atomic functions that are used from SDL_kmsdrmopengles.c and SDL_kmsdrmmouse.c */
|
|
void drm_atomic_set_plane_props(struct KMSDRM_PlaneInfo *info);
|
|
|
|
void drm_atomic_waitpending(_THIS);
|
|
int drm_atomic_commit(_THIS, SDL_bool blocking);
|
|
int add_plane_property(drmModeAtomicReq *req, struct plane *plane,
|
|
const char *name, uint64_t value);
|
|
int add_crtc_property(drmModeAtomicReq *req, struct crtc *crtc,
|
|
const char *name, uint64_t value);
|
|
int add_connector_property(drmModeAtomicReq *req, struct connector *connector,
|
|
const char *name, uint64_t value);
|
|
int setup_plane(_THIS, struct plane **plane, uint32_t plane_type);
|
|
void free_plane(struct plane **plane);
|
|
|
|
/****************************************************************************/
|
|
/* SDL_VideoDevice functions declaration */
|
|
/****************************************************************************/
|
|
|
|
/* Display and window functions */
|
|
int KMSDRM_VideoInit(_THIS);
|
|
void KMSDRM_VideoQuit(_THIS);
|
|
void KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
|
|
int KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
|
|
int KMSDRM_CreateWindow(_THIS, SDL_Window * window);
|
|
int KMSDRM_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
|
|
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_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen);
|
|
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);
|
|
void KMSDRM_DestroyWindow(_THIS, SDL_Window * window);
|
|
|
|
/* Window manager function */
|
|
SDL_bool KMSDRM_GetWindowWMInfo(_THIS, SDL_Window * window,
|
|
struct SDL_SysWMinfo *info);
|
|
|
|
/* OpenGL/OpenGL ES functions */
|
|
int KMSDRM_GLES_LoadLibrary(_THIS, const char *path);
|
|
void *KMSDRM_GLES_GetProcAddress(_THIS, const char *proc);
|
|
void KMSDRM_GLES_UnloadLibrary(_THIS);
|
|
SDL_GLContext KMSDRM_GLES_CreateContext(_THIS, SDL_Window * window);
|
|
int KMSDRM_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
|
|
int KMSDRM_GLES_SetSwapInterval(_THIS, int interval);
|
|
int KMSDRM_GLES_GetSwapInterval(_THIS);
|
|
int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window);
|
|
void KMSDRM_GLES_DeleteContext(_THIS, SDL_GLContext context);
|
|
|
|
#endif /* __SDL_KMSDRMVIDEO_H__ */
|
|
|
|
/* vi: set ts=4 sw=4 expandtab: */
|