* evas: break engine API !!!

Improvements: Now evas rendering loop is the one responsible to
	initialize the surface to 0 correctly (taking into account surface
	alpha and object opacity). This will reduce the number of memset
	we do.

	Note: Current software_x11 (xlib and xcb) are buggy. They are
	copying too much data when the surface use a mask. That's why
	two memset are left in their code. They could be removed, but
	we should fix the surface we copy on change (look at mxob user
	and evas_software_xlib_x_output_buffer_paste).


SVN revision: 41206
This commit is contained in:
Cedric BAIL 2009-06-26 13:26:52 +00:00
parent 7e62952adf
commit a7f2974e13
24 changed files with 194 additions and 59 deletions

View File

@ -315,6 +315,7 @@ evas_render_updates_internal(Evas *e, unsigned char make_updates, unsigned char
Eina_List *ll;
void *surface;
Eina_Bool clean_them = EINA_FALSE;
Eina_Bool alpha;
Eina_Rectangle *r;
int ux, uy, uw, uh;
int cx, cy, cw, ch;
@ -412,6 +413,8 @@ evas_render_updates_internal(Evas *e, unsigned char make_updates, unsigned char
{
unsigned int offset = 0;
alpha = e->engine.func->canvas_alpha_get(e->engine.data.output, e->engine.data.context);
while ((surface =
e->engine.func->output_redraws_next_update_get(e->engine.data.output,
&ux, &uy, &uw, &uh,
@ -436,8 +439,58 @@ evas_render_updates_internal(Evas *e, unsigned char make_updates, unsigned char
obj = (Evas_Object *) eina_array_data_get(&e->obscuring_objects, i);
if (evas_object_is_in_output_rect(obj, ux, uy, uw, uh))
eina_array_push(&e->temporary_objects, obj);
{
eina_array_push(&e->temporary_objects, obj);
/* reset the background of the area if needed (using cutout and engine alpha flag to help) */
if (alpha)
{
if (evas_object_is_opaque(obj))
e->engine.func->context_cutout_add(e->engine.data.output,
e->engine.data.context,
obj->cur.cache.clip.x + off_x,
obj->cur.cache.clip.y + off_y,
obj->cur.cache.clip.w,
obj->cur.cache.clip.h);
else
{
if (obj->func->get_opaque_rect)
{
Evas_Coord obx, oby, obw, obh;
obj->func->get_opaque_rect(obj, &obx, &oby, &obw, &obh);
if ((obw > 0) && (obh > 0))
{
obx += off_x;
oby += off_y;
RECTS_CLIP_TO_RECT(obx, oby, obw, obh,
obj->cur.cache.clip.x + off_x,
obj->cur.cache.clip.y + off_y,
obj->cur.cache.clip.w,
obj->cur.cache.clip.h);
e->engine.func->context_cutout_add(e->engine.data.output,
e->engine.data.context,
obx, oby,
obw, obh);
}
}
}
}
}
}
if (alpha)
{
e->engine.func->context_color_set(e->engine.data.output, e->engine.data.context, 0, 0, 0, 0);
e->engine.func->context_multiplier_unset(e->engine.data.output, e->engine.data.context);
e->engine.func->context_render_op_set(e->engine.data.output, e->engine.data.context, EVAS_RENDER_COPY);
e->engine.func->rectangle_draw(e->engine.data.output,
e->engine.data.context,
surface,
cx, cy, cw, ch);
e->engine.func->context_cutout_clear(e->engine.data.output,
e->engine.data.context);
}
/* render all object that intersect with rect */
for (i = 0; i < e->active_objects.count; ++i)
{

View File

@ -542,6 +542,7 @@ struct _Evas_Func
void (*output_idle_flush) (void *data);
void *(*context_new) (void *data);
Eina_Bool (*canvas_alpha_get) (void *data, void *context);
void (*context_free) (void *data, void *context);
void (*context_clip_set) (void *data, void *context, int x, int y, int w, int h);
void (*context_clip_clip) (void *data, void *context, int x, int y, int w, int h);

View File

@ -322,6 +322,17 @@ eng_output_idle_flush(void *data)
re = (Render_Engine *)data;
}
static Eina_Bool
eng_canvas_alpha_get(void *data)
{
Render_Engine *re;
re = (Render_Engine *)data;
if (re->ob->priv.back_buf)
return re->ob->priv.back_buf->cache_entry.flags.alpha;
return EINA_TRUE;
}
/* module advertising code */
static int
module_open(Evas_Module *em)
@ -336,6 +347,7 @@ module_open(Evas_Module *em)
ORD(info);
ORD(info_free);
ORD(setup);
ORD(canvas_alpha_get);
ORD(output_free);
ORD(output_resize);
ORD(output_tile_size_set);

View File

@ -81,18 +81,6 @@ evas_buffer_outbuf_buf_new_region_for_update(Outbuf *buf, int x, int y, int w, i
if (buf->priv.back_buf)
{
*cx = x; *cy = y; *cw = w; *ch = h;
if (buf->priv.back_buf->cache_entry.flags.alpha)
{
int ww = w;
ptr = buf->priv.back_buf->image.data + (y * buf->priv.back_buf->cache_entry.w) + x;
while (h--)
{
while (w--)
*ptr++ = 0;
w = ww;
ptr += (buf->priv.back_buf->cache_entry.w - w);
}
}
return buf->priv.back_buf;
}
else
@ -106,10 +94,6 @@ evas_buffer_outbuf_buf_new_region_for_update(Outbuf *buf, int x, int y, int w, i
{
im->cache_entry.flags.alpha = 1;
im = (RGBA_Image *) evas_cache_image_size_set(&im->cache_entry, w, h);
if (im)
{
memset(im->image.data, 0, w * h * sizeof(DATA32));
}
}
}
}

View File

@ -23,6 +23,7 @@ static void eng_output_redraws_next_update_push(void *data, void *surface, int x
static void eng_output_flush(void *data);
static void *eng_context_new(void *data);
static Eina_Bool eng_canvas_alpha_get(void *data, void *context);
static void eng_context_free(void *data, void *context);
static void eng_context_clip_set(void *data, void *context, int x, int y, int w, int h);
static void eng_context_clip_clip(void *data, void *context, int x, int y, int w, int h);
@ -144,6 +145,7 @@ static Evas_Func eng_func =
eng_output_flush,
/* draw context virtual methods */
eng_context_new,
eng_canvas_alpha_get,
eng_context_free,
eng_context_clip_set,
eng_context_clip_clip,
@ -1478,6 +1480,12 @@ eng_font_hinting_can_hint(void *data, int hinting)
re = (Render_Engine *)data;
}
static Eina_Bool
eng_canvas_alpha_get(void *data, void *context)
{
return EINA_FALSE;
}
static int
module_open(Evas_Module *em)
{

View File

@ -941,8 +941,6 @@ evas_engine_dfb_output_redraws_next_update_get(void *data, int *x, int *y, int *
re->end = 1;
}
_image_clear(re->screen_image, *x, *y, *w, *h );
return re->screen_image->surface;
}
@ -1602,6 +1600,14 @@ evas_engine_dfb_image_scale_hint_get(void *data __UNUSED__, void *image)
return EVAS_IMAGE_SCALE_HINT_NONE;
}
static Eina_Bool
evas_engine_dfb_canvas_alpha_get(void *data, void *context)
{
Render_Engine *re = data;
return re->screen_image->cache_entry.src->flags.alpha
}
static int
module_open(Evas_Module *em)
{

View File

@ -247,6 +247,15 @@ eng_output_idle_flush(void *data)
re = (Render_Engine *)data;
}
static Eina_Bool
eng_canvas_alpha_get(void *data, void *context)
{
Render_Engine *re;
re = (Render_Engine *)data;
return (re->ob->priv.fb.fb->fb_var.transp.length > 0);
}
/* module advertising code */
static int
module_open(Evas_Module *em)
@ -261,6 +270,7 @@ module_open(Evas_Module *em)
ORD(info);
ORD(info_free);
ORD(setup);
ORD(canvas_alpha_get);
ORD(output_free);
ORD(output_resize);
ORD(output_tile_size_set);

View File

@ -220,10 +220,6 @@ evas_fb_outbuf_fb_new_region_for_update(Outbuf *buf, int x, int y, int w, int h,
im->cache_entry.flags.alpha = 1;
im = (RGBA_Image *) evas_cache_image_size_set(&im->cache_entry, w, h);
/* handle framebuffers with alpha channel */
if (buf->priv.fb.fb->fb_var.transp.length > 0) {
memset(im->image.data, 0, w * h * sizeof(DATA32));
}
return im;
}
return NULL;

View File

@ -824,6 +824,11 @@ eng_font_hinting_can_hint(void *data __UNUSED__, int hinting)
return evas_common_hinting_available(hinting);
}
static Eina_Bool
eng_canvas_alpha_get(void *data __UNUSED__, void *context __UNUSED__)
{
return EINA_TRUE;
}
/*
*****
@ -850,6 +855,7 @@ static Evas_Func func =
NULL,
/* draw context virtual methods */
eng_context_new,
eng_canvas_alpha_get,
eng_context_free,
eng_context_clip_set,
eng_context_clip_clip,

View File

@ -562,6 +562,11 @@ eng_output_idle_flush(void *data)
}
}
static Eina_Bool
eng_canvas_alpha_get(void *data, void *context)
{
return EINA_FALSE;
}
/* module advertising code */
static int
@ -577,6 +582,7 @@ module_open(Evas_Module *em)
ORD(info);
ORD(info_free);
ORD(setup);
ORD(canvas_alpha_get);
ORD(output_free);
ORD(output_resize);
ORD(output_tile_size_set);

View File

@ -368,8 +368,6 @@ evas_engine_sdl16_output_redraws_next_update_get(void *data,
rect.w = *w;
rect.h = *h;
SDL_FillRect(re->soft16_engine_image->surface, &rect, 0);
/* Return the "fake" surface so it is passed to the drawing routines. */
return re->soft16_engine_image;
}
@ -1018,6 +1016,12 @@ evas_engine_sdl16_image_stride_get(void *data __UNUSED__, void *image, int *stri
if (stride) *stride = ((Soft16_Image*) eim->cache_entry.src)->stride;
}
static Eina_Bool
evas_engine_sdl16_canvas_alpha_get(void *data, void *context)
{
return EINA_FALSE;
}
/* module advertising code */
static int
module_open(Evas_Module *em)
@ -1032,6 +1036,7 @@ module_open(Evas_Module *em)
ORD(info);
ORD(info_free);
ORD(setup);
ORD(canvas_alpha_get);
ORD(output_free);
ORD(output_resize);
ORD(output_tile_size_set);

View File

@ -703,6 +703,11 @@ eng_output_idle_flush(void *data)
}
}
static Eina_Bool
eng_canvas_alpha_get(void *data, void *context)
{
return EINA_FALSE;
}
/* module advertising code */
static int
@ -718,6 +723,7 @@ module_open(Evas_Module *em)
ORD(info);
ORD(info_free);
ORD(setup);
ORD(canvas_alpha_get);
ORD(output_free);
ORD(output_resize);
ORD(output_tile_size_set);

View File

@ -542,6 +542,11 @@ eng_output_idle_flush(void *data)
}
}
static Eina_Bool
eng_canvas_alpha_get(void *data, void *context)
{
return EINA_FALSE;
}
/* module advertising code */
static int
@ -557,6 +562,7 @@ module_open(Evas_Module *em)
ORD(info);
ORD(info_free);
ORD(setup);
ORD(canvas_alpha_get);
ORD(output_free);
ORD(output_resize);
ORD(output_tile_size_set);

View File

@ -309,6 +309,11 @@ eng_output_idle_flush(void *data)
evas_software_ddraw_outbuf_idle_flush(re->ob);
}
static Eina_Bool
eng_canvas_alpha_get(void *data, void *context)
{
return EINA_FALSE;
}
/* module advertising code */
static int
@ -324,6 +329,7 @@ module_open(Evas_Module *em)
ORD(info);
ORD(info_free);
ORD(setup);
ORD(canvas_alpha_get);
ORD(output_free);
ORD(output_resize);
ORD(output_tile_size_set);

View File

@ -319,6 +319,11 @@ eng_output_idle_flush(void *data)
evas_software_gdi_outbuf_idle_flush(re->ob);
}
static Eina_Bool
eng_canvas_alpha_get(void *data, void *context)
{
return EINA_FALSE;
}
/* module advertising code */
static int
@ -334,6 +339,7 @@ module_open(Evas_Module *em)
ORD(info);
ORD(info_free);
ORD(setup);
ORD(canvas_alpha_get);
ORD(output_free);
ORD(output_resize);
ORD(output_tile_size_set);

View File

@ -961,6 +961,11 @@ eng_font_hinting_can_hint(void *data __UNUSED__, int hinting)
return evas_common_hinting_available(hinting);
}
static Eina_Bool
eng_canvas_alpha_get(void *data __UNUSED__, void *info __UNUSED__)
{
return EINA_TRUE;
}
/*
*****
@ -987,6 +992,7 @@ static Evas_Func func =
NULL,
/* draw context virtual methods */
eng_context_new,
eng_canvas_alpha_get,
eng_context_free,
eng_context_clip_set,
eng_context_clip_clip,

View File

@ -262,6 +262,12 @@ eng_output_idle_flush(void *data)
re = (Render_Engine *)data;
}
static Eina_Bool
eng_canvas_alpha_get(void *data, void *context)
{
return EINA_FALSE;
}
/* module advertising code */
static int
module_open(Evas_Module *em)
@ -276,6 +282,7 @@ module_open(Evas_Module *em)
ORD(info);
ORD(info_free);
ORD(setup);
ORD(canvas_alpha_get);
ORD(output_free);
ORD(output_resize);
ORD(output_tile_size_set);

View File

@ -255,8 +255,6 @@ evas_engine_sdl_output_redraws_next_update_get (void *data,
rect.w = *w;
rect.h = *h;
SDL_FillRect(re->rgba_engine_image->surface, &rect, 0);
/* Return the "fake" surface so it is passed to the drawing routines. */
return re->rgba_engine_image;
}

View File

@ -34,6 +34,7 @@ struct _Render_Engine
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);
};
/* prototypes we will use here */
@ -380,6 +381,7 @@ eng_setup(Evas *e, void *in)
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 BUILD_ENGINE_SOFTWARE_XCB
@ -409,6 +411,7 @@ eng_setup(Evas *e, void *in)
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;
}
#endif
@ -611,6 +614,14 @@ eng_output_idle_flush(void *data)
re->outbuf_idle_flush(re->ob);
}
static Eina_Bool
eng_canvas_alpha_get(void *data, void *context)
{
Render_Engine *re;
re = (Render_Engine *)data;
return (re->ob->priv.destination_alpha) || (re->outbuf_alpha_get(re->ob));
}
/* module advertising code */
static int
@ -626,6 +637,7 @@ module_open(Evas_Module *em)
ORD(info);
ORD(info_free);
ORD(setup);
ORD(canvas_alpha_get);
ORD(output_free);
ORD(output_resize);
ORD(output_tile_size_set);

View File

@ -414,17 +414,6 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf,
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;
}
if ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha))
{
int yy;
im = buf->priv.onebuf;
for (yy = y; yy < (y + h); yy++)
{
memset(im->image.data + (im->cache_entry.w * yy) + x,
0, w * sizeof(DATA32));
}
}
return buf->priv.onebuf;
}
obr = calloc(1, sizeof(Outbuf_Region));
@ -1049,3 +1038,9 @@ evas_software_xcb_outbuf_debug_show(Outbuf *buf,
free(xcb_get_input_focus_reply(buf->priv.x11.xcb.conn, xcb_get_input_focus_unchecked(buf->priv.x11.xcb.conn), NULL));
}
}
Eina_Bool
evas_software_xcb_outbuf_alpha_get (Outbuf *buf)
{
return buf->priv.x11.xcb.mask;
}

View File

@ -83,4 +83,7 @@ void evas_software_xcb_outbuf_debug_show (Outbuf *buf,
int w,
int h);
Eina_Bool evas_software_xcb_outbuf_alpha_get (Outbuf *buf);
#endif

View File

@ -28,7 +28,7 @@ static int shmcountlimit = 32;
static X_Output_Buffer *
_find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
{
Eina_List *l, *xl;
Eina_List *l, *xl = NULL;
X_Output_Buffer *xob = NULL;
X_Output_Buffer *xob2;
int fitness = 0x7fffffff;
@ -363,17 +363,6 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
XSync(buf->priv.x11.xlib.disp, False);
buf->priv.synced = 1;
}
if ((buf->priv.x11.xlib.mask) || (buf->priv.destination_alpha))
{
int yy;
im = buf->priv.onebuf;
for (yy = y; yy < (y + h); yy++)
{
memset(im->image.data + (im->cache_entry.w * yy) + x,
0, w * sizeof(DATA32));
}
}
return buf->priv.onebuf;
}
obr = calloc(1, sizeof(Outbuf_Region));
@ -450,6 +439,8 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
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 (alpha)
/* FIXME: faster memset! */
memset(im->image.data, 0, w * h * sizeof(DATA32));
@ -581,6 +572,8 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
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))
/* FIXME: faster memset! */
memset(im->image.data, 0, w * h * sizeof(DATA32));
@ -1037,3 +1030,9 @@ evas_software_xlib_outbuf_debug_show(Outbuf * buf, Drawable draw, int x, int y,
XSync(buf->priv.x11.xlib.disp, False);
}
}
Eina_Bool
evas_software_xlib_outbuf_alpha_get(Outbuf *buf)
{
return buf->priv.x11.xlib.mask;
}

View File

@ -82,4 +82,6 @@ void evas_software_xlib_outbuf_debug_show (Outbuf *buf,
int w,
int h);
Eina_Bool evas_software_xlib_outbuf_alpha_get (Outbuf *buf);
#endif

View File

@ -369,7 +369,7 @@ eng_info_free(Evas *e __UNUSED__, void *info)
static void
eng_setup(Evas *e, void *in)
{
Render_Engine *re;
Render_Engine *re = NULL;
Evas_Engine_Info_XRender_X11 *info;
int resize = 1;
@ -559,14 +559,6 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i
*x = ux; *y = uy; *w = uw; *h = uh;
*cx = 0; *cy = 0; *cw = uw; *ch = uh;
if ((re->destination_alpha) || (re->x11.mask))
{
Xrender_Surface *surface;
surface = re->render_surface_new(re->xinf, uw, uh, re->xinf->x11.fmt32, 1);
re->render_surface_solid_rectangle_set(surface, 0, 0, 0, 0, 0, 0, uw, uh);
return surface;
}
// use target format to avoid conversion to depth when copying to screen
// return _xr_render_surface_new(re->xinf, uw, uh, re->xinf->fmtdef, 0);
// use 24/32bpp for tmp buf for better quality. rendering in 24/32bpp
@ -1397,6 +1389,15 @@ eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y
evas_cache_image_drop(&im->cache_entry);
}
static Eina_Bool
eng_canvas_alpha_get(void *data, void *context)
{
Render_Engine *re;
re = (Render_Engine *)data;
return (re->destination_alpha) || (re->x11.mask);
}
/* module advertising code */
static int
module_open(Evas_Module *em)
@ -1412,6 +1413,7 @@ module_open(Evas_Module *em)
ORD(info);
ORD(info_free);
ORD(setup);
ORD(canvas_alpha_get);
ORD(output_free);
ORD(output_resize);
ORD(output_tile_size_set);