summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/ecore_drm2/ecore_drm2_fb.c204
1 files changed, 173 insertions, 31 deletions
diff --git a/src/lib/ecore_drm2/ecore_drm2_fb.c b/src/lib/ecore_drm2/ecore_drm2_fb.c
index fc40a8edea..94c6fa3ee5 100644
--- a/src/lib/ecore_drm2/ecore_drm2_fb.c
+++ b/src/lib/ecore_drm2/ecore_drm2_fb.c
@@ -31,6 +31,83 @@ _fb2_create(Ecore_Drm2_Fb *fb)
31 return EINA_TRUE; 31 return EINA_TRUE;
32} 32}
33 33
34#ifdef HAVE_ATOMIC_DRM
35static int
36_fb_atomic_flip(Ecore_Drm2_Output *output, Ecore_Drm2_Plane_State *pstate, uint32_t flags)
37{
38 int ret = 0;
39 drmModeAtomicReq *req = NULL;
40
41 req = drmModeAtomicAlloc();
42 if (!req) return -1;
43
44 drmModeAtomicSetCursor(req, 0);
45
46 if (flags & DRM_MODE_ATOMIC_ALLOW_MODESET)
47 {
48 Ecore_Drm2_Crtc_State *cstate;
49
50 cstate = output->crtc_state;
51
52 ret = drmModeAtomicAddProperty(req, cstate->obj_id, cstate->mode.id,
53 cstate->mode.value);
54 if (ret < 0) goto err;
55
56 ret = drmModeAtomicAddProperty(req, cstate->obj_id, cstate->active.id,
57 cstate->active.value);
58 if (ret < 0) goto err;
59 }
60
61 ret = drmModeAtomicAddProperty(req, pstate->obj_id,
62 pstate->cid.id, pstate->cid.value);
63 if (ret < 0) goto err;
64
65 ret = drmModeAtomicAddProperty(req, pstate->obj_id,
66 pstate->fid.id, pstate->fid.value);
67 if (ret < 0) goto err;
68
69 ret = drmModeAtomicAddProperty(req, pstate->obj_id,
70 pstate->sx.id, pstate->sx.value);
71 if (ret < 0) goto err;
72
73 ret = drmModeAtomicAddProperty(req, pstate->obj_id,
74 pstate->sy.id, pstate->sy.value);
75 if (ret < 0) goto err;
76
77 ret = drmModeAtomicAddProperty(req, pstate->obj_id,
78 pstate->sw.id, pstate->sw.value);
79 if (ret < 0) goto err;
80
81 ret = drmModeAtomicAddProperty(req, pstate->obj_id,
82 pstate->sh.id, pstate->sh.value);
83 if (ret < 0) goto err;
84
85 ret = drmModeAtomicAddProperty(req, pstate->obj_id,
86 pstate->cx.id, pstate->cx.value);
87 if (ret < 0) goto err;
88
89 ret = drmModeAtomicAddProperty(req, pstate->obj_id,
90 pstate->cy.id, pstate->cy.value);
91 if (ret < 0) goto err;
92
93 ret = drmModeAtomicAddProperty(req, pstate->obj_id,
94 pstate->cw.id, pstate->cw.value);
95 if (ret < 0) goto err;
96
97 ret = drmModeAtomicAddProperty(req, pstate->obj_id,
98 pstate->ch.id, pstate->ch.value);
99 if (ret < 0) goto err;
100
101 ret = drmModeAtomicCommit(output->fd, req, flags, output->user_data);
102 if (ret < 0) ERR("Failed to commit Atomic FB Flip: %m");
103 else ret = 0;
104
105err:
106 drmModeAtomicFree(req);
107 return ret;
108}
109#endif
110
34EAPI Ecore_Drm2_Fb * 111EAPI Ecore_Drm2_Fb *
35ecore_drm2_fb_create(int fd, int width, int height, int depth, int bpp, unsigned int format) 112ecore_drm2_fb_create(int fd, int width, int height, int depth, int bpp, unsigned int format)
36{ 113{
@@ -275,48 +352,113 @@ ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output)
275 /* If we don't have an fb to set by now, BAIL! */ 352 /* If we don't have an fb to set by now, BAIL! */
276 if (!fb) return -1; 353 if (!fb) return -1;
277 354
278 if ((!output->current) || 355#ifdef HAVE_ATOMIC_DRM
279 (output->current->stride != fb->stride)) 356 if (_ecore_drm2_use_atomic)
280 { 357 {
281 ret = 358 Ecore_Drm2_Plane_State *pstate;
282 drmModeSetCrtc(fb->fd, output->crtc_id, fb->id, 359 uint32_t flags =
283 output->x, output->y, &output->conn_id, 1, 360 DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT;
284 &output->current_mode->info); 361
285 if (ret) 362 pstate = output->plane_state;
363
364 pstate->cid.value = output->crtc_id;
365 pstate->fid.value = fb->id;
366
367 pstate->sx.value = 0;
368 pstate->sy.value = 0;
369 pstate->sw.value = fb->w << 16;
370 pstate->sh.value = fb->h << 16;
371 pstate->cx.value = output->x;
372 pstate->cy.value = output->y;
373 pstate->cw.value = output->current_mode->width;
374 pstate->ch.value = output->current_mode->height;
375
376 if ((!output->current) ||
377 (output->current->stride != fb->stride))
378 {
379 flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
380
381 ret = _fb_atomic_flip(output, pstate, flags);
382 if (ret < 0)
383 {
384 ERR("\tCrtc: %d FB: %d", output->crtc_id, fb->id);
385 return ret;
386 }
387
388 if (output->current) _release_buffer(output, output->current);
389 output->current = fb;
390 output->current->busy = EINA_TRUE;
391 output->next = NULL;
392
393 return 0;
394 }
395
396 ret = _fb_atomic_flip(output, pstate, flags);
397 if ((ret < 0) && (errno != EBUSY))
286 { 398 {
287 ERR("Failed to set Mode %dx%d for Output %s: %m", 399 ERR("Atomic Pageflip Failed for Crtc %u on Connector %u: %m",
288 output->current_mode->width, output->current_mode->height, 400 output->crtc_id, output->conn_id);
289 output->name);
290 return ret; 401 return ret;
291 } 402 }
403 else if (ret < 0)
404 {
405 output->next = fb;
406 if (output->next) output->next->busy = EINA_TRUE;
292 407
293 if (output->current) _release_buffer(output, output->current); 408 return 0;
294 output->current = fb; 409 }
295 output->current->busy = EINA_TRUE;
296 output->next = NULL;
297 410
298 return 0; 411 output->pending = fb;
299 } 412 output->pending->busy = EINA_TRUE;
300 413
301 ret = 414 return 0;
302 drmModePageFlip(fb->fd, output->crtc_id, fb->id,
303 DRM_MODE_PAGE_FLIP_EVENT, output->user_data);
304 if ((ret < 0) && (errno != EBUSY))
305 {
306 DBG("Pageflip Failed for Crtc %u on Connector %u: %m",
307 output->crtc_id, output->conn_id);
308 return ret;
309 } 415 }
310 else if (ret < 0) 416 else
417#endif
311 { 418 {
312 output->next = fb; 419 if ((!output->current) ||
313 output->next->busy = EINA_TRUE; 420 (output->current->stride != fb->stride))
421 {
422 ret =
423 drmModeSetCrtc(fb->fd, output->crtc_id, fb->id,
424 output->x, output->y, &output->conn_id, 1,
425 &output->current_mode->info);
426 if (ret)
427 {
428 ERR("Failed to set Mode %dx%d for Output %s: %m",
429 output->current_mode->width, output->current_mode->height,
430 output->name);
431 return ret;
432 }
433
434 if (output->current) _release_buffer(output, output->current);
435 output->current = fb;
436 output->current->busy = EINA_TRUE;
437 output->next = NULL;
438
439 return 0;
440 }
441
442 ret =
443 drmModePageFlip(fb->fd, output->crtc_id, fb->id,
444 DRM_MODE_PAGE_FLIP_EVENT, output->user_data);
445 if ((ret < 0) && (errno != EBUSY))
446 {
447 DBG("Pageflip Failed for Crtc %u on Connector %u: %m",
448 output->crtc_id, output->conn_id);
449 return ret;
450 }
451 else if (ret < 0)
452 {
453 output->next = fb;
454 output->next->busy = EINA_TRUE;
455 return 0;
456 }
457
458 output->pending = fb;
459 output->pending->busy = EINA_TRUE;
314 return 0; 460 return 0;
315 } 461 }
316
317 output->pending = fb;
318 output->pending->busy = EINA_TRUE;
319 return 0;
320} 462}
321 463
322EAPI Eina_Bool 464EAPI Eina_Bool