update of the software xcb engine:

* use the pixman library for the region code (it is required, now). That
   libray can be found in the cairo ftp.
 * use the new xcb_image api that is in git repository. There is still a
   seg fault occuring because of xcb_image. I'll commit the fix in git
   next week.

The performance are not good at all. With expedite, 360 fps compared to
the 470 fps with xlib. I don't know why yet.


SVN revision: 33965
This commit is contained in:
doursse 2008-03-09 13:21:16 +00:00 committed by doursse
parent c1fb45dcea
commit 9f50836a12
6 changed files with 572 additions and 820 deletions

View File

@ -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"

View File

@ -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;

View File

@ -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 */

View File

@ -8,7 +8,6 @@
#include <xcb/xcb_image.h>
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);

File diff suppressed because it is too large Load Diff

View File

@ -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;
}