diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index cb79b49c40..af00028038 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -1179,10 +1179,8 @@ WAYLAND_SHM_SOURCES = \ modules/evas/engines/wayland_shm/Evas_Engine_Wayland_Shm.h \ modules/evas/engines/wayland_shm/evas_engine.c \ modules/evas/engines/wayland_shm/evas_engine.h \ -modules/evas/engines/wayland_shm/evas_swapbuf.c \ -modules/evas/engines/wayland_shm/evas_swapbuf.h \ -modules/evas/engines/wayland_shm/evas_swapper.c \ -modules/evas/engines/wayland_shm/evas_swapper.h +modules/evas/engines/wayland_shm/evas_shm.c \ +modules/evas/engines/wayland_shm/evas_outbuf.c if EVAS_STATIC_BUILD_WAYLAND_SHM lib_evas_libevas_la_SOURCES += $(WAYLAND_SHM_SOURCES) lib_evas_libevas_la_CPPFLAGS += @evas_engine_wayland_shm_cflags@ diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c index e7521d5f86..926269d1e5 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c @@ -46,15 +46,6 @@ static void _ecore_evas_wayland_alpha_do(Ecore_Evas *ee, int alpha); static void _ecore_evas_wayland_transparent_do(Ecore_Evas *ee, int transparent); static void _ecore_evas_wl_common_border_update(Ecore_Evas *ee); -/* Frame listener */ -static void _ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback, uint32_t tm); - -/* Frame listener */ -static const struct wl_callback_listener frame_listener = -{ - _ecore_evas_wl_frame_complete, -}; - /* local functions */ static void _ecore_evas_wl_common_state_update(Ecore_Evas *ee) @@ -592,8 +583,6 @@ _ecore_evas_wl_common_free(Ecore_Evas *ee) if (!ee) return; wdata = ee->engine.data; - if (wdata->frame_callback) wl_callback_destroy(wdata->frame_callback); - wdata->frame_callback = NULL; if (wdata->win) ecore_wl_window_free(wdata->win); wdata->win = NULL; free(wdata); @@ -1441,42 +1430,6 @@ _ecore_evas_wl_common_post_render(Ecore_Evas *ee) if (ee->func.fn_post_render) ee->func.fn_post_render(ee); } -void -_ecore_evas_wl_common_frame_callback_clean(Ecore_Evas *ee) -{ - Ecore_Evas_Engine_Wl_Data *wdata; - - wdata = ee->engine.data; - - if (!wdata->frame_pending) - return; - wl_callback_destroy(wdata->frame_callback); - wdata->frame_callback = NULL; - wdata->frame_pending = EINA_FALSE; -} - -static void -_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback EINA_UNUSED, uint32_t tm EINA_UNUSED) -{ - Ecore_Evas *ee = data; - Ecore_Wl_Window *win = NULL; - Ecore_Evas_Engine_Wl_Data *wdata; - - if (!ee) return; - - _ecore_evas_wl_common_frame_callback_clean(ee); - - wdata = ee->engine.data; - if (!(win = wdata->win)) return; - - if (ecore_wl_window_surface_get(win)) - { - wdata->frame_callback = - wl_surface_frame(ecore_wl_window_surface_get(win)); - wl_callback_add_listener(wdata->frame_callback, &frame_listener, ee); - } -} - int _ecore_evas_wl_common_render(Ecore_Evas *ee) { @@ -1516,20 +1469,6 @@ _ecore_evas_wl_common_render(Ecore_Evas *ee) updates = evas_render_updates(ee->evas); rend = _ecore_evas_wl_common_render_updates_process(ee, updates); evas_render_updates_free(updates); - - if (!wdata->frame_pending) - { - if (!wdata->frame_callback) - { - wdata->frame_callback = - wl_surface_frame(ecore_wl_window_surface_get(win)); - wl_callback_add_listener(wdata->frame_callback, - &frame_listener, ee); - } - - if (rend) - wdata->frame_pending = EINA_TRUE; - } } else if (evas_render_async(ee->evas)) { diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c index 46003e8555..d9b579de53 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c @@ -373,7 +373,6 @@ _ecore_evas_wl_hide(Ecore_Evas *ee) if (!ee->visible) return; ee->visible = 0; ee->should_be_visible = 0; - _ecore_evas_wl_common_frame_callback_clean(ee); if (ee->func.fn_hide) ee->func.fn_hide(ee); } diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h index 98e2624936..206d178008 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h @@ -35,8 +35,6 @@ struct _Ecore_Evas_Engine_Wl_Data #ifdef BUILD_ECORE_EVAS_WAYLAND_EGL struct wl_egl_window *egl_win; #endif - Eina_Bool frame_pending : 1; - struct wl_callback *frame_callback; }; Ecore_Evas_Interface_Wayland *_ecore_evas_wl_interface_new(void); diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c index 9355e50b03..7e9e353694 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c @@ -366,7 +366,6 @@ _ecore_evas_wl_hide(Ecore_Evas *ee) if (!ee->visible) return; ee->visible = 0; ee->should_be_visible = 0; - _ecore_evas_wl_common_frame_callback_clean(ee); if (ee->func.fn_hide) ee->func.fn_hide(ee); } diff --git a/src/modules/evas/engines/wayland_shm/evas_engine.c b/src/modules/evas/engines/wayland_shm/evas_engine.c index 21f4ef33b2..fd97de602b 100644 --- a/src/modules/evas/engines/wayland_shm/evas_engine.c +++ b/src/modules/evas/engines/wayland_shm/evas_engine.c @@ -1,171 +1,156 @@ #include "evas_common_private.h" #include "evas_private.h" -#include "Evas_Engine_Wayland_Shm.h" +#ifdef EVAS_CSERVE2 +# include "evas_cs2_private.h" +#endif + #include "evas_engine.h" -#include "evas_swapbuf.h" -/* local structures */ +/* logging domain variable */ +int _evas_engine_way_shm_log_dom = -1; + +/* evas function tables - filled in later (func and parent func) */ +static Evas_Func func, pfunc; + +/* engine structure data */ typedef struct _Render_Engine Render_Engine; - struct _Render_Engine { Render_Engine_Software_Generic generic; - void (*outbuf_reconfigure)(Outbuf *ob, int x, int y, int w, int h, int rot, Outbuf_Depth depth, Eina_Bool alpha); + void (*outbuf_reconfigure)(Outbuf *ob, int x, int y, int w, int h, int rot, Outbuf_Depth depth, Eina_Bool alpha, Eina_Bool resize); }; -/* engine function prototypes */ -static void *eng_info(Evas *eo_evas EINA_UNUSED); -static void eng_info_free(Evas *eo_evas EINA_UNUSED, void *einfo); -static int eng_setup(Evas *eo_evas, void *einfo); -static void eng_output_free(void *data); - -/* local variables */ -static Evas_Func func, pfunc; - -/* external variables */ -int _evas_engine_way_shm_log_dom = -1; - -/* local functions */ -static void * -_output_engine_setup(Evas_Engine_Info_Wayland_Shm *info, - int w, int h, - unsigned int rotation, unsigned int depth, - Eina_Bool destination_alpha, - struct wl_shm *wl_shm, - struct wl_surface *wl_surface) +/* LOCAL FUNCTIONS */ +Render_Engine * +_render_engine_swapbuf_setup(int w, int h, unsigned int rotation, unsigned int depth, Eina_Bool alpha, struct wl_shm *shm, struct wl_surface *surface) { - Render_Engine *re = NULL; + Render_Engine *re; Outbuf *ob; LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* try to allocate a new render engine */ - if (!(re = calloc(1, sizeof(Render_Engine)))) - return NULL; + /* try to allocate space for new render engine */ + if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL; + ob = _evas_outbuf_setup(w, h, rotation, depth, alpha, shm, surface); + if (!ob) goto err; - ob = evas_swapbuf_setup(info, w, h, rotation, depth, - destination_alpha, wl_shm, - wl_surface); - if (!ob) goto on_error; - - if (!evas_render_engine_software_generic_init(&re->generic, ob, - evas_swapbuf_state_get, - evas_swapbuf_rotation_get, + if (!evas_render_engine_software_generic_init(&re->generic, ob, + _evas_outbuf_swapmode_get, + _evas_outbuf_rotation_get, NULL, - NULL, - evas_swapbuf_update_region_new, - evas_swapbuf_update_region_push, - evas_swapbuf_update_region_free, - evas_swapbuf_idle_flush, - evas_swapbuf_flush, - evas_swapbuf_free, + NULL, + _evas_outbuf_update_region_new, + _evas_outbuf_update_region_push, + _evas_outbuf_update_region_free, + _evas_outbuf_idle_flush, + _evas_outbuf_flush, + _evas_outbuf_free, w, h)) - goto on_error; + goto err; - re->outbuf_reconfigure = evas_swapbuf_reconfigure; + re->outbuf_reconfigure = _evas_outbuf_reconfigure; /* return allocated render engine */ return re; - on_error: - if (ob) evas_swapbuf_free(ob); +err: + if (ob) _evas_outbuf_free(ob); free(re); return NULL; } -/* engine functions */ +/* ENGINE API FUNCTIONS WE PROVIDE */ static void * eng_info(Evas *eo_evas EINA_UNUSED) { - Evas_Engine_Info_Wayland_Shm *info; + Evas_Engine_Info_Wayland_Shm *einfo; - /* try to allocate space for engine info */ - if (!(info = calloc(1, sizeof(Evas_Engine_Info_Wayland_Shm)))) + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + /* try to allocate space for new engine info */ + if (!(einfo = calloc(1, sizeof(Evas_Engine_Info_Wayland_Shm)))) return NULL; - /* fill in default engine info fields */ - info->magic.magic = rand(); - info->render_mode = EVAS_RENDER_MODE_BLOCKING; + /* fill in engine info */ + einfo->magic.magic = rand(); + einfo->render_mode = EVAS_RENDER_MODE_BLOCKING; /* return allocated engine info */ - return info; + return einfo; } static void -eng_info_free(Evas *eo_evas EINA_UNUSED, void *einfo) +eng_info_free(Evas *eo_evas EINA_UNUSED, void *info) { - Evas_Engine_Info_Wayland_Shm *info; + Evas_Engine_Info_Wayland_Shm *einfo; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); /* try to free previously allocated engine info */ - if ((info = (Evas_Engine_Info_Wayland_Shm *)einfo)) - free(info); + if ((einfo = (Evas_Engine_Info_Wayland_Shm *)info)) + free(einfo); } static int -eng_setup(Evas *eo_evas, void *einfo) +eng_setup(Evas *eo_evas, void *info) { - Evas_Engine_Info_Wayland_Shm *info; + Evas_Engine_Info_Wayland_Shm *einfo; Evas_Public_Data *epd; Render_Engine *re = NULL; LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* try to cast the engine info to our engine info */ - if (!(info = (Evas_Engine_Info_Wayland_Shm *)einfo)) + /* try to cast to our engine info */ + if (!(einfo = (Evas_Engine_Info_Wayland_Shm *)info)) return 0; - /* try to get evas public data from the canvas */ + /* try to get evas public data */ if (!(epd = eo_data_scope_get(eo_evas, EVAS_CANVAS_CLASS))) return 0; /* test for valid engine output */ if (!(re = epd->engine.data.output)) { - static int try_swap = -1; - - /* NB: If we have no valid output then assume we have not been - * initialized yet and call any needed common init routines */ + /* if we have no engine data, assume we have not initialized yet */ evas_common_init(); - if (try_swap == -1) - { - /* check for env var to see if we should try swapping */ - if (getenv("EVAS_NO_WAYLAND_SWAPBUF")) try_swap = 0; - else try_swap = 1; - } + re = _render_engine_swapbuf_setup(epd->output.w, epd->output.h, + einfo->info.rotation, + einfo->info.depth, + einfo->info.destination_alpha, + einfo->info.wl_shm, + einfo->info.wl_surface); - if (!(re = - _output_engine_setup(info, epd->output.w, epd->output.h, - info->info.rotation, info->info.depth, - info->info.destination_alpha, - info->info.wl_shm, info->info.wl_surface))) - return 0; - } + if (re) + re->generic.ob->info = einfo; + else + goto err; + } else { Outbuf *ob; - int ponebuf = 0; - if ((re) && (re->generic.ob)) ponebuf = re->generic.ob->onebuf; - - ob = evas_swapbuf_setup(info, epd->output.w, epd->output.h, - info->info.rotation, - info->info.depth, - info->info.destination_alpha, - info->info.wl_shm, - info->info.wl_surface); - if (!ob) return 0; - - evas_render_engine_software_generic_update(&re->generic, ob, epd->output.w, epd->output.h); - - if ((re) && (re->generic.ob)) re->generic.ob->onebuf = ponebuf; + ob = _evas_outbuf_setup(epd->output.w, epd->output.h, + einfo->info.rotation, einfo->info.depth, + einfo->info.destination_alpha, + einfo->info.wl_shm, einfo->info.wl_surface); + if (ob) + { + ob->info = einfo; + evas_render_engine_software_generic_update(&re->generic, ob, + epd->output.w, + epd->output.h); + } } - /* reassign render engine to output */ epd->engine.data.output = re; - if (!epd->engine.data.output) return 0; + if (!epd->engine.data.output) + { + ERR("Failed to create Render Engine"); + goto err; + } if (!epd->engine.data.context) { @@ -173,86 +158,92 @@ eng_setup(Evas *eo_evas, void *einfo) epd->engine.func->context_new(epd->engine.data.output); } - /* return success */ return 1; + +err: + evas_common_shutdown(); + return 0; } -static void +static void eng_output_free(void *data) { - Render_Engine *re = data; + Render_Engine *re; - LOGFN(__FILE__, __LINE__, __FUNCTION__); - evas_render_engine_software_generic_clean(&re->generic); - free(re); + if ((re = (Render_Engine *)data)) + { + evas_render_engine_software_generic_clean(&re->generic); + free(re); + } evas_common_shutdown(); } -static void +static void eng_output_resize(void *data, int w, int h) { Render_Engine *re; - Evas_Engine_Info_Wayland_Shm *info; + Evas_Engine_Info_Wayland_Shm *einfo; int dx = 0, dy = 0; + Eina_Bool resize = EINA_FALSE; LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!(re = (Render_Engine *)data)) return; + if (!(einfo = re->generic.ob->info)) return; - if (!(info = re->generic.ob->info)) return; - - if (info->info.edges & 4) + if (einfo->info.edges & 4) // resize from left { - if ((info->info.rotation == 90) || (info->info.rotation == 270)) + if ((einfo->info.rotation == 90) || (einfo->info.rotation == 270)) dx = re->generic.ob->h - h; else dx = re->generic.ob->w - w; } - if (info->info.edges & 1) + if (einfo->info.edges & 1) // resize from top { - if ((info->info.rotation == 90) || (info->info.rotation == 270)) + if ((einfo->info.rotation == 90) || (einfo->info.rotation == 270)) dy = re->generic.ob->w - w; else dy = re->generic.ob->h - h; } - re->outbuf_reconfigure(re->generic.ob, dx, dy, w, h, - info->info.rotation, info->info.depth, - info->info.destination_alpha); + if (einfo->info.edges) resize = EINA_TRUE; + + re->outbuf_reconfigure(re->generic.ob, dx, dy, w, h, + einfo->info.rotation, einfo->info.depth, + einfo->info.destination_alpha, resize); evas_common_tilebuf_free(re->generic.tb); if ((re->generic.tb = evas_common_tilebuf_new(w, h))) evas_common_tilebuf_set_tile_size(re->generic.tb, TILESIZE, TILESIZE); } -/* module functions */ +/* EVAS MODULE FUNCTIONS */ static int module_open(Evas_Module *em) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + /* check for valid evas module */ if (!em) return 0; + /* try to get functions from whatever engine module we inherit from */ + if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0; + /* try to create our logging domain */ _evas_engine_way_shm_log_dom = eina_log_domain_register("evas-wayland_shm", EVAS_DEFAULT_LOG_COLOR); if (_evas_engine_way_shm_log_dom < 0) { - /* creating the logging domain failed. notify user */ - EINA_LOG_ERR("Could not create a module log domain."); - - /* return failure */ + EINA_LOG_ERR("Cannot create a module logging domain"); return 0; } - /* try to inherit base functions from the software generic engine */ - if (!_evas_module_engine_inherit(&pfunc, "software_generic")) - return 0; - - /* copy base functions from the software_generic engine */ + /* copy parent functions */ func = pfunc; - /* override any engine specific functions that we provide */ + /* override engine specific functions */ #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_) ORD(info); ORD(info_free); @@ -260,19 +251,23 @@ module_open(Evas_Module *em) ORD(output_free); ORD(output_resize); - /* advertise out our own api */ + /* advertise our own engine functions */ em->functions = (void *)(&func); - /* return success */ return 1; } static void module_close(Evas_Module *em EINA_UNUSED) { - /* if we have the log domain, unregister it */ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + /* unregister logging domain */ if (_evas_engine_way_shm_log_dom > -1) eina_log_domain_unregister(_evas_engine_way_shm_log_dom); + + /* reset logging domain variable */ + _evas_engine_way_shm_log_dom = -1; } static Evas_Module_Api evas_modapi = diff --git a/src/modules/evas/engines/wayland_shm/evas_engine.h b/src/modules/evas/engines/wayland_shm/evas_engine.h index 989244922c..4a74f4fe97 100644 --- a/src/modules/evas/engines/wayland_shm/evas_engine.h +++ b/src/modules/evas/engines/wayland_shm/evas_engine.h @@ -38,32 +38,69 @@ extern int _evas_engine_way_shm_log_dom; # define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_way_shm_log_dom, __VA_ARGS__) # include +# include "../software_generic/Evas_Engine_Software_Generic.h" +# include "Evas_Engine_Wayland_Shm.h" -#include "Evas_Engine_Wayland_Shm.h" +# define MAX_BUFFERS 4 +# define SURFACE_HINT_RESIZING 0x10 -#include "../software_generic/Evas_Engine_Software_Generic.h" +typedef struct _Shm_Pool Shm_Pool; +struct _Shm_Pool +{ + struct wl_shm_pool *pool; + size_t size, used; + void *data; +}; + +typedef struct _Shm_Data Shm_Data; +struct _Shm_Data +{ + struct wl_buffer *buffer; + Shm_Pool *pool; + void *map; +}; + +typedef struct _Shm_Leaf Shm_Leaf; +struct _Shm_Leaf +{ + int w, h, busy; + Shm_Data *data; + Shm_Pool *resize_pool; + Eina_Bool valid : 1; +}; + +typedef struct _Shm_Surface Shm_Surface; +struct _Shm_Surface +{ + struct wl_shm *shm; + struct wl_surface *surface; + struct wl_callback *frame_cb; + uint32_t flags; + int w, h; + int dx, dy; + int num_buff; + + Shm_Leaf leaf[MAX_BUFFERS]; + Shm_Leaf *current; + + Eina_Bool redraw : 1; + Eina_Bool alpha : 1; +}; struct _Outbuf { - Evas_Engine_Info_Wayland_Shm *info; - int w, h; int rotation; int onebuf; + int num_buff; Outbuf_Depth depth; + Evas_Engine_Info_Wayland_Shm *info; + + Shm_Surface *surface; + struct { - struct - { - /* wayland shared memory object */ - struct wl_shm *shm; - struct wl_surface *surface; - } wl; - - /* swapper */ - void *swapper; - /* one big buffer for updates. flushed on idle_flush */ RGBA_Image *onebuf; Eina_Array onebuf_regions; @@ -74,8 +111,28 @@ struct _Outbuf /* list of previous frame pending regions to write out */ Eina_List *prev_pending_writes; + /* Eina_Bool redraw : 1; */ Eina_Bool destination_alpha : 1; } priv; }; +Shm_Surface *_evas_shm_surface_create(struct wl_shm *shm, struct wl_surface *surface, int w, int h, Eina_Bool alpha); +void _evas_shm_surface_destroy(Shm_Surface *surface); +void _evas_shm_surface_prepare(Shm_Surface *surface, int dx, int dy, int w, int h, int num_buff, uint32_t flags); +void _evas_shm_surface_swap(Shm_Surface *surface, Eina_Rectangle *rects, unsigned int count); +void *_evas_shm_surface_data_get(Shm_Surface *surface, int *w, int *h); +void _evas_shm_surface_redraw(Shm_Surface *surface); + +Outbuf *_evas_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *shm, struct wl_surface *surface); +void _evas_outbuf_free(Outbuf *ob); +void _evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); +void _evas_outbuf_idle_flush(Outbuf *ob); + +Render_Engine_Swap_Mode _evas_outbuf_swapmode_get(Outbuf *ob); +int _evas_outbuf_rotation_get(Outbuf *ob); +void _evas_outbuf_reconfigure(Outbuf *ob, int x, int y, int w, int h, int rot, Outbuf_Depth depth, Eina_Bool alpha, Eina_Bool resize); +void *_evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); +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); + #endif diff --git a/src/modules/evas/engines/wayland_shm/evas_swapbuf.c b/src/modules/evas/engines/wayland_shm/evas_outbuf.c similarity index 64% rename from src/modules/evas/engines/wayland_shm/evas_swapbuf.c rename to src/modules/evas/engines/wayland_shm/evas_outbuf.c index 79101b4455..cedd2f1282 100644 --- a/src/modules/evas/engines/wayland_shm/evas_swapbuf.c +++ b/src/modules/evas/engines/wayland_shm/evas_outbuf.c @@ -1,383 +1,87 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -//#include - +#include "evas_common_private.h" +#include "evas_private.h" #ifdef EVAS_CSERVE2 # include "evas_cs2_private.h" #endif - -#include "evas_common_private.h" -#include "evas_macros.h" #include "evas_engine.h" -#include "evas_swapbuf.h" -#include "evas_swapper.h" #define RED_MASK 0x00ff0000 #define GREEN_MASK 0x0000ff00 #define BLUE_MASK 0x000000ff -/* local function prototypes */ - Outbuf * -evas_swapbuf_setup(Evas_Engine_Info_Wayland_Shm *info, int w, int h, unsigned int rotation, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *wl_shm, struct wl_surface *wl_surface) +_evas_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *shm, struct wl_surface *surface) { Outbuf *ob = NULL; + char *num; LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* try to allocate a new Outbuf */ - if (!(ob = calloc(1, sizeof(Outbuf)))) - return NULL; + /* try to allocate space for new Outbuf */ + if (!(ob = calloc(1, sizeof(Outbuf)))) return NULL; - /* set some properties */ + /* set outbuf properties */ ob->w = w; ob->h = h; - ob->rotation = rotation; + ob->rotation = rot; ob->depth = depth; ob->priv.destination_alpha = alpha; - ob->priv.wl.shm = wl_shm; - ob->priv.wl.surface = wl_surface; - ob->info = info; - if ((ob->rotation == 0) || (ob->rotation == 180)) + /* default to double buffer */ + ob->num_buff = 2; + + /* check for any 'number of buffers' override in the environment */ + if ((num = getenv("EVAS_WAYLAND_SHM_BUFFERS"))) { - ob->priv.swapper = - evas_swapper_setup(0, 0, w, h, depth, alpha, ob->priv.wl.shm, - ob->priv.wl.surface); - } - else if ((ob->rotation == 90) || (ob->rotation == 270)) - { - ob->priv.swapper = - evas_swapper_setup(0, 0, h, w, depth, alpha, ob->priv.wl.shm, - ob->priv.wl.surface); + int n = 0; + + n = atoi(num); + if (n <= 0) n = 1; + if (n > 4) n = 4; + + ob->num_buff = n; } - /* check that a swapper was created */ - if (!ob->priv.swapper) - { - /* free the Outbuf structure allocation */ - free(ob); + /* try to create the outbuf surface */ + if (!(ob->surface = _evas_shm_surface_create(shm, surface, w, h, alpha))) + goto surf_err; - return NULL; - } + /* call prepare function to setup first buffer */ + _evas_shm_surface_prepare(ob->surface, 0, 0, w, h, + ob->num_buff, ob->surface->flags); - /* set step size of regions array */ eina_array_step_set(&ob->priv.onebuf_regions, sizeof(Eina_Array), 8); - /* return allocated Outbuf */ return ob; -} -void -evas_swapbuf_free(Outbuf *ob) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* check for valid output buffer */ - if (!ob) return; - - /* flush the output buffer */ - evas_swapbuf_flush(ob, NULL, MODE_FULL); - evas_swapbuf_idle_flush(ob); - evas_swapper_free(ob->priv.swapper); - eina_array_flush(&ob->priv.onebuf_regions); - - /* free the allocated structure */ +surf_err: free(ob); -} - -void -evas_swapbuf_reconfigure(Outbuf *ob, int x, int y, int w, int h, int rotation, Outbuf_Depth depth, Eina_Bool alpha) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* check for valid output buffer */ - if (!ob) return; - - if (depth == OUTBUF_DEPTH_INHERIT) depth = ob->depth; - - /* check that something was actually changed */ - if ((ob->w == w) && (ob->h == h) && - (ob->rotation == rotation) && (ob->depth == depth)) - return; - - /* set some properties */ - ob->w = w; - ob->h = h; - ob->rotation = rotation; - ob->depth = depth; - ob->priv.destination_alpha = alpha; - - /* check for valid swapper */ - if (ob->priv.swapper) - { - if ((ob->rotation == 0) || (ob->rotation == 180)) - ob->priv.swapper = evas_swapper_reconfigure(ob->priv.swapper, - x, y, w, h, depth, - alpha); - else if ((ob->rotation == 90) || (ob->rotation == 270)) - ob->priv.swapper = evas_swapper_reconfigure(ob->priv.swapper, - x, y, h, w, depth, - alpha); - return; - } - - /* create new swapper */ - if ((ob->rotation == 0) || (ob->rotation == 180)) - { - ob->priv.swapper = - evas_swapper_setup(x, y, w, h, depth, alpha, ob->priv.wl.shm, - ob->priv.wl.surface); - } - else if ((ob->rotation == 90) || (ob->rotation == 270)) - { - ob->priv.swapper = - evas_swapper_setup(x, y, h, w, depth, alpha, ob->priv.wl.shm, - ob->priv.wl.surface); - } -} - -void * -evas_swapbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch) -{ - RGBA_Image *img; - Eina_Rectangle *rect; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, ob->w, ob->h); - if ((w <= 0) || (h <= 0)) return NULL; - - if (ob->rotation == 0) - { - if (!(img = ob->priv.onebuf)) - { - int bpl = 0; - int bw = 0, bh = 0; - void *data; - - data = evas_swapper_buffer_map(ob->priv.swapper, &bw, &bh); - bpl = (bw * sizeof(int)); - -#ifdef EVAS_CSERVE2 - if (evas_cserve2_use_get()) - img = (RGBA_Image *)evas_cache2_image_data(evas_common_image_cache2_get(), - bpl / sizeof(int), bh, - data, - ob->priv.destination_alpha, - EVAS_COLORSPACE_ARGB8888); - else -#endif - img = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), - bpl / sizeof(int), bh, - data, - ob->priv.destination_alpha, - EVAS_COLORSPACE_ARGB8888); - - ob->priv.onebuf = img; - if (!img) return NULL; - } - - if (!(rect = eina_rectangle_new(x, y, w, h))) - return NULL; - - if (!eina_array_push(&ob->priv.onebuf_regions, rect)) - { -#ifdef EVAS_CSERVE2 - if (evas_cserve2_use_get()) - evas_cache2_image_close(&img->cache_entry); - else -#endif - evas_cache_image_drop(&img->cache_entry); - - eina_rectangle_free(rect); - - return NULL; - } - - /* clip the region to the onebuf region */ - if (cx) *cx = x; - if (cy) *cy = y; - if (cw) *cw = w; - if (ch) *ch = h; - return img; - } - else - { - if (!(rect = eina_rectangle_new(x, y, w, h))) - return NULL; - -#ifdef EVAS_CSERVE2 - if (evas_cserve2_use_get()) - img = (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get()); - else -#endif - img = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get()); - - if (!img) - { - eina_rectangle_free(rect); - return NULL; - } - - img->cache_entry.flags.alpha |= ob->priv.destination_alpha; - -#ifdef EVAS_CSERVE2 - if (evas_cserve2_use_get()) - evas_cache2_image_surface_alloc(&img->cache_entry, w, h); - else -#endif - evas_cache_image_surface_alloc(&img->cache_entry, w, h); - - img->extended_info = rect; - - ob->priv.pending_writes = - eina_list_append(ob->priv.pending_writes, img); - - if (cx) *cx = 0; - if (cy) *cy = 0; - if (cw) *cw = w; - if (ch) *ch = h; - return img; - } - return NULL; } void -evas_swapbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h) +_evas_outbuf_free(Outbuf *ob) { - Gfx_Func_Convert func = NULL; - Eina_Rectangle rect = {0, 0, 0, 0}, pr; - DATA32 *src; - DATA8 *dst; - int depth = 32, bpp = 0, bpl = 0, wid = 0; - int ww = 0, hh = 0; - int rx = 0, ry = 0; - LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* check for valid output buffer */ - if (!ob) return; + _evas_outbuf_flush(ob, NULL, MODE_FULL); + _evas_outbuf_idle_flush(ob); - /* check for pending writes */ - if (!ob->priv.pending_writes) return; + if (ob->surface) _evas_shm_surface_destroy(ob->surface); - if ((ob->rotation == 0) || (ob->rotation == 180)) - { - func = - evas_common_convert_func_get(0, w, h, depth, - RED_MASK, GREEN_MASK, BLUE_MASK, - PAL_MODE_NONE, ob->rotation); - } - else if ((ob->rotation == 90) || (ob->rotation == 270)) - { - func = - evas_common_convert_func_get(0, h, w, depth, - RED_MASK, GREEN_MASK, BLUE_MASK, - PAL_MODE_NONE, ob->rotation); - } + eina_array_flush(&ob->priv.onebuf_regions); - /* make sure we have a valid convert function */ - if (!func) return; - - /* based on rotation, set rectangle position */ - if (ob->rotation == 0) - { - rect.x = x; - rect.y = y; - } - else if (ob->rotation == 90) - { - rect.x = y; - rect.y = (ob->w - x - w); - } - else if (ob->rotation == 180) - { - rect.x = (ob->w - x - w); - rect.y = (ob->h - y - h); - } - else if (ob->rotation == 270) - { - rect.x = (ob->h - y - h); - rect.y = x; - } - - /* based on rotation, set rectangle size */ - if ((ob->rotation == 0) || (ob->rotation == 180)) - { - rect.w = w; - rect.h = h; - } - else if ((ob->rotation == 90) || (ob->rotation == 270)) - { - rect.w = h; - rect.h = w; - } - - /* check for valid update image data */ - if (!(src = update->image.data)) return; - - bpp = depth / 8; - if (bpp <= 0) return; - - /* check for valid desination data */ - if (!(dst = evas_swapper_buffer_map(ob->priv.swapper, &ww, &hh))) return; - - bpl = (ww * sizeof(int)); - - if (ob->rotation == 0) - { - RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh); - dst += (bpl * rect.y) + (rect.x * bpp); - w -= rx; - } - else if (ob->rotation == 180) - { - pr = rect; - RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh); - rx = pr.w - rect.w; - ry = pr.h - rect.h; - src += (update->cache_entry.w * ry) + rx; - w -= rx; - } - else if (ob->rotation == 90) - { - pr = rect; - RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh); - rx = pr.w - rect.w; ry = pr.h - rect.h; - src += ry; - w -= ry; - } - else if (ob->rotation == 270) - { - pr = rect; - RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh); - rx = pr.w - rect.w; ry = pr.h - rect.h; - src += (update->cache_entry.w * rx); - w -= ry; - } - - if ((rect.w <= 0) || (rect.h <= 0)) return; - - wid = bpl / bpp; - - dst += (bpl * rect.y) + (rect.x * bpp); - - func(src, dst, (update->cache_entry.w - w), (wid - rect.w), - rect.w, rect.h, x + rx, y + ry, NULL); + free(ob); } void -evas_swapbuf_update_region_free(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_UNUSED) +_evas_outbuf_idle_flush(Outbuf *ob) { - /* NB: nothing to do, they are cleaned up on flush */ + _evas_shm_surface_redraw(ob->surface); } void -evas_swapbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode) +_evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode) { Eina_Rectangle *result; RGBA_Image *img; @@ -387,8 +91,11 @@ evas_swapbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; - /* check for valid output buffer */ - if (!ob) return; + if (!ob->surface->current) + { + WRN("Cannot Flush. No Current Leaf !!"); + return; + } /* check for pending writes */ if (!ob->priv.pending_writes) @@ -407,11 +114,8 @@ evas_swapbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode EINA_ARRAY_ITER_NEXT(&ob->priv.onebuf_regions, i, rect, it) result[i] = *rect; - /* unmap the buffer */ - evas_swapper_buffer_unmap(ob->priv.swapper); - /* force a buffer swap */ - evas_swapper_swap(ob->priv.swapper, result, n); + _evas_shm_surface_swap(ob->surface, result, n); /* clean array */ eina_array_clean(&ob->priv.onebuf_regions); @@ -493,45 +197,319 @@ evas_swapbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode i++; } - /* unmap the buffer */ - evas_swapper_buffer_unmap(ob->priv.swapper); - /* force a buffer swap */ - evas_swapper_swap(ob->priv.swapper, result, n); + _evas_shm_surface_swap(ob->surface, result, n); } + + _evas_shm_surface_redraw(ob->surface); } -void -evas_swapbuf_idle_flush(Outbuf *ob EINA_UNUSED) +Render_Engine_Swap_Mode +_evas_outbuf_swapmode_get(Outbuf *ob) { -// LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* check for valid output buffer */ - /* if (!ob) return; */ - - /* check for valid swapper */ - /* if (!ob->priv.swapper) return; */ - - /* tell the swapper to release any buffers that have been rendered */ - /* evas_swapper_buffer_idle_flush(ob->priv.swapper); */ -} - -Render_Engine_Swap_Mode -evas_swapbuf_state_get(Outbuf *ob) -{ - int mode = 0; + int i = 0, count = 0; LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!ob->priv.swapper) return MODE_FULL; - mode = evas_swapper_buffer_state_get(ob->priv.swapper); - return mode; + for (; i < ob->num_buff; i++) + { + if (ob->surface->leaf[i].busy) + count++; + } + + switch (count) + { + case 0: + return MODE_COPY; + case 1: + return MODE_DOUBLE; + case 2: + return MODE_TRIPLE; + case 3: + return MODE_QUADRUPLE; + default: + return MODE_FULL; + } } -int -evas_swapbuf_rotation_get(Outbuf *ob) +int +_evas_outbuf_rotation_get(Outbuf *ob) { + LOGFN(__FILE__, __LINE__, __FUNCTION__); + return ob->rotation; } -/* local functions */ +void +_evas_outbuf_reconfigure(Outbuf *ob, int x, int y, int w, int h, int rot, Outbuf_Depth depth, Eina_Bool alpha, Eina_Bool resize) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (depth == OUTBUF_DEPTH_INHERIT) depth = ob->depth; + + if ((ob->w == w) && (ob->h == h) && + (ob->rotation == rot) && (ob->depth == depth) && + (ob->priv.destination_alpha == alpha)) + return; + + ob->w = w; + ob->h = h; + ob->rotation = rot; + ob->depth = depth; + ob->priv.destination_alpha = alpha; + + if (resize) + ob->surface->flags = SURFACE_HINT_RESIZING; + else + ob->surface->flags = 0; + + _evas_shm_surface_prepare(ob->surface, x, y, w, h, + ob->num_buff, ob->surface->flags); +} + +void * +_evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch) +{ + RGBA_Image *img; + Eina_Rectangle *rect; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, ob->w, ob->h); + if ((w <= 0) || (h <= 0)) return NULL; + + if (ob->rotation == 0) + { + if (!(img = ob->priv.onebuf)) + { + int bw = 0, bh = 0, bpl = 0; + void *data; + + if (!(data = _evas_shm_surface_data_get(ob->surface, &bw, &bh))) + { + ERR("Could not get surface data"); + return NULL; + } + + bpl = (bw * sizeof(int)); + +#ifdef EVAS_CSERVE2 + if (evas_cserve2_use_get()) + { + img = (RGBA_Image *) + evas_cache2_image_data(evas_common_image_cache2_get(), + bpl / sizeof(int), bh, data, + ob->priv.destination_alpha, + EVAS_COLORSPACE_ARGB8888); + } + else +#endif + { + img = (RGBA_Image *) + evas_cache_image_data(evas_common_image_cache_get(), + bpl / sizeof(int), bh, data, + ob->priv.destination_alpha, + EVAS_COLORSPACE_ARGB8888); + + } + + ob->priv.onebuf = img; + if (!img) return NULL; + } + + if (!(rect = eina_rectangle_new(x, y, w, h))) + return NULL; + + if (!eina_array_push(&ob->priv.onebuf_regions, rect)) + { +#ifdef EVAS_CSERVE2 + if (evas_cserve2_use_get()) + evas_cache2_image_close(&img->cache_entry); + else +#endif + evas_cache_image_drop(&img->cache_entry); + + eina_rectangle_free(rect); + return NULL; + } + + if (cx) *cx = x; + if (cy) *cy = y; + if (cw) *cw = w; + if (ch) *ch = h; + + img->extended_info = rect; + + return img; + } + else + { + if (!(rect = eina_rectangle_new(x, y, w, h))) + return NULL; + +#ifdef EVAS_CSERVE2 + if (evas_cserve2_use_get()) + img = (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get()); + else +#endif + img = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get()); + + if (!img) + { + eina_rectangle_free(rect); + return NULL; + } + + img->cache_entry.flags.alpha |= ob->priv.destination_alpha ? 1 : 0; + +#ifdef EVAS_CSERVE2 + if (evas_cserve2_use_get()) + evas_cache2_image_surface_alloc(&img->cache_entry, w, h); + else +#endif + evas_cache_image_surface_alloc(&img->cache_entry, w, h); + + img->extended_info = rect; + + ob->priv.pending_writes = + eina_list_append(ob->priv.pending_writes, img); + + if (cx) *cx = 0; + if (cy) *cy = 0; + if (cw) *cw = w; + if (ch) *ch = h; + return img; + } + + return NULL; +} + +void +_evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h) +{ + Gfx_Func_Convert func = NULL; + Eina_Rectangle rect = {0, 0, 0, 0}, pr; + DATA32 *src; + DATA8 *dst; + int depth = 32, bpp = 0, bpl = 0, wid = 0; + int ww = 0, hh = 0; + int rx = 0, ry = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + /* check for valid output buffer */ + if (!ob) return; + + /* check for pending writes */ + if (!ob->priv.pending_writes) return; + + if ((ob->rotation == 0) || (ob->rotation == 180)) + { + func = + evas_common_convert_func_get(0, w, h, depth, + RED_MASK, GREEN_MASK, BLUE_MASK, + PAL_MODE_NONE, ob->rotation); + } + else if ((ob->rotation == 90) || (ob->rotation == 270)) + { + func = + evas_common_convert_func_get(0, h, w, depth, + RED_MASK, GREEN_MASK, BLUE_MASK, + PAL_MODE_NONE, ob->rotation); + } + + /* make sure we have a valid convert function */ + if (!func) return; + + /* based on rotation, set rectangle position */ + if (ob->rotation == 0) + { + rect.x = x; + rect.y = y; + } + else if (ob->rotation == 90) + { + rect.x = y; + rect.y = (ob->w - x - w); + } + else if (ob->rotation == 180) + { + rect.x = (ob->w - x - w); + rect.y = (ob->h - y - h); + } + else if (ob->rotation == 270) + { + rect.x = (ob->h - y - h); + rect.y = x; + } + + /* based on rotation, set rectangle size */ + if ((ob->rotation == 0) || (ob->rotation == 180)) + { + rect.w = w; + rect.h = h; + } + else if ((ob->rotation == 90) || (ob->rotation == 270)) + { + rect.w = h; + rect.h = w; + } + + /* check for valid update image data */ + if (!(src = update->image.data)) return; + + bpp = depth / 8; + if (bpp <= 0) return; + + /* check for valid desination data */ + if (!(dst = _evas_shm_surface_data_get(ob->surface, &ww, &hh))) return; + + bpl = (ww * sizeof(int)); + + if (ob->rotation == 0) + { + RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh); + dst += (bpl * rect.y) + (rect.x * bpp); + w -= rx; + } + else if (ob->rotation == 180) + { + pr = rect; + RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh); + rx = pr.w - rect.w; + ry = pr.h - rect.h; + src += (update->cache_entry.w * ry) + rx; + w -= rx; + } + else if (ob->rotation == 90) + { + pr = rect; + RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh); + rx = pr.w - rect.w; ry = pr.h - rect.h; + src += ry; + w -= ry; + } + else if (ob->rotation == 270) + { + pr = rect; + RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh); + rx = pr.w - rect.w; ry = pr.h - rect.h; + src += (update->cache_entry.w * rx); + w -= ry; + } + + if ((rect.w <= 0) || (rect.h <= 0)) return; + + wid = bpl / bpp; + + dst += (bpl * rect.y) + (rect.x * bpp); + + func(src, dst, (update->cache_entry.w - w), (wid - rect.w), + rect.w, rect.h, x + rx, y + ry, NULL); +} + +void +_evas_outbuf_update_region_free(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_UNUSED) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); +} diff --git a/src/modules/evas/engines/wayland_shm/evas_shm.c b/src/modules/evas/engines/wayland_shm/evas_shm.c new file mode 100644 index 0000000000..16c7d27665 --- /dev/null +++ b/src/modules/evas/engines/wayland_shm/evas_shm.c @@ -0,0 +1,477 @@ +#include "evas_common_private.h" +#include "evas_private.h" +#ifdef EVAS_CSERVE2 +# include "evas_cs2_private.h" +#endif +#include "evas_engine.h" +#include + +static void +_evas_shm_surface_cb_frame(void *data, struct wl_callback *callback, uint32_t timestamp EINA_UNUSED) +{ + Shm_Surface *surf; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(surf = data)) return; + if (callback != surf->frame_cb) return; + + wl_callback_destroy(callback); + surf->frame_cb = NULL; + surf->redraw = EINA_FALSE; +} + +static const struct wl_callback_listener _frame_listener = +{ + _evas_shm_surface_cb_frame +}; + +static struct wl_shm_pool * +_shm_pool_make(struct wl_shm *shm, int size, void **data) +{ + struct wl_shm_pool *pool; + static const char tmp[] = "/evas-wayland_shm-XXXXXX"; + const char *path; + char *name; + int fd = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + /* check for valid wl_shm */ + if (!shm) return NULL; + + /* create tmp file name */ + if ((path = getenv("XDG_RUNTIME_DIR"))) + { + if ((name = malloc(strlen(path) + sizeof(tmp)))) + strcpy(name, path); + } + else + { + if ((name = malloc(strlen("/tmp") + sizeof(tmp)))) + strcpy(name, "/tmp"); + } + + if (!name) return NULL; + + strcat(name, tmp); + + /* try to create tmp file */ + if ((fd = mkstemp(name)) < 0) + { + ERR("Could not create temporary file: %m"); + free(name); + return NULL; + } + + unlink(name); + free(name); + + /* try to truncate file to size */ + if (ftruncate(fd, size) < 0) + { + ERR("Could not truncate temporary file: %m"); + goto fd_err; + } + + /* try to mmap the file */ + *data = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0); + if (*data == MAP_FAILED) + { + ERR("Could not mmap temporary file: %m"); + goto fd_err; + } + + /* create wl_shm_pool using fd */ + pool = wl_shm_create_pool(shm, fd, size); + + close(fd); + + return pool; + +fd_err: + close(fd); + return NULL; +} + +static Shm_Pool * +_shm_pool_create(struct wl_shm *shm, size_t size) +{ + Shm_Pool *pool; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(pool = malloc(sizeof(Shm_Pool)))) return NULL; + + pool->pool = _shm_pool_make(shm, size, &pool->data); + if (!pool->pool) goto err; + + pool->size = size; + pool->used = 0; + + return pool; + +err: + free(pool); + return NULL; +} + +static void +_shm_pool_destroy(Shm_Pool *pool) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + munmap(pool->data, pool->size); + wl_shm_pool_destroy(pool->pool); + free(pool); +} + +static void * +_shm_pool_allocate(Shm_Pool *pool, size_t size, int *offset) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((pool->used + size) > pool->size) + return NULL; + + *offset = pool->used; + pool->used += size; + + return (char *)pool->data + *offset; +} + +static void +_shm_pool_reset(Shm_Pool *pool) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + pool->used = 0; +} + +static Shm_Data * +_shm_data_create_from_pool(Shm_Pool *pool, int w, int h, Eina_Bool alpha) +{ + Shm_Data *data; + int len, offset; + uint32_t wl_format = WL_SHM_FORMAT_XRGB8888; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + /* try to malloc space for data */ + if (!(data = malloc(sizeof(Shm_Data)))) + { + ERR("Could not allocate space for data"); + return NULL; + } + + len = (w * sizeof(int)) * h; + data->pool = NULL; + + if (!(data->map = _shm_pool_allocate(pool, len, &offset))) + { + ERR("Could not map leaf data"); + free(data); + return NULL; + } + + if (alpha) + wl_format = WL_SHM_FORMAT_ARGB8888; + + data->buffer = + wl_shm_pool_create_buffer(pool->pool, offset, w, h, + (w * sizeof(int)), wl_format); + if (!data->buffer) + { + ERR("Could not create buffer from pool: %m"); + free(data); + return NULL; + } + + return data; +} + +static void +_shm_data_create(Shm_Pool *alt_pool, Shm_Data **ret, Shm_Surface *surface, int w, int h) +{ + Shm_Pool *pool; + Shm_Data *data; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (alt_pool) + { + _shm_pool_reset(alt_pool); + if ((data = _shm_data_create_from_pool(alt_pool, w, h, surface->alpha))) + goto out; + } + + if (!(pool = _shm_pool_create(surface->shm, ((w * sizeof(int)) * h)))) + { + ERR("Could not create shm pool"); + goto err; + } + + if (!(data = _shm_data_create_from_pool(pool, w, h, surface->alpha))) + { + ERR("Could not create data from pool"); + _shm_pool_destroy(pool); + goto err; + } + + data->pool = pool; + +out: + if (ret) *ret = data; + return; +err: + if (ret) *ret = NULL; +} + +static void +_shm_data_destroy(Shm_Data *data) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (data->buffer) wl_buffer_destroy(data->buffer); + if (data->pool) _shm_pool_destroy(data->pool); + free(data); +} + +static void +_shm_leaf_release(Shm_Leaf *leaf) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (leaf->data) _shm_data_destroy(leaf->data); + if (leaf->resize_pool) _shm_pool_destroy(leaf->resize_pool); + memset(leaf, 0, sizeof(*leaf)); +} + +static void +_shm_buffer_release(void *data, struct wl_buffer *buffer) +{ + Shm_Surface *surf; + Shm_Leaf *leaf; + int i = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + surf = data; + + for (; i < surf->num_buff; i++) + { + leaf = &surf->leaf[i]; + if ((leaf->data) && (leaf->data->buffer == buffer)) + { + leaf->busy = 0; + break; + } + } +} + +static const struct wl_buffer_listener _shm_buffer_listener = +{ + _shm_buffer_release +}; + +Shm_Surface * +_evas_shm_surface_create(struct wl_shm *shm, struct wl_surface *surface, int w, int h, Eina_Bool alpha) +{ + Shm_Surface *surf; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(surf = calloc(1, sizeof(Shm_Surface)))) return NULL; + + surf->dx = 0; + surf->dy = 0; + surf->w = w; + surf->h = h; + surf->shm = shm; + surf->surface = surface; + surf->alpha = alpha; + surf->flags = 0; + + return surf; +} + +void +_evas_shm_surface_destroy(Shm_Surface *surface) +{ + int i = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + for (; i < surface->num_buff; i++) + _shm_leaf_release(&surface->leaf[i]); + + free(surface); +} + +void +_evas_shm_surface_prepare(Shm_Surface *surface, int dx, int dy, int w, int h, int num_buff, uint32_t flags) +{ + Shm_Leaf *leaf = NULL; + int i = 0, resize = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + resize = !!(flags & SURFACE_HINT_RESIZING); + + /* update surface properties */ + surface->w = w; + surface->h = h; + surface->dx = dx; + surface->dy = dy; + surface->num_buff = num_buff; + + for (; i < num_buff; i++) + { + if (surface->leaf[i].busy) continue; + if ((!leaf) || (leaf->valid)) + { + leaf = &surface->leaf[i]; + break; + } + } + + if (!leaf) + { + CRI("All buffers held by server"); + return; + } + + if ((!resize) && (leaf->resize_pool)) + { + _shm_data_destroy(leaf->data); + leaf->data = NULL; + + _shm_pool_destroy(leaf->resize_pool); + leaf->resize_pool = NULL; + } + + if (leaf->valid) + { + if ((leaf->w == w) && (leaf->h == h)) goto out; + } + + if (leaf->data) _shm_data_destroy(leaf->data); + leaf->data = NULL; + + if ((resize) && (!leaf->resize_pool)) + { + leaf->resize_pool = + _shm_pool_create(surface->shm, 6 * 1024 * 1024); + } + + _shm_data_create(leaf->resize_pool, &leaf->data, surface, w, h); + if (!leaf->data) + { + CRI("Failed to create leaf data"); + abort(); + } + + leaf->w = w; + leaf->h = h; + leaf->valid = EINA_TRUE; + + wl_buffer_add_listener(leaf->data->buffer, &_shm_buffer_listener, surface); + +out: + surface->current = leaf; +} + +void +_evas_shm_surface_swap(Shm_Surface *surface, Eina_Rectangle *rects, unsigned int count) +{ + Shm_Leaf *leaf; + Eina_Rectangle *rect; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(leaf = surface->current)) + { + ERR("No Current Leaf"); + return; + } + + if (!leaf->valid) + { + ERR("Leaf Not Valid"); + return; + } + + rect = eina_rectangle_new(0, 0, 0, 0); + if ((rects) && (count > 0)) + { + unsigned int i = 0; + + for (; i < count; i++) + eina_rectangle_union(rect, &rects[i]); + } + else + { + Eina_Rectangle r; + + r.x = 0; r.y = 0; + r.w = leaf->w; r.h = leaf->h; + + eina_rectangle_union(rect, &r); + } + + wl_surface_attach(surface->surface, leaf->data->buffer, 0, 0); + wl_surface_damage(surface->surface, rect->x, rect->y, rect->w, rect->h); + wl_surface_commit(surface->surface); + + eina_rectangle_free(rect); + + leaf->busy = 1; + surface->dx = 0; + surface->dy = 0; + surface->redraw = EINA_TRUE; +} + +void * +_evas_shm_surface_data_get(Shm_Surface *surface, int *bw, int *bh) +{ + Shm_Leaf *leaf; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (bw) *bw = 0; + if (bh) *bh = 0; + + if (!(leaf = surface->current)) + { + _evas_shm_surface_prepare(surface, 0, 0, surface->w, surface->h, + surface->num_buff, surface->flags); + + if (!(leaf = surface->current)) + { + CRI("NO Current Surface"); + return NULL; + } + } + + if (bw) *bw = leaf->w; + if (bh) *bh = leaf->h; + + return leaf->data->map; +} + +void +_evas_shm_surface_redraw(Shm_Surface *surface) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (surface->frame_cb) + { + if (!surface->redraw) return; + wl_callback_destroy(surface->frame_cb); + } + + if (!surface->surface) return; + + surface->frame_cb = wl_surface_frame(surface->surface); + wl_callback_add_listener(surface->frame_cb, &_frame_listener, surface); +} diff --git a/src/modules/evas/engines/wayland_shm/evas_swapbuf.h b/src/modules/evas/engines/wayland_shm/evas_swapbuf.h deleted file mode 100644 index 8716a37c29..0000000000 --- a/src/modules/evas/engines/wayland_shm/evas_swapbuf.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _EVAS_SWAPBUF_H -# define _EVAS_SWAPBUF_H - -# include "evas_engine.h" - -Outbuf *evas_swapbuf_setup(Evas_Engine_Info_Wayland_Shm *info, int w, int h, unsigned int rotation, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *wl_shm, struct wl_surface *wl_surface); -void evas_swapbuf_free(Outbuf *ob); -void evas_swapbuf_reconfigure(Outbuf *ob, int x, int y, int w, int h, int rotation, Outbuf_Depth depth, Eina_Bool alpha); -void *evas_swapbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); -void evas_swapbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h); -void evas_swapbuf_update_region_free(Outbuf *ob, RGBA_Image *update); -void evas_swapbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); -void evas_swapbuf_idle_flush(Outbuf *ob EINA_UNUSED); -Render_Engine_Swap_Mode evas_swapbuf_state_get(Outbuf *ob); -int evas_swapbuf_rotation_get(Outbuf *ob); - -#endif diff --git a/src/modules/evas/engines/wayland_shm/evas_swapper.c b/src/modules/evas/engines/wayland_shm/evas_swapper.c deleted file mode 100644 index 3b4d8f03ae..0000000000 --- a/src/modules/evas/engines/wayland_shm/evas_swapper.c +++ /dev/null @@ -1,541 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#ifdef EVAS_CSERVE2 -# include "evas_cs2_private.h" -#endif - -#include "evas_common_private.h" -#include "evas_macros.h" -#include "evas_engine.h" -#include "evas_swapper.h" - -/* local structures */ -typedef struct _Wl_Buffer Wl_Buffer; -struct _Wl_Buffer -{ - Wl_Swapper *ws; - int w, h; - struct wl_buffer *buffer; - void *data; - int offset; - size_t size; - Eina_Bool valid : 1; -}; - -struct _Wl_Swapper -{ - Wl_Buffer buff[3]; - Wl_Buffer *buffer_sent; - int in_use; - int dx, dy, w, h, depth; - int buff_cur, buff_num, buff_last; - struct wl_shm *shm; - struct wl_surface *surface; - struct wl_shm_pool *pool; - size_t pool_size; - size_t used_size; - void *data; - Eina_Bool alpha : 1; - Eina_Bool mapped : 1; - Eina_Bool delete_me : 1; -}; - -/* local function prototypes */ -static Eina_Bool _evas_swapper_shm_pool_new(Wl_Swapper *ws); -static void _evas_swapper_shm_pool_free(Wl_Swapper *ws); -static Eina_Bool _evas_swapper_buffer_new(Wl_Swapper *ws, Wl_Buffer *wb); -static void _evas_swapper_buffer_free(Wl_Buffer *wb); -static void _evas_swapper_buffer_put(Wl_Swapper *ws, Wl_Buffer *wb, Eina_Rectangle *rects, unsigned int count); -static void _evas_swapper_buffer_release(void *data, struct wl_buffer *buffer); - -static const struct wl_buffer_listener _evas_swapper_buffer_listener = -{ - _evas_swapper_buffer_release -}; - -/* local variables */ - -Wl_Swapper * -evas_swapper_setup(int dx, int dy, int w, int h, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *shm, struct wl_surface *surface) -{ - Wl_Swapper *ws; - int i = 0; - char *num_buffers; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* try to allocate a new swapper */ - if (!(ws = calloc(1, sizeof(Wl_Swapper)))) - return NULL; - - /* set some properties */ - ws->dx = dx; - ws->dy = dy; - ws->w = w; - ws->h = h; - ws->depth = depth; - ws->alpha = alpha; - ws->shm = shm; - ws->surface = surface; - - /* double buffer by default */ - ws->buff_num = 2; - - /* check for buffer override number */ - if ((num_buffers = getenv("EVAS_WAYLAND_SHM_BUFFERS"))) - { - int num = 0; - - num = atoi(num_buffers); - - if (num <= 0) num = 1; - if (num > 3) num = 3; - - ws->buff_num = num; - } - - /* create the shm pool */ - if (!_evas_swapper_shm_pool_new(ws)) - { - evas_swapper_free(ws); - return NULL; - } - - for (i = 0; i < ws->buff_num; i++) - { - /* try to create new internal Wl_Buffer */ - if (!_evas_swapper_buffer_new(ws, &(ws->buff[i]))) - { - /* failed to create wl_buffer. free the swapper */ - evas_swapper_free(ws); - return NULL; - } - } - - /* return allocated swapper */ - return ws; -} - -Wl_Swapper * -evas_swapper_reconfigure(Wl_Swapper *ws, int dx, int dy, int w, int h, Outbuf_Depth depth, Eina_Bool alpha) -{ - int i = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ws) - { - ERR("No swapper to reconfigure."); - return NULL; - } - - /* loop the swapper's buffers and free them */ - for (i = 0; i < ws->buff_num; i++) - _evas_swapper_buffer_free(&(ws->buff[i])); - - /* free the shm pool */ - _evas_swapper_shm_pool_free(ws); - - ws->dx += dx; - ws->dy += dy; - ws->w = w; - ws->h = h; - ws->depth = depth; - ws->alpha = alpha; - - /* create the shm pool */ - if (!_evas_swapper_shm_pool_new(ws)) - { - ERR("Could not allocate new shm pool."); - evas_swapper_free(ws); - return NULL; - } - - for (i = 0; i < ws->buff_num; i++) - { - /* try to create new internal Wl_Buffer */ - if (!_evas_swapper_buffer_new(ws, &(ws->buff[i]))) - { - ERR("failed to create wl_buffer. free the swapper."); - evas_swapper_free(ws); - return NULL; - } - } - - /* return reconfigured swapper */ - return ws; -} - -void -evas_swapper_swap(Wl_Swapper *ws, Eina_Rectangle *rects, unsigned int count) -{ - int n = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* check for valid swapper */ - if (!ws) return; - - ws->buff_last = n = ws->buff_cur; - _evas_swapper_buffer_put(ws, &(ws->buff[n]), rects, count); - ws->buff[n].valid = EINA_TRUE; - ws->in_use++; - ws->buff_cur = (ws->buff_cur + 1) % ws->buff_num; -} - -void -evas_swapper_free(Wl_Swapper *ws) -{ - int i = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* check for valid swapper */ - if (!ws) return; - - /* loop the swapper's buffers and free them */ - for (i = 0; i < ws->buff_num; i++) - _evas_swapper_buffer_free(&(ws->buff[i])); - - if (ws->in_use) - { - ws->delete_me = EINA_TRUE; - return; - } - - /* free the shm pool */ - _evas_swapper_shm_pool_free(ws); - - /* free the allocated structure */ - free(ws); -} - -void * -evas_swapper_buffer_map(Wl_Swapper *ws, int *w, int *h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* check for valid swapper */ - if (!ws) return NULL; - - /* set mapped property */ - ws->mapped = EINA_TRUE; - if (w) *w = ws->w; - if (h) *h = ws->h; - - /* return wl_buffer data */ - return ws->buff[ws->buff_cur].data; -} - -void -evas_swapper_buffer_unmap(Wl_Swapper *ws) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* check for valid swapper */ - if (!ws) return; - - ws->mapped = EINA_FALSE; -} - -int -evas_swapper_buffer_state_get(Wl_Swapper *ws) -{ - int delta; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - delta = (ws->buff_last - ws->buff_cur + - (ws->buff_last > ws->buff_last ? - 0 : ws->buff_num)) % ws->buff_num; - - /* This is the number of frame since last frame */ - switch (delta) - { - case 0: - return MODE_COPY; - case 1: - return MODE_DOUBLE; - case 2: - return MODE_TRIPLE; - default: - return MODE_FULL; - } -} - -void -evas_swapper_buffer_idle_flush(Wl_Swapper *ws) -{ - int i = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* check for valid swapper */ - if (!ws) return; - - /* loop the swapper's buffers and free them */ - for (i = 0; i < ws->buff_num; i++) - { - Wl_Buffer *wb = NULL; - - /* try to get out Wl_Buffer struct */ - if (!(wb = (&(ws->buff[i])))) continue; - - /* if this buffer is not valid, then unmap data */ - if (!wb->valid) _evas_swapper_buffer_free(wb); - } -} - -/* local functions */ -static Eina_Bool -_evas_swapper_shm_pool_new(Wl_Swapper *ws) -{ - static const char tmp[] = "/evas-wayland_shm-XXXXXX"; - const char *path; - char *name; - size_t size; - int fd = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* make sure swapper has a shm */ - if (!ws->shm) return EINA_FALSE; - - /* calculate new required size */ - size = (((ws->w * sizeof(int)) * ws->h) * ws->buff_num); - - /* check pool size to see if we need to realloc the pool */ - if (size <= ws->pool_size) return EINA_TRUE; - - /* create tmp file, trying to use XDG_RUNTIME if set */ - if ((path = getenv("XDG_RUNTIME_DIR"))) - { - if ((name = malloc(strlen(path) + sizeof(tmp)))) - strcpy(name, path); - } - else - { - if ((name = malloc(strlen("/tmp") + sizeof(tmp)))) - strcpy(name, "/tmp"); - } - - if (!name) return EINA_FALSE; - - strcat(name, tmp); - - /* try to create the tmp file */ - if ((fd = mkstemp(name)) < 0) - { - ERR("Could not create temporary file."); - free(name); - return EINA_FALSE; - } - - /* unlink the temp file */ - unlink(name); - free(name); - - /* try to truncate the tmp file to requested size */ - if (ftruncate(fd, size) < 0) - { - ERR("Could not truncate temporary file."); - close(fd); - return EINA_FALSE; - } - - /* mem map the file */ - ws->data = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0); - - /* if we failed to mem map the file, return an error */ - if (ws->data == MAP_FAILED) - { - ERR("Could not mmap temporary file."); - close(fd); - return EINA_FALSE; - } - - /* actually create the shm pool */ - ws->pool = wl_shm_create_pool(ws->shm, fd, size); - - ws->pool_size = size; - ws->used_size = 0; - - /* close the file */ - close(fd); - - return EINA_TRUE; -} - -static void -_evas_swapper_shm_pool_free(Wl_Swapper *ws) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* check for valid swapper */ - if (!ws) return; - - /* check for valid pool */ - if (!ws->pool) return; - - /* unmap any existing data */ - if (ws->data) munmap(ws->data, ws->pool_size); - - /* destroy the shm pool */ - wl_shm_pool_destroy(ws->pool); - - ws->pool_size = 0; - ws->used_size = 0; -} - -static Eina_Bool -_evas_swapper_buffer_new(Wl_Swapper *ws, Wl_Buffer *wb) -{ - unsigned int format = WL_SHM_FORMAT_XRGB8888; - size_t size; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* make sure swapper has a shm */ - if (!ws->shm) return EINA_FALSE; - - wb->w = ws->w; - wb->h = ws->h; - - /* calculate new required size */ - size = ((wb->w * sizeof(int)) * wb->h); - - /* check pool size to see if we need to realloc the pool */ - if (ws->used_size + size > ws->pool_size) - { - size_t newsize; - - /* calculate new required size */ - newsize = (ws->pool_size + size); - - /* resize the shm pool */ - wl_shm_pool_resize(ws->pool, newsize); - - ws->pool_size = newsize; - } - - /* check if this buffer needs argb and set format */ - if (ws->alpha) format = WL_SHM_FORMAT_ARGB8888; - - /* create actual wl_buffer */ - wb->buffer = - wl_shm_pool_create_buffer(ws->pool, ws->used_size, wb->w, wb->h, - (wb->w * sizeof(int)), format); - - /* add wayland buffer listener */ - wl_buffer_add_listener(wb->buffer, &_evas_swapper_buffer_listener, wb); - - wb->data = (char *)ws->data + ws->used_size; - wb->size = size; - - ws->used_size += size; - - wb->ws = ws; - - /* return allocated buffer */ - return EINA_TRUE; -} - -static void -_evas_swapper_buffer_free(Wl_Buffer *wb) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* check for valid buffer */ - if ((!wb) || (wb->valid)) return; - - /* kill the wl_buffer */ - if (wb->buffer) wl_buffer_destroy(wb->buffer); - wb->buffer = NULL; - - /* unmap the buffer data */ - /* if (wb->data) munmap(wb->data, wb->size); */ - wb->data = NULL; -} - -static void -_evas_swapper_buffer_put(Wl_Swapper *ws, Wl_Buffer *wb, Eina_Rectangle *rects, unsigned int count) -{ - Eina_Rectangle *rect; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* check for valid swapper */ - if (!ws) return; - - /* make sure swapper has a surface */ - if (!ws->surface) return; - - /* check for valid buffer */ - if (!wb) return; - - /* make sure buffer has mapped data */ - if ((!wb->data) || (!wb->buffer)) - { - /* call function to mmap buffer data */ - /* if (!_evas_swapper_buffer_new(ws, wb)) */ - return; - } - - rect = eina_rectangle_new(0, 0, 0, 0); - if ((rects) && (count > 0)) - { - unsigned int i = 0; - - for (i = 0; i < count; i++) - eina_rectangle_union(rect, &rects[i]); - } - else - { - Eina_Rectangle r; - - r.x = 0; r.y = 0; - r.w = wb->w; r.h = wb->h; - - eina_rectangle_union(rect, &r); - } - - /* surface attach */ - if (ws->buffer_sent != wb) - { - wl_surface_attach(ws->surface, wb->buffer, ws->dx, ws->dy); - ws->dx = 0; - ws->dy = 0; - ws->buffer_sent = wb; - } - - wl_surface_damage(ws->surface, rect->x, rect->y, rect->w, rect->h); - - /* surface commit */ - wl_surface_commit(ws->surface); - - eina_rectangle_free(rect); -} - -static void -_evas_swapper_buffer_release(void *data, struct wl_buffer *buffer EINA_UNUSED) -{ - Wl_Buffer *wb = NULL; - Wl_Swapper *ws = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* try to get out Wl_Buffer struct */ - if (!(wb = data)) return; - - /* invalidate buffer */ - wb->valid = EINA_FALSE; - - ws = wb->ws; - ws->in_use--; - if (ws->delete_me && (ws->in_use <= 0)) - evas_swapper_free(ws); -} diff --git a/src/modules/evas/engines/wayland_shm/evas_swapper.h b/src/modules/evas/engines/wayland_shm/evas_swapper.h deleted file mode 100644 index f9fc90a988..0000000000 --- a/src/modules/evas/engines/wayland_shm/evas_swapper.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _EVAS_SWAPPER_H -# define _EVAS_SWAPPER_H - -#include "evas_engine.h" - -typedef struct _Wl_Swapper Wl_Swapper; - -Wl_Swapper *evas_swapper_setup(int dx, int dy, int w, int h, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *shm, struct wl_surface *surface); -Wl_Swapper *evas_swapper_reconfigure(Wl_Swapper *ws, int dx, int dy, int w, int h, Outbuf_Depth depth, Eina_Bool alpha); -void evas_swapper_swap(Wl_Swapper *ws, Eina_Rectangle *rects, unsigned int count); -void evas_swapper_free(Wl_Swapper *ws); -void *evas_swapper_buffer_map(Wl_Swapper *ws, int *w, int *h); -void evas_swapper_buffer_unmap(Wl_Swapper *ws); -int evas_swapper_buffer_state_get(Wl_Swapper *ws); -void evas_swapper_buffer_idle_flush(Wl_Swapper *ws); - -#endif