diff options
Diffstat (limited to '')
-rw-r--r-- | src/lib/ecore_drm/ecore_drm_fb.c | 100 | ||||
-rw-r--r-- | 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 | |||
174 | */ | 174 | */ |
175 | } | 175 | } |
176 | 176 | ||
177 | void | ||
178 | _ecore_drm_output_fb_send(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb, Ecore_Drm_Output *output) | ||
179 | { | ||
180 | if (output->next) WRN("fb reused too soon, tearing may be visible"); | ||
181 | |||
182 | /* If we changed display parameters or haven't displayed anything | ||
183 | * yet we need to do a SetCrtc | ||
184 | */ | ||
185 | if ((!output->current) || | ||
186 | (output->current->stride != fb->stride)) | ||
187 | { | ||
188 | int x = 0, y = 0; | ||
189 | |||
190 | if (!output->cloned) | ||
191 | { | ||
192 | x = output->x; | ||
193 | y = output->y; | ||
194 | } | ||
195 | if (drmModeSetCrtc(dev->drm.fd, output->crtc_id, fb->id, | ||
196 | x, y, &output->conn_id, 1, | ||
197 | &output->current_mode->info)) | ||
198 | { | ||
199 | ERR("Failed to set Mode %dx%d for Output %s: %m", | ||
200 | output->current_mode->width, output->current_mode->height, | ||
201 | output->name); | ||
202 | return; | ||
203 | } | ||
204 | output->current = fb; | ||
205 | output->next = NULL; | ||
206 | |||
207 | /* TODO: set dpms on ?? */ | ||
208 | return; | ||
209 | } | ||
210 | |||
211 | /* The normal case: We do a flip which waits for vblank and | ||
212 | * posts an event. | ||
213 | */ | ||
214 | if (drmModePageFlip(dev->drm.fd, output->crtc_id, fb->id, | ||
215 | DRM_MODE_PAGE_FLIP_EVENT, output) < 0) | ||
216 | { | ||
217 | /* Failure to flip - likely there's already a flip | ||
218 | * queued, and we can't cancel, so just store this | ||
219 | * fb for later and it'll be queued in the flip | ||
220 | * handler */ | ||
221 | DBG("flip crtc %u for connector %u failed, re-queued", | ||
222 | output->crtc_id, output->conn_id); | ||
223 | output->next = fb; | ||
224 | return; | ||
225 | } | ||
226 | output->current = fb; | ||
227 | } | ||
228 | |||
177 | EAPI void | 229 | EAPI void |
178 | ecore_drm_fb_send(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb, Ecore_Drm_Pageflip_Cb func EINA_UNUSED, void *data EINA_UNUSED) | 230 | ecore_drm_fb_send(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb, Ecore_Drm_Pageflip_Cb func EINA_UNUSED, void *data EINA_UNUSED) |
179 | { | 231 | { |
@@ -199,52 +251,6 @@ ecore_drm_fb_send(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb, Ecore_Drm_Pageflip_Cb | |||
199 | { | 251 | { |
200 | if ((!output->enabled) || (!output->current_mode)) continue; | 252 | if ((!output->enabled) || (!output->current_mode)) continue; |
201 | 253 | ||
202 | if (output->next) WRN("fb reused too soon, tearing may be visible"); | 254 | _ecore_drm_output_fb_send(dev, fb, output); |
203 | |||
204 | /* If we changed display parameters or haven't displayed anything | ||
205 | * yet we need to do a SetCrtc | ||
206 | */ | ||
207 | if ((!output->current) || | ||
208 | (output->current->stride != fb->stride)) | ||
209 | { | ||
210 | int x = 0, y = 0; | ||
211 | |||
212 | if (!output->cloned) | ||
213 | { | ||
214 | x = output->x; | ||
215 | y = output->y; | ||
216 | } | ||
217 | if (drmModeSetCrtc(dev->drm.fd, output->crtc_id, fb->id, | ||
218 | x, y, &output->conn_id, 1, | ||
219 | &output->current_mode->info)) | ||
220 | { | ||
221 | ERR("Failed to set Mode %dx%d for Output %s: %m", | ||
222 | output->current_mode->width, output->current_mode->height, | ||
223 | output->name); | ||
224 | continue; | ||
225 | } | ||
226 | output->current = fb; | ||
227 | output->next = NULL; | ||
228 | |||
229 | /* TODO: set dpms on ?? */ | ||
230 | continue; | ||
231 | } | ||
232 | |||
233 | /* The normal case: We do a flip which waits for vblank and | ||
234 | * posts an event. | ||
235 | */ | ||
236 | if (drmModePageFlip(dev->drm.fd, output->crtc_id, fb->id, | ||
237 | DRM_MODE_PAGE_FLIP_EVENT, output) < 0) | ||
238 | { | ||
239 | /* Failure to flip - likely there's already a flip | ||
240 | * queued, and we can't cancel, so just store this | ||
241 | * fb for later and it'll be queued in the flip | ||
242 | * handler */ | ||
243 | DBG("flip crtc %u for connector %u failed, re-queued", | ||
244 | output->crtc_id, output->conn_id); | ||
245 | output->next = fb; | ||
246 | continue; | ||
247 | } | ||
248 | output->current = fb; | ||
249 | } | 255 | } |
250 | } | 256 | } |
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); | |||
293 | void _ecore_drm_outputs_update(Ecore_Drm_Device *dev); | 293 | void _ecore_drm_outputs_update(Ecore_Drm_Device *dev); |
294 | void _ecore_drm_output_render_enable(Ecore_Drm_Output *output); | 294 | void _ecore_drm_output_render_enable(Ecore_Drm_Output *output); |
295 | void _ecore_drm_output_render_disable(Ecore_Drm_Output *output); | 295 | void _ecore_drm_output_render_disable(Ecore_Drm_Output *output); |
296 | void _ecore_drm_output_fb_send(Ecore_Drm_Device *dev, Ecore_Drm_Fb *fb, Ecore_Drm_Output *output); | ||
296 | 297 | ||
297 | Eina_Bool _ecore_drm_logind_connect(Ecore_Drm_Device *dev); | 298 | Eina_Bool _ecore_drm_logind_connect(Ecore_Drm_Device *dev); |
298 | void _ecore_drm_logind_disconnect(Ecore_Drm_Device *dev); | 299 | void _ecore_drm_logind_disconnect(Ecore_Drm_Device *dev); |