diff --git a/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c b/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c index 8289a76332..e53ffdab81 100644 --- a/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c +++ b/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c @@ -19,6 +19,8 @@ # include #endif +#include + #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: diff --git a/src/modules/evas/engines/drm/evas_engine.h b/src/modules/evas/engines/drm/evas_engine.h index 37336104c0..94ddcf42ca 100644 --- a/src/modules/evas/engines/drm/evas_engine.h +++ b/src/modules/evas/engines/drm/evas_engine.h @@ -63,9 +63,6 @@ struct _Outbuf Eina_List *pending; } priv; - drmEventContext ctx; - Ecore_Fd_Handler *hdlr; - Eina_Bool alpha : 1; Eina_Bool vsync : 1; }; diff --git a/src/modules/evas/engines/drm/evas_outbuf.c b/src/modules/evas/engines/drm/evas_outbuf.c index 3ae032e585..891be790a8 100644 --- a/src/modules/evas/engines/drm/evas_outbuf.c +++ b/src/modules/evas/engines/drm/evas_outbuf.c @@ -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; diff --git a/src/modules/evas/engines/gl_drm/evas_engine.c b/src/modules/evas/engines/gl_drm/evas_engine.c index fecbb875e1..6b4122f98b 100644 --- a/src/modules/evas/engines/gl_drm/evas_engine.c +++ b/src/modules/evas/engines/gl_drm/evas_engine.c @@ -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) diff --git a/src/modules/evas/engines/gl_drm/evas_engine.h b/src/modules/evas/engines/gl_drm/evas_engine.h index 8a51d59c93..6ad81df453 100644 --- a/src/modules/evas/engines/gl_drm/evas_engine.h +++ b/src/modules/evas/engines/gl_drm/evas_engine.h @@ -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); diff --git a/src/modules/evas/engines/gl_drm/evas_outbuf.c b/src/modules/evas/engines/gl_drm/evas_outbuf.c index c8710b53df..0737c5744b 100644 --- a/src/modules/evas/engines/gl_drm/evas_outbuf.c +++ b/src/modules/evas/engines/gl_drm/evas_outbuf.c @@ -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; }