diff --git a/legacy/evas/src/lib/engines/xrender_x11/evas_engine.c b/legacy/evas/src/lib/engines/xrender_x11/evas_engine.c index 72fef62938..ec081d692e 100644 --- a/legacy/evas/src/lib/engines/xrender_x11/evas_engine.c +++ b/legacy/evas/src/lib/engines/xrender_x11/evas_engine.c @@ -74,7 +74,14 @@ static void evas_engine_xrender_x11_font_cache_flush(void *data); static void evas_engine_xrender_x11_font_cache_set(void *data, int bytes); static int evas_engine_xrender_x11_font_cache_get(void *data); -typedef struct _Render_Engine Render_Engine; +typedef struct _Render_Engine Render_Engine; +typedef struct _Render_Engine_Update Render_Engine_Update; + +struct _Render_Engine_Update +{ + int x, y, w, h; + Xrender_Surface *surface; +}; struct _Render_Engine { @@ -92,6 +99,8 @@ struct _Render_Engine Tilebuf_Rect *rects; Evas_Object_List *cur_rect; int end : 1; + + Evas_List *updates; }; Evas_Func evas_engine_xrender_x11_func = @@ -257,6 +266,15 @@ evas_engine_xrender_x11_output_free(void *data) re = (Render_Engine *)data; evas_common_font_shutdown(); evas_common_image_shutdown(); + while (re->updates) + { + Render_Engine_Update *reu; + + reu = re->updates->data; + re->updates = evas_list_remove_list(re->updates, re->updates); + _xr_render_surface_free(reu->surface); + free(reu); + } if (re->tb) evas_common_tilebuf_free(re->tb); if (re->output) _xr_render_surface_free(re->output); if (re->mask_output) _xr_render_surface_free(re->mask_output); @@ -371,30 +389,17 @@ static void evas_engine_xrender_x11_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h) { Render_Engine *re; + Render_Engine_Update *reu; re = (Render_Engine *)data; - if (re->mask_output) - { - Xrender_Surface *tsurf; - - _xr_render_surface_copy((Xrender_Surface *)surface, re->output, 0, 0, - x, y, w, h); - tsurf = _xr_render_surface_new(re->xinf, w, h, re->xinf->fmt1, 1); - if (tsurf) - { - _xr_render_surface_copy((Xrender_Surface *)surface, tsurf, 0, 0, - 0, 0, w, h); - _xr_render_surface_copy(tsurf, re->mask_output, 0, 0, - x, y, w, h); - _xr_render_surface_free(tsurf); - } - } - else - { - _xr_render_surface_copy((Xrender_Surface *)surface, re->output, 0, 0, - x, y, w, h); - } - _xr_render_surface_free((Xrender_Surface *)surface); + reu = malloc(sizeof(Render_Engine_Update)); + if (!reu) return; + reu->x = x; + reu->y = y; + reu->w = w; + reu->h = h; + reu->surface = (Xrender_Surface *)surface; + re->updates = evas_list_append(re->updates, reu); } static void @@ -403,6 +408,36 @@ evas_engine_xrender_x11_output_flush(void *data) Render_Engine *re; re = (Render_Engine *)data; + while (re->updates) + { + Render_Engine_Update *reu; + + reu = re->updates->data; + re->updates = evas_list_remove_list(re->updates, re->updates); + if (re->mask_output) + { + Xrender_Surface *tsurf; + + _xr_render_surface_copy(reu->surface, re->output, 0, 0, + reu->x, reu->y, reu->w, reu->h); + tsurf = _xr_render_surface_new(re->xinf, reu->w, reu->h, re->xinf->fmt1, 1); + if (tsurf) + { + _xr_render_surface_copy(reu->surface, tsurf, 0, 0, + 0, 0, reu->w, reu->h); + _xr_render_surface_copy(tsurf, re->mask_output, 0, 0, + reu->x, reu->y, reu->w, reu->h); + _xr_render_surface_free(tsurf); + } + } + else + { + _xr_render_surface_copy(reu->surface, re->output, 0, 0, + reu->x, reu->y, reu->w, reu->h); + } + _xr_render_surface_free(reu->surface); + free(reu); + } XSync(re->disp, False); _xr_image_info_pool_flush(re->xinf, 0, 0); } @@ -621,10 +656,12 @@ static void * evas_engine_xrender_x11_image_load(void *data, char *file, char *key, int *error) { Render_Engine *re; + XR_Image *im; re = (Render_Engine *)data; *error = 0; - return _xre_image_load(re->xinf, file, key); + im = _xre_image_load(re->xinf, file, key); + return im; } static void * @@ -690,6 +727,7 @@ evas_engine_xrender_x11_image_size_set(void *data, void *image, int w, int h) image = _xre_image_copy((XR_Image *)old_image); if (image) { + ((XR_Image *)image)->alpha = old_image->alpha; _xre_image_free(old_image); } else @@ -708,21 +746,7 @@ evas_engine_xrender_x11_image_dirty_region(void *data, void *image, int x, int y re = (Render_Engine *)data; if (!image) return image; - if (((XR_Image *)image)->references > 1) - { - XR_Image *old_image; - - old_image = (XR_Image *)image; - image = _xre_image_copy((XR_Image *)old_image); - if (image) - { - _xre_image_free(old_image); - } - else - image = old_image; - } - else - _xre_image_dirty((XR_Image *)image); + _xre_image_dirty((XR_Image *)image); _xre_image_region_dirty((XR_Image *)image, x, y, w, h); return image; } @@ -744,6 +768,7 @@ evas_engine_xrender_x11_image_data_get(void *data, void *image, int to_write, DA image = _xre_image_copy((XR_Image *)old_image); if (image) { + ((XR_Image *)image)->alpha = old_image->alpha; _xre_image_free(old_image); } else @@ -769,20 +794,27 @@ evas_engine_xrender_x11_image_data_put(void *data, void *image, DATA32 *image_da old_image = (XR_Image *)image; image = _xre_image_data_find(image_data); - if (!image) + if (image != old_image) { - image = _xre_image_new_from_data(old_image->xinf, old_image->w, old_image->h, image_data); - if (image) + if (!image) { - ((XR_Image *)image)->alpha = old_image->alpha; - _xre_image_free(old_image); + image = _xre_image_new_from_data(old_image->xinf, old_image->w, old_image->h, image_data); + if (image) + { + ((XR_Image *)image)->alpha = old_image->alpha; + _xre_image_free(old_image); + } + else + image = old_image; } else - image = old_image; + { + _xre_image_free(old_image); + } } else { - _xre_image_free(old_image); + _xre_image_free(image); } } return image; diff --git a/legacy/evas/src/lib/engines/xrender_x11/evas_engine_image.c b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_image.c index e0267ad7c6..85c4380fc6 100644 --- a/legacy/evas/src/lib/engines/xrender_x11/evas_engine_image.c +++ b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_image.c @@ -238,6 +238,7 @@ _xre_image_dirty(XR_Image *im) if (im->fkey) _xr_image_hash = evas_hash_del(_xr_image_hash, im->fkey, im); im->dirty = 1; + __xre_image_dirty_hash_add(im); } XR_Image * @@ -426,7 +427,12 @@ _xre_image_data_put(XR_Image *im, void *data) _xr_render_surface_free(im->surface); im->surface = NULL; } - _xre_image_dirty(im); + if (!im->dirty) + { + if (im->fkey) + _xr_image_hash = evas_hash_del(_xr_image_hash, im->fkey, im); + im->dirty = 1; + } if (im->updates) { evas_common_tilebuf_free(im->updates); diff --git a/legacy/evas/src/lib/engines/xrender_x11/evas_engine_ximage.c b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_ximage.c index 4d4591998e..101412d670 100644 --- a/legacy/evas/src/lib/engines/xrender_x11/evas_engine_ximage.c +++ b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_ximage.c @@ -88,8 +88,8 @@ _xr_image_info_get(Display *disp, Drawable draw, Visual *vis) XSync(xinf->disp, False); XSetErrorHandler((XErrorHandler)ph); if (!_x_err) xinf->can_do_shm = 1; + shmdt(shm_info.shmaddr); } - shmdt(shm_info.shmaddr); shmctl(shm_info.shmid, IPC_RMID, 0); } XDestroyImage(xim); @@ -177,8 +177,8 @@ _xr_image_new(Ximage_Info *xinf, int w, int h, int depth) XSync(xim->xinf->disp, False); XSetErrorHandler((XErrorHandler)ph); if (!_x_err) goto xim_ok; + shmdt(xim->shm_info->shmaddr); } - shmdt(xim->shm_info->shmaddr); shmctl(xim->shm_info->shmid, IPC_RMID, 0); } XDestroyImage(xim->xim); diff --git a/legacy/evas/src/lib/engines/xrender_x11/evas_engine_xrender.c b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_xrender.c index cf85b746ce..cf4d7b16ea 100644 --- a/legacy/evas/src/lib/engines/xrender_x11/evas_engine_xrender.c +++ b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_xrender.c @@ -1,4 +1,5 @@ #include "evas_common.h" +#include "evas_macros.h" #include "evas_private.h" #include "evas_engine.h" #include "evas_engine_api_xrender_x11.h" @@ -285,19 +286,37 @@ _xr_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Dr XRenderPictureAttributes att; Picture mask; int r, g, b, a, op; + int sf; if ((sw <= 0) || (sh <= 0) || (w <= 0) || (h <= 0)) return; - xf.matrix[0][0] = (0x10000 * sw) / w; + + sf = MAX(sw, sh); +#define BMAX 26 + if (sf <= 8 ) sf = 1 << (BMAX - 3); + else if (sf <= 16 ) sf = 1 << (BMAX - 4); + else if (sf <= 32 ) sf = 1 << (BMAX - 5); + else if (sf <= 64 ) sf = 1 << (BMAX - 6); + else if (sf <= 128 ) sf = 1 << (BMAX - 7); + else if (sf <= 256 ) sf = 1 << (BMAX - 8); + else if (sf <= 512 ) sf = 1 << (BMAX - 9); + else if (sf <= 1024 ) sf = 1 << (BMAX - 10); + else if (sf <= 2048 ) sf = 1 << (BMAX - 11); + else if (sf <= 4096 ) sf = 1 << (BMAX - 12); + else if (sf <= 8192 ) sf = 1 << (BMAX - 13); + else if (sf <= 16384) sf = 1 << (BMAX - 14); + else sf = 1 << (BMAX - 15); + + xf.matrix[0][0] = (sf * sw) / w; xf.matrix[0][1] = 0; xf.matrix[0][2] = 0; xf.matrix[1][0] = 0; - xf.matrix[1][1] = (0x10000 * sh) / h; + xf.matrix[1][1] = (sf * sh) / h; xf.matrix[1][2] = 0; xf.matrix[2][0] = 0; xf.matrix[2][1] = 0; - xf.matrix[2][2] = 0x10000; + xf.matrix[2][2] = sf; op = PictOpSrc; if (srs->alpha) op = PictOpOver;