From 82e101d902abf8d152fad21ec3d17436c05ea1c5 Mon Sep 17 00:00:00 2001 From: devilhorns Date: Fri, 8 Jul 2011 00:21:17 +0000 Subject: [PATCH] Evas: Commit new XCB engine code for Evas. NB: XCB Engine is currently disabled by default as it's not considered 'complete' yet and is of little use to users/devs at the moment without the needed ecore_x & E changes. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@61139 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- .../software_x11/Evas_Engine_Software_X11.h | 70 +- src/modules/engines/software_x11/Makefile.am | 31 +- src/modules/engines/software_x11/evas_engine.c | 485 +++--- src/modules/engines/software_x11/evas_engine.h | 208 +-- src/modules/engines/software_x11/evas_xcb_buffer.c | 472 +++--- src/modules/engines/software_x11/evas_xcb_buffer.h | 79 +- src/modules/engines/software_x11/evas_xcb_color.c | 6 +- src/modules/engines/software_x11/evas_xcb_color.h | 15 +- src/modules/engines/software_x11/evas_xcb_main.c | 5 +- src/modules/engines/software_x11/evas_xcb_outbuf.c | 1707 ++++++++++---------- src/modules/engines/software_x11/evas_xcb_outbuf.h | 113 +- 11 files changed, 1501 insertions(+), 1690 deletions(-) diff --git a/src/modules/engines/software_x11/Evas_Engine_Software_X11.h b/src/modules/engines/software_x11/Evas_Engine_Software_X11.h index de6da96..e42c10a 100644 --- a/src/modules/engines/software_x11/Evas_Engine_Software_X11.h +++ b/src/modules/engines/software_x11/Evas_Engine_Software_X11.h @@ -1,24 +1,14 @@ #ifndef _EVAS_ENGINE_SOFTWARE_X11_H -#define _EVAS_ENGINE_SOFTWARE_X11_H +# define _EVAS_ENGINE_SOFTWARE_X11_H typedef enum { - EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB, - EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB + EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB, + EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB } Evas_Engine_Info_Software_X11_Backend; typedef struct _Evas_Engine_Info_Software_X11 Evas_Engine_Info_Software_X11; -/* - * Xlib | XCB - * connection | Display * | xcb_connection_t * - * screen | NULL | xcb_screen_t * - * drawable | Drawable | xcb_drawable_t - * mask | Pixmap | xcb_pixmap_t - * visual | Visual * | xcb_visualtype_t * - * colormap | Colormap | xcb_colormap_t - */ - struct _Evas_Engine_Info_Software_X11 { /* PRIVATE - don't mess with this baby or evas will poke its tongue out */ @@ -26,37 +16,37 @@ struct _Evas_Engine_Info_Software_X11 Evas_Engine_Info magic; /* engine specific data & parameters it needs to set up */ - struct { - Evas_Engine_Info_Software_X11_Backend backend; - void *connection; - void *screen; - unsigned int drawable; - unsigned int mask; - void *visual; - unsigned int colormap; - int depth; - int rotation; - - unsigned int alloc_grayscale : 1; - unsigned int debug : 1; - unsigned int shape_dither : 1; - unsigned int destination_alpha : 1; - unsigned int track_mask_changes : 1; - - int alloc_colors_max; - } info; + struct + { + Evas_Engine_Info_Software_X11_Backend backend; + + void *connection, *screen; + unsigned int drawable, mask; + void *visual; + unsigned int colormap; + int depth, rotation; + + Eina_Bool alloc_grayscale : 1; + Eina_Bool debug : 1; + Eina_Bool shape_dither : 1; + Eina_Bool destination_alpha : 1; + Eina_Bool track_mask_changes : 1; + + int alloc_colors_max; + } info; + /* engine specific function calls to query stuff about the destination */ - struct { - void *(*best_visual_get) (int backend, void *connection, int screen); - unsigned int (*best_colormap_get) (int backend, void *connection, int screen); - int (*best_depth_get) (int backend, void *connection, int screen); - } func; + struct + { + void *(*best_visual_get) (int backend, void *connection, int screen); + unsigned int (*best_colormap_get) (int backend, void *connection, int screen); + int (*best_depth_get) (int backend, void *connection, int screen); + } func; + + unsigned char mask_changed : 1; - int mask_changed; /* non-blocking or blocking mode */ Evas_Engine_Render_Mode render_mode; }; #endif - - diff --git a/src/modules/engines/software_x11/Makefile.am b/src/modules/engines/software_x11/Makefile.am index 675c6cd..9163fbe 100644 --- a/src/modules/engines/software_x11/Makefile.am +++ b/src/modules/engines/software_x11/Makefile.am @@ -1,6 +1,12 @@ MAINTAINERCLEANFILES = Makefile.in +if BUILD_ENGINE_SOFTWARE_X11 + +SOFTWARE_X11_SOURCES = evas_engine.c + +if BUILD_ENGINE_SOFTWARE_XLIB + AM_CPPFLAGS = \ -I. \ -I$(top_srcdir)/src/lib \ @@ -9,14 +15,7 @@ AM_CPPFLAGS = \ @FREETYPE_CFLAGS@ \ @PIXMAN_CFLAGS@ \ @EINA_CFLAGS@ \ -@evas_engine_software_xlib_cflags@ \ -@evas_engine_software_xcb_cflags@ - -if BUILD_ENGINE_SOFTWARE_X11 - -SOFTWARE_X11_SOURCES = evas_engine.c - -if BUILD_ENGINE_SOFTWARE_XLIB +@evas_engine_software_xlib_cflags@ SOFTWARE_X11_SOURCES += \ evas_xlib_outbuf.c \ @@ -24,18 +23,30 @@ evas_xlib_buffer.c \ evas_xlib_color.c \ evas_xlib_main.c -SOFTWARE_X11_LIBADD = @evas_engine_software_xlib_libs@ @evas_engine_software_xcb_libs@ +SOFTWARE_X11_LIBADD = @FREETYPE_LIBS@ @EINA_LIBS@ @evas_engine_software_xlib_libs@ endif if BUILD_ENGINE_SOFTWARE_XCB +AM_CPPFLAGS = \ +-I. \ +-I$(top_srcdir)/src/lib \ +-I$(top_srcdir)/src/lib/include \ +-I$(top_srcdir)/src/modules/engines \ +@FREETYPE_CFLAGS@ \ +@PIXMAN_CFLAGS@ \ +@EINA_CFLAGS@ \ +@evas_engine_software_xcb_cflags@ + SOFTWARE_X11_SOURCES += \ evas_xcb_outbuf.c \ evas_xcb_buffer.c \ evas_xcb_color.c \ evas_xcb_main.c +SOFTWARE_X11_LIBADD = @FREETYPE_LIBS@ @PIXMAN_LIBS@ @EINA_LIBS@ @evas_engine_software_xcb_libs@ + endif includes_HEADERS = Evas_Engine_Software_X11.h @@ -47,7 +58,7 @@ pkgdir = $(libdir)/evas/modules/engines/software_x11/$(MODULE_ARCH) pkg_LTLIBRARIES = module.la module_la_SOURCES = $(SOFTWARE_X11_SOURCES) -module_la_LIBADD = $(top_builddir)/src/lib/libevas.la @EINA_LIBS@ $(SOFTWARE_X11_LIBADD) +module_la_LIBADD = $(top_builddir)/src/lib/libevas.la $(SOFTWARE_X11_LIBADD) module_la_LDFLAGS = -no-undefined -module -avoid-version module_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/src/modules/engines/software_x11/evas_engine.c b/src/modules/engines/software_x11/evas_engine.c index aff3469..93f3fbf 100644 --- a/src/modules/engines/software_x11/evas_engine.c +++ b/src/modules/engines/software_x11/evas_engine.c @@ -2,7 +2,6 @@ #include "evas_private.h" #include "Evas_Engine_Software_X11.h" - #include "evas_engine.h" #ifdef BUILD_ENGINE_SOFTWARE_XLIB @@ -16,7 +15,7 @@ #endif int _evas_engine_soft_x11_log_dom = -1; -int test ; + /* function tables - filled in later (func and parent func) */ static Evas_Func func, pfunc; @@ -32,16 +31,21 @@ static struct xrdb_user xrdb_user = {0, 0, NULL}; static Eina_Bool xrdb_user_query(const char *name, const char *cls, char **type, XrmValue *val) { - time_t last = xrdb_user.last_stat, now = time(NULL); + time_t last, now; + + last = xrdb_user.last_stat; + now = time(NULL); xrdb_user.last_stat = now; if (last != now) /* don't stat() more than once every second */ { struct stat st; - const char *home = getenv("HOME"); + const char *home; char tmp[PATH_MAX]; - if (!home) goto failed; + if (!(home = getenv("HOME"))) + goto failed; + snprintf(tmp, sizeof(tmp), "%s/.Xdefaults", home); if (stat(tmp, &st) != 0) goto failed; if (xrdb_user.last_mtime != st.st_mtime) @@ -72,40 +76,42 @@ typedef struct _Render_Engine Render_Engine; struct _Render_Engine { - Tilebuf *tb; - Outbuf *ob; + Tilebuf *tb; + Outbuf *ob; Tilebuf_Rect *rects; - Eina_Inlist *cur_rect; - int end : 1; - + Eina_Inlist *cur_rect; + unsigned char end : 1; + #ifdef BUILD_ENGINE_SOFTWARE_XLIB - XrmDatabase xrdb; // xres - dpi - struct { // xres - dpi - int dpi; // xres - dpi - } xr; // xres - dpi + XrmDatabase xrdb; #endif + struct + { + int dpi; + } xr; + #ifdef EVAS_FRAME_QUEUING Evas_Engine_Render_Mode render_mode; #endif - void (*outbuf_free)(Outbuf *ob); - void (*outbuf_reconfigure)(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth); - int (*outbuf_get_rot)(Outbuf *ob); + void (*outbuf_free)(Outbuf *ob); + void (*outbuf_reconfigure)(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth); + int (*outbuf_get_rot)(Outbuf *ob); RGBA_Image *(*outbuf_new_region_for_update)(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); - void (*outbuf_push_updated_region)(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h); - void (*outbuf_free_region_for_update)(Outbuf *ob, RGBA_Image *update); - void (*outbuf_flush)(Outbuf *ob); - void (*outbuf_idle_flush)(Outbuf *ob); - Eina_Bool (*outbuf_alpha_get)(Outbuf *ob); + void (*outbuf_push_updated_region)(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h); + void (*outbuf_free_region_for_update)(Outbuf *ob, RGBA_Image *update); + void (*outbuf_flush)(Outbuf *ob); + void (*outbuf_idle_flush)(Outbuf *ob); + Eina_Bool (*outbuf_alpha_get)(Outbuf *ob); #ifdef EVAS_FRAME_QUEUING - void (*outbuf_set_priv)(Outbuf *ob, void *cur, void *prev); + void (*outbuf_set_priv)(Outbuf *ob, void *cur, void *prev); #endif }; /* prototypes we will use here */ -static void *_best_visual_get (int backend, void *connection, int screen); -static unsigned int _best_colormap_get (int backend, void *connection, int screen); -static int _best_depth_get (int backend, void *connection, int screen); +static void *_best_visual_get(int backend, void *connection, int screen); +static unsigned int _best_colormap_get(int backend, void *connection, int screen); +static int _best_depth_get(int backend, void *connection, int screen); static void *eng_info(Evas *e); static void eng_info_free(Evas *e, void *info); @@ -121,104 +127,81 @@ static void eng_output_redraws_next_update_push(void *data, void *surface, int x static void eng_output_flush(void *data); static void eng_output_idle_flush(void *data); - /* internal engine routines */ #ifdef BUILD_ENGINE_SOFTWARE_XLIB static void * -_output_xlib_setup(int w, - int h, - int rot, - Display *disp, - Drawable draw, - Visual *vis, - Colormap cmap, - int depth, - int debug, - int grayscale, - int max_colors, - Pixmap mask, - int shape_dither, - int destination_alpha) +_output_xlib_setup(int w, int h, int rot, Display *disp, Drawable draw, + Visual *vis, Colormap cmap, int depth, int debug, + int grayscale, int max_colors, Pixmap mask, + int shape_dither, int destination_alpha) { Render_Engine *re; + int status; + char *type = NULL; + XrmValue val; - re = calloc(1, sizeof(Render_Engine)); - if (!re) - return NULL; + if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL; evas_software_xlib_x_init(); evas_software_xlib_x_color_init(); evas_software_xlib_outbuf_init(); + re->xr.dpi = 75000; // dpy * 1000 + + status = xrdb_user_query("Xft.dpi", "Xft.Dpi", &type, &val); + if ((!status) || (!type)) { - int status; - char *type = NULL; - XrmValue val; - - re->xr.dpi = 75000; // dpy * 1000 - - status = xrdb_user_query("Xft.dpi", "Xft.Dpi", &type, &val); - if ((!status) || (!type)) - { - if (!re->xrdb) re->xrdb = XrmGetDatabase(disp); - if (re->xrdb) - status = XrmGetResource(re->xrdb, - "Xft.dpi", "Xft.Dpi", &type, &val); - } + if (!re->xrdb) re->xrdb = XrmGetDatabase(disp); + if (re->xrdb) + status = XrmGetResource(re->xrdb, + "Xft.dpi", "Xft.Dpi", &type, &val); + } - if ((status) && (type)) + if ((status) && (type)) + { + if (!strcmp(type, "String")) { - if (!strcmp(type, "String")) - { - const char *str, *dp; + const char *str, *dp; - str = val.addr; - dp = strchr(str, '.'); - if (!dp) dp = strchr(str, ','); - - if (dp) - { - int subdpi, len, i; - char *buf; - - buf = alloca(dp - str + 1); - strncpy(buf, str, dp - str); - buf[dp - str] = 0; - len = strlen(dp + 1); - subdpi = atoi(dp + 1); + str = val.addr; + dp = strchr(str, '.'); + if (!dp) dp = strchr(str, ','); + + if (dp) + { + int subdpi, len, i; + char *buf; - if (len < 3) - { - for (i = len; i < 3; i++) subdpi *= 10; - } - else if (len > 3) - { - for (i = len; i > 3; i--) subdpi /= 10; - } - re->xr.dpi = atoi(buf) * 1000; + buf = alloca(dp - str + 1); + strncpy(buf, str, dp - str); + buf[dp - str] = 0; + len = strlen(dp + 1); + subdpi = atoi(dp + 1); + + if (len < 3) + { + for (i = len; i < 3; i++) + subdpi *= 10; } - else - re->xr.dpi = atoi(str) * 1000; - evas_common_font_dpi_set(re->xr.dpi / 1000); + else if (len > 3) + { + for (i = len; i > 3; i--) + subdpi /= 10; + } + re->xr.dpi = atoi(buf) * 1000; } + else + re->xr.dpi = atoi(str) * 1000; + evas_common_font_dpi_set(re->xr.dpi / 1000); } } - re->ob = evas_software_xlib_outbuf_setup_x(w, - h, - rot, - OUTBUF_DEPTH_INHERIT, - disp, - draw, - vis, - cmap, - depth, - grayscale, - max_colors, - mask, - shape_dither, - destination_alpha); + re->ob = + evas_software_xlib_outbuf_setup_x(w, h, rot, OUTBUF_DEPTH_INHERIT, disp, + draw, vis, cmap, depth, grayscale, + max_colors, mask, shape_dither, + destination_alpha); if (!re->ob) { free(re); @@ -226,12 +209,13 @@ _output_xlib_setup(int w, } /* for updates return 1 big buffer, but only use portions of it, also cache - it and keepit around until an idle_flush */ + * it and keepit around until an idle_flush */ + /* disable for now - i am hunting down why some expedite tests are slower, * as well as shaped stuff is broken and probable non-32bpp is broken as * convert funcs dont do the right thing * - re->ob->onebuf = 1; + re->ob->onebuf = 1; */ evas_software_xlib_outbuf_debug_set(re->ob, debug); @@ -242,6 +226,7 @@ _output_xlib_setup(int w, free(re); return NULL; } + /* in preliminary tests 16x16 gave highest framerates */ evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); return re; @@ -250,65 +235,47 @@ _output_xlib_setup(int w, #ifdef BUILD_ENGINE_SOFTWARE_XCB static void * -_output_xcb_setup(int w, - int h, - int rot, - xcb_connection_t *conn, - xcb_screen_t *screen, - xcb_drawable_t draw, - xcb_visualtype_t *vis, - xcb_colormap_t cmap, - int depth, - int debug, - int grayscale, - int max_colors, - xcb_drawable_t mask, - int shape_dither, - int destination_alpha) +_output_xcb_setup(int w, int h, int rot, xcb_connection_t *conn, + xcb_screen_t *screen, xcb_drawable_t draw, + xcb_visualtype_t *vis, xcb_colormap_t cmap, int depth, + int debug, int grayscale, int max_colors, xcb_drawable_t mask, + int shape_dither, int destination_alpha) { Render_Engine *re; - re = calloc(1, sizeof(Render_Engine)); - if (!re) - return NULL; + if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL; - evas_software_xcb_x_init(); - evas_software_xcb_x_color_init(); + evas_software_xcb_init(); + evas_software_xcb_color_init(); evas_software_xcb_outbuf_init(); // FIXME: re->xrdb - - re->ob = evas_software_xcb_outbuf_setup_x(w, - h, - rot, - OUTBUF_DEPTH_INHERIT, - conn, - screen, - draw, - vis, - cmap, - depth, - grayscale, - max_colors, - mask, - shape_dither, - destination_alpha); + re->xr.dpi = 75000; // dpy * 1000 + evas_common_font_dpi_set(re->xr.dpi / 1000); + + re->ob = + evas_software_xcb_outbuf_setup(w, h, rot, OUTBUF_DEPTH_INHERIT, conn, + screen, draw, vis, cmap, depth, + grayscale, max_colors, mask, + shape_dither, destination_alpha); if (!re->ob) { free(re); return NULL; } - /* for updates return 1 big buffer, but only use portions of it, also cache - it and keepit around until an idle_flush */ + /* for updates return 1 big buffer, but only use portions of it, also cache + * it and keepit around until an idle_flush */ + /* disable for now - i am hunting down why some expedite tests are slower, * as well as shaped stuff is broken and probable non-32bpp is broken as * convert funcs dont do the right thing * - re->ob->onebuf = 1; + re->ob->onebuf = 1; */ evas_software_xcb_outbuf_debug_set(re->ob, debug); + re->tb = evas_common_tilebuf_new(w, h); if (!re->tb) { @@ -316,6 +283,7 @@ _output_xcb_setup(int w, free(re); return NULL; } + /* in preliminary tests 16x16 gave highest framerates */ evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); return re; @@ -329,20 +297,19 @@ _best_visual_get(int backend, void *connection, int screen) #ifdef BUILD_ENGINE_SOFTWARE_XLIB if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB) - { - return DefaultVisual((Display *)connection, screen); - } + return DefaultVisual((Display *)connection, screen); #endif #ifdef BUILD_ENGINE_SOFTWARE_XCB if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB) { xcb_screen_iterator_t iter_screen; - xcb_depth_iterator_t iter_depth; - xcb_screen_t *s; + xcb_depth_iterator_t iter_depth; + xcb_screen_t *s = NULL; - iter_screen = xcb_setup_roots_iterator(xcb_get_setup((xcb_connection_t *)connection)); - for (; iter_screen.rem; --screen, xcb_screen_next (&iter_screen)) + iter_screen = + xcb_setup_roots_iterator(xcb_get_setup((xcb_connection_t *)connection)); + for (; iter_screen.rem; --screen, xcb_screen_next(&iter_screen)) if (screen == 0) { s = iter_screen.data; @@ -350,12 +317,12 @@ _best_visual_get(int backend, void *connection, int screen) } iter_depth = xcb_screen_allowed_depths_iterator(s); - for (; iter_depth.rem; xcb_depth_next (&iter_depth)) + for (; iter_depth.rem; xcb_depth_next(&iter_depth)) { xcb_visualtype_iterator_t iter_vis; iter_vis = xcb_depth_visuals_iterator(iter_depth.data); - for (; iter_vis.rem; xcb_visualtype_next (&iter_vis)) + for (; iter_vis.rem; xcb_visualtype_next(&iter_vis)) { if (s->root_visual == iter_vis.data->visual_id) return iter_vis.data; @@ -374,19 +341,18 @@ _best_colormap_get(int backend, void *connection, int screen) #ifdef BUILD_ENGINE_SOFTWARE_XLIB if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB) - { - return DefaultColormap((Display *)connection, screen); - } + return DefaultColormap((Display *)connection, screen); #endif #ifdef BUILD_ENGINE_SOFTWARE_XCB if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB) { xcb_screen_iterator_t iter_screen; - xcb_screen_t *s; + xcb_screen_t *s = NULL; - iter_screen = xcb_setup_roots_iterator(xcb_get_setup((xcb_connection_t *)connection)); - for (; iter_screen.rem; --screen, xcb_screen_next (&iter_screen)) + iter_screen = + xcb_setup_roots_iterator(xcb_get_setup((xcb_connection_t *)connection)); + for (; iter_screen.rem; --screen, xcb_screen_next(&iter_screen)) if (screen == 0) { s = iter_screen.data; @@ -407,19 +373,18 @@ _best_depth_get(int backend, void *connection, int screen) #ifdef BUILD_ENGINE_SOFTWARE_XLIB if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB) - { - return DefaultDepth((Display *)connection, screen); - } + return DefaultDepth((Display *)connection, screen); #endif #ifdef BUILD_ENGINE_SOFTWARE_XCB if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB) { xcb_screen_iterator_t iter_screen; - xcb_screen_t *s; + xcb_screen_t *s = NULL; - iter_screen = xcb_setup_roots_iterator(xcb_get_setup((xcb_connection_t *)connection)); - for (; iter_screen.rem; --screen, xcb_screen_next (&iter_screen)) + iter_screen = + xcb_setup_roots_iterator(xcb_get_setup((xcb_connection_t *)connection)); + for (; iter_screen.rem; --screen, xcb_screen_next(&iter_screen)) if (screen == 0) { s = iter_screen.data; @@ -438,8 +403,10 @@ static void * eng_info(Evas *e __UNUSED__) { Evas_Engine_Info_Software_X11 *info; - info = calloc(1, sizeof(Evas_Engine_Info_Software_X11)); - if (!info) return NULL; + + if (!(info = calloc(1, sizeof(Evas_Engine_Info_Software_X11)))) + return NULL; + info->magic.magic = rand(); info->info.debug = 0; info->info.alloc_grayscale = 0; @@ -455,6 +422,7 @@ static void eng_info_free(Evas *e __UNUSED__, void *info) { Evas_Engine_Info_Software_X11 *in; + in = (Evas_Engine_Info_Software_X11 *)info; free(in); } @@ -484,65 +452,64 @@ eng_setup(Evas *e, void *in) #ifdef BUILD_ENGINE_SOFTWARE_XLIB if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB) { - re = _output_xlib_setup(e->output.w, - e->output.h, - info->info.rotation, - info->info.connection, - info->info.drawable, - info->info.visual, + re = _output_xlib_setup(e->output.w, e->output.h, + info->info.rotation, info->info.connection, + info->info.drawable, info->info.visual, info->info.colormap, - info->info.depth, - info->info.debug, + info->info.depth, info->info.debug, info->info.alloc_grayscale, info->info.alloc_colors_max, - info->info.mask, - info->info.shape_dither, + info->info.mask, info->info.shape_dither, info->info.destination_alpha); re->outbuf_free = evas_software_xlib_outbuf_free; re->outbuf_reconfigure = evas_software_xlib_outbuf_reconfigure; re->outbuf_get_rot = evas_software_xlib_outbuf_get_rot; - re->outbuf_new_region_for_update = evas_software_xlib_outbuf_new_region_for_update; - re->outbuf_push_updated_region = evas_software_xlib_outbuf_push_updated_region; - re->outbuf_free_region_for_update = evas_software_xlib_outbuf_free_region_for_update; + re->outbuf_new_region_for_update = + evas_software_xlib_outbuf_new_region_for_update; + re->outbuf_push_updated_region = + evas_software_xlib_outbuf_push_updated_region; + re->outbuf_free_region_for_update = + evas_software_xlib_outbuf_free_region_for_update; re->outbuf_flush = evas_software_xlib_outbuf_flush; re->outbuf_idle_flush = evas_software_xlib_outbuf_idle_flush; re->outbuf_alpha_get = evas_software_xlib_outbuf_alpha_get; -#ifdef EVAS_FRAME_QUEUING +# ifdef EVAS_FRAME_QUEUING re->outbuf_set_priv = evas_software_xlib_outbuf_set_priv; re->render_mode = info->render_mode; -#endif +# endif } #endif #ifdef BUILD_ENGINE_SOFTWARE_XCB if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB) { - re = _output_xcb_setup(e->output.w, - e->output.h, - info->info.rotation, - info->info.connection, - info->info.screen, - info->info.drawable, - info->info.visual, - info->info.colormap, - info->info.depth, - info->info.debug, + re = _output_xcb_setup(e->output.w, e->output.h, + info->info.rotation, info->info.connection, + info->info.screen, info->info.drawable, + info->info.visual, info->info.colormap, + info->info.depth, info->info.debug, info->info.alloc_grayscale, info->info.alloc_colors_max, - info->info.mask, - info->info.shape_dither, + info->info.mask, info->info.shape_dither, info->info.destination_alpha); re->outbuf_free = evas_software_xcb_outbuf_free; re->outbuf_reconfigure = evas_software_xcb_outbuf_reconfigure; - re->outbuf_get_rot = evas_software_xcb_outbuf_get_rot; - re->outbuf_new_region_for_update = evas_software_xcb_outbuf_new_region_for_update; - re->outbuf_push_updated_region = evas_software_xcb_outbuf_push_updated_region; - re->outbuf_free_region_for_update = evas_software_xcb_outbuf_free_region_for_update; + re->outbuf_get_rot = evas_software_xcb_outbuf_rotation_get; + re->outbuf_new_region_for_update = + evas_software_xcb_outbuf_new_region_for_update; + re->outbuf_push_updated_region = + evas_software_xcb_outbuf_push_updated_region; + re->outbuf_free_region_for_update = + evas_software_xcb_outbuf_free_region_for_update; re->outbuf_flush = evas_software_xcb_outbuf_flush; re->outbuf_idle_flush = evas_software_xcb_outbuf_idle_flush; re->outbuf_alpha_get = evas_software_xcb_outbuf_alpha_get; +# ifdef EVAS_FRAME_QUEUING + re->outbuf_set_priv = evas_software_xcb_outbuf_priv_set; + re->render_mode = info->render_mode; +# endif } #endif @@ -550,10 +517,10 @@ eng_setup(Evas *e, void *in) } else { - int ponebuf = 0; + int ponebuf = 0; #ifdef EVAS_FRAME_QUEUING - evas_common_frameq_flush (); + evas_common_frameq_flush(); #endif re = e->engine.data.output; ponebuf = re->ob->onebuf; @@ -562,24 +529,25 @@ eng_setup(Evas *e, void *in) if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB) { evas_software_xlib_outbuf_free(re->ob); - re->ob = evas_software_xlib_outbuf_setup_x(e->output.w, - e->output.h, - info->info.rotation, - OUTBUF_DEPTH_INHERIT, - info->info.connection, - info->info.drawable, - info->info.visual, - info->info.colormap, - info->info.depth, - info->info.alloc_grayscale, - info->info.alloc_colors_max, - info->info.mask, - info->info.shape_dither, - info->info.destination_alpha); + re->ob = + evas_software_xlib_outbuf_setup_x(e->output.w, e->output.h, + info->info.rotation, + OUTBUF_DEPTH_INHERIT, + info->info.connection, + info->info.drawable, + info->info.visual, + info->info.colormap, + info->info.depth, + info->info.alloc_grayscale, + info->info.alloc_colors_max, + info->info.mask, + info->info.shape_dither, + info->info.destination_alpha); + evas_software_xlib_outbuf_debug_set(re->ob, info->info.debug); -#ifdef EVAS_FRAME_QUEUING +# ifdef EVAS_FRAME_QUEUING re->render_mode = info->render_mode; -#endif +# endif } #endif @@ -587,30 +555,36 @@ eng_setup(Evas *e, void *in) if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB) { evas_software_xcb_outbuf_free(re->ob); - re->ob = evas_software_xcb_outbuf_setup_x(e->output.w, - e->output.h, - info->info.rotation, - OUTBUF_DEPTH_INHERIT, - info->info.connection, - info->info.screen, - info->info.drawable, - info->info.visual, - info->info.colormap, - info->info.depth, - info->info.alloc_grayscale, - info->info.alloc_colors_max, - info->info.mask, - info->info.shape_dither, - info->info.destination_alpha); + re->ob = + evas_software_xcb_outbuf_setup(e->output.w, e->output.h, + info->info.rotation, + OUTBUF_DEPTH_INHERIT, + info->info.connection, + info->info.screen, + info->info.drawable, + info->info.visual, + info->info.colormap, + info->info.depth, + info->info.alloc_grayscale, + info->info.alloc_colors_max, + info->info.mask, + info->info.shape_dither, + info->info.destination_alpha); + evas_software_xcb_outbuf_debug_set(re->ob, info->info.debug); +#ifdef EVAS_FRAME_QUEUING + re->render_mode = info->render_mode; +#endif } #endif re->ob->onebuf = ponebuf; } if (!e->engine.data.output) return 0; - if (!e->engine.data.context) - e->engine.data.context = - e->engine.func->context_new(e->engine.data.output); + if (!e->engine.data.context) + { + e->engine.data.context = + e->engine.func->context_new(e->engine.data.output); + } re = e->engine.data.output; @@ -646,8 +620,7 @@ eng_output_resize(void *data, int w, int h) Render_Engine *re; re = (Render_Engine *)data; - re->outbuf_reconfigure(re->ob, w, h, - re->outbuf_get_rot(re->ob), + re->outbuf_reconfigure(re->ob, w, h, re->outbuf_get_rot(re->ob), OUTBUF_DEPTH_INHERIT); evas_common_tilebuf_free(re->tb); re->tb = evas_common_tilebuf_new(w, h); @@ -721,7 +694,9 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i re->end = 1; } - surface = re->outbuf_new_region_for_update (re->ob, ux, uy, uw, uh, cx, cy, cw, ch); + surface = + re->outbuf_new_region_for_update(re->ob, ux, uy, uw, uh, cx, cy, cw, ch); + *x = ux; *y = uy; *w = uw; *h = uh; return surface; } @@ -767,9 +742,9 @@ eng_image_map_surface_new(void *data , int w, int h, int alpha) re = (Render_Engine *)data; - surface = evas_cache_image_copied_data(evas_common_image_cache_get(), - w, h, NULL, alpha, - EVAS_COLORSPACE_ARGB8888); + surface = + evas_cache_image_copied_data(evas_common_image_cache_get(), w, h, NULL, + alpha, EVAS_COLORSPACE_ARGB8888); pixels = evas_cache_image_pixels(surface); if (re->render_mode == EVAS_RENDER_MODE_NONBLOCKING) @@ -778,8 +753,10 @@ eng_image_map_surface_new(void *data , int w, int h, int alpha) evas_common_frameq_prepare_frame(); /* add surface into the frame */ - e_surface = evas_common_frameq_new_surface (surface, 0, 0, w, h); - e_surface->dontpush = 1; // this surface is not going to be pushed to screen + e_surface = evas_common_frameq_new_surface(surface, 0, 0, w, h); + + /* this surface is not going to be pushed to screen */ + e_surface->dontpush = 1; evas_common_frameq_add_surface(e_surface); } return surface; @@ -825,17 +802,15 @@ eng_output_flush(void *data) if (re->render_mode == EVAS_RENDER_MODE_NONBLOCKING) { evas_common_frameq_set_frame_data(data, - eng_output_frameq_redraws_next_update_push, - eng_output_frameq_flush, - eng_output_frameq_set_priv); + eng_output_frameq_redraws_next_update_push, + eng_output_frameq_flush, + eng_output_frameq_set_priv); evas_common_frameq_ready_frame(); evas_common_frameq_begin(); } else #endif - { - re->outbuf_flush(re->ob); - } + re->outbuf_flush(re->ob); } static void @@ -863,6 +838,7 @@ module_open(Evas_Module *em) { #ifdef BUILD_ENGINE_SOFTWARE_XLIB static Eina_Bool xrm_inited = EINA_FALSE; + if (!xrm_inited) { xrm_inited = EINA_TRUE; @@ -874,15 +850,19 @@ module_open(Evas_Module *em) /* get whatever engine module we inherit from */ if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0; - _evas_engine_soft_x11_log_dom = eina_log_domain_register - ("evas-software_x11", EVAS_DEFAULT_LOG_COLOR); + + _evas_engine_soft_x11_log_dom = + eina_log_domain_register("evas-software_x11", EVAS_DEFAULT_LOG_COLOR); + if (_evas_engine_soft_x11_log_dom < 0) { EINA_LOG_ERR("Can not create a module log domain."); return 0; } + /* store it for later use */ func = pfunc; + /* now to override methods */ #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_) ORD(info); @@ -899,11 +879,11 @@ module_open(Evas_Module *em) ORD(output_redraws_next_update_push); ORD(output_flush); ORD(output_idle_flush); - /* now advertise out own api */ #ifdef EVAS_FRAME_QUEUING ORD(image_map_surface_new); #endif + /* now advertise out own api */ em->functions = (void *)(&func); return 1; } @@ -925,9 +905,7 @@ module_close(Evas_Module *em __UNUSED__) static Evas_Module_Api evas_modapi = { - EVAS_MODULE_API_VERSION, - "software_x11", - "none", + EVAS_MODULE_API_VERSION, "software_x11", "none", { module_open, module_close @@ -939,4 +917,3 @@ EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, software_x11); #ifndef EVAS_STATIC_BUILD_SOFTWARE_X11 EVAS_EINA_MODULE_DEFINE(engine, software_x11); #endif - diff --git a/src/modules/engines/software_x11/evas_engine.h b/src/modules/engines/software_x11/evas_engine.h index 808a3e5..80b71b7 100644 --- a/src/modules/engines/software_x11/evas_engine.h +++ b/src/modules/engines/software_x11/evas_engine.h @@ -1,49 +1,52 @@ #ifndef EVAS_ENGINE_H -#define EVAS_ENGINE_H +# define EVAS_ENGINE_H -#include -#include +# include +# include -#ifdef BUILD_ENGINE_SOFTWARE_XLIB -# include -# include -# include -# include -# include // xres - dpi -#endif +# ifdef BUILD_ENGINE_SOFTWARE_XLIB +# include +# include +# include +# include +# include // xres - dpi +# endif -#ifdef BUILD_ENGINE_SOFTWARE_XCB -# include -# include -#endif +# ifdef BUILD_ENGINE_SOFTWARE_XCB +# include +# include +# include +# endif extern int _evas_engine_soft_x11_log_dom; -#ifdef ERR -# undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_evas_engine_soft_x11_log_dom, __VA_ARGS__) -#ifdef DBG -# undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_evas_engine_soft_x11_log_dom, __VA_ARGS__) +# ifdef ERR +# undef ERR +# endif +# define ERR(...) EINA_LOG_DOM_ERR(_evas_engine_soft_x11_log_dom, __VA_ARGS__) -#ifdef INF -# undef INF -#endif -#define INF(...) EINA_LOG_DOM_INFO(_evas_engine_soft_x11_log_dom, __VA_ARGS__) +# ifdef DBG +# undef DBG +# endif +# define DBG(...) EINA_LOG_DOM_DBG(_evas_engine_soft_x11_log_dom, __VA_ARGS__) -#ifdef WRN -# undef WRN -#endif -#define WRN(...) EINA_LOG_DOM_WARN(_evas_engine_soft_x11_log_dom, __VA_ARGS__) +# ifdef INF +# undef INF +# endif +# define INF(...) EINA_LOG_DOM_INFO(_evas_engine_soft_x11_log_dom, __VA_ARGS__) -#ifdef CRIT -# undef CRIT -#endif -#define CRIT(...) EINA_LOG_DOM_CRIT(_evas_engine_soft_x11_log_dom, __VA_ARGS__) +# ifdef WRN +# undef WRN +# endif +# define WRN(...) EINA_LOG_DOM_WARN(_evas_engine_soft_x11_log_dom, __VA_ARGS__) -typedef enum _Outbuf_Depth Outbuf_Depth; +# ifdef CRIT +# undef CRIT +# endif +# define CRIT(...) \ + EINA_LOG_DOM_CRIT(_evas_engine_soft_x11_log_dom, __VA_ARGS__) + +typedef enum _Outbuf_Depth Outbuf_Depth; enum _Outbuf_Depth { @@ -57,77 +60,78 @@ enum _Outbuf_Depth OUTBUF_DEPTH_LAST }; -typedef struct _Outbuf Outbuf; +typedef struct _Outbuf Outbuf; struct _Outbuf { - Outbuf_Depth depth; - int w, h; - int rot; - int onebuf; - - struct { - Convert_Pal *pal; - union { -#ifdef BUILD_ENGINE_SOFTWARE_XLIB - struct { - Display *disp; - Window win; - Pixmap mask; - Visual *vis; - Colormap cmap; - int depth; - int shm; - GC gc; - GC gcm; - unsigned char swap : 1; - unsigned char bit_swap : 1; - } xlib; -#endif -#ifdef BUILD_ENGINE_SOFTWARE_XCB - struct { - xcb_connection_t *conn; - xcb_screen_t *screen; - xcb_drawable_t win; - xcb_pixmap_t mask; - xcb_visualtype_t *vis; - xcb_colormap_t cmap; - int depth; - int shm; - xcb_gcontext_t gc; - xcb_gcontext_t gcm; - unsigned char swap : 1; - unsigned char bit_swap : 1; - } xcb; -#endif - } x11; - struct { - DATA32 r, g, b; - } mask; - - /* 1 big buffer for updates - flush on idle_flush */ - RGBA_Image *onebuf; - Eina_List *onebuf_regions; - - /* a list of pending regions to write to the target */ - Eina_List *pending_writes; - /* a list of previous frame pending regions to write to the target */ - Eina_List *prev_pending_writes; -#ifdef EVAS_FRAME_QUEUING - /* protecting prev_pending_writes */ - LK(lock); -#endif - - unsigned char mask_dither : 1; - unsigned char destination_alpha : 1; - unsigned char debug : 1; - unsigned char synced : 1; - } priv; + Outbuf_Depth depth; + int w, h; + int rot; + int onebuf; + + struct + { + Convert_Pal *pal; + union + { +# ifdef BUILD_ENGINE_SOFTWARE_XLIB + struct + { + Display *disp; + Window win; + Pixmap mask; + Visual *vis; + Colormap cmap; + int depth, shm; + GC gc, gcm; + unsigned char swap : 1; + unsigned char bit_swap : 1; + } xlib; +# endif +# ifdef BUILD_ENGINE_SOFTWARE_XCB + struct + { + xcb_connection_t *conn; + xcb_screen_t *screen; + xcb_window_t win; + xcb_pixmap_t mask; + xcb_visualtype_t *visual; + xcb_colormap_t cmap; + int depth, shm; + xcb_gcontext_t gc, gcm; + unsigned char swap : 1; + unsigned char bit_swap : 1; + } xcb; +# endif + } x11; + struct + { + DATA32 r, g, b; + } mask; + + /* 1 big buffer for updates - flush on idle_flush */ + RGBA_Image *onebuf; + Eina_List *onebuf_regions; + + /* a list of pending regions to write to the target */ + Eina_List *pending_writes; + + /* a list of previous frame pending regions to write to the target */ + Eina_List *prev_pending_writes; + +# ifdef EVAS_FRAME_QUEUING + /* protecting prev_pending_writes */ + LK(lock); +# endif + + unsigned char mask_dither : 1; + unsigned char destination_alpha : 1; + unsigned char debug : 1; + unsigned char synced : 1; + } priv; }; - -void evas_software_xlib_x_init (void); -void evas_software_xcb_x_init (void); - +void evas_software_xlib_x_init(void); +void evas_software_xcb_init(void); #endif diff --git a/src/modules/engines/software_x11/evas_xcb_buffer.c b/src/modules/engines/software_x11/evas_xcb_buffer.c index 304c1f2..06f0e35 100644 --- a/src/modules/engines/software_x11/evas_xcb_buffer.c +++ b/src/modules/engines/software_x11/evas_xcb_buffer.c @@ -1,23 +1,21 @@ #include "evas_common.h" - #include "evas_xcb_buffer.h" +#include -static int _xcb_err = 0; +/* local function prototypes */ +static void _xcbob_sync(xcb_connection_t *conn); +static xcb_image_t *_xcbob_create_native(xcb_connection_t *conn, int w, int h, xcb_image_format_t format, uint8_t depth, void *base, uint32_t bytes, uint8_t *data); +static xcb_format_t *_xcbob_find_format(const xcb_setup_t *setup, uint8_t depth); -void -evas_software_xcb_x_write_mask_line(Outbuf *buf, - Xcb_Output_Buffer *xcbob, - DATA32 *src, - int w, - int y) +void +evas_software_xcb_write_mask_line(Outbuf *buf, Xcb_Output_Buffer *xcbob, DATA32 *src, int w, int y) { - int x; + int x, bpl = 0; DATA32 *src_ptr; - DATA8 *dst_ptr; - int bpl = 0; + DATA8 *dst_ptr; src_ptr = src; - dst_ptr = evas_software_xcb_x_output_buffer_data(xcbob, &bpl); + dst_ptr = evas_software_xcb_output_buffer_data(xcbob, &bpl); dst_ptr = dst_ptr + (bpl * y); w -= 7; if (buf->priv.x11.xcb.bit_swap) @@ -56,26 +54,21 @@ evas_software_xcb_x_write_mask_line(Outbuf *buf, } w += 7; for (; x < w; x ++) - { - xcb_image_put_pixel(xcbob->image, x, y, A_VAL(src_ptr) >> 7); - src_ptr++; - } + { + xcb_image_put_pixel(xcbob->xim, x, y, A_VAL(src_ptr) >> 7); + src_ptr++; + } } -void -evas_software_xcb_x_write_mask_line_rev(Outbuf *buf, - Xcb_Output_Buffer *xcbob, - DATA32 *src, - int w, - int y) +void +evas_software_xcb_write_mask_line_rev(Outbuf *buf, Xcb_Output_Buffer *xcbob, DATA32 *src, int w, int y) { - int x; + int x, bpl = 0; DATA32 *src_ptr; - DATA8 *dst_ptr; - int bpl = 0; + DATA8 *dst_ptr; src_ptr = src + w - 1; - dst_ptr = evas_software_xcb_x_output_buffer_data(xcbob, &bpl); + dst_ptr = evas_software_xcb_output_buffer_data(xcbob, &bpl); dst_ptr = dst_ptr + (bpl * y); w -= 7; if (buf->priv.x11.xcb.bit_swap) @@ -115,31 +108,25 @@ evas_software_xcb_x_write_mask_line_rev(Outbuf *buf, w += 7; for (; x < w; x ++) { - xcb_image_put_pixel(xcbob->image, x, y, A_VAL(src_ptr) >> 7); + xcb_image_put_pixel(xcbob->xim, x, y, A_VAL(src_ptr) >> 7); src_ptr--; } } -void -evas_software_xcb_x_write_mask_line_vert(Outbuf *buf, - Xcb_Output_Buffer *xcbob, - DATA32 *src, - int h, - int ym, - int w) +void +evas_software_xcb_write_mask_line_vert(Outbuf *buf, Xcb_Output_Buffer *xcbob, DATA32 *src, int h, int y, int w) { - int y; + int yy, bpl = 0; DATA32 *src_ptr; - DATA8 *dst_ptr; - int bpl = 0; + DATA8 *dst_ptr; src_ptr = src; - dst_ptr = evas_software_xcb_x_output_buffer_data(xcbob, &bpl); - dst_ptr = dst_ptr + (bpl * ym); + dst_ptr = evas_software_xcb_output_buffer_data(xcbob, &bpl); + dst_ptr = dst_ptr + (bpl * y); h -= 7; if (buf->priv.x11.xcb.bit_swap) { - for (y = 0; y < h; y += 8) + for (yy = 0; yy < h; yy += 8) { *dst_ptr = ((A_VAL(&(src_ptr[0 * w])) >> 7) << 7) | @@ -156,7 +143,7 @@ evas_software_xcb_x_write_mask_line_vert(Outbuf *buf, } else { - for (y = 0; y < h; y += 8) + for (yy = 0; yy < h; yy += 8) { *dst_ptr = ((A_VAL(&(src_ptr[0 * w])) >> 7) << 0) | @@ -172,33 +159,27 @@ evas_software_xcb_x_write_mask_line_vert(Outbuf *buf, } } h += 7; - for (; y < h; y ++) + for (; yy < h; yy ++) { - xcb_image_put_pixel(xcbob->image, y, ym, A_VAL(src_ptr) >> 7); + xcb_image_put_pixel(xcbob->xim, yy, y, A_VAL(src_ptr) >> 7); src_ptr += w; } } -void -evas_software_xcb_x_write_mask_line_vert_rev(Outbuf *buf, - Xcb_Output_Buffer *xcbob, - DATA32 *src, - int h, - int ym, - int w) +void +evas_software_xcb_write_mask_line_vert_rev(Outbuf *buf, Xcb_Output_Buffer *xcbob, DATA32 *src, int h, int y, int w) { - int y; + int yy, bpl = 0; DATA32 *src_ptr; - DATA8 *dst_ptr; - int bpl = 0; + DATA8 *dst_ptr; src_ptr = src + ((h - 1) * w); - dst_ptr = evas_software_xcb_x_output_buffer_data(xcbob, &bpl); - dst_ptr = dst_ptr + (bpl * ym); + dst_ptr = evas_software_xcb_output_buffer_data(xcbob, &bpl); + dst_ptr = dst_ptr + (bpl * y); h -= 7; if (buf->priv.x11.xcb.bit_swap) { - for (y = 0; y < h; y += 8) + for (yy = 0; yy < h; yy += 8) { *dst_ptr = ((A_VAL(&(src_ptr[ 0 * w])) >> 7) << 7) | @@ -215,7 +196,7 @@ evas_software_xcb_x_write_mask_line_vert_rev(Outbuf *buf, } else { - for (y = 0; y < h; y += 8) + for (yy = 0; yy < h; yy += 8) { *dst_ptr = ((A_VAL(&(src_ptr[ 0 * w])) >> 7) << 0) | @@ -231,238 +212,259 @@ evas_software_xcb_x_write_mask_line_vert_rev(Outbuf *buf, } } h += 7; - for (; y < h; y ++) + for (; yy < h; yy ++) { - xcb_image_put_pixel(xcbob->image, y, ym, A_VAL(src_ptr) >> 7); + xcb_image_put_pixel(xcbob->xim, yy, y, A_VAL(src_ptr) >> 7); src_ptr -= w; } } -int -evas_software_xcb_x_can_do_shm(xcb_connection_t *c, - xcb_screen_t *screen) +Eina_Bool +evas_software_xcb_can_do_shm(xcb_connection_t *conn, xcb_screen_t *screen) { - static xcb_connection_t *cached_c = NULL; - static int cached_result = 0; - - if (c == cached_c) return cached_result; - cached_c = c; - - if (xcb_get_extension_data(c, &xcb_shm_id)) + static xcb_connection_t *cached_conn = NULL; + static int cached_result = 0; + Xcb_Output_Buffer *xcbob = NULL; + xcb_visualtype_t *visual; + + if (conn == cached_conn) return cached_result; + cached_conn = conn; + + visual = xcb_aux_find_visual_by_id(screen, screen->root_visual); + + xcbob = + evas_software_xcb_output_buffer_new(conn, visual, screen->root_depth, + 1, 1, EINA_TRUE, NULL); + if (!xcbob) + cached_result = 0; + else { - Xcb_Output_Buffer *xcbob; - - xcbob = evas_software_xcb_x_output_buffer_new(c, - screen->root_depth, - 16, - 16, - 2, - NULL); - if (!xcbob) - { - cached_result = 0; - return 0; - } - evas_software_xcb_x_output_buffer_free(xcbob, 1); - cached_result = 1; - return 1; + evas_software_xcb_output_buffer_free(xcbob, EINA_TRUE); + cached_result = 1; } - cached_result = 0; - return 0; -} - -/* - * FIXME: no error mechanism - */ -/* static void */ -/* x_output_tmp_xcb_err(xcb_connection_t *c, XErrorEvent * ev) */ -/* { */ -/* _xcb_err = 1; */ -/* return; */ -/* } */ + return cached_result; +} Xcb_Output_Buffer * -evas_software_xcb_x_output_buffer_new(xcb_connection_t *c, - int depth, - int w, - int h, - int try_shm, - void *data) +evas_software_xcb_output_buffer_new(xcb_connection_t *conn, xcb_visualtype_t *vis, int depth, int w, int h, Eina_Bool try_shm, unsigned char *data) { - Xcb_Output_Buffer *xcbob; + Xcb_Output_Buffer *xcbob = NULL; - xcbob = calloc(1, sizeof(Xcb_Output_Buffer)); - if (!xcbob) return NULL; + if (!(xcbob = calloc(1, sizeof(Xcb_Output_Buffer)))) + return NULL; - xcbob->connection = c; - xcbob->image = NULL; - xcbob->shm_info = NULL; + xcbob->connection = conn; + xcbob->visual = vis; + xcbob->xim = NULL; + xcbob->shm_info = NULL; xcbob->w = w; xcbob->h = h; + xcbob->data = data; - if (try_shm > 0) + if (try_shm) { xcbob->shm_info = malloc(sizeof(xcb_shm_segment_info_t)); - if (xcbob->shm_info) + if (xcbob->shm_info) { - xcbob->shm_info->shmseg = xcb_generate_id(c); - xcbob->image = xcb_image_create_native(c, w, h, - XCB_IMAGE_FORMAT_Z_PIXMAP, - depth, NULL, ~0, NULL); - if (xcbob->image) + xcbob->shm_info->shmseg = xcb_generate_id(conn); + xcbob->xim = + _xcbob_create_native(conn, w, h, XCB_IMAGE_FORMAT_Z_PIXMAP, + depth, NULL, ~0, NULL); + if (xcbob->xim) { - xcbob->shm_info->shmid = shmget(IPC_PRIVATE, - xcbob->image->size, - IPC_CREAT | 0777); - if (xcbob->shm_info->shmid >= 0) + xcbob->shm_info->shmid = + shmget(IPC_PRIVATE, xcbob->xim->size, (IPC_CREAT | 0666)); + if (xcbob->shm_info->shmid == (uint32_t)-1) + { + xcb_image_destroy(xcbob->xim); + free(xcbob->shm_info); + free(xcbob); + return NULL; + } + xcbob->shm_info->shmaddr = + shmat(xcbob->shm_info->shmid, 0, 0); + if (xcbob->shm_info->shmaddr != ((void *)-1)) + { + xcbob->xim->data = xcbob->shm_info->shmaddr; + xcb_shm_attach(conn, xcbob->shm_info->shmseg, + xcbob->shm_info->shmid, 0); + xcbob->bpl = xcbob->xim->stride; + xcbob->psize = (xcbob->bpl * xcbob->h); + return xcbob; + } + else { - xcbob->shm_info->shmaddr = xcbob->image->data = - shmat(xcbob->shm_info->shmid, 0, 0); - if (xcbob->shm_info->shmaddr) - { - /* - * FIXME: no error mechanism - */ - - /* XErrorHandler ph; */ - /* EventHandlers eh; */ - - if (try_shm == 2) // only needed during testing - { - free(xcb_get_input_focus_reply(c, xcb_get_input_focus_unchecked(c), NULL)); - _xcb_err = 0; - /* ph = XSetErrorHandler((XErrorHandler) */ - } - xcb_shm_attach(c, - xcbob->shm_info->shmseg, - xcbob->shm_info->shmid, 0); - if (try_shm == 2) // only needed during testing - { - free(xcb_get_input_focus_reply(c, xcb_get_input_focus_unchecked(c), NULL)); - /* XSetErrorHandler((XErrorHandler)ph); */ - } - if (!_xcb_err) - { - xcbob->bpl = xcbob->image->stride; - xcbob->psize = xcbob->bpl * xcbob->h; - return xcbob; - } - } - shmdt(xcbob->shm_info->shmaddr); shmctl(xcbob->shm_info->shmid, IPC_RMID, 0); + xcb_image_destroy(xcbob->xim); + free(xcbob->shm_info); + free(xcbob); + return NULL; } - if (xcbob->image) xcb_image_destroy(xcbob->image); - xcbob->image = NULL; } - if (xcbob->shm_info) free(xcbob->shm_info); - xcbob->shm_info = NULL; + else + { + free(xcbob->shm_info); + free(xcbob); + return NULL; + } + } + else + { + free(xcbob); + return NULL; } } - - if (try_shm > 1) return NULL; - - xcbob->image = xcb_image_create_native(c, w, h, XCB_IMAGE_FORMAT_Z_PIXMAP, - depth, NULL, ~0, NULL); - if (!xcbob->image) - { - free(xcbob); - return NULL; - } - - xcbob->data = data; - - if (!xcbob->image->data) + else { - xcbob->image->data = malloc(xcbob->image->size); - if (!xcbob->image->data) - { - xcb_image_destroy(xcbob->image); - free(xcbob); - return NULL; - } + /* no shm */ + xcbob->xim = + _xcbob_create_native(conn, w, h, XCB_IMAGE_FORMAT_Z_PIXMAP, + depth, NULL, ~0, NULL); + if (!xcbob->xim) + { + free(xcbob); + return NULL; + } + if (!xcbob->xim->data) + { + xcbob->xim->data = malloc(xcbob->xim->size); + if (!xcbob->xim->data) + { + xcb_image_destroy(xcbob->xim); + free(xcbob); + return NULL; + } + } + xcbob->bpl = xcbob->xim->stride; + xcbob->psize = xcbob->xim->size; } - - xcbob->bpl = xcbob->image->stride; - xcbob->psize = xcbob->image->size; - return xcbob; } -void -evas_software_xcb_x_output_buffer_free(Xcb_Output_Buffer *xcbob, - int sync) +void +evas_software_xcb_output_buffer_free(Xcb_Output_Buffer *xcbob, Eina_Bool sync) { - if (xcbob->shm_info) + if (xcbob->shm_info) { - if (sync) - free(xcb_get_input_focus_reply(xcbob->connection, - xcb_get_input_focus_unchecked(xcbob->connection), - NULL)); - xcb_shm_detach(xcbob->connection, xcbob->shm_info->shmseg); - xcb_image_destroy(xcbob->image); - shmdt(xcbob->shm_info->shmaddr); - shmctl(xcbob->shm_info->shmid, IPC_RMID, 0); - free(xcbob->shm_info); + if (sync) _xcbob_sync(xcbob->connection); + xcb_shm_detach(xcbob->connection, xcbob->shm_info->shmseg); + xcb_image_destroy(xcbob->xim); + shmdt(xcbob->shm_info->shmaddr); + shmctl(xcbob->shm_info->shmid, IPC_RMID, 0); + free(xcbob->shm_info); } - else + else { - if (xcbob->data) xcbob->image->data = NULL; - free(xcbob->image->data); - xcb_image_destroy(xcbob->image); + if (xcbob->data) xcbob->xim->data = NULL; + free(xcbob->xim->data); + xcb_image_destroy(xcbob->xim); } free(xcbob); } -void -evas_software_xcb_x_output_buffer_paste(Xcb_Output_Buffer *xcbob, - xcb_drawable_t d, - xcb_gcontext_t gc, - int x, - int y, - int sync) +void +evas_software_xcb_output_buffer_paste(Xcb_Output_Buffer *xcbob, xcb_drawable_t drawable, xcb_gcontext_t gc, int x, int y, Eina_Bool sync) { - if (xcbob->shm_info) + if (xcbob->shm_info) { - xcb_image_shm_put(xcbob->connection, d, gc, - xcbob->image, *xcbob->shm_info, - 0, 0, - x, y, - xcbob->w, xcbob->h, - 0); - if (sync) - free(xcb_get_input_focus_reply(xcbob->connection, - xcb_get_input_focus_unchecked(xcbob->connection), - NULL)); + xcb_image_shm_put(xcbob->connection, drawable, gc, xcbob->xim, + *xcbob->shm_info, 0, 0, x, y, xcbob->w, xcbob->h, 0); + if (sync) _xcbob_sync(xcbob->connection); } - else - xcb_image_put(xcbob->connection, d, gc, - xcbob->image, - x, y, 0); + else + xcb_image_put(xcbob->connection, drawable, gc, xcbob->xim, x, y, 0); } DATA8 * -evas_software_xcb_x_output_buffer_data(Xcb_Output_Buffer *xcbob, - int *bytes_per_line_ret) +evas_software_xcb_output_buffer_data(Xcb_Output_Buffer *xcbob, int *bpl_ret) +{ + if (bpl_ret) *bpl_ret = xcbob->xim->stride; + return xcbob->xim->data; +} + +int +evas_software_xcb_output_buffer_depth(Xcb_Output_Buffer *xcbob) +{ + return xcbob->xim->bpp; +} + +int +evas_software_xcb_output_buffer_byte_order(Xcb_Output_Buffer *xcbob) { - if (bytes_per_line_ret) *bytes_per_line_ret = xcbob->image->stride; - return xcbob->image->data; + return xcbob->xim->byte_order; } -int -evas_software_xcb_x_output_buffer_depth(Xcb_Output_Buffer *xcbob) +int +evas_software_xcb_output_buffer_bit_order(Xcb_Output_Buffer *xcbob) { - return xcbob->image->bpp; + return xcbob->xim->bit_order; } -int -evas_software_xcb_x_output_buffer_byte_order(Xcb_Output_Buffer *xcbob) +/* local functions */ +static void +_xcbob_sync(xcb_connection_t *conn) { - return xcbob->image->byte_order; + free(xcb_get_input_focus_reply(conn, + xcb_get_input_focus_unchecked(conn), NULL)); } -int -evas_software_xcb_x_output_buffer_bit_order(Xcb_Output_Buffer *xcbob) +static xcb_image_t * +_xcbob_create_native(xcb_connection_t *conn, int w, int h, xcb_image_format_t format, uint8_t depth, void *base, uint32_t bytes, uint8_t *data) { - return xcbob->image->bit_order; + const xcb_setup_t *setup; + xcb_format_t *fmt = NULL; + xcb_image_format_t xif; + + /* NB: We cannot use xcb_image_create_native as it only creates images + * using MSB_FIRST, so this routine recreates that function and checks + * endian-ness correctly */ + setup = xcb_get_setup(conn); + xif = format; + + if ((xif == XCB_IMAGE_FORMAT_Z_PIXMAP) && (depth == 1)) + xif = XCB_IMAGE_FORMAT_XY_PIXMAP; + + fmt = _xcbob_find_format(setup, depth); + if (!fmt) return 0; + + switch (xif) + { + case XCB_IMAGE_FORMAT_XY_BITMAP: + if (depth != 1) return 0; + case XCB_IMAGE_FORMAT_XY_PIXMAP: + return xcb_image_create(w, h, xif, + fmt->scanline_pad, + fmt->depth, fmt->bits_per_pixel, + setup->bitmap_format_scanline_unit, + setup->image_byte_order, + setup->bitmap_format_bit_order, + base, bytes, data); + case XCB_IMAGE_FORMAT_Z_PIXMAP: + return xcb_image_create(w, h, xif, + fmt->scanline_pad, + fmt->depth, fmt->bits_per_pixel, + setup->bitmap_format_scanline_unit, + setup->image_byte_order, + setup->bitmap_format_bit_order, + base, bytes, data); + default: + break; + } + + return 0; +} + +static xcb_format_t * +_xcbob_find_format(const xcb_setup_t *setup, uint8_t depth) +{ + xcb_format_t *fmt, *fmtend; + + fmt = xcb_setup_pixmap_formats(setup); + fmtend = fmt + xcb_setup_pixmap_formats_length(setup); + for (; fmt != fmtend; ++fmt) + if (fmt->depth == depth) + return fmt; + + return 0; } diff --git a/src/modules/engines/software_x11/evas_xcb_buffer.h b/src/modules/engines/software_x11/evas_xcb_buffer.h index f9582c8..88bec9b 100644 --- a/src/modules/engines/software_x11/evas_xcb_buffer.h +++ b/src/modules/engines/software_x11/evas_xcb_buffer.h @@ -1,67 +1,30 @@ #ifndef EVAS_XCB_BUFFER_H -#define EVAS_XCB_BUFFER_H +# define EVAS_XCB_BUFFER_H +# include "evas_engine.h" -#include "evas_engine.h" - - -typedef struct _Xcb_Output_Buffer Xcb_Output_Buffer; - -struct _Xcb_Output_Buffer +typedef struct _Xcb_Output_Buffer Xcb_Output_Buffer; +struct _Xcb_Output_Buffer { - xcb_connection_t *connection; - xcb_image_t *image; + xcb_connection_t *connection; + xcb_visualtype_t *visual; + xcb_image_t *xim; xcb_shm_segment_info_t *shm_info; - void *data; - int w; - int h; - int bpl; - int psize; + unsigned char *data; + int w, h, bpl, psize; }; -void evas_software_xcb_x_write_mask_line (Outbuf *buf, - Xcb_Output_Buffer *xcbob, - DATA32 *src, - int w, - int y); -void evas_software_xcb_x_write_mask_line_rev (Outbuf *buf, - Xcb_Output_Buffer *xcbob, - DATA32 *src, - int w, - int y); -void evas_software_xcb_x_write_mask_line_vert (Outbuf *buf, - Xcb_Output_Buffer *xcbob, - DATA32 *src, - int h, - int ym, - int w); -void evas_software_xcb_x_write_mask_line_vert_rev(Outbuf *buf, - Xcb_Output_Buffer *xcbob, - DATA32 *src, - int h, - int ym, - int w); -int evas_software_xcb_x_can_do_shm (xcb_connection_t *c, - xcb_screen_t *screen); -Xcb_Output_Buffer *evas_software_xcb_x_output_buffer_new (xcb_connection_t *c, - int depth, - int w, - int h, - int try_shm, - void *data); -void evas_software_xcb_x_output_buffer_free (Xcb_Output_Buffer *xcbob, - int sync); -void evas_software_xcb_x_output_buffer_paste (Xcb_Output_Buffer *xcbob, - xcb_drawable_t d, - xcb_gcontext_t gc, - int x, - int y, - int sync); -DATA8 *evas_software_xcb_x_output_buffer_data (Xcb_Output_Buffer *xcbob, - int *bytes_per_line_ret); -int evas_software_xcb_x_output_buffer_depth (Xcb_Output_Buffer *xcbob); -int evas_software_xcb_x_output_buffer_byte_order(Xcb_Output_Buffer *xcbob); -int evas_software_xcb_x_output_buffer_bit_order (Xcb_Output_Buffer *xcbob); - +void evas_software_xcb_write_mask_line(Outbuf *buf, Xcb_Output_Buffer *xcbob, DATA32 *src, int w, int y); +void evas_software_xcb_write_mask_line_rev(Outbuf *buf, Xcb_Output_Buffer *xcbob, DATA32 *src, int w, int y); +void evas_software_xcb_write_mask_line_vert(Outbuf *buf, Xcb_Output_Buffer *xcbob, DATA32 *src, int h, int y, int w); +void evas_software_xcb_write_mask_line_vert_rev(Outbuf *buf, Xcb_Output_Buffer *xcbob, DATA32 *src, int h, int y, int w); +Eina_Bool evas_software_xcb_can_do_shm(xcb_connection_t *conn, xcb_screen_t *screen); +Xcb_Output_Buffer *evas_software_xcb_output_buffer_new(xcb_connection_t *conn, xcb_visualtype_t *vis, int depth, int w, int h, Eina_Bool try_shm, unsigned char *data); +void evas_software_xcb_output_buffer_free(Xcb_Output_Buffer *xcbob, Eina_Bool sync); +void evas_software_xcb_output_buffer_paste(Xcb_Output_Buffer *xcbob, xcb_drawable_t drawable, xcb_gcontext_t gc, int x, int y, Eina_Bool sync); +DATA8 *evas_software_xcb_output_buffer_data(Xcb_Output_Buffer *xcbob, int *bpl_ret); +int evas_software_xcb_output_buffer_depth(Xcb_Output_Buffer *xcbob); +int evas_software_xcb_output_buffer_byte_order(Xcb_Output_Buffer *xcbob); +int evas_software_xcb_output_buffer_bit_order(Xcb_Output_Buffer *xcbob); #endif diff --git a/src/modules/engines/software_x11/evas_xcb_color.c b/src/modules/engines/software_x11/evas_xcb_color.c index 4b5aa30..3ed6037 100644 --- a/src/modules/engines/software_x11/evas_xcb_color.c +++ b/src/modules/engines/software_x11/evas_xcb_color.c @@ -293,7 +293,7 @@ x_color_alloc_mono(xcb_connection_t *conn, } void -evas_software_xcb_x_color_init(void) +evas_software_xcb_color_init(void) { static int initialised = 0; @@ -343,7 +343,7 @@ evas_software_xcb_x_color_init(void) } Convert_Pal * -evas_software_xcb_x_color_allocate(xcb_connection_t *conn, +evas_software_xcb_color_allocate(xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *vis, Convert_Pal_Mode colors) @@ -401,7 +401,7 @@ evas_software_xcb_x_color_allocate(xcb_connection_t *conn, } void -evas_software_xcb_x_color_deallocate(xcb_connection_t *conn, +evas_software_xcb_color_deallocate(xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *vis __UNUSED__, Convert_Pal *pal) diff --git a/src/modules/engines/software_x11/evas_xcb_color.h b/src/modules/engines/software_x11/evas_xcb_color.h index 0d04000..7dcaeaf 100644 --- a/src/modules/engines/software_x11/evas_xcb_color.h +++ b/src/modules/engines/software_x11/evas_xcb_color.h @@ -1,15 +1,10 @@ #ifndef EVAS_XCB_COLOR_H -#define EVAS_XCB_COLOR_H +# define EVAS_XCB_COLOR_H +# include "evas_engine.h" -void evas_software_xcb_x_color_init (void); -Convert_Pal *evas_software_xcb_x_color_allocate (xcb_connection_t *conn, - xcb_colormap_t cmap, - xcb_visualtype_t *vis, - Convert_Pal_Mode colors); -void evas_software_xcb_x_color_deallocate (xcb_connection_t *conn, - xcb_colormap_t cmap, - xcb_visualtype_t *vis, - Convert_Pal *pal); +void evas_software_xcb_color_init(void); +Convert_Pal *evas_software_xcb_color_allocate(xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *vis, Convert_Pal_Mode colors); +void evas_software_xcb_color_deallocate(xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *vis, Convert_Pal *pal); #endif diff --git a/src/modules/engines/software_x11/evas_xcb_main.c b/src/modules/engines/software_x11/evas_xcb_main.c index e395b02..d187016 100644 --- a/src/modules/engines/software_x11/evas_xcb_main.c +++ b/src/modules/engines/software_x11/evas_xcb_main.c @@ -1,7 +1,8 @@ #include "evas_common.h" #include "evas_engine.h" -void -evas_software_xcb_x_init(void) +void +evas_software_xcb_init(void) { + } diff --git a/src/modules/engines/software_x11/evas_xcb_outbuf.c b/src/modules/engines/software_x11/evas_xcb_outbuf.c index ef61755..72da52e 100644 --- a/src/modules/engines/software_x11/evas_xcb_outbuf.c +++ b/src/modules/engines/software_x11/evas_xcb_outbuf.c @@ -1,995 +1,785 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include - #include "evas_common.h" #include "evas_macros.h" #include "evas_xcb_outbuf.h" #include "evas_xcb_buffer.h" #include "evas_xcb_color.h" +#include - -typedef struct _Outbuf_Region Outbuf_Region; - -struct _Outbuf_Region +/* local structures */ +typedef struct _Outbuf_Region Outbuf_Region; +struct _Outbuf_Region { - Xcb_Output_Buffer *xcbob; - Xcb_Output_Buffer *mxcbob; - int x; - int y; - int w; - int h; + Xcb_Output_Buffer *xcbob, *mask; + int x, y, w, h; }; -static Eina_List *shmpool = NULL; -static int shmsize = 0; -static int shmmemlimit = 10 * 1024 * 1024; -static int shmcountlimit = 32; - -static Xcb_Output_Buffer * -_find_xcbob(xcb_connection_t *conn, int depth, int w, int h, int shm, void *data) -{ - Eina_List *l; - Eina_List *xl = NULL; - Xcb_Output_Buffer *xcbob = NULL; - Xcb_Output_Buffer *xcbob2; - int fitness = 0x7fffffff; - int sz; - int lbytes; - int bpp; - - if (!shm) - return evas_software_xcb_x_output_buffer_new(conn, depth, w, h, shm, data); - if (depth > 1) - { - bpp = depth / 8; - if (bpp == 3) bpp = 4; - lbytes = (((w * bpp) + 3) / 4) * 4; - } - else - lbytes = ((w + 31) / 32) * 4; - sz = lbytes * h; - EINA_LIST_FOREACH(shmpool, l, xcbob2) - { - int szdif; - - if ((xcbob2->image->depth != depth) || - (xcbob2->connection != conn)) - continue; - szdif = xcbob2->psize - sz; - if (szdif < 0) continue; - if (szdif == 0) - { - xcbob = xcbob2; - xl = l; - goto have_xcbob; - } - if (szdif < fitness) - { - fitness = szdif; - xcbob = xcbob2; - xl = l; - } - } - if ((fitness > (100 * 100)) || (!xcbob)) - return evas_software_xcb_x_output_buffer_new(conn, depth, w, h, shm, data); - - have_xcbob: - shmpool = eina_list_remove_list(shmpool, xl); - xcbob->w = w; - xcbob->h = h; - xcbob->bpl = lbytes; - xcbob->image->width = xcbob->w; - xcbob->image->height = xcbob->h; - xcbob->image->stride = xcbob->bpl; - shmsize -= xcbob->psize * (xcbob->image->depth / 8); - return xcbob; -} - -static void -_unfind_xcbob(Xcb_Output_Buffer *xcbob, int sync) -{ - if (xcbob->shm_info) - { - shmpool = eina_list_prepend(shmpool, xcbob); - shmsize += xcbob->psize * xcbob->image->depth / 8; - while ((shmsize > (shmmemlimit)) || - (eina_list_count(shmpool) > shmcountlimit)) - { - Eina_List *xl; - - xl = eina_list_last(shmpool); - if (!xl) - { - shmsize = 0; - break; - } - xcbob = xl->data; - shmpool = eina_list_remove_list(shmpool, xl); - evas_software_xcb_x_output_buffer_free(xcbob, sync); - } - } - else - evas_software_xcb_x_output_buffer_free(xcbob, sync); -} - -static void -_clear_xcbob(int sync) -{ - while (shmpool) - { - Xcb_Output_Buffer *xcbob; - - xcbob = shmpool->data; - shmpool = eina_list_remove_list(shmpool, shmpool); - evas_software_xcb_x_output_buffer_free(xcbob, sync); - } - shmsize = 0; -} +/* local function prototypes */ +static Xcb_Output_Buffer *_find_xcbob(xcb_connection_t *conn, xcb_visualtype_t *vis, int depth, int w, int h, Eina_Bool shm, void *data); +static void _unfind_xcbob(Xcb_Output_Buffer *xcbob, Eina_Bool sync); +static void _clear_xcbob(Eina_Bool sync); +static xcb_format_t *_find_format_by_depth(const xcb_setup_t *setup, uint8_t depth); +static void _xcbob_sync(xcb_connection_t *conn); + +/* local variables */ +static Eina_List *_shmpool = NULL; +static int _shmsize = 0; +static int _shmlimit = (10 * 1024 * 1024); +static int _shmcountlimit = 32; + +#ifdef EVAS_FRAME_QUEUING +static LK(lock_shmpool); +# define SHMPOOL_LOCK() LKL(lock_shmpool); +# define SHMPOOL_UNLOCK() LKU(lock_shmpool); +#else +# define SHMPOOL_LOCK() +# define SHMPOOL_UNLOCK() +#endif -void -evas_software_xcb_outbuf_init(void) +void +evas_software_xcb_outbuf_init(void) { +#ifdef EVAS_FRAME_QUEUING + LKI(lock_shmpool); +#endif } -void -evas_software_xcb_outbuf_free(Outbuf * buf) +void +evas_software_xcb_outbuf_free(Outbuf *buf) { - while (buf->priv.pending_writes) +#ifdef EVAS_FRAME_QUEUING + LKL(buf->priv.lock); +#endif + while (buf->priv.pending_writes) { - RGBA_Image *im; - Outbuf_Region *obr; - - im = buf->priv.pending_writes->data; - buf->priv.pending_writes = eina_list_remove_list(buf->priv.pending_writes, buf->priv.pending_writes); - obr = im->extended_info; - evas_cache_image_drop(&im->cache_entry); - if (obr->xcbob) _unfind_xcbob(obr->xcbob, 0); - if (obr->mxcbob) _unfind_xcbob(obr->mxcbob, 0); - free(obr); + RGBA_Image *im = NULL; + Outbuf_Region *obr = NULL; + + im = buf->priv.pending_writes->data; + buf->priv.pending_writes = + eina_list_remove_list(buf->priv.pending_writes, + buf->priv.pending_writes); + obr = im->extended_info; + evas_cache_image_drop(&im->cache_entry); + if (obr->xcbob) _unfind_xcbob(obr->xcbob, EINA_FALSE); + if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE); + free(obr); } +#ifdef EVAS_FRAME_QUEUING + LKU(buf->priv.lock); +#endif evas_software_xcb_outbuf_idle_flush(buf); evas_software_xcb_outbuf_flush(buf); if (buf->priv.x11.xcb.gc) - xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc); + xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc); if (buf->priv.x11.xcb.gcm) - xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gcm); + xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gcm); if (buf->priv.pal) - evas_software_xcb_x_color_deallocate(buf->priv.x11.xcb.conn, - buf->priv.x11.xcb.cmap, - buf->priv.x11.xcb.vis, - buf->priv.pal); + evas_software_xcb_color_deallocate(buf->priv.x11.xcb.conn, + buf->priv.x11.xcb.cmap, + buf->priv.x11.xcb.visual, + buf->priv.pal); +#ifdef EVAS_FRAME_QUEUING + LKD(buf->priv.lock); +#endif free(buf); - _clear_xcbob(0); -} - -void -evas_software_xcb_outbuf_rotation_set(Outbuf *buf, int rot) -{ - buf->rot = rot; + _clear_xcbob(EINA_FALSE); } Outbuf * -evas_software_xcb_outbuf_setup_x(int w, - int h, - int rot, - Outbuf_Depth depth, - xcb_connection_t *conn, - xcb_screen_t *screen, - xcb_drawable_t draw, - xcb_visualtype_t *vis, - xcb_colormap_t cmap, - int x_depth, - int grayscale, - int max_colors, - xcb_drawable_t mask, - int shape_dither, - int destination_alpha) +evas_software_xcb_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, xcb_connection_t *conn, xcb_screen_t *screen, xcb_drawable_t draw, xcb_visualtype_t *vis, xcb_colormap_t cmap, int xdepth, Eina_Bool grayscale, int max_colors, xcb_drawable_t mask, Eina_Bool shape_dither, Eina_Bool alpha) { - Outbuf *buf; + Outbuf *buf = NULL; + Gfx_Func_Convert func_conv= NULL; + const xcb_setup_t *setup; + xcb_format_t *fmt; - buf = calloc(1, sizeof(Outbuf)); - if (!buf) - return NULL; + if (!(buf = calloc(1, sizeof(Outbuf)))) + return NULL; + + setup = xcb_get_setup(conn); + fmt = _find_format_by_depth(setup, xdepth); buf->w = w; buf->h = h; buf->depth = depth; buf->rot = rot; - buf->priv.x11.xcb.conn = conn; buf->priv.x11.xcb.screen = screen; - buf->priv.x11.xcb.vis = vis; + buf->priv.x11.xcb.visual = vis; buf->priv.x11.xcb.cmap = cmap; - buf->priv.x11.xcb.depth = x_depth; - + buf->priv.x11.xcb.depth = xdepth; buf->priv.mask_dither = shape_dither; - buf->priv.destination_alpha = destination_alpha; - - { - Gfx_Func_Convert conv_func; - Xcb_Output_Buffer *xcbob; + buf->priv.destination_alpha = alpha; + buf->priv.x11.xcb.shm = evas_software_xcb_can_do_shm(conn, screen); - buf->priv.x11.xcb.shm = evas_software_xcb_x_can_do_shm(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.screen); - xcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x11.xcb.conn, - buf->priv.x11.xcb.depth, - 1, 1, - buf->priv.x11.xcb.shm, NULL); - - conv_func = NULL; - if (xcbob) - { #ifdef WORDS_BIGENDIAN - if (evas_software_xcb_x_output_buffer_byte_order(xcbob) == XCB_IMAGE_ORDER_LSB_FIRST) - buf->priv.x11.xcb.swap = 1; - if (evas_software_xcb_x_output_buffer_bit_order(xcbob) == XCB_IMAGE_ORDER_MSB_FIRST) - buf->priv.x11.xcb.bit_swap = 1; + if (setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST) + buf->priv.x11.xcb.swap = EINA_TRUE; #else - if (evas_software_xcb_x_output_buffer_byte_order(xcbob) == XCB_IMAGE_ORDER_MSB_FIRST) - buf->priv.x11.xcb.swap = 1; - if (evas_software_xcb_x_output_buffer_bit_order(xcbob) == XCB_IMAGE_ORDER_MSB_FIRST) - buf->priv.x11.xcb.bit_swap = 1; + if (setup->image_byte_order == XCB_IMAGE_ORDER_MSB_FIRST) + buf->priv.x11.xcb.swap = EINA_TRUE; +#endif + if (setup->bitmap_format_bit_order == XCB_IMAGE_ORDER_MSB_FIRST) + buf->priv.x11.xcb.bit_swap = EINA_TRUE; + + if (((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) || + (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) && (xdepth > 8)) + { + buf->priv.mask.r = (DATA32)vis->red_mask; + buf->priv.mask.g = (DATA32)vis->green_mask; + buf->priv.mask.b = (DATA32)vis->blue_mask; + if (buf->priv.x11.xcb.swap) + { + SWAP32(buf->priv.mask.r); + SWAP32(buf->priv.mask.g); + SWAP32(buf->priv.mask.b); + } + } + else if ((vis->_class == XCB_VISUAL_CLASS_PSEUDO_COLOR) || + (vis->_class == XCB_VISUAL_CLASS_STATIC_COLOR) || + (vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) || + (vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY) || + (xdepth <= 8)) + { + Convert_Pal_Mode pm = PAL_MODE_RGB332; + + if ((vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) || + (vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY)) + grayscale = EINA_TRUE; + if (grayscale) + { + if (max_colors >= 256) + pm = PAL_MODE_GRAY256; + else if (max_colors >= 64) + pm = PAL_MODE_GRAY64; + else if (max_colors >= 16) + pm = PAL_MODE_GRAY16; + else if (max_colors >= 4) + pm = PAL_MODE_GRAY4; + else + pm = PAL_MODE_MONO; + } + else + { + if (max_colors >= 256) + pm = PAL_MODE_RGB332; + else if (max_colors >= 216) + pm = PAL_MODE_RGB666; + else if (max_colors >= 128) + pm = PAL_MODE_RGB232; + else if (max_colors >= 64) + pm = PAL_MODE_RGB222; + else if (max_colors >= 32) + pm = PAL_MODE_RGB221; + else if (max_colors >= 16) + pm = PAL_MODE_RGB121; + else if (max_colors >= 8) + pm = PAL_MODE_RGB111; + else if (max_colors >= 4) + pm = PAL_MODE_GRAY4; + else + pm = PAL_MODE_MONO; + } + buf->priv.pal = + evas_software_xcb_color_allocate(conn, cmap, vis, pm); + if (!buf->priv.pal) + { + free(buf); + return NULL; + } + } + if ((buf->rot == 0) || (buf->rot == 180)) + { + w = buf->w; + h = buf->h; + } + else if ((buf->rot == 90) || (buf->rot == 270)) + { + w = buf->h; + h = buf->w; + } + + if (buf->priv.pal) + { + func_conv = + evas_common_convert_func_get(0, w, h, fmt->bits_per_pixel, + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + buf->priv.pal->colors, buf->rot); + } + else + { + func_conv = + evas_common_convert_func_get(0, w, h, fmt->bits_per_pixel, + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + PAL_MODE_NONE, buf->rot); + } + if (!func_conv) + { + ERR("XCB Engine" + " {" + " At depth %i:" + " RGB format mask: %08x, %08x, %08x" + " Palette mode: %i" + " Not supported by and compiled in converters!" + " }", buf->priv.x11.xcb.depth, buf->priv.mask.r, + buf->priv.mask.g, buf->priv.mask.b, + buf->priv.pal ? (int)buf->priv.pal->colors : -1); + } + + evas_software_xcb_outbuf_drawable_set(buf, draw); + evas_software_xcb_outbuf_mask_set(buf, mask); + +#ifdef EVAS_FRAME_QUEUING + LKI(buf->priv.lock); #endif - if (((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) || - (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) && - (x_depth > 8)) - - { - buf->priv.mask.r = (DATA32) vis->red_mask; - buf->priv.mask.g = (DATA32) vis->green_mask; - buf->priv.mask.b = (DATA32) vis->blue_mask; - if (buf->priv.x11.xcb.swap) - { - SWAP32(buf->priv.mask.r); - SWAP32(buf->priv.mask.g); - SWAP32(buf->priv.mask.b); - } - } - else if ((vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY) || - (vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) || - (vis->_class == XCB_VISUAL_CLASS_STATIC_COLOR) || - (vis->_class == XCB_VISUAL_CLASS_PSEUDO_COLOR) || - (x_depth <= 8)) - { - Convert_Pal_Mode pm = PAL_MODE_RGB332; - - if ((vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) || - (vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY)) - grayscale = 1; - if (grayscale) - { - if (max_colors >= 256) - pm = PAL_MODE_GRAY256; - else if (max_colors >= 64) - pm = PAL_MODE_GRAY64; - else if (max_colors >= 16) - pm = PAL_MODE_GRAY16; - else if (max_colors >= 4) - pm = PAL_MODE_GRAY4; - else - pm = PAL_MODE_MONO; - } - else - { - if (max_colors >= 256) - pm = PAL_MODE_RGB332; - else if (max_colors >= 216) - pm = PAL_MODE_RGB666; - else if (max_colors >= 128) - pm = PAL_MODE_RGB232; - else if (max_colors >= 64) - pm = PAL_MODE_RGB222; - else if (max_colors >= 32) - pm = PAL_MODE_RGB221; - else if (max_colors >= 16) - pm = PAL_MODE_RGB121; - else if (max_colors >= 8) - pm = PAL_MODE_RGB111; - else if (max_colors >= 4) - pm = PAL_MODE_GRAY4; - else - pm = PAL_MODE_MONO; - } - /* FIXME: only alloc once per display+cmap */ - buf->priv.pal = - evas_software_xcb_x_color_allocate(conn, - cmap, - vis, - pm); - if (!buf->priv.pal) - { - free(buf); - return NULL; - } - } - if (buf->priv.pal) - { - if (buf->rot == 0 || buf->rot == 180) - conv_func = evas_common_convert_func_get(0, - buf->w, - buf->h, - evas_software_xcb_x_output_buffer_depth (xcbob), - buf->priv.mask.r, - buf->priv.mask.g, - buf->priv.mask.b, - buf->priv.pal->colors, - buf->rot); - else if (buf->rot == 90 || buf->rot == 270) - conv_func = evas_common_convert_func_get(0, - buf->h, - buf->w, - evas_software_xcb_x_output_buffer_depth (xcbob), - buf->priv.mask.r, - buf->priv.mask.g, - buf->priv.mask.b, - buf->priv.pal->colors, - buf->rot); - } - else - { - if (buf->rot == 0 || buf->rot == 180) - conv_func = evas_common_convert_func_get(0, - buf->w, - buf->h, - evas_software_xcb_x_output_buffer_depth(xcbob), - buf->priv.mask.r, - buf->priv.mask.g, - buf->priv.mask.b, - PAL_MODE_NONE, - buf->rot); - else if (buf->rot == 90 || buf->rot == 270) - conv_func = evas_common_convert_func_get(0, - buf->h, - buf->w, - evas_software_xcb_x_output_buffer_depth(xcbob), - buf->priv.mask.r, - buf->priv.mask.g, - buf->priv.mask.b, - PAL_MODE_NONE, - buf->rot); - } - evas_software_xcb_x_output_buffer_free(xcbob, 1); - if (!conv_func) - { - ERR("XCB Engine" - " {" - " At depth %i:" - " RGB format mask: %08x, %08x, %08x" - " Palette mode: %i" - " Not supported by and compiled in converters!" - " }", - buf->priv.x11.xcb.depth, - buf->priv.mask.r, - buf->priv.mask.g, - buf->priv.mask.b, - buf->priv.pal ? buf->priv.pal->colors : -1); - } - } - evas_software_xcb_outbuf_drawable_set(buf, draw); - evas_software_xcb_outbuf_mask_set(buf, mask); - } return buf; } RGBA_Image * -evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, - int x, - int y, - int w, - int h, - int *cx, - int *cy, - int *cw, - int *ch) +evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch) { - RGBA_Image *im; - Outbuf_Region *obr; - int bpl = 0; - int use_shm = 1; - int alpha; + RGBA_Image *im = NULL; + Outbuf_Region *obr = NULL; + Eina_Bool use_shm = EINA_TRUE; + Eina_Bool alpha = EINA_FALSE; + int bpl = 0; - if ((buf->onebuf) && (buf->priv.x11.xcb.shm)) + if ((buf->onebuf) && (buf->priv.x11.xcb.shm)) { - Eina_Rectangle *rect; + Eina_Rectangle *rect; + + if (!(obr = calloc(1, sizeof(Outbuf_Region)))) + return NULL; - RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, buf->w, buf->h); - obr = calloc(1, sizeof(Outbuf_Region)); - if (!obr) return NULL; - rect = eina_rectangle_new(x, y, w, h); - if (!rect) + RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, buf->w, buf->h); + if (!(rect = eina_rectangle_new(x, y, w, h))) { free(obr); return NULL; } - buf->priv.onebuf_regions = eina_list_append(buf->priv.onebuf_regions, rect); - if (buf->priv.onebuf) - { - *cx = x; - *cy = y; - *cw = w; - *ch = h; - if (!buf->priv.synced) - { - /* we sync */ - free(xcb_get_input_focus_reply(buf->priv.x11.xcb.conn, xcb_get_input_focus_unchecked(buf->priv.x11.xcb.conn), NULL)); - buf->priv.synced = 1; - } - return buf->priv.onebuf; - } - obr->x = 0; - obr->y = 0; - obr->w = buf->w; - obr->h = buf->h; - *cx = x; - *cy = y; - *cw = w; - *ch = h; - + buf->priv.onebuf_regions = + eina_list_append(buf->priv.onebuf_regions, rect); + if (buf->priv.onebuf) + { + if (cx) *cx = x; + if (cy) *cy = y; + if (cw) *cw = w; + if (ch) *ch = h; + if (!buf->priv.synced) + { + _xcbob_sync(buf->priv.x11.xcb.conn); + buf->priv.synced = EINA_TRUE; + } + eina_rectangle_free(rect); + return buf->priv.onebuf; + } + obr->x = 0; + obr->y = 0; + obr->w = buf->w; + obr->h = buf->h; + if (cx) *cx = x; + if (cy) *cy = y; + if (cw) *cw = w; + if (ch) *ch = h; alpha = ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha)); - - use_shm = buf->priv.x11.xcb.shm; - if ((buf->rot == 0) && - (buf->priv.mask.r == 0xff0000) && - (buf->priv.mask.g == 0x00ff00) && - (buf->priv.mask.b == 0x0000ff)) - { - obr->xcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x11.xcb.conn, - buf->priv.x11.xcb.depth, - buf->w, buf->h, - use_shm, - NULL); - if (!obr->xcbob) + use_shm = buf->priv.x11.xcb.shm; + if ((buf->rot == 0) && (buf->priv.mask.r == 0xff0000) && + (buf->priv.mask.g == 0x00ff00) && (buf->priv.mask.b == 0x0000ff)) + { + obr->xcbob = + evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, + buf->priv.x11.xcb.visual, + buf->priv.x11.xcb.depth, + buf->w, buf->h, use_shm, + NULL); + if (!obr->xcbob) { + eina_rectangle_free(rect); free(obr); return NULL; } - im = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(), - buf->w, buf->h, - (DATA32 *)evas_software_xcb_x_output_buffer_data(obr->xcbob, &bpl), - alpha, EVAS_COLORSPACE_ARGB8888); - if (!im) + im = + (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), + buf->w, buf->h, + (DATA32 *)evas_software_xcb_output_buffer_data(obr->xcbob, &bpl), + alpha, EVAS_COLORSPACE_ARGB8888); + if (!im) { - evas_software_xcb_x_output_buffer_free(obr->xcbob, 0); + evas_software_xcb_output_buffer_free(obr->xcbob, EINA_FALSE); + eina_rectangle_free(rect); free(obr); return NULL; } im->extended_info = obr; - if (buf->priv.x11.xcb.mask) - obr->mxcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x11.xcb.conn, - 1, - buf->w, buf->h, - use_shm, - NULL); - } - else - { - im = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get()); - if (!im) + if (buf->priv.x11.xcb.mask) + { + obr->mask = + evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, + buf->priv.x11.xcb.visual, + 1, buf->w, buf->h, + use_shm, NULL); + } + } + else + { + int bw = 0, bh = 0; + + im = + (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get()); + if (!im) { + eina_rectangle_free(rect); free(obr); return NULL; } - im->cache_entry.flags.alpha |= alpha ? 1 : 0; + im->cache_entry.flags.alpha |= (alpha ? 1 : 0); evas_cache_image_surface_alloc(&im->cache_entry, buf->w, buf->h); - im->extended_info = obr; - if ((buf->rot == 0) || (buf->rot == 180)) + im->extended_info = obr; + if ((buf->rot == 0) || (buf->rot == 180)) { - obr->xcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x11.xcb.conn, - buf->priv.x11.xcb.depth, - buf->w, buf->h, - use_shm, - NULL); - if (!obr->xcbob) - { - evas_cache_image_drop(&im->cache_entry); - free(obr); - return NULL; - } - if (buf->priv.x11.xcb.mask) - obr->mxcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x11.xcb.conn, - 1, - buf->w, buf->h, - use_shm, - NULL); + bw = buf->w; + bh = buf->h; } - else if ((buf->rot == 90) || (buf->rot == 270)) + else if ((buf->rot == 90) || (buf->rot == 270)) { - obr->xcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x11.xcb.conn, - buf->priv.x11.xcb.depth, - buf->h, buf->w, - use_shm, - NULL); - if (!obr->xcbob) - { - evas_cache_image_drop(&im->cache_entry); - free(obr); - return NULL; - } - if (buf->priv.x11.xcb.mask) - obr->mxcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x11.xcb.conn, - 1, - buf->h, buf->w, - use_shm, - NULL); + bw = buf->h; + bh = buf->w; } - } - /* FIXME: We should be able to remove this memset, but somewhere in the process - we copy too much to the destination surface and some area are not cleaned before copy. */ - if ((alpha) && (im->image.data)) + obr->xcbob = + evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, + buf->priv.x11.xcb.visual, + buf->priv.x11.xcb.depth, + bw, bh, use_shm, NULL); + if (!obr->xcbob) + { + evas_cache_image_drop(&im->cache_entry); + eina_rectangle_free(rect); + free(obr); + return NULL; + } + if (buf->priv.x11.xcb.mask) + { + obr->mask = + evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, + buf->priv.x11.xcb.visual, + 1, bw, bh, use_shm, + NULL); + } + } + /* FIXME: */ + if ((alpha) && (im->image.data)) { - /* FIXME: faster memset! */ - memset(im->image.data, 0, w * h * sizeof(DATA32)); + /* FIXME: Faster memset */ + memset(im->image.data, 0, (w * h * sizeof(DATA32))); } - - buf->priv.onebuf = im; - return im; + buf->priv.onebuf = im; + return im; } + if (!(obr = calloc(1, sizeof(Outbuf_Region)))) + return NULL; - obr = calloc(1, sizeof(Outbuf_Region)); - if (!obr) return NULL; obr->x = x; obr->y = y; obr->w = w; obr->h = h; - *cx = 0; - *cy = 0; - *cw = w; - *ch = h; + if (cx) *cx = 0; + if (cy) *cy = 0; + if (cw) *cw = w; + if (ch) *ch = h; use_shm = buf->priv.x11.xcb.shm; - /* FIXME: magic - i found if shm regions are smaller than 200x200 its - * faster to use ximages over unix sockets - trial and error - */ -// use_shm = 0; /* 630 -> 1006 fps */ -// if ((w * h) < (200 * 200)) use_shm = 0; /* 630 -> 962 fps */ - alpha = ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha)); - - if ((buf->rot == 0) && - (buf->priv.mask.r == 0xff0000) && - (buf->priv.mask.g == 0x00ff00) && - (buf->priv.mask.b == 0x0000ff)) + if ((buf->rot == 0) && (buf->priv.mask.r == 0xff0000) && + (buf->priv.mask.g == 0x00ff00) && (buf->priv.mask.b == 0x0000ff)) { - obr->xcbob = _find_xcbob(buf->priv.x11.xcb.conn, - buf->priv.x11.xcb.depth, - w, h, - use_shm, - NULL); - if (!obr->xcbob) + obr->xcbob = + _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, + buf->priv.x11.xcb.depth, w, h, use_shm, NULL); + if (!obr->xcbob) { free(obr); return NULL; } - im = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), - w, h, - (DATA32 *) evas_software_xcb_x_output_buffer_data(obr->xcbob, &bpl), - alpha, EVAS_COLORSPACE_ARGB8888); - if (!im) + im = + (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), + w, h, + (DATA32 *)evas_software_xcb_output_buffer_data(obr->xcbob, &bpl), + alpha, EVAS_COLORSPACE_ARGB8888); + if (!im) { - _unfind_xcbob(obr->xcbob, 0); + _unfind_xcbob(obr->xcbob, EINA_FALSE); free(obr); return NULL; } im->extended_info = obr; - if (buf->priv.x11.xcb.mask) - obr->mxcbob = _find_xcbob(buf->priv.x11.xcb.conn, - 1, - w, h, - use_shm, - NULL); + if (buf->priv.x11.xcb.mask) + { + obr->mask = + _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, + 1, w, h, use_shm, NULL); + } } - else + else { - im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get()); - if (!im) + int bw = 0, bh = 0; + + im = + (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get()); + if (!im) { free(obr); return NULL; } - im->cache_entry.flags.alpha |= alpha ? 1 : 0; + im->cache_entry.flags.alpha |= (alpha ? 1 : 0); evas_cache_image_surface_alloc(&im->cache_entry, w, h); - im->extended_info = obr; - if ((buf->rot == 0) || (buf->rot == 180)) + im->extended_info = obr; + if ((buf->rot == 0) || (buf->rot == 180)) { - obr->xcbob = _find_xcbob(buf->priv.x11.xcb.conn, - buf->priv.x11.xcb.depth, - w, h, - use_shm, - NULL); - if (!obr->xcbob) - { - evas_cache_image_drop(&im->cache_entry); - free(obr); - return NULL; - } - if (buf->priv.x11.xcb.mask) - obr->mxcbob = _find_xcbob(buf->priv.x11.xcb.conn, - 1, - w, h, - use_shm, - NULL); + bw = w; + bh = h; } - else if ((buf->rot == 90) || (buf->rot == 270)) + else if ((buf->rot == 90) || (buf->rot == 270)) { - obr->xcbob = _find_xcbob(buf->priv.x11.xcb.conn, - buf->priv.x11.xcb.depth, - h, w, - use_shm, - NULL); - if (!obr->xcbob) - { - evas_cache_image_drop(&im->cache_entry); - free(obr); - return NULL; - } - if (buf->priv.x11.xcb.mask) - obr->mxcbob = _find_xcbob(buf->priv.x11.xcb.conn, - 1, - h, w, - use_shm, - NULL); + bw = h; + bh = w; + } + obr->xcbob = + _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, + buf->priv.x11.xcb.depth, bw, bh, use_shm, NULL); + if (!obr->xcbob) + { + evas_cache_image_drop(&im->cache_entry); + free(obr); + return NULL; + } + if (buf->priv.x11.xcb.mask) + { + obr->mask = + _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, 1, + bw, bh, use_shm, NULL); } } - /* FIXME: We should be able to remove this memset, but somewhere in the process - we copy too much to the destination surface and some area are not cleaned before copy. */ - if (((buf->priv.x11.xlib.mask) || (buf->priv.destination_alpha)) && - (im->image.data)) + /* FIXME: */ + if (((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha)) && + (im->image.data)) { - /* FIXME: faster memset! */ - memset(im->image.data, 0, w * h * sizeof(DATA32)); + /* FIXME: Faster memset */ + memset(im->image.data, 0, (w * h * sizeof(DATA32))); } - buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im); +#ifdef EVAS_FRAME_QUEUING + if (!evas_common_frameq_enabled()) +#endif + buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im); + return im; } -void -evas_software_xcb_outbuf_free_region_for_update(Outbuf *buf __UNUSED__, - RGBA_Image *update __UNUSED__) +void +evas_software_xcb_outbuf_free_region_for_update(Outbuf *buf __UNUSED__, RGBA_Image *update __UNUSED__) { - /* no need to do anything - they are cleaned up on flush */ + /* NOOP: Cleaned up on flush */ } -void -evas_software_xcb_outbuf_flush(Outbuf *buf) +void +evas_software_xcb_outbuf_flush(Outbuf *buf) { - Eina_List *l; - RGBA_Image *im; - Outbuf_Region *obr; + Eina_List *l = NULL; + RGBA_Image *im = NULL; + Outbuf_Region *obr = NULL; - - if ((buf->priv.onebuf) && (buf->priv.onebuf_regions)) + if ((buf->priv.onebuf) && (buf->priv.onebuf_regions)) { - pixman_region16_t tmpr; + pixman_region16_t tmpr; - im = buf->priv.onebuf; - obr = im->extended_info; + im = buf->priv.onebuf; + obr = im->extended_info; pixman_region_init(&tmpr); - while (buf->priv.onebuf_regions) - { - Eina_Rectangle *rect; - - rect = buf->priv.onebuf_regions->data; - buf->priv.onebuf_regions = eina_list_remove_list(buf->priv.onebuf_regions, buf->priv.onebuf_regions); - pixman_region_union_rect(&tmpr, &tmpr, - rect->x, rect->y, + while (buf->priv.onebuf_regions) + { + Eina_Rectangle *rect; + + rect = buf->priv.onebuf_regions->data; + buf->priv.onebuf_regions = + eina_list_remove_list(buf->priv.onebuf_regions, + buf->priv.onebuf_regions); + pixman_region_union_rect(&tmpr, &tmpr, rect->x, rect->y, rect->w, rect->h); - if (buf->priv.debug) - evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win, - rect->x, rect->y, rect->w, rect->h); - eina_rectangle_free(rect); - } - xcb_set_clip_rectangles(buf->priv.x11.xcb.conn, XCB_CLIP_ORDERING_YX_BANDED, - buf->priv.x11.xcb.gc, - 0, 0, pixman_region_n_rects(&tmpr), + if (buf->priv.debug) + evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win, + rect->x, rect->y, rect->w, + rect->h); + eina_rectangle_free(rect); + } + xcb_set_clip_rectangles(buf->priv.x11.xcb.conn, + XCB_CLIP_ORDERING_YX_BANDED, + buf->priv.x11.xcb.gc, 0, 0, + pixman_region_n_rects(&tmpr), (const xcb_rectangle_t *)pixman_region_rectangles(&tmpr, NULL)); if (obr->xcbob) - evas_software_xcb_x_output_buffer_paste(obr->xcbob, buf->priv.x11.xcb.win, - buf->priv.x11.xcb.gc, - 0, 0, 0); - if (obr->mxcbob) - { - xcb_set_clip_rectangles(buf->priv.x11.xcb.conn, XCB_CLIP_ORDERING_YX_BANDED, - buf->priv.x11.xcb.gcm, - 0, 0, pixman_region_n_rects(&tmpr), + evas_software_xcb_output_buffer_paste(obr->xcbob, + buf->priv.x11.xcb.win, + buf->priv.x11.xcb.gc, 0, 0, 0); + if (obr->mask) + { + xcb_set_clip_rectangles(buf->priv.x11.xcb.conn, + XCB_CLIP_ORDERING_YX_BANDED, + buf->priv.x11.xcb.gcm, 0, 0, + pixman_region_n_rects(&tmpr), (const xcb_rectangle_t *)pixman_region_rectangles(&tmpr, NULL)); - evas_software_xcb_x_output_buffer_paste(obr->mxcbob, - buf->priv.x11.xcb.mask, - buf->priv.x11.xcb.gcm, - 0, 0, 0); - } - buf->priv.synced = 0; + evas_software_xcb_output_buffer_paste(obr->mask, + buf->priv.x11.xcb.mask, + buf->priv.x11.xcb.gcm, + 0, 0, 0); + } + pixman_region_fini(&tmpr); + buf->priv.synced = EINA_FALSE; } - else + else { #if 1 - /* we sync */ - free(xcb_get_input_focus_reply(buf->priv.x11.xcb.conn, xcb_get_input_focus_unchecked(buf->priv.x11.xcb.conn), NULL)); - EINA_LIST_FOREACH(buf->priv.pending_writes, l, im) + _xcbob_sync(buf->priv.x11.xcb.conn); + EINA_LIST_FOREACH(buf->priv.pending_writes, l, im) { obr = im->extended_info; if (buf->priv.debug) - evas_software_xcb_outbuf_debug_show(buf, - buf->priv.x11.xcb.win, - obr->x, - obr->y, - obr->w, - obr->h); + evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win, + obr->x, obr->y, obr->w, obr->h); if (obr->xcbob) - evas_software_xcb_x_output_buffer_paste(obr->xcbob, - buf->priv.x11.xcb.win, - buf->priv.x11.xcb.gc, - obr->x, - obr->y, 0); - if (obr->mxcbob) - evas_software_xcb_x_output_buffer_paste(obr->mxcbob, - buf->priv.x11.xcb.mask, - buf->priv.x11.xcb.gcm, - obr->x, - obr->y, 0); + evas_software_xcb_output_buffer_paste(obr->xcbob, + buf->priv.x11.xcb.win, + buf->priv.x11.xcb.gc, + obr->x, obr->y, 0); + if (obr->mask) + evas_software_xcb_output_buffer_paste(obr->mask, + buf->priv.x11.xcb.mask, + buf->priv.x11.xcb.gcm, + obr->x, obr->y, 0); } - while (buf->priv.pending_writes) +# ifdef EVAS_FRAME_QUEUING + LKL(buf->priv.lock); +# endif + while (buf->priv.prev_pending_writes) { - im = buf->priv.pending_writes->data; - buf->priv.pending_writes = eina_list_remove_list(buf->priv.pending_writes, - buf->priv.pending_writes); + im = buf->priv.prev_pending_writes->data; + buf->priv.prev_pending_writes = + eina_list_remove_list(buf->priv.prev_pending_writes, + buf->priv.prev_pending_writes); obr = im->extended_info; - evas_cache_image_drop(&im->cache_entry); - if (obr->xcbob) _unfind_xcbob(obr->xcbob, 0); - if (obr->mxcbob) _unfind_xcbob(obr->mxcbob, 0); + evas_cache_image_drop(&im->cache_entry); + if (obr->xcbob) _unfind_xcbob(obr->xcbob, EINA_FALSE); + if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE); free(obr); } - buf->priv.prev_pending_writes = buf->priv.pending_writes; - buf->priv.pending_writes = NULL; - xcb_flush(buf->priv.x11.xcb.conn); + buf->priv.prev_pending_writes = buf->priv.pending_writes; +# ifdef EVAS_FRAME_QUEUING + LKU(buf->priv.lock); +# endif + buf->priv.pending_writes = NULL; + xcb_flush(buf->priv.x11.xcb.conn); #else - /* XX async push - disable */ - /* - EINA_LIST_FOREACH(buf->priv.pending_writes, l, im) - { - obr = im->extended_info; - if (buf->priv.debug) - evas_software_x11_outbuf_debug_show(buf, buf->priv.x11.xcb.win, - obr->x, obr->y, obr->w, obr->h); - evas_software_x11_x_output_buffer_paste(obr->xcbob, buf->priv.x11.xcb.win, - buf->priv.x11.xcb.gc, - obr->x, obr->y, 0); - if (obr->mxcbob) - evas_software_x11_x_output_buffer_paste(obr->mxcbob, - buf->priv.x11.xcb.mask, - buf->priv.x11.xcb.gcm, - obr->x, obr->y, 0); - } - */ - /* we sync */ - free(xcb_get_input_focus_reply(buf->priv.x11.xcb.conn, xcb_get_input_focus_unchecked(buf->priv.x11.xcb.conn), NULL)); - - while (buf->priv.pending_writes) - { - im = eina_list_data_get(buf->priv.pending_writes); - buf->priv.pending_writes = eina_list_remove_list(buf->priv.pending_writes, buf->priv.pending_writes); - obr = im->extended_info; - evas_cache_image_drop(&im->cache_entry); - if (obr->xcbob) _unfind_xcbob(obr->xcbob, 0); - if (obr->mxcbob) _unfind_xcbob(obr->mxcbob, 0); - free(obr); - evas_cache_image_drop(&im->cache_entry); - } + /* FIXME: Async Push Disabled */ + _xcbob_sync(buf->priv.x11.xcb.conn); + while (buf->priv.pending_writes) + { + im = eina_list_data_get(buf->priv.pending_writes); + buf->priv.pending_writes = + eina_list_remove_list(buf->priv.pending_writes, + buf->priv.pending_writes); + obr = im->extended_info; + evas_cache_image_drop(&im->cache_entry); + if (obr->xcbob) _unfind_xcbob(obr->xcbob, EINA_FALSE); + if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE); + free(obr); + evas_cache_image_drop(&im->cache_entry); + } #endif } evas_common_cpu_end_opt(); } -void -evas_software_xcb_outbuf_idle_flush(Outbuf *buf) +void +evas_software_xcb_outbuf_idle_flush(Outbuf *buf) { - if (buf->priv.onebuf) + if (buf->priv.onebuf) { RGBA_Image *im; - Outbuf_Region *obr; - - im = buf->priv.onebuf; - buf->priv.onebuf = NULL; - obr = im->extended_info; - if (obr->xcbob) evas_software_xcb_x_output_buffer_free(obr->xcbob, 0); - if (obr->mxcbob) evas_software_xcb_x_output_buffer_free(obr->mxcbob, 0); - free(obr); - evas_cache_image_drop(&im->cache_entry); + Outbuf_Region *obr; + + im = buf->priv.onebuf; + buf->priv.onebuf = NULL; + obr = im->extended_info; + if (obr->xcbob) + evas_software_xcb_output_buffer_free(obr->xcbob, EINA_FALSE); + if (obr->mask) + evas_software_xcb_output_buffer_free(obr->mask, EINA_FALSE); + free(obr); + evas_cache_image_drop(&im->cache_entry); } - else + else { - if (buf->priv.prev_pending_writes) - free(xcb_get_input_focus_reply(buf->priv.x11.xcb.conn, xcb_get_input_focus_unchecked(buf->priv.x11.xcb.conn), NULL)); - while (buf->priv.prev_pending_writes) - { - RGBA_Image *im; - Outbuf_Region *obr; - - im = buf->priv.prev_pending_writes->data; - buf->priv.prev_pending_writes = - eina_list_remove_list(buf->priv.prev_pending_writes, - buf->priv.prev_pending_writes); - obr = im->extended_info; - evas_cache_image_drop(&im->cache_entry); - if (obr->xcbob) _unfind_xcbob(obr->xcbob, 0); - if (obr->mxcbob) _unfind_xcbob(obr->mxcbob, 0); - free(obr); - } - _clear_xcbob(0); +#ifdef EVAS_FRAME_QUEUING + LKL(buf->priv.lock); +#endif + if (buf->priv.prev_pending_writes) + _xcbob_sync(buf->priv.x11.xcb.conn); + while (buf->priv.prev_pending_writes) + { + RGBA_Image *im; + Outbuf_Region *obr; + + im = buf->priv.prev_pending_writes->data; + buf->priv.prev_pending_writes = + eina_list_remove_list(buf->priv.prev_pending_writes, + buf->priv.prev_pending_writes); + obr = im->extended_info; + evas_cache_image_drop(&im->cache_entry); + if (obr->xcbob) _unfind_xcbob(obr->xcbob, EINA_FALSE); + if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE); + free(obr); + } +#ifdef EVAS_FRAME_QUEUING + LKU(buf->priv.lock); +#endif + _clear_xcbob(EINA_FALSE); } } -void -evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, - RGBA_Image *update, - int x, - int y, - int w, - int h) +void +evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, int y, int w, int h) { - Gfx_Func_Convert conv_func = NULL; - Outbuf_Region *obr; - DATA32 *src_data; - void *data; - int bpl = 0; - int yy; + Gfx_Func_Convert func_conv = NULL; + Outbuf_Region *obr = NULL; + DATA32 *src_data = NULL; + void *data = NULL; + int bpl = 0, yy = 0; + int bw = 0, bh = 0; + int bpp = 0; obr = update->extended_info; - if (buf->priv.pal) + if (!obr->xcbob) return; + + if (obr->xcbob->xim) + bpp = obr->xcbob->xim->bpp; + else { - if ((buf->rot == 0) || (buf->rot == 180)) - conv_func = evas_common_convert_func_get(0, w, h, - evas_software_xcb_x_output_buffer_depth - (obr->xcbob), buf->priv.mask.r, - buf->priv.mask.g, buf->priv.mask.b, - buf->priv.pal->colors, buf->rot); - else if ((buf->rot == 90) || (buf->rot == 270)) - conv_func = evas_common_convert_func_get(0, h, w, - evas_software_xcb_x_output_buffer_depth - (obr->xcbob), buf->priv.mask.r, - buf->priv.mask.g, buf->priv.mask.b, - buf->priv.pal->colors, buf->rot); + const xcb_setup_t *setup; + xcb_format_t *fmt; + + setup = xcb_get_setup(buf->priv.x11.xcb.conn); + fmt = _find_format_by_depth(setup, buf->priv.x11.xcb.depth); + bpp = fmt->bits_per_pixel; } - else + + if ((buf->rot == 0) || (buf->rot == 180)) { - if ((buf->rot == 0) || (buf->rot == 180)) - conv_func = evas_common_convert_func_get(0, w, h, - evas_software_xcb_x_output_buffer_depth - (obr->xcbob), buf->priv.mask.r, - buf->priv.mask.g, buf->priv.mask.b, - PAL_MODE_NONE, buf->rot); - else if ((buf->rot == 90) || (buf->rot == 270)) - conv_func = evas_common_convert_func_get(0, h, w, - evas_software_xcb_x_output_buffer_depth - (obr->xcbob), buf->priv.mask.r, - buf->priv.mask.g, buf->priv.mask.b, - PAL_MODE_NONE, buf->rot); + bw = w; + bh = h; } - if (!conv_func) return; - - if (!obr->xcbob) return; - data = evas_software_xcb_x_output_buffer_data(obr->xcbob, &bpl); - if (!data) return; - src_data = update->image.data; - if (!src_data) return; - if (buf->rot == 0) + else if ((buf->rot == 90) || (buf->rot == 270)) { - obr->x = x; - obr->y = y; + bw = h; + bh = w; } - else if (buf->rot == 90) + if (buf->priv.pal) { - obr->x = y; - obr->y = buf->w - x - w; + func_conv = + evas_common_convert_func_get(0, bw, bh, bpp, buf->priv.mask.r, + buf->priv.mask.g, buf->priv.mask.b, + buf->priv.pal->colors, buf->rot); } - else if (buf->rot == 180) + else { - obr->x = buf->w - x - w; - obr->y = buf->h - y - h; + func_conv = + evas_common_convert_func_get(0, bw, bh, bpp, buf->priv.mask.r, + buf->priv.mask.g, buf->priv.mask.b, + PAL_MODE_NONE, buf->rot); } - else if (buf->rot == 270) + if (!func_conv) return; + if (!(data = evas_software_xcb_output_buffer_data(obr->xcbob, &bpl))) + return; + if (!(src_data = update->image.data)) return; + if (buf->rot == 0) { - obr->x = buf->h - y - h; - obr->y = x; + obr->x = x; + obr->y = y; + obr->w = w; + obr->h = h; } - if ((buf->rot == 0) || (buf->rot == 180)) + else if (buf->rot == 90) { - obr->w = w; - obr->h = h; + obr->x = y; + obr->y = (buf->w - x - w); + obr->w = h; + obr->h = w; } - else if ((buf->rot == 90) || (buf->rot == 270)) + else if (buf->rot == 180) { - obr->w = h; - obr->h = w; + obr->x = (buf->w - x - w); + obr->y = (buf->h - y - h); + obr->w = w; + obr->h = h; } - if (buf->priv.pal) + else if (buf->rot == 270) { - if (data != src_data) - conv_func(src_data, data, - 0, - bpl / - ((evas_software_xcb_x_output_buffer_depth(obr->xcbob) / 8)) - obr->w, - obr->w, obr->h, x, y, - buf->priv.pal->lookup); + obr->x = (buf->h - y - h); + obr->y = x; + obr->w = h; + obr->h = w; } - else + if (data != src_data) { - if (data != src_data) - conv_func(src_data, data, - 0, - bpl / - ((evas_software_xcb_x_output_buffer_depth(obr->xcbob) / 8)) - obr->w, + if (buf->priv.pal) + func_conv(src_data, data, 0, (bpl / (bpp / 8)) - obr->w, + obr->w, obr->h, x, y, buf->priv.pal->lookup); + else + func_conv(src_data, data, 0, (bpl / (bpp / 8)) - obr->w, obr->w, obr->h, x, y, NULL); } #if 1 #else - /* XX async push */ - if (!((buf->priv.onebuf) && (buf->priv.onebuf_regions))) - { - if (buf->priv.debug) - evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win, - obr->x, obr->y, obr->w, obr->h); - if (obr->xcbob) - evas_software_xcb_x_output_buffer_paste(obr->xcbob, buf->priv.x11.xcb.win, - buf->priv.x11.xcb.gc, - obr->x, obr->y, 0); - } + /* FIXME: Add async push code */ #endif - if (obr->mxcbob) + if (obr->mask) { - if (buf->rot == 0) + if (buf->rot == 0) { for (yy = 0; yy < obr->h; yy++) - evas_software_xcb_x_write_mask_line(buf, obr->mxcbob, - src_data + (yy * obr->w), - obr->w, - yy); + evas_software_xcb_write_mask_line(buf, obr->mask, + src_data + (yy * obr->w), + obr->w, yy); } - else if (buf->rot == 90) + else if (buf->rot == 90) { for (yy = 0; yy < obr->h; yy++) - evas_software_xcb_x_write_mask_line_vert(buf, obr->mxcbob, - src_data + yy, - h, // h - obr->h - yy - 1, // ym - w); // w + evas_software_xcb_write_mask_line_vert(buf, obr->mask, + src_data + yy, + h, (obr->h - yy - 1), w); } - else if (buf->rot == 180) + else if (buf->rot == 180) { for (yy = 0; yy < obr->h; yy++) - { - evas_software_xcb_x_write_mask_line_rev(buf, obr->mxcbob, - src_data + (yy * obr->w), - obr->w, - obr->h - yy - 1); - } + evas_software_xcb_write_mask_line_rev(buf, obr->mask, + src_data + (yy * obr->w), + obr->w, (obr->h - yy - 1)); } - else if (buf->rot == 270) + else if (buf->rot == 270) { for (yy = 0; yy < obr->h; yy++) - evas_software_xcb_x_write_mask_line_vert_rev(buf, obr->mxcbob, - src_data + yy, - h, // h - yy, // ym - w); // w + evas_software_xcb_write_mask_line_vert_rev(buf, obr->mask, + src_data + yy, + h, yy, w); } #if 1 #else - /* XX async push */ - if (!((buf->priv.onebuf) && (buf->priv.onebuf_regions))) - evas_software_xcb_x_output_buffer_paste(obr->mxcbob, - buf->priv.x11.xcb.mask, - buf->priv.x11.xcb.gcm, - obr->x, obr->y, 0); + /* FIXME: Add Async Push */ #endif } #if 1 @@ -998,16 +788,10 @@ evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, #endif } -void -evas_software_xcb_outbuf_reconfigure(Outbuf *buf, - int w, - int h, - int rot, - Outbuf_Depth depth) +void +evas_software_xcb_outbuf_reconfigure(Outbuf *buf, int w, int h, int rot, Outbuf_Depth depth) { - if ((w == buf->w) && - (h == buf->h) && - (rot == buf->rot) && + if ((w == buf->w) && (h == buf->h) && (rot == buf->rot) && (depth == buf->depth)) return; buf->w = w; buf->h = h; @@ -1015,130 +799,273 @@ evas_software_xcb_outbuf_reconfigure(Outbuf *buf, evas_software_xcb_outbuf_idle_flush(buf); } -int -evas_software_xcb_outbuf_get_width(Outbuf * buf) +int +evas_software_xcb_outbuf_width_get(Outbuf *buf) { return buf->w; } -int -evas_software_xcb_outbuf_get_height(Outbuf * buf) +int +evas_software_xcb_outbuf_height_get(Outbuf *buf) { return buf->h; } -Outbuf_Depth -evas_software_xcb_outbuf_get_depth(Outbuf * buf) +Outbuf_Depth +evas_software_xcb_outbuf_depth_get(Outbuf *buf) { return buf->depth; } -int -evas_software_xcb_outbuf_get_rot(Outbuf * buf) -{ - return buf->rot; -} - -void -evas_software_xcb_outbuf_drawable_set(Outbuf *buf, - xcb_drawable_t draw) +void +evas_software_xcb_outbuf_drawable_set(Outbuf *buf, xcb_drawable_t drawable) { - if (buf->priv.x11.xcb.win == draw) return; - if (buf->priv.x11.xcb.gc) + if (buf->priv.x11.xcb.win == drawable) return; + if (buf->priv.x11.xcb.gc) { - xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc); - buf->priv.x11.xcb.gc = 0; + xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc); + buf->priv.x11.xcb.gc = 0; } - buf->priv.x11.xcb.win = draw; + buf->priv.x11.xcb.win = drawable; buf->priv.x11.xcb.gc = xcb_generate_id(buf->priv.x11.xcb.conn); - xcb_create_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc, buf->priv.x11.xcb.win, 0, NULL); + xcb_create_gc(buf->priv.x11.xcb.conn, + buf->priv.x11.xcb.gc, buf->priv.x11.xcb.win, 0, NULL); } -void -evas_software_xcb_outbuf_mask_set(Outbuf *buf, - xcb_drawable_t mask) +void +evas_software_xcb_outbuf_mask_set(Outbuf *buf, xcb_drawable_t mask) { if (buf->priv.x11.xcb.mask == mask) return; - if (buf->priv.x11.xcb.gcm) + if (buf->priv.x11.xcb.gcm) { - xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gcm); - buf->priv.x11.xcb.gcm = 0; + xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gcm); + buf->priv.x11.xcb.gcm = 0; } buf->priv.x11.xcb.mask = mask; - if (buf->priv.x11.xcb.mask) + if (buf->priv.x11.xcb.mask) { buf->priv.x11.xcb.gcm = xcb_generate_id(buf->priv.x11.xcb.conn); - xcb_create_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gcm, buf->priv.x11.xcb.win, 0, NULL); + xcb_create_gc(buf->priv.x11.xcb.conn, + buf->priv.x11.xcb.gcm, buf->priv.x11.xcb.win, 0, NULL); } } -void -evas_software_xcb_outbuf_debug_set(Outbuf *buf, - int debug) +int +evas_software_xcb_outbuf_rotation_get(Outbuf *buf) +{ + return buf->rot; +} + +void +evas_software_xcb_outbuf_rotation_set(Outbuf *buf, int rotation) +{ + buf->rot = rotation; +} + +Eina_Bool +evas_software_xcb_outbuf_alpha_get(Outbuf *buf) +{ + return buf->priv.x11.xcb.mask; +} + +void +evas_software_xcb_outbuf_debug_set(Outbuf *buf, Eina_Bool debug) { buf->priv.debug = debug; } -void -evas_software_xcb_outbuf_debug_show(Outbuf *buf, - xcb_drawable_t draw, - int x, - int y, - int w, - int h) + +void +evas_software_xcb_outbuf_debug_show(Outbuf *buf, xcb_drawable_t drawable, int x, int y, int w, int h) { - int i; - xcb_screen_t *screen = NULL; - - { - xcb_get_geometry_reply_t *geom; - xcb_drawable_t root; - xcb_screen_iterator_t i; - - geom = xcb_get_geometry_reply (buf->priv.x11.xcb.conn, xcb_get_geometry_unchecked(buf->priv.x11.xcb.conn, draw), 0); - root = geom->root; - free (geom); - geom = xcb_get_geometry_reply (buf->priv.x11.xcb.conn, xcb_get_geometry_unchecked(buf->priv.x11.xcb.conn, root), 0); - - i = xcb_setup_roots_iterator((xcb_setup_t *)xcb_get_setup(buf->priv.x11.xcb.conn)); - for (; i.rem; xcb_screen_next(&i)) - { - if (i.data->root == geom->root) - { - screen = i.data; - break; - } - } - free (geom); - } + int i; + xcb_screen_t *screen = NULL; + xcb_get_geometry_reply_t *geom; + xcb_drawable_t root; + xcb_screen_iterator_t si; + + geom = + xcb_get_geometry_reply(buf->priv.x11.xcb.conn, + xcb_get_geometry_unchecked(buf->priv.x11.xcb.conn, + drawable), 0); + root = geom->root; + free (geom); + geom = + xcb_get_geometry_reply(buf->priv.x11.xcb.conn, + xcb_get_geometry_unchecked(buf->priv.x11.xcb.conn, + root), 0); + + si = xcb_setup_roots_iterator((xcb_setup_t *)xcb_get_setup(buf->priv.x11.xcb.conn)); + for (; si.rem; xcb_screen_next(&si)) + { + if (si.data->root == geom->root) + { + screen = si.data; + break; + } + } + free (geom); + for (i = 0; i < 20; i++) { xcb_rectangle_t rect = { x, y, w, h}; - uint32_t mask; - uint32_t value[2]; + uint32_t mask; + uint32_t value[2]; mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES; value[0] = screen->black_pixel; - value[1] = XCB_EXPOSURES_NOT_ALLOWED; /* no graphics exposures allowed */ - xcb_change_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc, mask, value); - xcb_poly_fill_rectangle (buf->priv.x11.xcb.conn, draw, buf->priv.x11.xcb.gc, 1, &rect); - /* we sync */ - free(xcb_get_input_focus_reply(buf->priv.x11.xcb.conn, xcb_get_input_focus_unchecked(buf->priv.x11.xcb.conn), NULL)); - /* we sync */ - free(xcb_get_input_focus_reply(buf->priv.x11.xcb.conn, xcb_get_input_focus_unchecked(buf->priv.x11.xcb.conn), NULL)); + value[1] = XCB_EXPOSURES_NOT_ALLOWED; + xcb_change_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc, + mask, value); + xcb_poly_fill_rectangle(buf->priv.x11.xcb.conn, drawable, + buf->priv.x11.xcb.gc, 1, &rect); + _xcbob_sync(buf->priv.x11.xcb.conn); + mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES; value[0] = screen->white_pixel; - value[1] = XCB_EXPOSURES_NOT_ALLOWED; /* no graphics exposures allowed */ - xcb_change_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc, mask, value); - xcb_poly_fill_rectangle (buf->priv.x11.xcb.conn, draw, buf->priv.x11.xcb.gc, 1, &rect); - /* we sync */ - free(xcb_get_input_focus_reply(buf->priv.x11.xcb.conn, xcb_get_input_focus_unchecked(buf->priv.x11.xcb.conn), NULL)); - /* we sync */ - free(xcb_get_input_focus_reply(buf->priv.x11.xcb.conn, xcb_get_input_focus_unchecked(buf->priv.x11.xcb.conn), NULL)); + value[1] = XCB_EXPOSURES_NOT_ALLOWED; + xcb_change_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc, + mask, value); + xcb_poly_fill_rectangle(buf->priv.x11.xcb.conn, drawable, + buf->priv.x11.xcb.gc, 1, &rect); + _xcbob_sync(buf->priv.x11.xcb.conn); } } -Eina_Bool -evas_software_xcb_outbuf_alpha_get (Outbuf *buf) +# ifdef EVAS_FRAME_QUEUING +void +evas_software_xcb_outbuf_priv_set(Outbuf *buf, void *cur, void *prev __UNUSED__) { - return buf->priv.x11.xcb.mask; + buf->priv.pending_writes = (Eina_List *)cur; +} +# endif + +/* local functions */ +static Xcb_Output_Buffer * +_find_xcbob(xcb_connection_t *conn, xcb_visualtype_t *vis, int depth, int w, int h, Eina_Bool shm, void *data) +{ + Eina_List *l = NULL, *xl = NULL; + Xcb_Output_Buffer *xcbob = NULL, *xcbob2 = NULL; + int lbytes = 0, bpp = 0, sz = 0; + int fitness = 0x7fffffff; + + if (!shm) + return evas_software_xcb_output_buffer_new(conn, vis, depth, w, h, + shm, data); + + lbytes = (((w + 31) / 32) * 4); + if (depth > 1) + { + bpp = (depth / 8); + if (bpp == 3) bpp = 4; + lbytes = ((((w * bpp) + 3) / 4) * 4); + } + + sz = (lbytes * h); + SHMPOOL_LOCK(); + EINA_LIST_FOREACH(_shmpool, l, xcbob2) + { + int szdif = 0; + + if ((xcbob2->xim->depth != depth) || (xcbob2->visual != vis) || + (xcbob2->connection != conn)) continue; + szdif = (xcbob2->psize - sz); + if (szdif < 0) continue; + if (szdif == 0) + { + xcbob = xcbob2; + xl = l; + goto have_xcbob; + } + if (szdif < fitness) + { + xcbob = xcbob2; + xl = l; + fitness = szdif; + } + } + if ((fitness > (100 * 100)) || (!xcbob)) + { + SHMPOOL_UNLOCK(); + return evas_software_xcb_output_buffer_new(conn, vis, depth, + w, h, shm, data); + } + +have_xcbob: + _shmpool = eina_list_remove_list(_shmpool, xl); + xcbob->w = w; + xcbob->h = h; + xcbob->bpl = lbytes; + xcbob->xim->width = xcbob->w; + xcbob->xim->height = xcbob->h; + xcbob->xim->stride = xcbob->bpl; + _shmsize -= (xcbob->psize * (xcbob->xim->depth / 8)); + SHMPOOL_UNLOCK(); + return xcbob; +} + +static void +_unfind_xcbob(Xcb_Output_Buffer *xcbob, Eina_Bool sync) +{ + if (xcbob->shm_info) + { + SHMPOOL_LOCK(); + _shmpool = eina_list_prepend(_shmpool, xcbob); + _shmsize += xcbob->psize * xcbob->xim->depth / 8; + while ((_shmsize > _shmlimit) || + ((int)eina_list_count(_shmpool) > _shmcountlimit)) + { + Eina_List *xl = NULL; + + if (!(xl = eina_list_last(_shmpool))) + { + _shmsize = 0; + break; + } + xcbob = xl->data; + _shmpool = eina_list_remove_list(_shmpool, xl); + _shmsize -= xcbob->psize * xcbob->xim->depth / 8; + evas_software_xcb_output_buffer_free(xcbob, sync); + } + SHMPOOL_UNLOCK(); + } + else + evas_software_xcb_output_buffer_free(xcbob, sync); +} + +static void +_clear_xcbob(Eina_Bool sync) +{ + SHMPOOL_LOCK(); + while (_shmpool) + { + Xcb_Output_Buffer *xcbob; + + xcbob = _shmpool->data; + _shmpool = eina_list_remove_list(_shmpool, _shmpool); + evas_software_xcb_output_buffer_free(xcbob, sync); + } + _shmsize = 0; + SHMPOOL_UNLOCK(); +} + +static xcb_format_t * +_find_format_by_depth(const xcb_setup_t *setup, uint8_t depth) +{ + xcb_format_t *fmt, *fmt_end; + + fmt = xcb_setup_pixmap_formats(setup); + fmt_end = fmt + xcb_setup_pixmap_formats_length(setup); + + for (; fmt != fmt_end; ++fmt) + if (fmt->depth == depth) + return fmt; + + return 0; +} + +static void +_xcbob_sync(xcb_connection_t *conn) +{ + free(xcb_get_input_focus_reply(conn, + xcb_get_input_focus_unchecked(conn), NULL)); } diff --git a/src/modules/engines/software_x11/evas_xcb_outbuf.h b/src/modules/engines/software_x11/evas_xcb_outbuf.h index 7a4f087..b711848 100644 --- a/src/modules/engines/software_x11/evas_xcb_outbuf.h +++ b/src/modules/engines/software_x11/evas_xcb_outbuf.h @@ -1,89 +1,30 @@ #ifndef EVAS_XCB_OUTBUF_H -#define EVAS_XCB_OUTBUF_H - - -#include "evas_engine.h" - - -void evas_software_xcb_outbuf_init (void); - -void evas_software_xcb_outbuf_free (Outbuf *buf); - -Outbuf *evas_software_xcb_outbuf_setup_x (int w, - int h, - int rot, - Outbuf_Depth depth, - xcb_connection_t *conn, - xcb_screen_t *screen, - xcb_drawable_t draw, - xcb_visualtype_t *vis, - xcb_colormap_t cmap, - int x_depth, - int grayscale, - int max_colors, - xcb_drawable_t mask, - int shape_dither, - int destination_alpha); - - -RGBA_Image *evas_software_xcb_outbuf_new_region_for_update (Outbuf *buf, - int x, - int y, - int w, - int h, - int *cx, - int *cy, - int *cw, - int *ch); - -void evas_software_xcb_outbuf_free_region_for_update (Outbuf *buf, - RGBA_Image *update); - -void evas_software_xcb_outbuf_flush (Outbuf *buf); - -void evas_software_xcb_outbuf_idle_flush (Outbuf *buf); - -void evas_software_xcb_outbuf_push_updated_region (Outbuf *buf, - RGBA_Image *update, - int x, - int y, - int w, - int h); - -void evas_software_xcb_outbuf_reconfigure (Outbuf *buf, - int w, - int h, - int rot, - Outbuf_Depth depth); - -int evas_software_xcb_outbuf_get_width (Outbuf *buf); - -int evas_software_xcb_outbuf_get_height (Outbuf *buf); - -Outbuf_Depth evas_software_xcb_outbuf_get_depth (Outbuf *buf); - -int evas_software_xcb_outbuf_get_rot (Outbuf *buf); - -void evas_software_xcb_outbuf_drawable_set (Outbuf *buf, - xcb_drawable_t draw); - -void evas_software_xcb_outbuf_mask_set (Outbuf *buf, - xcb_drawable_t mask); - -void evas_software_xcb_outbuf_rotation_set (Outbuf *buf, - int rot); - -void evas_software_xcb_outbuf_debug_set (Outbuf *buf, - int debug); - -void evas_software_xcb_outbuf_debug_show (Outbuf *buf, - xcb_drawable_t draw, - int x, - int y, - int w, - int h); - -Eina_Bool evas_software_xcb_outbuf_alpha_get (Outbuf *buf); - +# define EVAS_XCB_OUTBUF_H + +# include "evas_engine.h" + +void evas_software_xcb_outbuf_init(void); +void evas_software_xcb_outbuf_free(Outbuf *buf); +Outbuf *evas_software_xcb_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, xcb_connection_t *conn, xcb_screen_t *screen, xcb_drawable_t draw, xcb_visualtype_t *vis, xcb_colormap_t cmap, int xdepth, Eina_Bool grayscale, int max_colors, xcb_drawable_t mask, Eina_Bool shape_dither, Eina_Bool alpha); +RGBA_Image *evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); +void evas_software_xcb_outbuf_free_region_for_update(Outbuf *buf, RGBA_Image *update); +void evas_software_xcb_outbuf_flush(Outbuf *buf); +void evas_software_xcb_outbuf_idle_flush(Outbuf *buf); +void evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, int y, int w, int h); +void evas_software_xcb_outbuf_reconfigure(Outbuf *buf, int w, int h, int rot, Outbuf_Depth depth); +int evas_software_xcb_outbuf_width_get(Outbuf *buf); +int evas_software_xcb_outbuf_height_get(Outbuf *buf); +Outbuf_Depth evas_software_xcb_outbuf_depth_get(Outbuf *buf); +void evas_software_xcb_outbuf_drawable_set(Outbuf *buf, xcb_drawable_t drawable); +void evas_software_xcb_outbuf_mask_set(Outbuf *buf, xcb_drawable_t mask); +int evas_software_xcb_outbuf_rotation_get(Outbuf *buf); +void evas_software_xcb_outbuf_rotation_set(Outbuf *buf, int rotation); +Eina_Bool evas_software_xcb_outbuf_alpha_get(Outbuf *buf); +void evas_software_xcb_outbuf_debug_set(Outbuf *buf, Eina_Bool debug); +void evas_software_xcb_outbuf_debug_show(Outbuf *buf, xcb_drawable_t drawable, int x, int y, int w, int h); + +# ifdef EVAS_FRAME_QUEUING +void evas_software_xcb_outbuf_priv_set(Outbuf *buf, void *cur, void *prev); +# endif #endif -- 2.7.4