ee_drm: Move all ticking into ecore_evas_drm and use new tick system

Combines all the gl_drm and drm ticking code into one set in
ecore_evas_drm and uses the new evas tick register/unregister callbacks
to set it up.
This commit is contained in:
Derek Foreman 2016-09-02 14:47:49 -05:00
parent 3d39c1e9b8
commit 794798f559
6 changed files with 117 additions and 257 deletions

View File

@ -19,6 +19,8 @@
# include <dlfcn.h>
#endif
#include <xf86drm.h>
#ifdef EAPI
# undef EAPI
#endif
@ -49,14 +51,17 @@ typedef struct _Ecore_Evas_Engine_Drm_Data
int x, y, w, h;
int depth, bpp;
unsigned int format;
drmEventContext ctx;
Ecore_Fd_Handler *hdlr;
Ecore_Drm2_Device *dev;
Ecore_Drm2_Output *output;
Eina_Bool ticking : 1;
} Ecore_Evas_Engine_Drm_Data;
static int _drm_init_count = 0;
static int
_ecore_evas_drm_init(Ecore_Evas_Engine_Drm_Data *edata, const char *device)
_ecore_evas_drm_init(Ecore_Evas *ee, Ecore_Evas_Engine_Drm_Data *edata, const char *device)
{
if (++_drm_init_count != 1) return _drm_init_count;
@ -92,8 +97,8 @@ _ecore_evas_drm_init(Ecore_Evas_Engine_Drm_Data *edata, const char *device)
}
edata->output = ecore_drm2_output_find(edata->dev, edata->x, edata->y);
if (!edata->output)
WRN("Could not find output at %d %d", edata->x, edata->y);
if (edata->output) ecore_drm2_output_user_data_set(edata->output, ee);
else WRN("Could not find output at %d %d", edata->x, edata->y);
ecore_event_evas_init();
@ -586,6 +591,97 @@ _ecore_evas_drm_interface_new(void)
return iface;
}
static Eina_Bool
_cb_drm_event(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
{
Ecore_Evas *ee;
Ecore_Evas_Engine_Drm_Data *edata;
int ret;
ee = data;
edata = ee->engine.data;
ret = drmHandleEvent(edata->fd, &edata->ctx);
if (ret)
{
WRN("drmHandleEvent failed to read an event");
return EINA_FALSE;
}
return EINA_TRUE;
}
static void
_tick_schedule(int fd, Ecore_Evas *ee)
{
Ecore_Evas_Engine_Drm_Data *edata;
edata = ee->engine.data;
if (!edata->ticking) return;
drmVBlank vbl =
{
.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT,
.request.sequence = 1,
.request.signal = (unsigned long)ee,
};
/* FIXME: On some systems this can fail, breaking ticking forever. */
drmWaitVBlank(fd, &vbl);
}
static void
_cb_pageflip(int fd EINA_UNUSED, unsigned int frame EINA_UNUSED, unsigned int sec EINA_UNUSED, unsigned int usec EINA_UNUSED, void *data)
{
Ecore_Evas *ee;
Ecore_Evas_Engine_Drm_Data *edata;
Ecore_Drm2_Fb *current, *next;
ee = data;
edata = ee->engine.data;
current = ecore_drm2_output_current_fb_get(edata->output);
if (current) ecore_drm2_fb_busy_set(current, EINA_FALSE);
next = ecore_drm2_output_next_fb_get(edata->output);
if (next)
{
ecore_drm2_output_next_fb_set(edata->output, NULL);
ecore_drm2_fb_flip(next, edata->output);
}
}
static void
_cb_vblank(int fd, unsigned int frame EINA_UNUSED, unsigned int sec EINA_UNUSED, unsigned int usec EINA_UNUSED, void *data)
{
Ecore_Evas *ee;
Ecore_Evas_Engine_Drm_Data *edata;
ee = data;
edata = ee->engine.data;
ecore_evas_animator_tick(ee, NULL);
if (edata->ticking) _tick_schedule(fd, ee);
}
static void
_drm_animator_register(Ecore_Evas *ee)
{
Ecore_Evas_Engine_Drm_Data *edata;
edata = ee->engine.data;
edata->ticking = EINA_TRUE;
_tick_schedule(edata->fd, ee);
}
static void
_drm_animator_unregister(Ecore_Evas *ee)
{
Ecore_Evas_Engine_Drm_Data *edata;
edata = ee->engine.data;
edata->ticking = EINA_FALSE;
}
static Ecore_Evas_Engine_Func _ecore_evas_drm_engine_func =
{
_drm_free,
@ -662,8 +758,8 @@ static Ecore_Evas_Engine_Func _ecore_evas_drm_engine_func =
NULL, // aux_hints_set
NULL, // animator_register
NULL, // animator_unregister
_drm_animator_register, // animator_register
_drm_animator_unregister, // animator_unregister
NULL // evas_changed
};
@ -700,7 +796,7 @@ _ecore_evas_new_internal(const char *device, int x, int y, int w, int h, Eina_Bo
edata->bpp = 32; // FIXME: Remove hardcode
edata->format = DRM_FORMAT_XRGB8888;
if (_ecore_evas_drm_init(edata, device) < 1)
if (_ecore_evas_drm_init(ee, edata, device) < 1)
{
free(edata);
free(ee);
@ -808,6 +904,15 @@ _ecore_evas_new_internal(const char *device, int x, int y, int w, int h, Eina_Bo
ecore_drm2_device_pointer_max_set(edata->dev, mw, mh);
ecore_drm2_device_pointer_warp(edata->dev, mw / 2, mh / 2);
/* setup vblank handler */
memset(&edata->ctx, 0, sizeof(edata->ctx));
edata->ctx.version = DRM_EVENT_CONTEXT_VERSION;
edata->ctx.vblank_handler = _cb_vblank;
edata->ctx.page_flip_handler = _cb_pageflip;
edata->hdlr =
ecore_main_fd_handler_add(edata->fd, ECORE_FD_READ, _cb_drm_event, ee,
NULL, NULL);
return ee;
eng_err:

View File

@ -63,9 +63,6 @@ struct _Outbuf
Eina_List *pending;
} priv;
drmEventContext ctx;
Ecore_Fd_Handler *hdlr;
Eina_Bool alpha : 1;
Eina_Bool vsync : 1;
};

View File

@ -8,68 +8,6 @@
#define GREEN_MASK 0x00ff00
#define BLUE_MASK 0x0000ff
static void _outbuf_tick_schedule(int fd, void *data);
static Eina_Bool ticking = EINA_FALSE;
static void
_outbuf_tick_begin(void *data)
{
Outbuf *ob;
ob = data;
ticking = EINA_TRUE;
if (ob) _outbuf_tick_schedule(ob->fd, ob);
}
static void
_outbuf_tick_end(void *data EINA_UNUSED)
{
ticking = EINA_FALSE;
}
static void
_outbuf_tick_source_set(Outbuf *ob)
{
if (ob)
{
ecore_animator_custom_source_tick_begin_callback_set
(_outbuf_tick_begin, ob);
ecore_animator_custom_source_tick_end_callback_set
(_outbuf_tick_end, ob);
ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM);
}
else
{
ecore_animator_custom_source_tick_begin_callback_set(NULL, NULL);
ecore_animator_custom_source_tick_end_callback_set(NULL, NULL);
ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER);
}
}
static void
_outbuf_tick_schedule(int fd, void *data)
{
if (!ticking) return;
drmVBlank vbl =
{
.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT,
.request.sequence = 1,
.request.signal = (unsigned long)data,
};
if (drmWaitVBlank(fd, &vbl) < 0)
_outbuf_tick_source_set(NULL);
}
static void
_cb_vblank(int fd, unsigned int frame EINA_UNUSED, unsigned int sec EINA_UNUSED, unsigned int usec EINA_UNUSED, void *data)
{
ecore_animator_custom_tick();
if (ticking) _outbuf_tick_schedule(fd, data);
}
Outbuf_Fb *
_outbuf_fb_find(Outbuf *ob, Ecore_Drm2_Fb *key)
{
@ -81,43 +19,6 @@ _outbuf_fb_find(Outbuf *ob, Ecore_Drm2_Fb *key)
return NULL;
}
static void
_cb_pageflip(int fd EINA_UNUSED, unsigned int frame EINA_UNUSED, unsigned int sec EINA_UNUSED, unsigned int usec EINA_UNUSED, void *data)
{
Outbuf *ob;
Outbuf_Fb *ofb;
Ecore_Drm2_Fb *next;
ob = data;
ofb = ob->priv.display;
if (ofb) ecore_drm2_fb_busy_set(ofb->fb, EINA_FALSE);
next = ecore_drm2_output_next_fb_get(ob->priv.output);
if (next)
{
ecore_drm2_output_next_fb_set(ob->priv.output, NULL);
ecore_drm2_fb_flip(next, ob->priv.output);
}
}
static Eina_Bool
_cb_drm_event(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
{
Outbuf *ob;
int ret;
ob = data;
ret = drmHandleEvent(ob->fd, &ob->ctx);
if (ret)
{
WRN("drmHandleEvent failed to read an event");
return EINA_FALSE;
}
return EINA_TRUE;
}
static void
_outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count)
{
@ -250,20 +151,6 @@ _outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h)
}
}
/* setup vblank handler */
memset(&ob->ctx, 0, sizeof(ob->ctx));
ob->ctx.version = DRM_EVENT_CONTEXT_VERSION;
ob->ctx.vblank_handler = _cb_vblank;
ob->ctx.page_flip_handler = _cb_pageflip;
ecore_drm2_output_user_data_set(ob->priv.output, ob);
ob->hdlr =
ecore_main_fd_handler_add(ob->fd, ECORE_FD_READ, _cb_drm_event, ob,
NULL, NULL);
_outbuf_tick_source_set(ob);
return ob;
}
@ -275,8 +162,6 @@ _outbuf_free(Outbuf *ob)
for (i = 0; i < ob->priv.num; i++)
_outbuf_fb_destroy(&ob->priv.ofb[i]);
ecore_main_fd_handler_del(ob->hdlr);
free(ob);
}
@ -363,18 +248,13 @@ _outbuf_reconfigure(Outbuf *ob, int w, int h, int rotation, Outbuf_Depth depth)
static Outbuf_Fb *
_outbuf_fb_wait(Outbuf *ob)
{
int iter = 0, i = 0;
int i = 0;
while (iter++ < 10)
for (i = 0; i < ob->priv.num; i++)
{
for (i = 0; i < ob->priv.num; i++)
{
if (&ob->priv.ofb[i] == ob->priv.display) continue;
if (ecore_drm2_fb_busy_get(ob->priv.ofb[i].fb)) continue;
if (ob->priv.ofb[i].valid) return &(ob->priv.ofb[i]);
}
drmHandleEvent(ob->fd, &ob->ctx);
if (&ob->priv.ofb[i] == ob->priv.display) continue;
if (ecore_drm2_fb_busy_get(ob->priv.ofb[i].fb)) continue;
if (ob->priv.ofb[i].valid) return &(ob->priv.ofb[i]);
}
return NULL;

View File

@ -778,37 +778,6 @@ _native_cb_free(void *image)
free(n);
}
static void
_cb_vblank(int fd, unsigned int frame EINA_UNUSED, unsigned int sec EINA_UNUSED, unsigned int usec EINA_UNUSED, void *data)
{
evas_outbuf_vblank(data, fd);
}
static void
_cb_page_flip(int fd, unsigned int frame EINA_UNUSED, unsigned int sec EINA_UNUSED, unsigned int usec EINA_UNUSED, void *data)
{
evas_outbuf_page_flip(data, fd);
}
static Eina_Bool
_cb_drm_event(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
{
Render_Engine *re;
int ret;
re = data;
if (!re) return EINA_TRUE;
ret = drmHandleEvent(re->fd, &re->ctx);
if (ret)
{
ERR("drmHandleEvent failed to read an event: %m");
return EINA_FALSE;
}
return EINA_TRUE;
}
/* engine specific override functions */
static void *
eng_info(Evas *eo_e EINA_UNUSED)
@ -924,15 +893,6 @@ eng_setup(Evas *evas, void *in)
re->fd = info->info.fd;
memset(&re->ctx, 0, sizeof(re->ctx));
re->ctx.version = DRM_EVENT_CONTEXT_VERSION;
re->ctx.vblank_handler = _cb_vblank;
re->ctx.page_flip_handler = _cb_page_flip;
re->hdlr =
ecore_main_fd_handler_add(info->info.fd, ECORE_FD_READ,
_cb_drm_event, re, NULL, NULL);
/* try to create new outbuf */
ob = evas_outbuf_new(info, epd->output.w, epd->output.h, swap_mode);
if (!ob)

View File

@ -71,8 +71,6 @@ struct _Render_Engine
Render_Engine_GL_Generic generic;
int fd;
drmEventContext ctx;
Ecore_Fd_Handler *hdlr;
};
struct _Context_3D
@ -132,8 +130,6 @@ void *evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int
void evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h);
void evas_outbuf_update_region_free(Outbuf *ob, RGBA_Image *update);
void evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode);
void evas_outbuf_vblank(void *data, int fd);
void evas_outbuf_page_flip(void *data, int fd);
Evas_Engine_GL_Context* evas_outbuf_gl_context_get(Outbuf *ob);
void *evas_outbuf_egl_display_get(Outbuf *ob);

View File

@ -5,86 +5,12 @@
static Outbuf *_evas_gl_drm_window = NULL;
static EGLContext context = EGL_NO_CONTEXT;
static int win_count = 0;
static Eina_Bool ticking = EINA_FALSE;
#ifdef EGL_MESA_platform_gbm
static PFNEGLGETPLATFORMDISPLAYEXTPROC dlsym_eglGetPlatformDisplayEXT = NULL;
static PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC dlsym_eglCreatePlatformWindowSurfaceEXT = NULL;
#endif
static void
_outbuf_tick_schedule(int fd, void *data)
{
if (!ticking) return;
drmVBlank vbl =
{
.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT,
.request.sequence = 1,
.request.signal = (unsigned long)data,
};
drmWaitVBlank(fd, &vbl);
}
static void
_outbuf_tick_begin(void *data)
{
Outbuf *ob;
ob = data;
ticking = EINA_TRUE;
if (ob) _outbuf_tick_schedule(ob->fd, ob);
}
static void
_outbuf_tick_end(void *data EINA_UNUSED)
{
ticking = EINA_FALSE;
}
static void
_outbuf_tick_source_set(Outbuf *ob)
{
if (ob)
{
ecore_animator_custom_source_tick_begin_callback_set
(_outbuf_tick_begin, ob);
ecore_animator_custom_source_tick_end_callback_set
(_outbuf_tick_end, ob);
ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM);
}
else
{
ecore_animator_custom_source_tick_begin_callback_set(NULL, NULL);
ecore_animator_custom_source_tick_end_callback_set(NULL, NULL);
ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER);
}
}
void
evas_outbuf_vblank(void *data, int fd)
{
ecore_animator_custom_tick();
if (ticking) _outbuf_tick_schedule(fd, data);
}
void
evas_outbuf_page_flip(void *data, int fd EINA_UNUSED)
{
Outbuf *ob;
Ecore_Drm2_Fb *next;
ob = data;
next = ecore_drm2_output_next_fb_get(ob->priv.output);
if (next)
{
ecore_drm2_output_next_fb_set(ob->priv.output, NULL);
if (ecore_drm2_fb_flip(next, ob->priv.output) < 0)
_outbuf_tick_source_set(NULL);
}
}
static void
_evas_outbuf_gbm_surface_destroy(Outbuf *ob)
{
@ -176,8 +102,7 @@ _evas_outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count)
if (fb)
{
ecore_drm2_fb_dirty(fb, rects, count);
if (ecore_drm2_fb_flip(fb, ob->priv.output) < 0)
_outbuf_tick_source_set(NULL);
ecore_drm2_fb_flip(fb, ob->priv.output);
/* Ecore_Drm2_Plane *plane; */
@ -480,9 +405,6 @@ evas_outbuf_new(Evas_Engine_Info_GL_Drm *info, int w, int h, Render_Engine_Swap_
return NULL;
}
ecore_drm2_output_user_data_set(ob->priv.output, ob);
_outbuf_tick_source_set(ob);
return ob;
}