summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2017-04-27 09:11:41 -0400
committerDerek Foreman <derekf@osg.samsung.com>2017-05-05 12:53:21 -0500
commit0595e70b2283db391cd98e234f8759095f211845 (patch)
tree90a7f7e3b683e418409467f9f451cdb01d0e8e85 /src/lib
parent2ba64a4c0a96689fb144b1fcb05c93c140279755 (diff)
ecore-drm2: Do atomic commits per-output
In cases where output monitors have different frequencies, we need to be doing atomic commits on a per-output basis. This patch modifies the ecore_drm2_fb_flip function to support doing atomic commits per output. Signed-off-by: Chris Michael <cp.michael@samsung.com>
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ecore_drm2/ecore_drm2_fb.c179
1 files changed, 172 insertions, 7 deletions
diff --git a/src/lib/ecore_drm2/ecore_drm2_fb.c b/src/lib/ecore_drm2/ecore_drm2_fb.c
index bd5f4e543e..056dc877d6 100644
--- a/src/lib/ecore_drm2/ecore_drm2_fb.c
+++ b/src/lib/ecore_drm2/ecore_drm2_fb.c
@@ -228,17 +228,160 @@ ecore_drm2_fb_flip_complete(Ecore_Drm2_Output *output)
228 return !!output->next; 228 return !!output->next;
229} 229}
230 230
231EAPI int 231static Eina_Bool
232ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output) 232_fb_atomic_flip_test(Ecore_Drm2_Output *output)
233{ 233{
234 Eina_Bool repeat; 234 Eina_Bool res = EINA_FALSE;
235 int count = 0; 235#ifdef HAVE_ATOMIC_DRM
236 int ret = 0; 236 int ret = 0;
237 Eina_List *l;
238 Ecore_Drm2_Crtc_State *cstate;
239 Ecore_Drm2_Plane_State *pstate;
240 Ecore_Drm2_Plane *plane;
241 drmModeAtomicReq *req = NULL;
242 uint32_t flags = DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_ATOMIC_ALLOW_MODESET |
243 DRM_MODE_ATOMIC_TEST_ONLY;
237 244
238 EINA_SAFETY_ON_NULL_RETURN_VAL(output, -1); 245 req = sym_drmModeAtomicAlloc();
239 EINA_SAFETY_ON_NULL_RETURN_VAL(output->current_mode, -1); 246 if (!req) return EINA_FALSE;
240 247
241 if (!output->enabled) return -1; 248 sym_drmModeAtomicSetCursor(req, 0);
249
250 cstate = output->crtc_state;
251
252 ret =
253 sym_drmModeAtomicAddProperty(req, cstate->obj_id, cstate->mode.id,
254 cstate->mode.value);
255 if (ret < 0) goto err;
256
257 ret =
258 sym_drmModeAtomicAddProperty(req, cstate->obj_id, cstate->active.id,
259 cstate->active.value);
260 if (ret < 0) goto err;
261
262 EINA_LIST_FOREACH(output->planes, l, plane)
263 {
264 pstate = plane->state;
265
266 ret =
267 sym_drmModeAtomicAddProperty(req, pstate->obj_id,
268 pstate->cid.id, pstate->cid.value);
269 if (ret < 0) goto err;
270
271 ret =
272 sym_drmModeAtomicAddProperty(req, pstate->obj_id,
273 pstate->fid.id, pstate->fid.value);
274 if (ret < 0) goto err;
275
276 ret =
277 sym_drmModeAtomicAddProperty(req, pstate->obj_id,
278 pstate->sx.id, pstate->sx.value);
279 if (ret < 0) goto err;
280
281 ret =
282 sym_drmModeAtomicAddProperty(req, pstate->obj_id,
283 pstate->sy.id, pstate->sy.value);
284 if (ret < 0) goto err;
285
286 ret =
287 sym_drmModeAtomicAddProperty(req, pstate->obj_id,
288 pstate->sw.id, pstate->sw.value);
289 if (ret < 0) goto err;
290
291 ret =
292 sym_drmModeAtomicAddProperty(req, pstate->obj_id,
293 pstate->sh.id, pstate->sh.value);
294 if (ret < 0) goto err;
295
296 ret =
297 sym_drmModeAtomicAddProperty(req, pstate->obj_id,
298 pstate->cx.id, pstate->cx.value);
299 if (ret < 0) goto err;
300
301 ret =
302 sym_drmModeAtomicAddProperty(req, pstate->obj_id,
303 pstate->cy.id, pstate->cy.value);
304 if (ret < 0) goto err;
305
306 ret =
307 sym_drmModeAtomicAddProperty(req, pstate->obj_id,
308 pstate->cw.id, pstate->cw.value);
309 if (ret < 0) goto err;
310
311 ret =
312 sym_drmModeAtomicAddProperty(req, pstate->obj_id,
313 pstate->ch.id, pstate->ch.value);
314 if (ret < 0) goto err;
315 }
316
317 ret =
318 sym_drmModeAtomicCommit(output->fd, req, flags, NULL);
319 if (ret < 0) ERR("Failed Atomic Commit Test: %m");
320 else res = EINA_TRUE;
321
322 if (res)
323 {
324 if (output->atomic_req)
325 {
326 /* merge this test commit with previous */
327 ret = sym_drmModeAtomicMerge(output->atomic_req, req);
328 if (ret < 0)
329 {
330 /* we failed to merge for some reason. */
331
332 /* clear any previous request */
333 sym_drmModeAtomicFree(output->atomic_req);
334
335 /* just use the new request */
336 output->atomic_req = req;
337 }
338 }
339 else
340 output->atomic_req = req;
341 }
342
343 return res;
344
345err:
346 sym_drmModeAtomicFree(req);
347#endif
348
349 return res;
350}
351
352static int
353_fb_atomic_flip(Ecore_Drm2_Output *output)
354{
355#ifdef HAVE_ATOMIC_DRM
356 int res = 0;
357 uint32_t flags =
358 DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT |
359 DRM_MODE_ATOMIC_ALLOW_MODESET;
360#endif
361
362#ifdef HAVE_ATOMIC_DRM
363 if (!output->atomic_req) return -1;
364
365 res =
366 sym_drmModeAtomicCommit(output->fd, output->atomic_req, flags, NULL);
367 if (res < 0)
368 {
369 ERR("Failed Atomic Commit Test: %m");
370 return -1;
371 }
372
373 return 0;
374#endif
375
376 return -1;
377}
378
379static int
380_fb_flip(Ecore_Drm2_Output *output, Ecore_Drm2_Fb *fb)
381{
382 Eina_Bool repeat;
383 int count = 0;
384 int ret = 0;
242 385
243 if (output->pending) 386 if (output->pending)
244 { 387 {
@@ -341,9 +484,31 @@ ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output)
341 484
342 output->pending = fb; 485 output->pending = fb;
343 output->pending->busy = EINA_TRUE; 486 output->pending->busy = EINA_TRUE;
487
344 return 0; 488 return 0;
345} 489}
346 490
491EAPI int
492ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output)
493{
494 int ret = -1;
495
496 EINA_SAFETY_ON_NULL_RETURN_VAL(output, -1);
497 EINA_SAFETY_ON_NULL_RETURN_VAL(output->current_mode, -1);
498
499 if (!output->enabled) return -1;
500
501 if (_ecore_drm2_use_atomic)
502 {
503 if (_fb_atomic_flip_test(output))
504 ret = _fb_atomic_flip(output);
505 }
506 else
507 ret = _fb_flip(output, fb);
508
509 return ret;
510}
511
347EAPI Eina_Bool 512EAPI Eina_Bool
348ecore_drm2_fb_busy_get(Ecore_Drm2_Fb *fb) 513ecore_drm2_fb_busy_get(Ecore_Drm2_Fb *fb)
349{ 514{