Skip to content

Latest commit

 

History

History
152 lines (122 loc) · 5.5 KB

SDL_kmsdrmopengles.c

File metadata and controls

152 lines (122 loc) · 5.5 KB
 
1
2
/*
Simple DirectMedia Layer
Jan 17, 2020
Jan 17, 2020
3
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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.
*/
Aug 22, 2017
Aug 22, 2017
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL
#include "SDL_log.h"
#include "SDL_kmsdrmvideo.h"
#include "SDL_kmsdrmopengles.h"
#include "SDL_kmsdrmdyn.h"
#ifndef EGL_PLATFORM_GBM_MESA
#define EGL_PLATFORM_GBM_MESA 0x31D7
#endif
/* EGL implementation of SDL OpenGL support */
int
KMSDRM_GLES_LoadLibrary(_THIS, const char *path) {
Feb 27, 2020
Feb 27, 2020
40
41
NativeDisplayType display = (NativeDisplayType)((SDL_VideoData *)_this->driverdata)->gbm;
return SDL_EGL_LoadLibrary(_this, path, display, EGL_PLATFORM_GBM_MESA);
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
}
SDL_EGL_CreateContext_impl(KMSDRM)
int KMSDRM_GLES_SetSwapInterval(_THIS, int interval) {
if (!_this->egl_data) {
return SDL_SetError("EGL not initialized");
}
if (interval == 0 || interval == 1) {
_this->egl_data->egl_swapinterval = interval;
} else {
return SDL_SetError("Only swap intervals of 0 or 1 are supported");
}
return 0;
}
int
KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) {
Feb 9, 2020
Feb 9, 2020
62
63
64
SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata);
SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
65
KMSDRM_FBInfo *fb_info;
Feb 15, 2020
Feb 15, 2020
66
int ret, timeout;
Feb 9, 2020
Feb 9, 2020
68
69
70
71
72
73
74
/* Recreate the GBM / EGL surfaces if the display mode has changed */
if (windata->egl_surface_dirty) {
KMSDRM_CreateSurfaces(_this, window);
}
/* Wait for confirmation that the next front buffer has been flipped, at which
point the previous front buffer can be released */
Feb 15, 2020
Feb 15, 2020
75
timeout = 0;
76
77
78
if (_this->egl_data->egl_swapinterval == 1) {
timeout = -1;
}
Feb 9, 2020
Feb 9, 2020
79
if (!KMSDRM_WaitPageFlip(_this, windata, timeout)) {
80
81
82
return 0;
}
Feb 9, 2020
Feb 9, 2020
83
84
85
86
87
/* Release the previous front buffer */
if (windata->curr_bo) {
KMSDRM_gbm_surface_release_buffer(windata->gs, windata->curr_bo);
/* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Released GBM surface %p", (void *)windata->curr_bo); */
windata->curr_bo = NULL;
Feb 9, 2020
Feb 9, 2020
90
91
92
93
windata->curr_bo = windata->next_bo;
/* Make the current back buffer the next front buffer */
if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, windata->egl_surface))) {
94
95
96
97
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "eglSwapBuffers failed.");
return 0;
}
Feb 9, 2020
Feb 9, 2020
98
99
100
/* Lock the next front buffer so it can't be allocated as a back buffer */
windata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(windata->gs);
if (!windata->next_bo) {
101
102
103
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not lock GBM surface front buffer");
return 0;
/* } else {
Feb 9, 2020
Feb 9, 2020
104
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Locked GBM surface %p", (void *)windata->next_bo); */
Feb 9, 2020
Feb 9, 2020
107
108
fb_info = KMSDRM_FBFromBO(_this, windata->next_bo);
if (!fb_info) {
Aug 5, 2017
Aug 5, 2017
109
110
return 0;
}
Oct 21, 2017
Oct 21, 2017
111
Feb 9, 2020
Feb 9, 2020
112
113
114
115
116
117
if (!windata->curr_bo) {
/* On the first swap, immediately present the new front buffer. Before
drmModePageFlip can be used the CRTC has to be configured to use
the current connector and mode with drmModeSetCrtc */
ret = KMSDRM_drmModeSetCrtc(viddata->drm_fd, dispdata->crtc_id, fb_info->fb_id, 0,
0, &dispdata->conn->connector_id, 1, &dispdata->mode);
Oct 21, 2017
Oct 21, 2017
118
Feb 9, 2020
Feb 9, 2020
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
if (ret) {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not configure CRTC");
}
} else {
/* On subsequent swaps, queue the new front buffer to be flipped during
the next vertical blank */
ret = KMSDRM_drmModePageFlip(viddata->drm_fd, dispdata->crtc_id, fb_info->fb_id,
DRM_MODE_PAGE_FLIP_EVENT, &windata->waiting_for_flip);
/* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "drmModePageFlip(%d, %u, %u, DRM_MODE_PAGE_FLIP_EVENT, &windata->waiting_for_flip)",
viddata->drm_fd, displaydata->crtc_id, fb_info->fb_id); */
if (_this->egl_data->egl_swapinterval == 1) {
if (ret == 0) {
windata->waiting_for_flip = SDL_TRUE;
} else {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not queue pageflip: %d", ret);
}
Oct 26, 2017
Oct 26, 2017
137
138
139
/* Wait immediately for vsync (as if we only had two buffers), for low input-lag scenarios.
Run your SDL2 program with "SDL_KMSDRM_DOUBLE_BUFFER=1 <program_name>" to enable this. */
Feb 9, 2020
Feb 9, 2020
140
141
if (_this->egl_data->egl_swapinterval == 1 && windata->double_buffer) {
KMSDRM_WaitPageFlip(_this, windata, -1);
Oct 26, 2017
Oct 26, 2017
142
}
143
144
145
146
147
148
149
150
151
152
}
return 0;
}
SDL_EGL_MakeCurrent_impl(KMSDRM)
#endif /* SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL */
/* vi: set ts=4 sw=4 expandtab: */