From aa584dad19fdb1b93a881c6d9a8712239508d742 Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Tue, 26 Jan 2016 10:37:15 -0600 Subject: [PATCH] ecore_drm: Refactor ecore_drm_fb_send into two functions We'll need to set outputs individually from the page flip handle to handle page flip problems, so we need the per output setting logic in its own function. --- src/lib/ecore_drm/ecore_drm_fb.c | 100 ++++++++++++++------------ src/lib/ecore_drm/ecore_drm_private.h | 1 + 2 files changed, 54 insertions(+), 47 deletions(-) diff --git a/src/lib/ecore_drm/ecore_drm_fb.c b/src/lib/ecore_drm/ecore_drm_fb.c index 8b7ca52fa9..fea2ddd592 100644 --- a/src/lib/ecore_drm/ecore_drm_fb.c +++ b/src/lib/ecore_drm/ecore_drm_fb.c @@ -174,6 +174,58 @@ ecore_drm_fb_set(Ecore_Drm_Device *dev EINA_UNUSED, Ecore_Drm_Fb *fb EINA_UNUSED */ } +void +_ecore_drm_output_fb_send(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb, Ecore_Drm_Output *output) +{ + if (output->next) WRN("fb reused too soon, tearing may be visible"); + + /* If we changed display parameters or haven't displayed anything + * yet we need to do a SetCrtc + */ + if ((!output->current) || + (output->current->stride != fb->stride)) + { + int x = 0, y = 0; + + if (!output->cloned) + { + x = output->x; + y = output->y; + } + if (drmModeSetCrtc(dev->drm.fd, output->crtc_id, fb->id, + x, y, &output->conn_id, 1, + &output->current_mode->info)) + { + ERR("Failed to set Mode %dx%d for Output %s: %m", + output->current_mode->width, output->current_mode->height, + output->name); + return; + } + output->current = fb; + output->next = NULL; + + /* TODO: set dpms on ?? */ + return; + } + + /* The normal case: We do a flip which waits for vblank and + * posts an event. + */ + if (drmModePageFlip(dev->drm.fd, output->crtc_id, fb->id, + DRM_MODE_PAGE_FLIP_EVENT, output) < 0) + { + /* Failure to flip - likely there's already a flip + * queued, and we can't cancel, so just store this + * fb for later and it'll be queued in the flip + * handler */ + DBG("flip crtc %u for connector %u failed, re-queued", + output->crtc_id, output->conn_id); + output->next = fb; + return; + } + output->current = fb; +} + EAPI void ecore_drm_fb_send(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb, Ecore_Drm_Pageflip_Cb func EINA_UNUSED, void *data EINA_UNUSED) { @@ -199,52 +251,6 @@ ecore_drm_fb_send(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb, Ecore_Drm_Pageflip_Cb { if ((!output->enabled) || (!output->current_mode)) continue; - if (output->next) WRN("fb reused too soon, tearing may be visible"); - - /* If we changed display parameters or haven't displayed anything - * yet we need to do a SetCrtc - */ - if ((!output->current) || - (output->current->stride != fb->stride)) - { - int x = 0, y = 0; - - if (!output->cloned) - { - x = output->x; - y = output->y; - } - if (drmModeSetCrtc(dev->drm.fd, output->crtc_id, fb->id, - x, y, &output->conn_id, 1, - &output->current_mode->info)) - { - ERR("Failed to set Mode %dx%d for Output %s: %m", - output->current_mode->width, output->current_mode->height, - output->name); - continue; - } - output->current = fb; - output->next = NULL; - - /* TODO: set dpms on ?? */ - continue; - } - - /* The normal case: We do a flip which waits for vblank and - * posts an event. - */ - if (drmModePageFlip(dev->drm.fd, output->crtc_id, fb->id, - DRM_MODE_PAGE_FLIP_EVENT, output) < 0) - { - /* Failure to flip - likely there's already a flip - * queued, and we can't cancel, so just store this - * fb for later and it'll be queued in the flip - * handler */ - DBG("flip crtc %u for connector %u failed, re-queued", - output->crtc_id, output->conn_id); - output->next = fb; - continue; - } - output->current = fb; + _ecore_drm_output_fb_send(dev, fb, output); } } diff --git a/src/lib/ecore_drm/ecore_drm_private.h b/src/lib/ecore_drm/ecore_drm_private.h index 4271a7e481..b4b0fb244c 100644 --- a/src/lib/ecore_drm/ecore_drm_private.h +++ b/src/lib/ecore_drm/ecore_drm_private.h @@ -293,6 +293,7 @@ void _ecore_drm_output_frame_finish(Ecore_Drm_Output *output); void _ecore_drm_outputs_update(Ecore_Drm_Device *dev); void _ecore_drm_output_render_enable(Ecore_Drm_Output *output); void _ecore_drm_output_render_disable(Ecore_Drm_Output *output); +void _ecore_drm_output_fb_send(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb, Ecore_Drm_Output *output); Eina_Bool _ecore_drm_logind_connect(Ecore_Drm_Device *dev); void _ecore_drm_logind_disconnect(Ecore_Drm_Device *dev);