forked from enlightenment/efl
gl-drm: revise page flip logic
We can't really drive this buffer unlocking from the page flip handler for a lot of ugly reasons. This will be better in the future when evas supports multiple target buffers. For now let's cut this down and keep 2 buffers locked at all times. This gets drm-gl to work without massive tearing artifacts. @fix
This commit is contained in:
parent
f10b3f79a2
commit
6e1c7065d7
|
@ -88,45 +88,32 @@ _evas_outbuf_fb_get(Ecore_Drm_Device *dev, struct gbm_bo *bo)
|
||||||
return fb;
|
return fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
_evas_outbuf_cb_pageflip(void *data)
|
|
||||||
{
|
|
||||||
Outbuf *ob;
|
|
||||||
Ecore_Drm_Fb *fb;
|
|
||||||
struct gbm_bo *bo;
|
|
||||||
|
|
||||||
if (!(ob = data)) return;
|
|
||||||
|
|
||||||
bo = ob->priv.bo[ob->priv.curr];
|
|
||||||
if (!bo) return;
|
|
||||||
|
|
||||||
fb = _evas_outbuf_fb_get(ob->info->info.dev, bo);
|
|
||||||
if (fb) fb->pending_flip = EINA_FALSE;
|
|
||||||
|
|
||||||
gbm_surface_release_buffer(ob->surface, bo);
|
|
||||||
|
|
||||||
ob->priv.last = ob->priv.curr;
|
|
||||||
ob->priv.curr = (ob->priv.curr + 1) % ob->priv.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_evas_outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count)
|
_evas_outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count)
|
||||||
{
|
{
|
||||||
Ecore_Drm_Fb *fb;
|
Ecore_Drm_Fb *fb;
|
||||||
|
|
||||||
ob->priv.bo[ob->priv.curr] = gbm_surface_lock_front_buffer(ob->surface);
|
/* Repulsive hack: Right now we don't actually have a proper way to retire
|
||||||
if (!ob->priv.bo[ob->priv.curr])
|
* buffers because the ticker and the flip handler are out of sync, the
|
||||||
|
* flip handler is per output, fbs are submit to multiple outputs and may
|
||||||
|
* be denied (and re-queued) by any output they're supposed to be on.
|
||||||
|
* This will all be magically fixed when evas supports multiple target
|
||||||
|
* regions, but until then we do this:
|
||||||
|
* always have 2 buffers locked
|
||||||
|
*/
|
||||||
|
if (ob->priv.bo[1]) gbm_surface_release_buffer(ob->surface, ob->priv.bo[1]);
|
||||||
|
ob->priv.bo[1] = ob->priv.bo[0];
|
||||||
|
ob->priv.bo[0] = gbm_surface_lock_front_buffer(ob->surface);
|
||||||
|
if (!ob->priv.bo[0])
|
||||||
{
|
{
|
||||||
WRN("Could not lock front buffer");
|
WRN("Could not lock front buffer");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
fb = _evas_outbuf_fb_get(ob->info->info.dev, ob->priv.bo[0]);
|
||||||
fb = _evas_outbuf_fb_get(ob->info->info.dev, ob->priv.bo[ob->priv.curr]);
|
|
||||||
if (fb)
|
if (fb)
|
||||||
{
|
{
|
||||||
ecore_drm_fb_dirty(fb, rects, count);
|
ecore_drm_fb_dirty(fb, rects, count);
|
||||||
ecore_drm_fb_set(ob->info->info.dev, fb);
|
ecore_drm_fb_send(ob->info->info.dev, fb, NULL, NULL);
|
||||||
ecore_drm_fb_send(ob->info->info.dev, fb, _evas_outbuf_cb_pageflip, ob);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue