diff options
author | Derek Foreman <derekf@osg.samsung.com> | 2018-01-26 14:32:10 -0600 |
---|---|---|
committer | Derek Foreman <derekf@osg.samsung.com> | 2018-01-26 15:54:00 -0600 |
commit | 376d8d1e36f903082212ffa0ce1bc0178b323ac2 (patch) | |
tree | 0d40df971edb8cc6731167dc5d766398495221be | |
parent | 3e230693e62696f32bc8ab64619843f2507ed393 (diff) | |
download | efl-376d8d1e36f903082212ffa0ce1bc0178b323ac2.tar.gz |
ecore_wl2: Make surface managers modular
This allows loading modules to handle wayland surfaces, and makes the
existing dmabuf manager a module.
-rw-r--r-- | src/Makefile_Ecore_Wl2.am | 20 | ||||
-rw-r--r-- | src/lib/ecore_wl2/ecore_wl2.c | 32 | ||||
-rw-r--r-- | src/lib/ecore_wl2/ecore_wl2_private.h | 2 | ||||
-rw-r--r-- | src/lib/ecore_wl2/ecore_wl2_surface.c | 214 | ||||
-rw-r--r-- | src/lib/ecore_wl2/ecore_wl2_surface_module_dmabuf.c | 230 |
5 files changed, 280 insertions, 218 deletions
diff --git a/src/Makefile_Ecore_Wl2.am b/src/Makefile_Ecore_Wl2.am index 311cd27eec..29838fcbac 100644 --- a/src/Makefile_Ecore_Wl2.am +++ b/src/Makefile_Ecore_Wl2.am @@ -49,7 +49,11 @@ lib/ecore_wl2/text-input-unstable-v1-protocol.c \ lib/ecore_wl2/efl-hints-client-protocol.h \ lib/ecore_wl2/efl-hints-protocol.c -lib_ecore_wl2_libecore_wl2_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_WL2_CFLAGS@ -I$(top_srcdir)/src/static_libs/libdrm +lib_ecore_wl2_libecore_wl2_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ +@ECORE_WL2_CFLAGS@ \ +-I$(top_srcdir)/src/static_libs/libdrm \ +-DPACKAGE_LIB_DIR=\"$(libdir)\" \ +-DMODULE_ARCH=\"$(MODULE_ARCH)\" lib_ecore_wl2_libecore_wl2_la_LIBADD = @ECORE_WL2_LIBS@ lib_ecore_wl2_libecore_wl2_la_DEPENDENCIES = @ECORE_WL2_INTERNAL_LIBS@ lib_ecore_wl2_libecore_wl2_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@ @@ -76,4 +80,18 @@ lib/ecore_wl2/efl-hints-protocol.c EXTRA_DIST2 += lib/ecore_wl2/window_v6.x +DMABUFSOURCES = lib/ecore_wl2/ecore_wl2_surface_module_dmabuf.c +ecorewl2enginedmabufpkgdir = $(libdir)/ecore_wl2/engines/dmabuf/$(MODULE_ARCH) +ecorewl2enginedmabufpkg_LTLIBRARIES = modules/ecore_wl2/engines/dmabuf/module.la + +# Workaround for broken parallel install support in automake (relink issue) +# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=7328 +install_ecorewl2enginedmabufpkgLTLIBRARIES = install-ecorewl2enginedmabufpkgLTLIBRARIES +$(install_ecorewl2enginedmabufpkgLTLIBRARIES): install-libLTLIBRARIES + +modules_ecore_wl2_engines_dmabuf_module_la_SOURCES = $(DMABUFSOURCES) +modules_ecore_wl2_engines_dmabuf_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_WL2_CFLAGS@ +modules_ecore_wl2_engines_dmabuf_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@ +modules_ecore_wl2_engines_dmabuf_module_la_LIBTOOLFLAGS = --tag=disable-static + endif diff --git a/src/lib/ecore_wl2/ecore_wl2.c b/src/lib/ecore_wl2/ecore_wl2.c index 7a1bbee649..479ee93ef0 100644 --- a/src/lib/ecore_wl2/ecore_wl2.c +++ b/src/lib/ecore_wl2/ecore_wl2.c @@ -57,10 +57,38 @@ EAPI int ECORE_WL2_EVENT_WINDOW_ICONIFY_STATE_CHANGE = 0; EAPI int _ecore_wl2_event_window_www = -1; EAPI int _ecore_wl2_event_window_www_drag = -1; +static Eina_Array *supplied_modules = NULL; +static Eina_Array *local_modules = NULL; + static Eina_Bool _ecore_wl2_surface_modules_init(void) { - return ecore_wl2_surface_manager_dmabuf_add(); + const char *mod_dir; + + supplied_modules = eina_module_arch_list_get(NULL, + PACKAGE_LIB_DIR"/ecore_wl2/engines", + MODULE_ARCH); + eina_module_list_load(supplied_modules); + + mod_dir = getenv("ECORE_WL2_SURFACE_MODULE_DIR"); + if (mod_dir) + { + local_modules = eina_module_list_get(NULL, mod_dir, + EINA_TRUE, NULL, NULL); + eina_module_list_load(local_modules); + } + + if (!supplied_modules && !local_modules) + return EINA_FALSE; + + return EINA_TRUE; +} + +static void +_ecore_wl2_surface_modules_unload(void) +{ + eina_module_list_unload(supplied_modules); + eina_module_list_unload(local_modules); } /* public API functions */ @@ -230,6 +258,8 @@ ecore_wl2_shutdown(void) eina_log_domain_unregister(_ecore_wl2_log_dom); _ecore_wl2_log_dom = -1; + _ecore_wl2_surface_modules_unload(); + /* shutdown eina */ eina_shutdown(); diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h index c321df1d30..05d264b993 100644 --- a/src/lib/ecore_wl2/ecore_wl2_private.h +++ b/src/lib/ecore_wl2/ecore_wl2_private.h @@ -606,6 +606,4 @@ EAPI void ecore_wl2_window_weight_set(Ecore_Wl2_Window *window, double w, double EAPI extern int _ecore_wl2_event_window_www; EAPI extern int _ecore_wl2_event_window_www_drag; -Eina_Bool ecore_wl2_surface_manager_dmabuf_add(void); - #endif diff --git a/src/lib/ecore_wl2/ecore_wl2_surface.c b/src/lib/ecore_wl2/ecore_wl2_surface.c index 255188207b..c3a791f7c8 100644 --- a/src/lib/ecore_wl2/ecore_wl2_surface.c +++ b/src/lib/ecore_wl2/ecore_wl2_surface.c @@ -7,199 +7,9 @@ #include <sys/types.h> #include <sys/stat.h> -#include "linux-dmabuf-unstable-v1-client-protocol.h" - -#define MAX_BUFFERS 4 - static Eina_List *_smanagers = NULL; static int _smanager_count = 0; -int ECORE_WL2_SURFACE_DMABUF = 0; - -typedef struct _Ecore_Wl2_Dmabuf_Private -{ - Ecore_Wl2_Buffer *current; - Eina_List *buffers; -} Ecore_Wl2_Dmabuf_Private; - -static void * -_evas_dmabuf_surface_setup(Ecore_Wl2_Window *win) -{ - Ecore_Wl2_Dmabuf_Private *priv; - Ecore_Wl2_Display *ewd; - Ecore_Wl2_Buffer_Type types = 0; - - priv = calloc(1, sizeof(*priv)); - if (!priv) return NULL; - - ewd = ecore_wl2_window_display_get(win); - if (ecore_wl2_display_shm_get(ewd)) - types |= ECORE_WL2_BUFFER_SHM; - if (ecore_wl2_display_dmabuf_get(ewd)) - types |= ECORE_WL2_BUFFER_DMABUF; - - if (!ecore_wl2_buffer_init(ewd, types)) - { - free(priv); - return NULL; - } - - return priv; -} - -static void -_evas_dmabuf_surface_reconfigure(Ecore_Wl2_Surface *s EINA_UNUSED, void *priv_data, int w, int h, uint32_t flags EINA_UNUSED) -{ - Ecore_Wl2_Dmabuf_Private *p; - Ecore_Wl2_Buffer *b; - Eina_List *l, *tmp; - - p = priv_data; - - if ((!w) || (!h)) return; - EINA_LIST_FOREACH_SAFE(p->buffers, l, tmp, b) - { - if (ecore_wl2_buffer_fit(b, w, h)) - continue; - - ecore_wl2_buffer_destroy(b); - p->buffers = eina_list_remove_list(p->buffers, l); - } -} - -static void * -_evas_dmabuf_surface_data_get(Ecore_Wl2_Surface *s EINA_UNUSED, void *priv_data, int *w, int *h) -{ - Ecore_Wl2_Dmabuf_Private *p; - Ecore_Wl2_Buffer *b; - void *ptr; - int stride; - - p = priv_data; - - b = p->current; - if (!b) return NULL; - - ptr = ecore_wl2_buffer_map(b, NULL, h, &stride); - if (!ptr) return NULL; - - /* We return stride/bpp because it may not match the allocated - * width. evas will figure out the clipping - */ - if (w) *w = stride / 4; - - return ptr; -} - -static Ecore_Wl2_Buffer * -_evas_dmabuf_surface_wait(Ecore_Wl2_Surface *s, Ecore_Wl2_Dmabuf_Private *p) -{ - Ecore_Wl2_Buffer *b, *best = NULL; - Eina_List *l; - int best_age = -1; - int age; - - EINA_LIST_FOREACH(p->buffers, l, b) - { - if (ecore_wl2_buffer_busy_get(b)) continue; - age = ecore_wl2_buffer_age_get(b); - if (age > best_age) - { - best = b; - best_age = age; - } - } - - if (!best && (eina_list_count(p->buffers) < MAX_BUFFERS)) - { - best = ecore_wl2_surface_buffer_create(s); - /* Start at -1 so it's age is incremented to 0 for first draw */ - ecore_wl2_buffer_age_set(best, -1); - p->buffers = eina_list_append(p->buffers, best); - } - return best; -} - -static int -_evas_dmabuf_surface_assign(Ecore_Wl2_Surface *s, void *priv_data) -{ - Ecore_Wl2_Dmabuf_Private *p; - Ecore_Wl2_Buffer *b; - Eina_List *l; - - p = priv_data; - p->current = _evas_dmabuf_surface_wait(s, p); - if (!p->current) - { - /* Should be unreachable and will result in graphical - * anomalies - we should probably blow away all the - * existing buffers and start over if we actually - * see this happen... - */ - WRN("No free DMAbuf buffers, dropping a frame"); - EINA_LIST_FOREACH(p->buffers, l, b) - ecore_wl2_buffer_age_set(b, 0); - return 0; - } - EINA_LIST_FOREACH(p->buffers, l, b) - ecore_wl2_buffer_age_inc(b); - - return ecore_wl2_buffer_age_get(p->current); -} - -static void -_evas_dmabuf_surface_post(Ecore_Wl2_Surface *s, void *priv_data, Eina_Rectangle *rects, unsigned int count) -{ - Ecore_Wl2_Dmabuf_Private *p; - Ecore_Wl2_Buffer *b; - Ecore_Wl2_Window *win; - struct wl_buffer *wlb; - - p = priv_data; - - b = p->current; - if (!b) return; - - ecore_wl2_buffer_unlock(b); - - p->current = NULL; - ecore_wl2_buffer_busy_set(b); - ecore_wl2_buffer_age_set(b, 0); - - win = ecore_wl2_surface_window_get(s); - - wlb = ecore_wl2_buffer_wl_buffer_get(b); - ecore_wl2_window_buffer_attach(win, wlb, 0, 0, EINA_FALSE); - ecore_wl2_window_damage(win, rects, count); - - ecore_wl2_window_commit(win, EINA_TRUE); -} - -static void -_evas_dmabuf_surface_destroy(Ecore_Wl2_Surface *s EINA_UNUSED, void *priv_data) -{ - Ecore_Wl2_Dmabuf_Private *p; - Ecore_Wl2_Buffer *b; - - p = priv_data; - - EINA_LIST_FREE(p->buffers, b) - ecore_wl2_buffer_destroy(b); -} - -static void -_evas_dmabuf_surface_flush(Ecore_Wl2_Surface *surface EINA_UNUSED, void *priv_data) -{ - Ecore_Wl2_Dmabuf_Private *p; - Ecore_Wl2_Buffer *b; - - p = priv_data; - - EINA_LIST_FREE(p->buffers, b) - ecore_wl2_buffer_destroy(b); -} - - EAPI void ecore_wl2_surface_destroy(Ecore_Wl2_Surface *surface) { @@ -253,18 +63,6 @@ ecore_wl2_surface_flush(Ecore_Wl2_Surface *surface) surface->funcs->flush(surface, surface->private_data); } -static Ecore_Wl2_Surface_Interface dmabuf_smanager = -{ - .version = 1, - .setup = _evas_dmabuf_surface_setup, - .destroy = _evas_dmabuf_surface_destroy, - .reconfigure = _evas_dmabuf_surface_reconfigure, - .data_get = _evas_dmabuf_surface_data_get, - .assign = _evas_dmabuf_surface_assign, - .post = _evas_dmabuf_surface_post, - .flush = _evas_dmabuf_surface_flush -}; - EAPI Ecore_Wl2_Surface * ecore_wl2_surface_create(Ecore_Wl2_Window *win, Eina_Bool alpha) { @@ -337,15 +135,3 @@ ecore_wl2_surface_window_get(Ecore_Wl2_Surface *surface) return surface->wl2_win; } - -/* TEMPORARY HACK FOR TESTING */ -Eina_Bool -ecore_wl2_surface_manager_dmabuf_add(void) -{ - ECORE_WL2_SURFACE_DMABUF = ecore_wl2_surface_manager_add(&dmabuf_smanager); - - if (ECORE_WL2_SURFACE_DMABUF < 1) - return EINA_FALSE; - - return EINA_TRUE; -} diff --git a/src/lib/ecore_wl2/ecore_wl2_surface_module_dmabuf.c b/src/lib/ecore_wl2/ecore_wl2_surface_module_dmabuf.c new file mode 100644 index 0000000000..a2ddb9119a --- /dev/null +++ b/src/lib/ecore_wl2/ecore_wl2_surface_module_dmabuf.c @@ -0,0 +1,230 @@ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "Ecore_Wl2.h" + +#include <sys/types.h> +#include <sys/stat.h> + +#include "linux-dmabuf-unstable-v1-client-protocol.h" + +#define MAX_BUFFERS 4 + +int ECORE_WL2_SURFACE_DMABUF = 0; + +typedef struct _Ecore_Wl2_Dmabuf_Private +{ + Ecore_Wl2_Buffer *current; + Eina_List *buffers; +} Ecore_Wl2_Dmabuf_Private; + +static void * +_evas_dmabuf_surface_setup(Ecore_Wl2_Window *win) +{ + Ecore_Wl2_Dmabuf_Private *priv; + Ecore_Wl2_Display *ewd; + Ecore_Wl2_Buffer_Type types = 0; + + priv = calloc(1, sizeof(*priv)); + if (!priv) return NULL; + + ewd = ecore_wl2_window_display_get(win); + if (ecore_wl2_display_shm_get(ewd)) + types |= ECORE_WL2_BUFFER_SHM; + if (ecore_wl2_display_dmabuf_get(ewd)) + types |= ECORE_WL2_BUFFER_DMABUF; + + if (!ecore_wl2_buffer_init(ewd, types)) + { + free(priv); + return NULL; + } + + return priv; +} + +static void +_evas_dmabuf_surface_reconfigure(Ecore_Wl2_Surface *s EINA_UNUSED, void *priv_data, int w, int h, uint32_t flags EINA_UNUSED) +{ + Ecore_Wl2_Dmabuf_Private *p; + Ecore_Wl2_Buffer *b; + Eina_List *l, *tmp; + + p = priv_data; + + if ((!w) || (!h)) return; + EINA_LIST_FOREACH_SAFE(p->buffers, l, tmp, b) + { + if (ecore_wl2_buffer_fit(b, w, h)) + continue; + + ecore_wl2_buffer_destroy(b); + p->buffers = eina_list_remove_list(p->buffers, l); + } +} + +static void * +_evas_dmabuf_surface_data_get(Ecore_Wl2_Surface *s EINA_UNUSED, void *priv_data, int *w, int *h) +{ + Ecore_Wl2_Dmabuf_Private *p; + Ecore_Wl2_Buffer *b; + void *ptr; + int stride; + + p = priv_data; + + b = p->current; + if (!b) return NULL; + + ptr = ecore_wl2_buffer_map(b, NULL, h, &stride); + if (!ptr) return NULL; + + /* We return stride/bpp because it may not match the allocated + * width. evas will figure out the clipping + */ + if (w) *w = stride / 4; + + return ptr; +} + +static Ecore_Wl2_Buffer * +_evas_dmabuf_surface_wait(Ecore_Wl2_Surface *s, Ecore_Wl2_Dmabuf_Private *p) +{ + Ecore_Wl2_Buffer *b, *best = NULL; + Eina_List *l; + int best_age = -1; + int age; + + EINA_LIST_FOREACH(p->buffers, l, b) + { + if (ecore_wl2_buffer_busy_get(b)) continue; + age = ecore_wl2_buffer_age_get(b); + if (age > best_age) + { + best = b; + best_age = age; + } + } + + if (!best && (eina_list_count(p->buffers) < MAX_BUFFERS)) + { + best = ecore_wl2_surface_buffer_create(s); + /* Start at -1 so it's age is incremented to 0 for first draw */ + ecore_wl2_buffer_age_set(best, -1); + p->buffers = eina_list_append(p->buffers, best); + } + return best; +} + +static int +_evas_dmabuf_surface_assign(Ecore_Wl2_Surface *s, void *priv_data) +{ + Ecore_Wl2_Dmabuf_Private *p; + Ecore_Wl2_Buffer *b; + Eina_List *l; + + p = priv_data; + p->current = _evas_dmabuf_surface_wait(s, p); + if (!p->current) + { + /* Should be unreachable and will result in graphical + * anomalies - we should probably blow away all the + * existing buffers and start over if we actually + * see this happen... + */ +// WRN("No free DMAbuf buffers, dropping a frame"); + EINA_LIST_FOREACH(p->buffers, l, b) + ecore_wl2_buffer_age_set(b, 0); + return 0; + } + EINA_LIST_FOREACH(p->buffers, l, b) + ecore_wl2_buffer_age_inc(b); + + return ecore_wl2_buffer_age_get(p->current); +} + +static void +_evas_dmabuf_surface_post(Ecore_Wl2_Surface *s, void *priv_data, Eina_Rectangle *rects, unsigned int count) +{ + Ecore_Wl2_Dmabuf_Private *p; + Ecore_Wl2_Buffer *b; + Ecore_Wl2_Window *win; + struct wl_buffer *wlb; + + p = priv_data; + + b = p->current; + if (!b) return; + + ecore_wl2_buffer_unlock(b); + + p->current = NULL; + ecore_wl2_buffer_busy_set(b); + ecore_wl2_buffer_age_set(b, 0); + + win = ecore_wl2_surface_window_get(s); + + wlb = ecore_wl2_buffer_wl_buffer_get(b); + ecore_wl2_window_buffer_attach(win, wlb, 0, 0, EINA_FALSE); + ecore_wl2_window_damage(win, rects, count); + + ecore_wl2_window_commit(win, EINA_TRUE); +} + +static void +_evas_dmabuf_surface_destroy(Ecore_Wl2_Surface *s EINA_UNUSED, void *priv_data) +{ + Ecore_Wl2_Dmabuf_Private *p; + Ecore_Wl2_Buffer *b; + + p = priv_data; + + EINA_LIST_FREE(p->buffers, b) + ecore_wl2_buffer_destroy(b); +} + +static void +_evas_dmabuf_surface_flush(Ecore_Wl2_Surface *surface EINA_UNUSED, void *priv_data) +{ + Ecore_Wl2_Dmabuf_Private *p; + Ecore_Wl2_Buffer *b; + + p = priv_data; + + EINA_LIST_FREE(p->buffers, b) + ecore_wl2_buffer_destroy(b); +} + +static Ecore_Wl2_Surface_Interface dmabuf_smanager = +{ + .version = 1, + .setup = _evas_dmabuf_surface_setup, + .destroy = _evas_dmabuf_surface_destroy, + .reconfigure = _evas_dmabuf_surface_reconfigure, + .data_get = _evas_dmabuf_surface_data_get, + .assign = _evas_dmabuf_surface_assign, + .post = _evas_dmabuf_surface_post, + .flush = _evas_dmabuf_surface_flush +}; + +Eina_Bool +ecore_wl2_surface_module_dmabuf_init(void) +{ + ECORE_WL2_SURFACE_DMABUF = ecore_wl2_surface_manager_add(&dmabuf_smanager); + + if (ECORE_WL2_SURFACE_DMABUF < 1) + return EINA_FALSE; + + return EINA_TRUE; +} + +void +ecore_wl2_surface_module_dmabuf_shutdown(void) +{ + ecore_wl2_surface_manager_del(&dmabuf_smanager); +} + +EINA_MODULE_INIT(ecore_wl2_surface_module_dmabuf_init); +EINA_MODULE_SHUTDOWN(ecore_wl2_surface_module_dmabuf_shutdown); + |