diff --git a/legacy/evas/configure.in b/legacy/evas/configure.in index a9162b9c69..b1be1f84aa 100644 --- a/legacy/evas/configure.in +++ b/legacy/evas/configure.in @@ -347,7 +347,7 @@ AC_MSG_RESULT($want_evas_software_xcb) if test "x$want_evas_software_xcb" = "xyes"; then PKG_CHECK_MODULES( XCB, - xcb xcb-shm xcb-image, + xcb xcb-shm xcb-image pixman-1, [ AC_DEFINE(BUILD_ENGINE_SOFTWARE_XCB, 1, [Software XCB Rendering Backend]) have_evas_software_xcb="yes" diff --git a/legacy/evas/src/modules/engines/software_xcb/Evas_Engine_Software_Xcb.h b/legacy/evas/src/modules/engines/software_xcb/Evas_Engine_Software_Xcb.h index 1a05abca2c..5c53471e90 100644 --- a/legacy/evas/src/modules/engines/software_xcb/Evas_Engine_Software_Xcb.h +++ b/legacy/evas/src/modules/engines/software_xcb/Evas_Engine_Software_Xcb.h @@ -31,32 +31,10 @@ struct _Evas_Engine_Info_Software_Xcb int alloc_colors_max; } info; /* engine specific function calls to query stuff about the destination */ - /* engine (what visual & colormap & depth to use, performance info etc. */ struct { xcb_visualtype_t * (*best_visual_get) (xcb_connection_t *conn, int screen); xcb_colormap_t (*best_colormap_get) (xcb_connection_t *conn, int screen); int (*best_depth_get) (xcb_connection_t *conn, int screen); - - Evas_Performance *(*performance_test) (Evas *e, - xcb_connection_t *conn, - xcb_screen_t *screen, - xcb_visualtype_t *vis, - xcb_colormap_t cmap, - xcb_drawable_t draw, - int depth); - void (*performance_free) (Evas_Performance *perf); - char * (*performance_data_get) (Evas_Performance *perf); - char * (*performance_key_get) (Evas_Performance *perf); - Evas_Performance *(*performance_new) (Evas *e, - xcb_connection_t *conn, - xcb_screen_t *screen, - xcb_visualtype_t *vis, - xcb_colormap_t cmap, - xcb_drawable_t draw, - int depth); - void (*performance_build) (Evas_Performance *perf, - const char *data); - void (*performance_device_store) (Evas_Performance *perf); } func; int mask_changed; diff --git a/legacy/evas/src/modules/engines/software_xcb/evas_engine.c b/legacy/evas/src/modules/engines/software_xcb/evas_engine.c index 12bf5eb784..00a46e2f72 100644 --- a/legacy/evas/src/modules/engines/software_xcb/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_xcb/evas_engine.c @@ -24,13 +24,6 @@ static void *_output_setup(int w, int h, int rot, xcb_connection_t *conn, xcb_sc static xcb_visualtype_t *_best_visual_get(xcb_connection_t *conn, int screen); static xcb_colormap_t _best_colormap_get(xcb_connection_t *conn, int screen); static int _best_depth_get(xcb_connection_t *conn, int screen); -static Evas_Performance *_output_perf_new(Evas *e, xcb_connection_t *conn, xcb_screen_t *screen, xcb_visualtype_t *vis, xcb_colormap_t cmap, xcb_drawable_t draw, int depth); -static Evas_Performance *_output_perf_test(Evas *e, xcb_connection_t *conn, xcb_screen_t *screen, xcb_visualtype_t *vis, xcb_colormap_t cmap, xcb_drawable_t draw, int depth); -static char *_output_perf_data(Evas_Performance *perf); -static char *_output_perf_key(Evas_Performance *perf); -static void _output_perf_free(Evas_Performance *perf); -static void _output_perf_build(Evas_Performance *perf, const char *data); -static void _output_perf_device_store(Evas_Performance *perf); static void *eng_info(Evas *e); static void eng_info_free(Evas *e, void *info); @@ -64,7 +57,6 @@ _output_setup(int w, int destination_alpha) { Render_Engine *re; - Outbuf_Perf *perf; re = calloc(1, sizeof(Render_Engine)); /* if we haven't initialized - init (automatic abort if already done) */ @@ -86,8 +78,6 @@ _output_setup(int w, evas_software_xcb_x_color_init(); evas_software_xcb_outbuf_init(); - /* get any stored performance metrics from device (xserver) */ - perf = evas_software_xcb_outbuf_perf_restore_x(conn, screen, draw, vis, cmap, depth); re->ob = evas_software_xcb_outbuf_setup_x(w, h, rot, OUTBUF_DEPTH_INHERIT, conn, @@ -96,7 +86,6 @@ _output_setup(int w, vis, cmap, depth, - perf, grayscale, max_colors, mask, @@ -104,10 +93,19 @@ _output_setup(int w, destination_alpha); if (!re->ob) { - evas_software_xcb_outbuf_perf_free(perf); 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 */ + /* 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; + */ + evas_software_xcb_outbuf_debug_set(re->ob, debug); re->tb = evas_common_tilebuf_new(w, h); if (!re->tb) @@ -186,50 +184,6 @@ _best_depth_get(xcb_connection_t *conn, int screen) return 0; } -static Evas_Performance * -_output_perf_new(Evas *e, xcb_connection_t *conn, xcb_screen_t *screen, xcb_visualtype_t *vis, xcb_colormap_t cmap, xcb_drawable_t draw, int depth) -{ - return evas_software_xcb_outbuf_perf_x(conn, screen, draw, vis, cmap, depth); - e = NULL; -} - -static Evas_Performance * -_output_perf_test(Evas *e, xcb_connection_t *conn, xcb_screen_t *screen, xcb_visualtype_t *vis, xcb_colormap_t cmap, xcb_drawable_t draw, int depth) -{ - return evas_software_xcb_outbuf_perf_x(conn, screen, draw, vis, cmap, depth); - e = NULL; -} - -static char * -_output_perf_data(Evas_Performance *perf) -{ - return evas_software_xcb_outbuf_perf_serialize_x(perf); -} - -static char * -_output_perf_key(Evas_Performance *perf) -{ - return evas_software_xcb_outbuf_perf_serialize_info_x(perf); -} - -static void -_output_perf_free(Evas_Performance *perf) -{ - evas_software_xcb_outbuf_perf_free(perf); -} - -static void -_output_perf_build(Evas_Performance *perf, const char *data) -{ - evas_software_xcb_outbuf_perf_deserialize_x(perf, data); -} - -static void -_output_perf_device_store(Evas_Performance *perf) -{ - evas_software_xcb_outbuf_perf_store_x(perf); -} - /* engine api this module provides */ static void * eng_info(Evas *e) @@ -245,13 +199,6 @@ eng_info(Evas *e) info->func.best_visual_get = _best_visual_get; info->func.best_colormap_get = _best_colormap_get; info->func.best_depth_get = _best_depth_get; - info->func.performance_test = _output_perf_test; - info->func.performance_free = _output_perf_free; - info->func.performance_data_get = _output_perf_data; - info->func.performance_key_get = _output_perf_key; - info->func.performance_new = _output_perf_new; - info->func.performance_build = _output_perf_build; - info->func.performance_device_store = _output_perf_device_store; return info; e = NULL; } @@ -291,25 +238,28 @@ eng_setup(Evas *e, void *in) info->info.destination_alpha); else { - re = e->engine.data.output; - 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.conn, - info->info.screen, - info->info.drawable, - info->info.visual, - info->info.colormap, - info->info.depth, - evas_software_xcb_outbuf_perf_restore_x(info->info.conn, 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); + int ponebuf = 0; + + re = e->engine.data.output; + ponebuf = re->ob->onebuf; + 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.conn, + 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); + re->ob->onebuf = ponebuf; } if (!e->engine.data.output) return; @@ -328,6 +278,8 @@ eng_output_free(void *data) { Render_Engine *re; + if (!data) return; + re = (Render_Engine *)data; evas_software_xcb_outbuf_free(re->ob); evas_common_tilebuf_free(re->tb); @@ -454,6 +406,7 @@ eng_output_idle_flush(void *data) Render_Engine *re; re = (Render_Engine *)data; + evas_software_xcb_outbuf_idle_flush(re->ob); } /* module advertising code */ diff --git a/legacy/evas/src/modules/engines/software_xcb/evas_engine.h b/legacy/evas/src/modules/engines/software_xcb/evas_engine.h index 3e36f1e717..4bca8a4ed2 100644 --- a/legacy/evas/src/modules/engines/software_xcb/evas_engine.h +++ b/legacy/evas/src/modules/engines/software_xcb/evas_engine.h @@ -8,7 +8,6 @@ #include typedef struct _Outbuf Outbuf; -typedef struct _Outbuf_Perf Outbuf_Perf; typedef struct _Outbuf_Region Outbuf_Region; typedef struct _Xcb_Output_Buffer Xcb_Output_Buffer; @@ -31,7 +30,7 @@ struct _Outbuf Outbuf_Depth depth; int w, h; int rot; - Outbuf_Perf *perf; + int onebuf; struct { Convert_Pal *pal; @@ -46,53 +45,29 @@ struct _Outbuf int shm; xcb_gcontext_t gc; xcb_gcontext_t gcm; - int swap : 1; + unsigned char swap : 1; unsigned char bit_swap : 1; } x; struct { DATA32 r, g, b; } mask; - /* lets not do back buf for now */ - /* RGBA_Image *back_buf; */ + + /* 1 big buffer for updates - flush on idle_flush */ + RGBA_Image *onebuf; + Evas_List *onebuf_regions; /* a list of pending regions to write to the target */ Evas_List *pending_writes; + /* a list of previous frame pending regions to write to the target */ + Evas_List *prev_pending_writes; - int mask_dither : 1; - int destination_alpha : 1; - - int debug : 1; + unsigned char mask_dither : 1; + unsigned char destination_alpha : 1; + unsigned char debug : 1; + unsigned char synced : 1; } priv; }; -struct _Outbuf_Perf -{ - struct { - xcb_connection_t *conn; - xcb_drawable_t root; - - char *display; - char *vendor; - int version; - int revision; - int release; - int w, h; - int screen_count; - int depth; - int screen_num; - } x; - struct{ - char *name; - char *version; - char *machine; - } os; - struct { - char *info; - } cpu; - - int min_shm_image_pixel_count; -}; - struct _Outbuf_Region { Xcb_Output_Buffer *xcbob, *mxcbob; @@ -105,6 +80,10 @@ struct _Xcb_Output_Buffer xcb_image_t *image; xcb_shm_segment_info_t *shm_info; void *data; + int w; + int h; + int bpl; + int psize; }; @@ -165,51 +144,11 @@ Outbuf *evas_software_xcb_outbuf_setup_x (int xcb_visualtype_t *vis, xcb_colormap_t cmap, int x_depth, - Outbuf_Perf *perf, int grayscale, int max_colors, xcb_drawable_t mask, int shape_dither, int destination_alpha); - -char *evas_software_xcb_outbuf_perf_serialize_x (Outbuf_Perf *perf); -void evas_software_xcb_outbuf_perf_deserialize_x (Outbuf_Perf *perf, - const char *data); -Outbuf_Perf *evas_software_xcb_outbuf_perf_new_x (xcb_connection_t *conn, - xcb_screen_t *screen, - xcb_drawable_t draw, - xcb_visualtype_t *vis, - xcb_colormap_t cmap, - int x_depth); - -char *evas_software_xcb_outbuf_perf_serialize_info_x (Outbuf_Perf *perf); -void evas_software_xcb_outbuf_perf_store_x (Outbuf_Perf *perf); -Outbuf_Perf *evas_software_xcb_outbuf_perf_restore_x (xcb_connection_t *conn, - xcb_screen_t *screen, - xcb_drawable_t draw, - xcb_visualtype_t *vis, - xcb_colormap_t cmap, - int x_depth); -void evas_software_xcb_outbuf_perf_free (Outbuf_Perf *perf); -Outbuf_Perf *evas_software_xcb_outbuf_perf_x (xcb_connection_t *conn, - xcb_screen_t *screen, - xcb_drawable_t draw, - xcb_visualtype_t *vis, - xcb_colormap_t cmap, - int x_depth); - -void evas_software_xcb_outbuf_blit (Outbuf *buf, - int src_x, - int src_y, - int w, - int h, - int dst_x, - int dst_y); -void evas_software_xcb_outbuf_update (Outbuf *buf, - int x, - int y, - int w, - int h); RGBA_Image *evas_software_xcb_outbuf_new_region_for_update (Outbuf *buf, int x, int y, @@ -222,6 +161,7 @@ RGBA_Image *evas_software_xcb_outbuf_new_region_for_update (Outbuf *buf, 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, @@ -237,8 +177,6 @@ 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); -int evas_software_xcb_outbuf_get_have_backbuf (Outbuf *buf); -void evas_software_xcb_outbuf_set_have_backbuf (Outbuf *buf, int have_backbuf); 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); diff --git a/legacy/evas/src/modules/engines/software_xcb/evas_outbuf.c b/legacy/evas/src/modules/engines/software_xcb/evas_outbuf.c index cefe5889e5..79cfe7c24e 100644 --- a/legacy/evas/src/modules/engines/software_xcb/evas_outbuf.c +++ b/legacy/evas/src/modules/engines/software_xcb/evas_outbuf.c @@ -4,9 +4,120 @@ #include #include #include +#include #include #include + +static Evas_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) +{ + Evas_List *l; + Evas_List *xl; + Xcb_Output_Buffer *xcbob = NULL; + int fitness = 0x7fffffff; + int sz; + int lbytes; + int bpp; + +// return evas_software_xcb_x_output_buffer_new(d, v, depth, w, h, shm, data); + 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; + for (l = shmpool; l; l = l->next) + { + Xcb_Output_Buffer *xcbob2; + int szdif; + + xcbob2 = l->data; + 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 = evas_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) +{ +// evas_software_xcb_x_output_buffer_free(xcbob, sync); return; + if (xcbob->shm_info) + { + shmpool = evas_list_prepend(shmpool, xcbob); + shmsize += xcbob->psize * xcbob->image->depth / 8; + while ((shmsize > (shmmemlimit)) || + (evas_list_count(shmpool) > shmcountlimit)) + { + Evas_List *xl; + + xl = evas_list_last(shmpool); + if (!xl) + { + shmsize = 0; + break; + } + xcbob = xl->data; + shmpool = evas_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 = evas_list_remove_list(shmpool, shmpool); + evas_software_xcb_x_output_buffer_free(xcbob, sync); + } + shmsize = 0; +} + void evas_software_xcb_outbuf_init(void) { @@ -15,8 +126,23 @@ evas_software_xcb_outbuf_init(void) void evas_software_xcb_outbuf_free(Outbuf * buf) { + while (buf->priv.pending_writes) + { + RGBA_Image *im; + Outbuf_Region *obr; + + im = buf->priv.pending_writes->data; + buf->priv.pending_writes = evas_list_remove_list(buf->priv.pending_writes, buf->priv.pending_writes); + obr = im->extended_info; + evas_cache_image_drop(im); + if (obr->xcbob) _unfind_xcbob(obr->xcbob, 0); + if (obr->mxcbob) _unfind_xcbob(obr->mxcbob, 0); + free(obr); + } + evas_software_xcb_outbuf_idle_flush(buf); evas_software_xcb_outbuf_flush(buf); - xcb_free_gc(buf->priv.x.conn, buf->priv.x.gc); + if (buf->priv.x.gc) + xcb_free_gc(buf->priv.x.conn, buf->priv.x.gc); if (buf->priv.x.gcm) xcb_free_gc(buf->priv.x.conn, buf->priv.x.gcm); if (buf->priv.pal) @@ -24,8 +150,8 @@ evas_software_xcb_outbuf_free(Outbuf * buf) buf->priv.x.cmap, buf->priv.x.vis, buf->priv.pal); - evas_software_xcb_outbuf_perf_free(buf->perf); free(buf); + _clear_xcbob(0); } void @@ -45,7 +171,6 @@ evas_software_xcb_outbuf_setup_x(int w, xcb_visualtype_t *vis, xcb_colormap_t cmap, int x_depth, - Outbuf_Perf *perf, int grayscale, int max_colors, xcb_drawable_t mask, @@ -115,7 +240,7 @@ evas_software_xcb_outbuf_setup_x(int w, (vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) || (vis->_class == XCB_VISUAL_CLASS_STATIC_COLOR) || (vis->_class == XCB_VISUAL_CLASS_PSEUDO_COLOR) || - (x_depth > 8)) + (x_depth <= 8)) { Convert_Pal_Mode pm = PAL_MODE_RGB332; @@ -235,8 +360,6 @@ evas_software_xcb_outbuf_setup_x(int w, evas_software_xcb_outbuf_mask_set(buf, mask); } - buf->perf = perf; - return buf; } @@ -256,6 +379,113 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int bpl = 0; int use_shm = 1; + if ((buf->onebuf) && (buf->priv.x.shm)) + { + Evas_Rectangle *rect; + + rect = malloc(sizeof(Evas_Rectangle)); + RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, buf->w, buf->h); + rect->x = x; + rect->y = y; + rect->w = w; + rect->h = h; + buf->priv.onebuf_regions = evas_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.x.conn, xcb_get_input_focus_unchecked(buf->priv.x.conn), NULL)); + buf->priv.synced = 1; + } + if ((buf->priv.x.mask) || (buf->priv.destination_alpha)) + { + int yy; + + im = buf->priv.onebuf; + for (yy = y; yy < (y + h); yy++) + { + memset(im->image->data + (im->image->w * yy) + x, + 0, w * sizeof(DATA32)); + } + } + return buf->priv.onebuf; + } + obr = calloc(1, sizeof(Outbuf_Region)); + obr->x = 0; + obr->y = 0; + obr->w = buf->w; + obr->h = buf->h; + *cx = x; + *cy = y; + *cw = w; + *ch = h; + + use_shm = buf->priv.x.shm; + if ((buf->rot == 0) && + (buf->priv.mask.r == 0xff0000) && + (buf->priv.mask.g == 0x00ff00) && + (buf->priv.mask.b == 0x0000ff)) + { + im = evas_cache_image_empty(evas_common_image_cache_get()); + im->image->w = buf->w; + im->image->h = buf->h; + im->image->data = NULL; + im->image->no_free = 1; + im->extended_info = obr; + obr->xcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, + buf->priv.x.depth, + buf->w, buf->h, + use_shm, + NULL); + im->image->data = (DATA32 *) evas_software_xcb_x_output_buffer_data(obr->xcbob, &bpl); + if (buf->priv.x.mask) + obr->mxcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, + 1, + buf->w, buf->h, + use_shm, + NULL); + } + else + { + im = evas_cache_image_empty(evas_common_image_cache_get()); + im->image->w = buf->w; + im->image->h = buf->h; + evas_common_image_surface_alloc(im->image); + im->extended_info = obr; + if ((buf->rot == 0) || (buf->rot == 180)) + obr->xcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, + buf->priv.x.depth, + buf->w, buf->h, + use_shm, + NULL); + else if ((buf->rot == 90) || (buf->rot == 270)) + obr->xcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, + buf->priv.x.depth, + buf->h, buf->w, + use_shm, + NULL); + if (buf->priv.x.mask) + obr->mxcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, + 1, buf->w, buf->h, + use_shm, + NULL); + } + if ((buf->priv.x.mask) || (buf->priv.destination_alpha)) + { + im->flags |= RGBA_IMAGE_HAS_ALPHA; + /* FIXME: faster memset! */ + memset(im->image->data, 0, w * h * sizeof(DATA32)); + } + buf->priv.onebuf = im; + return im; + } + + obr = calloc(1, sizeof(Outbuf_Region)); obr->x = x; obr->y = y; @@ -267,14 +497,11 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, *ch = h; use_shm = buf->priv.x.shm; - if (buf->perf) - { - if ((w * h) < buf->perf->min_shm_image_pixel_count) use_shm = 0; - } - else - { - if ((w * h) < (200 * 200)) use_shm = 0; - } + /* 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 */ if ((buf->rot == 0) && (buf->priv.mask.r == 0xff0000) && @@ -287,20 +514,29 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, im->image->data = NULL; im->image->no_free = 1; im->extended_info = obr; - obr->xcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, - buf->priv.x.depth, - w, - h, - use_shm, - NULL); + obr->xcbob = _find_xcbob(buf->priv.x.conn, + buf->priv.x.depth, + w, h, + use_shm, + NULL); +/* obr->xcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, */ +/* buf->priv.x.depth, */ +/* w, */ +/* h, */ +/* use_shm, */ +/* NULL); */ im->image->data = (DATA32 *)evas_software_xcb_x_output_buffer_data(obr->xcbob, &bpl); if (buf->priv.x.mask) - obr->mxcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, - 1, - w, - h, - use_shm, - NULL); + obr->mxcbob = _find_xcbob(buf->priv.x.conn, + 1, w, h, + use_shm, + NULL); +/* obr->mxcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, */ +/* 1, */ +/* w, */ +/* h, */ +/* use_shm, */ +/* NULL); */ } else { @@ -310,26 +546,40 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, evas_common_image_surface_alloc(im->image); im->extended_info = obr; if ((buf->rot == 0) || (buf->rot == 180)) - obr->xcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, - buf->priv.x.depth, - w, - h, - use_shm, - NULL); + obr->xcbob = _find_xcbob(buf->priv.x.conn, + buf->priv.x.depth, + w, h, + use_shm, + NULL); +/* obr->xcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, */ +/* buf->priv.x.depth, */ +/* w, */ +/* h, */ +/* use_shm, */ +/* NULL); */ else if ((buf->rot == 90) || (buf->rot == 270)) - obr->xcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, - buf->priv.x.depth, - h, - w, - use_shm, - NULL); + obr->xcbob = _find_xcbob(buf->priv.x.conn, + buf->priv.x.depth, + h, w, + use_shm, + NULL); +/* obr->xcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, */ +/* buf->priv.x.depth, */ +/* h, */ +/* w, */ +/* use_shm, */ +/* NULL); */ if (buf->priv.x.mask) - obr->mxcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, - 1, - w, - h, - use_shm, - NULL); + obr->mxcbob = _find_xcbob(buf->priv.x.conn, + 1, w, h, + use_shm, + NULL); +/* obr->mxcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, */ +/* 1, */ +/* w, */ +/* h, */ +/* use_shm, */ +/* NULL); */ } if ((buf->priv.x.mask) || (buf->priv.destination_alpha)) { @@ -352,53 +602,185 @@ void evas_software_xcb_outbuf_flush(Outbuf *buf) { Evas_List *l; - xcb_get_input_focus_reply_t *reply; - for (l = buf->priv.pending_writes; l; l = l->next) + if ((buf->priv.onebuf) && (buf->priv.onebuf_regions)) { RGBA_Image *im; - Outbuf_Region *obr; + Outbuf_Region *obr; + pixman_region16_t tmpr; - im = l->data; + im = buf->priv.onebuf; obr = im->extended_info; - /* paste now */ - if (buf->priv.debug) - evas_software_xcb_outbuf_debug_show(buf, - buf->priv.x.win, - obr->x, - obr->y, - obr->w, - obr->h); - evas_software_xcb_x_output_buffer_paste(obr->xcbob, - buf->priv.x.win, + pixman_region_init(&tmpr); + while (buf->priv.onebuf_regions) + { + Evas_Rectangle *rect; + + rect = buf->priv.onebuf_regions->data; + buf->priv.onebuf_regions = evas_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.x.win, + rect->x, rect->y, rect->w, rect->h); + free(rect); + } + xcb_set_clip_rectangles(buf->priv.x.conn, XCB_CLIP_ORDERING_YX_BANDED, + buf->priv.x.gc, + 0, 0, pixman_region_n_rects(&tmpr), + (const xcb_rectangle_t *)pixman_region_rectangles(&tmpr, NULL)); + evas_software_xcb_x_output_buffer_paste(obr->xcbob, buf->priv.x.win, buf->priv.x.gc, - obr->x, - obr->y, 0); + 0, 0, 0); if (obr->mxcbob) - evas_software_xcb_x_output_buffer_paste(obr->mxcbob, - buf->priv.x.mask, - buf->priv.x.gcm, - obr->x, - obr->y, 0); + { + xcb_set_clip_rectangles(buf->priv.x.conn, XCB_CLIP_ORDERING_YX_BANDED, + buf->priv.x.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.x.mask, + buf->priv.x.gcm, + 0, 0, 0); + } + buf->priv.synced = 0; } - /* we sync */ - reply = xcb_get_input_focus_reply(buf->priv.x.conn, xcb_get_input_focus_unchecked(buf->priv.x.conn), NULL); - free(reply); - while (buf->priv.pending_writes) + else { - RGBA_Image *im; +#if 1 + /* we sync */ + free(xcb_get_input_focus_reply(buf->priv.x.conn, xcb_get_input_focus_unchecked(buf->priv.x.conn), NULL)); + for (l = buf->priv.pending_writes; l; l = l->next) + { + RGBA_Image *im; + Outbuf_Region *obr; + + im = l->data; + obr = im->extended_info; + if (buf->priv.debug) + evas_software_xcb_outbuf_debug_show(buf, + buf->priv.x.win, + obr->x, + obr->y, + obr->w, + obr->h); + evas_software_xcb_x_output_buffer_paste(obr->xcbob, + buf->priv.x.win, + buf->priv.x.gc, + obr->x, + obr->y, 0); + if (obr->mxcbob) + evas_software_xcb_x_output_buffer_paste(obr->mxcbob, + buf->priv.x.mask, + buf->priv.x.gcm, + obr->x, + obr->y, 0); + } + while (buf->priv.pending_writes) + { + RGBA_Image *im; + Outbuf_Region *obr; + + im = buf->priv.pending_writes->data; + buf->priv.pending_writes = evas_list_remove_list(buf->priv.pending_writes, + buf->priv.pending_writes); + obr = im->extended_info; + evas_cache_image_drop(im); + if (obr->xcbob) _unfind_xcbob(obr->xcbob, 0); + if (obr->mxcbob) _unfind_xcbob(obr->mxcbob, 0); +/* 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); + } + buf->priv.prev_pending_writes = buf->priv.pending_writes; + buf->priv.pending_writes = NULL; + xcb_flush(buf->priv.x.conn); +#else + /* XX async push - disable */ + /* + for (l = buf->priv.pending_writes; l; l = l->next) + { + RGBA_Image *im; + Outbuf_Region *obr; + + im = l->data; + obr = im->extended_info; + if (buf->priv.debug) + evas_software_x11_outbuf_debug_show(buf, buf->priv.x.win, + obr->x, obr->y, obr->w, obr->h); + evas_software_x11_x_output_buffer_paste(obr->xob, buf->priv.x.win, + buf->priv.x.gc, + obr->x, obr->y, 0); + if (obr->mxob) + evas_software_x11_x_output_buffer_paste(obr->mxob, + buf->priv.x.mask, + buf->priv.x.gcm, + obr->x, obr->y, 0); + } + */ + /* we sync */ + free(xcb_get_input_focus_reply(buf->priv.x.conn, xcb_get_input_focus_unchecked(buf->priv.x.conn), NULL)); + + while (buf->priv.pending_writes) + { + RGBA_Image *im; + Outbuf_Region *obr; + + im = buf->priv.pending_writes->data; + buf->priv.pending_writes = evas_list_remove_list(buf->priv.pending_writes, buf->priv.pending_writes); + obr = im->extended_info; + evas_cache_image_drop(im); + if (obr->xob) _unfind_xob(obr->xob, 0); + if (obr->mxob) _unfind_xob(obr->mxob, 0); +/* + if (obr->xob) evas_software_x11_x_output_buffer_free(obr->xob, 0); + if (obr->mxob) evas_software_x11_x_output_buffer_free(obr->mxob, 0); + */ + free(obr); + } +#endif + } + evas_common_cpu_end_opt(); +} + +void +evas_software_xcb_outbuf_idle_flush(Outbuf *buf) +{ + if (buf->priv.onebuf) + { + RGBA_Image *im; Outbuf_Region *obr; - im = buf->priv.pending_writes->data; - buf->priv.pending_writes = evas_list_remove_list(buf->priv.pending_writes, - buf->priv.pending_writes); + im = buf->priv.onebuf; + buf->priv.onebuf = NULL; obr = im->extended_info; evas_cache_image_drop(im); 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_common_cpu_end_opt(); + else + { + if (buf->priv.prev_pending_writes) + free(xcb_get_input_focus_reply(buf->priv.x.conn, xcb_get_input_focus_unchecked(buf->priv.x.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 = + evas_list_remove_list(buf->priv.prev_pending_writes, + buf->priv.prev_pending_writes); + obr = im->extended_info; + evas_cache_image_drop(im); + if (obr->xcbob) _unfind_xcbob(obr->xcbob, 0); + if (obr->mxcbob) _unfind_xcbob(obr->mxcbob, 0); + free(obr); + } + _clear_xcbob(0); + } } void @@ -493,48 +875,46 @@ evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, } else { -#if 0 - DATA32 *s, *e; -#endif - 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, NULL); -#if 0 - /* FIXME: this is evil - but it makes ARGB targets look correct */ - if ((buf->priv.destination_alpha) && (!obr->mxcbob) && - (evas_software_xcb_x_output_buffer_depth(obr->xcbob) == 32)) - { - int i; - DATA32 a; - - for (i = 0; i < obr->h; i++) - { - s = ((DATA32 *)data) + ((bpl * i) / sizeof(DATA32)); - e = s + obr->w; - while (s < e) - { - a = A_VAL(s) + 1; - R_VAL(s) = (R_VAL(s) * a) >> 8; - G_VAL(s) = (G_VAL(s) * a) >> 8; - B_VAL(s) = (B_VAL(s) * a) >> 8; - s++; - } - } - } -#endif } +#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.x.win, + obr->x, obr->y, obr->w, obr->h); + evas_software_xcb_x_output_buffer_paste(obr->xcbob, buf->priv.x.win, + buf->priv.x.gc, + obr->x, obr->y, 0); + } +#endif if (obr->mxcbob) { 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_x_write_mask_line(buf, obr->mxcbob, + src_data + + (yy * obr->w), obr->w, yy); +#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.x.mask, + buf->priv.x.gcm, + obr->x, obr->y, 0); +#endif } +#if 1 +#else + xcb_flush(buf->priv.x.disp); +#endif } void @@ -551,6 +931,7 @@ evas_software_xcb_outbuf_reconfigure(Outbuf *buf, buf->w = w; buf->h = h; buf->rot = rot; + evas_software_xcb_outbuf_idle_flush(buf); } int @@ -626,7 +1007,6 @@ evas_software_xcb_outbuf_debug_show(Outbuf *buf, { int i; xcb_screen_t *screen = NULL; - xcb_get_input_focus_reply_t *reply; { xcb_get_geometry_reply_t *geom; @@ -649,7 +1029,7 @@ evas_software_xcb_outbuf_debug_show(Outbuf *buf, } for (i = 0; i < 20; i++) { - xcb_image_t *image; +/* xcb_image_t *image; */ xcb_rectangle_t rect = { x, y, w, h}; uint32_t mask; uint32_t value[2]; @@ -660,510 +1040,23 @@ evas_software_xcb_outbuf_debug_show(Outbuf *buf, xcb_change_gc(buf->priv.x.conn, buf->priv.x.gc, mask, value); xcb_poly_fill_rectangle (buf->priv.x.conn, draw, buf->priv.x.gc, 1, &rect); /* we sync */ - reply = xcb_get_input_focus_reply(buf->priv.x.conn, xcb_get_input_focus_unchecked(buf->priv.x.conn), NULL); - free(reply); + free(xcb_get_input_focus_reply(buf->priv.x.conn, xcb_get_input_focus_unchecked(buf->priv.x.conn), NULL)); // image = xcb_image_get(buf->priv.x.conn, draw, x, y, w, h, XCB_ALL_PLANES, XCB_IMAGE_FORMAT_Z_PIXMAP); // if (image) // xcb_image_destroy(image); /* we sync */ - reply = xcb_get_input_focus_reply(buf->priv.x.conn, xcb_get_input_focus_unchecked(buf->priv.x.conn), NULL); - free(reply); + free(xcb_get_input_focus_reply(buf->priv.x.conn, xcb_get_input_focus_unchecked(buf->priv.x.conn), NULL)); 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.x.conn, buf->priv.x.gc, mask, value); xcb_poly_fill_rectangle (buf->priv.x.conn, draw, buf->priv.x.gc, 1, &rect); /* we sync */ - reply = xcb_get_input_focus_reply(buf->priv.x.conn, xcb_get_input_focus_unchecked(buf->priv.x.conn), NULL); - free(reply); + free(xcb_get_input_focus_reply(buf->priv.x.conn, xcb_get_input_focus_unchecked(buf->priv.x.conn), NULL)); // image = xcb_image_get(buf->priv.x.conn, draw, x, y, w, h, XCB_ALL_PLANES, XCB_IMAGE_FORMAT_Z_PIXMAP); // if (image) // xcb_image_destroy(image); /* we sync */ - reply = xcb_get_input_focus_reply(buf->priv.x.conn, xcb_get_input_focus_unchecked(buf->priv.x.conn), NULL); - free(reply); + free(xcb_get_input_focus_reply(buf->priv.x.conn, xcb_get_input_focus_unchecked(buf->priv.x.conn), NULL)); } } - - - - - - - - - - - - - - - - - - - - - - -/* used for performance tester code */ -static double -_evas_get_time(void) -{ - struct timeval timev; - - gettimeofday(&timev, NULL); - return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000); -} - - -char * -evas_software_xcb_outbuf_perf_serialize_x(Outbuf_Perf *perf) -{ - /* take performance results and turn it inot a munged string that can be */ - /* written out somewhere by a program */ - char buf[256]; - - snprintf(buf, sizeof(buf), "%i", perf->min_shm_image_pixel_count); - return strdup(buf); -} - -void -evas_software_xcb_outbuf_perf_deserialize_x(Outbuf_Perf *perf, - const char *data) -{ - /* take a munged string that is the result of outbuf_perf_serialize_x() */ - /* and turn it back into a structure and fill the provided perf struct */ - /* with it. the perf struct is assumed to be pristine from */ - /* outbuf_perf_new_x() */ - int val; - - val = 200 * 200; - if (sscanf(data, "%i", &val) != 1) - val = 200 * 200; - if (val < 0) - val = 200 * 200; - perf->min_shm_image_pixel_count = val; - return; -} - -Outbuf_Perf * -evas_software_xcb_outbuf_perf_new_x(xcb_connection_t *conn, - xcb_screen_t *screen, - xcb_drawable_t draw, - xcb_visualtype_t *vis, - xcb_colormap_t cmap, - int x_depth) -{ - /* create an "empty" perf struct with just the system & display info */ - Outbuf_Perf *perf; -#if 0 - xcb_drawable_t root; - struct utsname un; - FILE *f; -#endif - - perf = calloc(1, sizeof(Outbuf_Perf)); - - perf->x.conn = conn; - - perf->min_shm_image_pixel_count = 200 * 200; /* default hard-coded */ - -#if 0 - root = screen->root; - if (draw) - { - xcb_get_geometry_reply_t *geom; - xcb_screen_iterator_t i; - int cur; - - geom = xcb_get_geometry_reply (conn, xcb_get_geometry_unchecked(conn, draw), NULL); - root = geom->root; - free (geom); - geom = xcb_get_geometry_reply (conn, xcb_get_geometry_unchecked(conn, root), 0); - perf->x.w = (int)geom->width; - perf->x.h = (int)geom->height; - - perf->x.screen_num = 0; - i = xcb_setup_roots_iterator((xcb_setup_t *)xcb_get_setup(conn)); - for (cur = 0; i.rem; xcb_screen_next(&i), ++cur) - if (i.data->root == geom->root) - { - perf->x.screen_num = cur; - break; - } - free (geom); - } - perf->x.root = root; - - perf->x.display = strdup (":0"); /* FIXME: there's no way to get the display value with XCB */ - perf->x.vendor = strdup(xcb_setup_vendor((xcb_setup_t *)xcb_get_setup(conn))); - perf->x.version = (int)((xcb_setup_t *)xcb_get_setup(conn))->protocol_major_version; - perf->x.revision = (int)((xcb_setup_t *)xcb_get_setup(conn))->protocol_minor_version; - perf->x.release = (int)((xcb_setup_t *)xcb_get_setup(conn))->release_number; - perf->x.screen_count = xcb_setup_roots_iterator((xcb_setup_t *)xcb_get_setup(conn)).rem; - perf->x.depth = x_depth; - - if (!uname(&un)) - { - perf->os.name = strdup(un.sysname); - perf->os.version = strdup(un.release); - perf->os.machine = strdup(un.machine); - } - /* for linux */ - f = fopen("/proc/cpuinfo", "r"); - if (f) - { - char buf[16384]; - size_t sz; - - /* read up tothe first 16k of it... shoudl be nice and fast and easy */ - sz = fread(buf, 1, 16380, f); - if (sz > 0) - { - perf->cpu.info = malloc(sz + 1); - strncpy(perf->cpu.info, buf, sz); - perf->cpu.info[sz] = 0; - } - fclose(f); - } - else - { - /* for FreeBSD... maybe */ - f = fopen("/var/run/dmesg.boot", "r"); - /* for NetBSD... maybe */ - if (!f) - f = fopen("/kern/msgbuf", "r"); - if (f) - { - char buf[4096]; - int l; - - l = 0; - while (fgets(buf, sizeof(buf), f)) - { - int len; - - /* to read lines like: */ - /* CPU: AMD-K7(tm) Processor (698.65-MHz 686-class CPU) */ - /* Features=0x81f9ff */ - if ((!strncmp(buf, "CPU: ", 5)) || - (!strncmp(buf, "Features=", 9))) - { - len = strlen(buf); - l += len; - if (!perf->cpu.info) - perf->cpu.info = strdup(buf); - else - { - perf->cpu.info = realloc(perf->cpu.info, l + 1); - if (perf->cpu.info) - strcat(perf->cpu.info, buf); - } - } - } - fclose(f); - } - } - if (!perf->cpu.info) - perf->cpu.info = strdup(""); -#endif - return perf; -} - -char * -evas_software_xcb_outbuf_perf_serialize_info_x(Outbuf_Perf *perf) -{ - /* get a seriazed string that is a unique identifier for your */ - /* hardware/x/connection setup. */ - return NULL; -#if 0 - char buf[32768]; - int sum1, sum2, i; - char *p; - - sum1 = 0; - sum2 = 0; - snprintf(buf, sizeof(buf), - "%s|%s|%i|%i|%i|%i|%i|%i|%i|%i|%s|%s|%s|%s", - perf->x.display, perf->x.vendor, perf->x.version, perf->x.revision, - perf->x.release, perf->x.w, perf->x.h, perf->x.screen_count, - perf->x.depth, perf->x.screen_num, - perf->os.name, perf->os.version, perf->os.machine, perf->cpu.info); - p = buf; - i = 0; - while (*p) - { - sum1 += (int)(*p) << (i % 24); - sum2 ^= ((int)(*p) << (i % 24)) * ((int)(*p)); - i++; - p++; - } - snprintf(buf, sizeof(buf), "%08x%08x", sum1, sum2); - return strdup(buf); -#endif -} - -void -evas_software_xcb_outbuf_perf_store_x(Outbuf_Perf *perf) -{ - /* write performance results to x root property */ - return; -#if 0 - xcb_intern_atom_cookie_t cookie_atom; - xcb_get_input_focus_cookie_t cookie_focus; - xcb_intern_atom_reply_t *reply_atom; - xcb_get_input_focus_reply_t *reply_focus; - xcb_atom_t type, format; - char *type_str; - char *str; - - type_str = "__EVAS_PERF_ENGINE_SOFTWARE"; - cookie_atom = xcb_intern_atom_unchecked(perf->x.conn, - 0, - strlen (type_str), - type_str); - cookie_focus = xcb_get_input_focus_unchecked(perf->x.conn); - - reply_atom = xcb_intern_atom_reply(perf->x.conn, - cookie_atom, - NULL); - if (!reply_atom) return; - - type = reply_atom->atom; - /* Atom STRING predefined in xorg. Value : 31 */ - format = 31; - - str = evas_software_xcb_outbuf_perf_serialize_x(perf); - xcb_change_property(perf->x.conn, XCB_PROP_MODE_REPLACE, perf->x.root, - type, format, 8, - strlen(str), str); - /* we sync */ - reply_focus = xcb_get_input_focus_reply(perf->x.conn, cookie_focus, NULL); - free(reply_focus); - free(str); - free (reply_atom); -#endif -} - -Outbuf_Perf * -evas_software_xcb_outbuf_perf_restore_x(xcb_connection_t *conn, - xcb_screen_t *screen, - xcb_drawable_t draw, - xcb_visualtype_t *vis, - xcb_colormap_t cmap, - int x_depth) -{ - /* read performance results from root window */ -#if 0 - xcb_intern_atom_reply_t *type_rep; - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *prop_rep; - char *type_str; - xcb_atom_t type, format; -#endif - Outbuf_Perf *perf; - - perf = evas_software_xcb_outbuf_perf_new_x(conn, screen, draw, vis, cmap, x_depth); - return perf; - -#if 0 - type_str = "__EVAS_PERF_ENGINE_SOFTWARE"; - type_rep = xcb_intern_atom_reply(conn, - xcb_intern_atom_unchecked(conn, - 0, - strlen (type_str), - type_str), - NULL); - if (!type_rep) - return perf; - - type = type_rep->atom; - /* Atom STRING predefined in xorg. Value : 31 */ - format = 31; - free(type_rep); - - cookie = xcb_get_property_unchecked(conn, 0, perf->x.root, - type, format, - 0, 16384); - prop_rep = xcb_get_property_reply(conn, cookie, NULL); - - if ((prop_rep) && - (prop_rep->format == 8) && - (prop_rep->type == type)) - { - char *retval; - int retnum; - - retval = xcb_get_property_value(prop_rep); - retnum = xcb_get_property_value_length(prop_rep); - retval[retnum] = '\0'; - evas_software_xcb_outbuf_perf_deserialize_x(perf, retval); - } - - if (prop_rep) - free(prop_rep); - - return perf; -#endif -} - -void -evas_software_xcb_outbuf_perf_free(Outbuf_Perf *perf) -{ - /* free the perf struct */ -#if 0 - free(perf->x.display); - free(perf->x.vendor); - free(perf->os.name); - free(perf->os.version); - free(perf->os.machine); - free(perf->cpu.info); -#endif - free(perf); -} - -Outbuf_Perf * -evas_software_xcb_outbuf_perf_x(xcb_connection_t *conn, - xcb_screen_t *screen, - xcb_drawable_t draw, - xcb_visualtype_t *vis, - xcb_colormap_t cmap, - int x_depth) -{ - Outbuf_Perf *perf; - xcb_get_input_focus_reply_t *reply; - xcb_drawable_t win; - uint32_t mask; - uint32_t value[7]; - uint32_t value2[1]; - int w, h; - int do_shm = 0; - - perf = evas_software_xcb_outbuf_perf_new_x(conn, screen, draw, vis, cmap, x_depth); - - mask = XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | - XCB_CW_BIT_GRAVITY | XCB_CW_BACKING_STORE | - XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; - value[0] = XCB_BACK_PIXMAP_NONE; - value[1] = 0; - value[2] = XCB_GRAVITY_BIT_FORGET; - value[3] = XCB_BACKING_STORE_ALWAYS; - value[4] = 1; - value[5] = XCB_EVENT_MASK_NO_EVENT; - value[6] = cmap; - w = perf->x.w; - h = perf->x.h; - win = xcb_generate_id (conn); - xcb_create_window (conn, x_depth, - win, perf->x.root, - 0, 0, - w, h, - 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - vis->visual_id, - mask, value); - /* we sync */ - reply = xcb_get_input_focus_reply(conn, - xcb_get_input_focus_unchecked(conn), - NULL); - free(reply); - mask = XCB_CONFIG_WINDOW_STACK_MODE; - value[0] = XCB_STACK_MODE_ABOVE; - xcb_configure_window (conn, win, mask, value2); - xcb_map_window (conn, win); - - do_shm = evas_software_xcb_x_can_do_shm(conn, screen); - - /* set it to something ridiculous to start */ - perf->min_shm_image_pixel_count = w * w; - - if (do_shm) - { - Xcb_Output_Buffer *xcbob; - xcb_gcontext_t gc; - int i; - int max; - int error; - int chosen; - - chosen = 0; - error = 0; - max = w; - if (w > h) - max = h; - gc = xcb_generate_id (conn); - xcb_create_gc (conn, gc, win, 0, NULL); - for (i = 16; i < max; i += 16) - { - int l; - double t0, t1, t2; - int loops; - - loops = (h * h * 5) / (i * i); - t0 = _evas_get_time(); - for (l = 0; l < loops; l++) - { - xcbob = evas_software_xcb_x_output_buffer_new(conn, - x_depth, - i, i, - do_shm, - NULL); - if (!xcbob) - error = 1; - else - { - evas_software_xcb_x_output_buffer_paste(xcbob, - win, - gc, - 0, 0, - 1); - evas_software_xcb_x_output_buffer_free(xcbob, 1); - } - } - /* we sync */ - reply = xcb_get_input_focus_reply(conn, - xcb_get_input_focus_unchecked(conn), - NULL); - free(reply); - t1 = _evas_get_time() - t0; - t0 = _evas_get_time(); - for (l = 0; l < loops; l++) - { - xcbob = evas_software_xcb_x_output_buffer_new(conn, - x_depth, - i, i, - 0, - NULL); - if (!xcbob) - error = 1; - else - { - evas_software_xcb_x_output_buffer_paste(xcbob, - win, - gc, - 0, 0, - 1); - evas_software_xcb_x_output_buffer_free(xcbob, 1); - } - } - /* we sync */ - reply = xcb_get_input_focus_reply(conn, - xcb_get_input_focus_unchecked(conn), - NULL); - free(reply); - t2 = _evas_get_time() - t0; - if ((!chosen) && (!error)) - { - if ((t1 / t2) < 1.0) - { - perf->min_shm_image_pixel_count = (i - 8) * (i - 8); - chosen = 1; - } - } - } - xcb_free_gc(conn, gc); - } - xcb_destroy_window(conn, win); - return perf; -} diff --git a/legacy/evas/src/modules/engines/software_xcb/evas_xcb_buffer.c b/legacy/evas/src/modules/engines/software_xcb/evas_xcb_buffer.c index 2518a84d7c..fe58b74f2a 100644 --- a/legacy/evas/src/modules/engines/software_xcb/evas_xcb_buffer.c +++ b/legacy/evas/src/modules/engines/software_xcb/evas_xcb_buffer.c @@ -128,12 +128,13 @@ evas_software_xcb_x_output_buffer_new(xcb_connection_t *c, if (xcbob->shm_info) { xcbob->shm_info->shmseg = xcb_generate_id(c); - xcbob->image = xcb_image_shm_create(c, depth, XCB_IMAGE_FORMAT_Z_PIXMAP, NULL, w, h); + xcbob->image = xcb_image_create_native(c, w, h, + XCB_IMAGE_FORMAT_Z_PIXMAP, + depth, NULL, ~0, NULL); if (xcbob->image) { xcbob->shm_info->shmid = shmget(IPC_PRIVATE, - xcbob->image->bytes_per_line * - xcbob->image->height, + xcbob->image->size, IPC_CREAT | 0777); if (xcbob->shm_info->shmid >= 0) { @@ -148,24 +149,26 @@ evas_software_xcb_x_output_buffer_new(xcb_connection_t *c, /* XErrorHandler ph; */ /* EventHandlers eh; */ -/* xcb_sync(c, 0); */ + // free(xcb_get_input_focus_reply(c, xcb_get_input_focus(c), NULL)); _xcb_err = 0; /* ph = XSetErrorHandler((XErrorHandler) */ /* x_output_tmp_x_err); */ xcb_shm_attach(c, - xcbob->shm_info->shmseg, - xcbob->shm_info->shmid, 0); -/* xcb_sync(c, 0); */ + xcbob->shm_info->shmseg, + xcbob->shm_info->shmid, 0); + // free(xcb_get_input_focus_reply(c, xcb_get_input_focus(c), NULL)); /* XSetErrorHandler((XErrorHandler)ph); */ if (!_xcb_err) { - return xcbob; + 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); } - if (xcbob->image) xcb_image_shm_destroy(xcbob->image); + if (xcbob->image) xcb_image_destroy(xcbob->image); xcbob->image = NULL; } if (xcbob->shm_info) free(xcbob->shm_info); @@ -175,7 +178,8 @@ evas_software_xcb_x_output_buffer_new(xcb_connection_t *c, if (try_shm > 1) return NULL; - xcbob->image = xcb_image_create(c, depth, XCB_IMAGE_FORMAT_Z_PIXMAP, 0, data, w, h, 32, 0); + xcbob->image = xcb_image_create_native(c, w, h, XCB_IMAGE_FORMAT_Z_PIXMAP, + depth, NULL, 0, data); if (!xcbob->image) { free(xcbob); @@ -186,7 +190,7 @@ evas_software_xcb_x_output_buffer_new(xcb_connection_t *c, if (!xcbob->image->data) { - xcbob->image->data = malloc(xcbob->image->bytes_per_line * xcbob->image->height); + xcbob->image->data = malloc(xcbob->image->size); if (!xcbob->image->data) { xcb_image_destroy(xcbob->image); @@ -204,16 +208,11 @@ evas_software_xcb_x_output_buffer_free(Xcb_Output_Buffer *xcbob, if (xcbob->shm_info) { if (sync) - { - xcb_get_input_focus_reply_t *reply; - - reply = xcb_get_input_focus_reply(xcbob->connection, - xcb_get_input_focus_unchecked(xcbob->connection), - NULL); - free(reply); - } + free(xcb_get_input_focus_reply(xcbob->connection, + xcb_get_input_focus(xcbob->connection), + NULL)); xcb_shm_detach(xcbob->connection, xcbob->shm_info->shmseg); - xcb_image_shm_destroy(xcbob->image); + xcb_image_destroy(xcbob->image); shmdt(xcbob->shm_info->shmaddr); shmctl(xcbob->shm_info->shmid, IPC_RMID, 0); free(xcbob->shm_info); @@ -243,47 +242,38 @@ evas_software_xcb_x_output_buffer_paste(Xcb_Output_Buffer *xcbob, xcbob->image->width, xcbob->image->height, 0); if (sync) - { - xcb_get_input_focus_reply_t *reply; - - reply = xcb_get_input_focus_reply(xcbob->connection, - xcb_get_input_focus_unchecked(xcbob->connection), - NULL); - free(reply); - } + free(xcb_get_input_focus_reply(xcbob->connection, + xcb_get_input_focus(xcbob->connection), + NULL)); } else - xcb_image_put(xcbob->connection, - d, - gc, + xcb_image_put(xcbob->connection, d, gc, xcbob->image, - 0, 0, - x, y, - xcbob->image->width, xcbob->image->height); + x, y, 0); } DATA8 * evas_software_xcb_x_output_buffer_data(Xcb_Output_Buffer *xcbob, int *bytes_per_line_ret) { - if (bytes_per_line_ret) *bytes_per_line_ret = xcbob->image->bytes_per_line; + if (bytes_per_line_ret) *bytes_per_line_ret = xcbob->image->stride; return xcbob->image->data; } int evas_software_xcb_x_output_buffer_depth(Xcb_Output_Buffer *xcbob) { - return xcbob->image->bits_per_pixel; + return xcbob->image->bpp; } int evas_software_xcb_x_output_buffer_byte_order(Xcb_Output_Buffer *xcbob) { - return xcbob->image->image_byte_order; + return xcbob->image->byte_order; } int evas_software_xcb_x_output_buffer_bit_order(Xcb_Output_Buffer *xcbob) { - return xcbob->image->bitmap_format_bit_order; + return xcbob->image->bit_order; }