@@ -72,12 +72,6 @@ SDL_EGL_CreateContext_impl(KMSDRM)
72
72
73
73
int KMSDRM_GLES_SetSwapInterval (_THIS , int interval ) {
74
74
75
- /* Issuing a new pageflip before the previous has completed
76
- causes drmModePageFlip() to return EBUSY errors.
77
- So just set egl_swapinterval to 1 to prevent that. */
78
-
79
- #if 0
80
-
81
75
if (!_this -> egl_data ) {
82
76
return SDL_SetError ("EGL not initialized" );
83
77
}
@@ -87,9 +81,6 @@ int KMSDRM_GLES_SetSwapInterval(_THIS, int interval) {
87
81
} else {
88
82
return SDL_SetError ("Only swap intervals of 0 or 1 are supported" );
89
83
}
90
- #endif
91
-
92
- _this -> egl_data -> egl_swapinterval = 1 ;
93
84
94
85
return 0 ;
95
86
}
@@ -100,15 +91,15 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) {
100
91
SDL_DisplayData * dispdata = (SDL_DisplayData * ) SDL_GetDisplayForWindow (window )-> driverdata ;
101
92
SDL_VideoData * viddata = ((SDL_VideoData * )_this -> driverdata );
102
93
KMSDRM_FBInfo * fb_info ;
103
- int ret , timeout ;
94
+ int ret = 0 ;
95
+
96
+ /* Always wait for the previous issued flip before issing a new one,
97
+ even if you do async flips. */
98
+ uint32_t flip_flags = DRM_MODE_PAGE_FLIP_EVENT ;
104
99
105
100
/* Wait for confirmation that the next front buffer has been flipped, at which
106
101
point the previous front buffer can be released */
107
- timeout = 0 ;
108
- if (_this -> egl_data -> egl_swapinterval == 1 ) {
109
- timeout = -1 ;
110
- }
111
- if (!KMSDRM_WaitPageFlip (_this , windata , timeout )) {
102
+ if (!KMSDRM_WaitPageFlip (_this , windata )) {
112
103
return 0 ;
113
104
}
114
105
@@ -162,24 +153,35 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) {
162
153
}
163
154
164
155
/* Issue pageflip on the next front buffer.
165
- The pageflip will be done during the next vblank. */
156
+ Remember: drmModePageFlip() never blocks, it just issues the flip,
157
+ which will be done during the next vblank.
158
+ Since it will return EBUSY if we call it again without having
159
+ completed the last issued flip, we must pass the
160
+ DRM_MODE_PAGE_FLIP_ASYNC if we don't block on EGL (egl_swapinterval = 0).
161
+ That makes it flip immediately, without waiting for the next vblank,
162
+ so even if we don't block on EGL, it will have flipped when we
163
+ get back here. */
164
+
165
+ if (_this -> egl_data -> egl_swapinterval == 0 ) {
166
+ flip_flags |= DRM_MODE_PAGE_FLIP_ASYNC ;
167
+ }
168
+
166
169
ret = KMSDRM_drmModePageFlip (viddata -> drm_fd , dispdata -> crtc -> crtc_id ,
167
- fb_info -> fb_id , DRM_MODE_PAGE_FLIP_EVENT , & windata -> waiting_for_flip );
170
+ fb_info -> fb_id , flip_flags , & windata -> waiting_for_flip );
168
171
169
172
if (ret == 0 ) {
170
- if (_this -> egl_data -> egl_swapinterval == 1 ) {
171
- windata -> waiting_for_flip = SDL_TRUE ;
172
- }
173
+ windata -> waiting_for_flip = SDL_TRUE ;
173
174
} else {
174
175
SDL_LogError (SDL_LOG_CATEGORY_VIDEO , "Could not queue pageflip: %d" , ret );
176
+ printf ("Could not queue pageflip: %s\n" , strerror (errno ));
175
177
}
176
178
177
179
/* If we are in double-buffer mode, wait immediately for vsync
178
180
(as if we only had two buffers),
179
181
Run your SDL2 program with "SDL_KMSDRM_DOUBLE_BUFFER=1 <program_name>"
180
182
to enable this. */
181
183
if (_this -> egl_data -> egl_swapinterval == 1 && windata -> double_buffer ) {
182
- KMSDRM_WaitPageFlip (_this , windata , -1 );
184
+ KMSDRM_WaitPageFlip (_this , windata );
183
185
}
184
186
185
187
return 0 ;
0 commit comments