@@ -41,6 +41,7 @@ There is much room for improvement!
4141#include < type_traits>
4242#include < atomic>
4343#include < array>
44+ #include < algorithm>
4445
4546#ifdef __cplusplus
4647extern " C" {
@@ -208,98 +209,101 @@ static auto FindModeSet (struct configuration& settings) -> uint32_t {
208209static auto ScanOut (struct configuration settings) -> bool {
209210 bool _ret = false ;
210211
211- uint32_t _width = gbm_bo_get_width (settings.gbm .bo );
212- uint32_t _height = gbm_bo_get_height (settings.gbm .bo );
213- uint32_t _format = gbm_bo_get_format (settings.gbm .bo );
214- uint32_t _bpp = gbm_bo_get_bpp (settings.gbm .bo );
215- uint32_t _handle = gbm_bo_get_handle (settings.gbm .bo ).u32 ;
216- uint32_t _stride = gbm_bo_get_stride (settings.gbm .bo );
212+ if (settings.gbm .bo != InvalidGBMbo ()) {
217213
218- if (settings.drm .fb != InvalidDRMfb ()) {
219- /* void */ drmModeRmFB (settings.drm .fd , settings.drm .fb );
220- settings.drm .fb = InvalidDRMfb ();
221- }
214+ uint32_t _width = gbm_bo_get_width (settings.gbm .bo );
215+ uint32_t _height = gbm_bo_get_height (settings.gbm .bo );
216+ uint32_t _format = gbm_bo_get_format (settings.gbm .bo );
217+ uint32_t _bpp = gbm_bo_get_bpp (settings.gbm .bo );
218+ uint32_t _handle = gbm_bo_get_handle (settings.gbm .bo ).u32 ;
219+ uint32_t _stride = gbm_bo_get_stride (settings.gbm .bo );
222220
223- if (drmModeAddFB (settings.drm .fd , _width, _height, _format != ColorFormat () ? _bpp - 8 : _bpp, _bpp, _stride, _handle, &settings.drm .fb ) == 0 ) {
224- static std::atomic <bool > _callback_data (true );
221+ if (settings.drm .fb != InvalidDRMfb ()) {
222+ /* void */ drmModeRmFB (settings.drm .fd , settings.drm .fb );
223+ settings.drm .fb = InvalidDRMfb ();
224+ }
225225
226- int _err = drmModePageFlip (settings.drm .fd , settings.drm .crtc , settings.drm .fb , DRM_MODE_PAGE_FLIP_EVENT, &_callback_data);
226+ if (drmModeAddFB (settings.drm .fd , _width, _height, _format != ColorFormat () ? _bpp - 8 : _bpp, _bpp, _stride, _handle, &settings.drm .fb ) == 0 ) {
227+ static std::atomic <bool > _callback_data (true );
227228
228- switch (0 - _err) {
229- case 0 : {
230- // Strictly speaking c++ linkage and not C linkage
231- auto handler = +[] (int fd, unsigned int frame, unsigned int sec, unsigned int usec, void * data) {
232- if (data != nullptr ) {
233- decltype (_callback_data) * _data = reinterpret_cast <decltype (_callback_data) *> (data);
234- *_data = false ;
235- }
236- else {
237- std::cout << " Error: invalid callback data" << std::endl;
238- }
239- };
229+ int _err = drmModePageFlip (settings.drm .fd , settings.drm .crtc , settings.drm .fb , DRM_MODE_PAGE_FLIP_EVENT, &_callback_data);
240230
241- // Use the magic constant here because the struct is versioned!
242- drmEventContext _context = { .version = 2 , . vblank_handler = nullptr , .page_flip_handler = handler };
231+ switch (0 - _err) {
232+ case 0 : {
233+ // Strictly speaking c++ linkage and not C linkage
234+ auto handler = +[] (int fd, unsigned int frame, unsigned int sec, unsigned int usec, void * data) {
235+ if (data != nullptr ) {
236+ decltype (_callback_data) * _data = reinterpret_cast <decltype (_callback_data) *> (data);
237+ *_data = false ;
238+ }
239+ else {
240+ std::cout << " Error: invalid callback data" << std::endl;
241+ }
242+ };
243243
244- bool _waiting = _callback_data;
244+ // Use the magic constant here because the struct is versioned!
245+ drmEventContext _context = { .version = 2 , . vblank_handler = nullptr , .page_flip_handler = handler };
245246
246- fd_set _fds ;
247+ bool _waiting = _callback_data ;
247248
248- struct timespec _timeout = { . tv_sec = FrameDurationMax (), . tv_nsec = 0 } ;
249+ fd_set _fds ;
249250
250- while (_waiting != false ) {
251- FD_ZERO (&_fds);
252- FD_SET (settings.drm .fd , &_fds);
251+ struct timespec _timeout = { .tv_sec = FrameDurationMax (), .tv_nsec = 0 };
253252
254- _err = pselect (settings.drm .fd + 1 , &_fds, nullptr , nullptr , &_timeout, nullptr );
253+ while (_waiting != false ) {
254+ FD_ZERO (&_fds);
255+ FD_SET (settings.drm .fd , &_fds);
255256
256- if (_err < 0 ) {
257- break ;
258- }
259- else {
260- if (_err == 0 ) {
261- // Timeout; retry
257+ _err = pselect (settings.drm .fd + 1 , &_fds, nullptr , nullptr , &_timeout, nullptr );
258+
259+ if (_err < 0 ) {
260+ break ;
262261 }
263- else { // ret > 0
264- if (FD_ISSET (settings.drm .fd , &_fds) != 0 ) {
265- if (drmHandleEvent (settings.drm .fd , &_context) != 0 ) {
266- _ret = false ;
267- break ;
262+ else {
263+ if (_err == 0 ) {
264+ // Timeout; retry
265+ }
266+ else { // ret > 0
267+ if (FD_ISSET (settings.drm .fd , &_fds) != 0 ) {
268+ if (drmHandleEvent (settings.drm .fd , &_context) != 0 ) {
269+ _ret = false ;
270+ break ;
271+ }
272+
273+ _ret = true ;
268274 }
269-
270- _ret = true ;
271275 }
272276 }
277+
278+ _waiting = _callback_data;
273279 }
274280
275- _waiting = _callback_data ;
281+ break ;
276282 }
283+ case EINVAL :
284+ { // Probably a missing drmModeSetCrtc or an invalid _crtc
285+ drmModeCrtcPtr _ptr = drmModeGetCrtc (settings.drm .fd , settings.drm .crtc );
277286
278- break ;
279- }
280- case EINVAL :
281- { // Probably a missing drmModeSetCrtc or an invalid _crtc
282- drmModeCrtcPtr _ptr = drmModeGetCrtc (settings.drm .fd , settings.drm .crtc );
287+ if (_ptr != nullptr ) {
288+ constexpr uint32_t _count = 1 ;
283289
284- if (_ptr != nullptr ) {
285- constexpr uint32_t _count = 1 ;
290+ _ret = drmModeSetCrtc (settings.drm .fd , settings.drm .crtc , settings.drm .fb , _ptr->x , _ptr->y , &settings.drm .connectors , _count, &_ptr->mode ) == 0 ;
286291
287- _ret = drmModeSetCrtc (settings.drm .fd , settings.drm .crtc , settings.drm .fb , _ptr->x , _ptr->y , &settings.drm .connectors , _count, &_ptr->mode ) == 0 ;
292+ drmModeFreeCrtc (_ptr);
293+ }
288294
289- drmModeFreeCrtc (_ptr) ;
295+ break ;
290296 }
291-
292- break ;
293- }
294- case EBUSY :
295- default :
296- {
297- // There is nothing to be done about it
298- }
297+ case EBUSY :
298+ default :
299+ {
300+ // There is nothing to be done about it
301+ }
302+ }
303+ }
304+ else {
305+ _ret = false ;
299306 }
300- }
301- else {
302- _ret = false ;
303307 }
304308
305309 return _ret;
@@ -970,17 +974,6 @@ bool RenderEGLImage (struct configuration& settings) {
970974 _ret = RenderTile ();
971975 }
972976
973- // TODO: move remainder, do after all tiles
974-
975- if (settings.gbm .bo != InvalidGBMbo ()) {
976- /* void */ gbm_surface_release_buffer (settings.gbm .surf , settings.gbm .bo );
977- settings.gbm .bo = InvalidGBMbo ();
978- }
979-
980- if (eglSwapBuffers (settings.egl .dpy , settings.egl .surf ) != EGL_FALSE) {
981- settings.gbm .bo = gbm_surface_lock_front_buffer (settings.gbm .surf );
982- }
983-
984977 return _ret;
985978}
986979
@@ -1160,7 +1153,18 @@ void Parent (int sock, pid_t child) {
11601153 std::cout << " Error: scan out impossible" << std::endl;
11611154 }
11621155 else {
1163- ScanOut (_settings);
1156+
1157+ if (eglSwapBuffers (_settings.egl .dpy , _settings.egl .surf ) != EGL_FALSE) {
1158+ _settings.gbm .bo = gbm_surface_lock_front_buffer (_settings.gbm .surf );
1159+ }
1160+
1161+ /* bool */ ScanOut (_settings);
1162+
1163+ if (_settings.gbm .bo != InvalidGBMbo ()) {
1164+ /* void */ gbm_surface_release_buffer (_settings.gbm .surf , _settings.gbm .bo );
1165+ _settings.gbm .bo = InvalidGBMbo ();
1166+ }
1167+
11641168 }
11651169 }
11661170 }
0 commit comments