diff --git a/src/modules/ecore_evas/engines/x/ecore_evas_x.c b/src/modules/ecore_evas/engines/x/ecore_evas_x.c index ac8d1b4938..48abefede7 100644 --- a/src/modules/ecore_evas/engines/x/ecore_evas_x.c +++ b/src/modules/ecore_evas/engines/x/ecore_evas_x.c @@ -236,7 +236,9 @@ _ecore_evas_x11_region_push_hook(Evas *e, int x, int y, int w, int h, { Ecore_Evas *ee; Ecore_Evas_Engine_Data_X11 *edata; - size_t size; + size_t size, src_stride; + int dy; + Eina_Bool new_buf = EINA_FALSE; ee = evas_data_attach_get(e); edata = ee->engine.data; @@ -249,10 +251,11 @@ _ecore_evas_x11_region_push_hook(Evas *e, int x, int y, int w, int h, new_fb = malloc(size); EINA_SAFETY_ON_NULL_RETURN(new_fb); free(edata->frame_buffer); - memcpy(new_fb, pixels, size); edata->frame_buffer = new_fb; edata->last_w = ee->w; edata->last_h = ee->h; + new_buf = EINA_TRUE; + if (edata->vnc_screen) { rfbNewFramebuffer(edata->vnc_screen, edata->frame_buffer, ee->w, @@ -261,17 +264,58 @@ _ecore_evas_x11_region_push_hook(Evas *e, int x, int y, int w, int h, _ecore_evas_x11_vnc_server_format_setup(edata); } } - else - { - //Partial update - int dy; - const int src_stride = w * VNC_BYTES_PER_PIXEL; - for (dy = 0; dy < h; dy++) + if (y > edata->last_h || x > edata->last_w) + return; + + //Do not paint outside the VNC canvas + if (y + h > edata->last_h) + h = edata->last_h - y; + + //Do not paint outside the VNC canvas + if (x + w > edata->last_w) + w = edata->last_w - x; + + src_stride = w * VNC_BYTES_PER_PIXEL; + + for (dy = 0; dy < h; dy++) + { + memcpy(edata->frame_buffer + (x * VNC_BYTES_PER_PIXEL) + + ((dy + y) * (edata->last_w * VNC_BYTES_PER_PIXEL)), + (char *)pixels + (dy * src_stride), src_stride); + } + + //We did not receive the whole buffer yet, zero the missing bytes for now. + if (new_buf) + { + //Missing width + if (edata->last_w != w || x != 0) { - memcpy(edata->frame_buffer + (x * VNC_BYTES_PER_PIXEL) - + ((dy + y) * (edata->last_w * VNC_BYTES_PER_PIXEL)), - (char *)pixels + (dy * src_stride), src_stride); + for (dy = 0; dy < h; dy++) + { + if (x) + { + memset(edata->frame_buffer + + ((dy + y) * (edata->last_w * VNC_BYTES_PER_PIXEL)), + 0, x * VNC_BYTES_PER_PIXEL); + } + + memset(edata->frame_buffer + + ((dy + y) * (edata->last_w * VNC_BYTES_PER_PIXEL)) + + ((x + w) * VNC_BYTES_PER_PIXEL), + 0, (edata->last_w - (w + x)) * VNC_BYTES_PER_PIXEL); + } + } + + //Missing height + if (edata->last_h != h || y != 0) + { + src_stride = edata->last_w * VNC_BYTES_PER_PIXEL; + for (dy = 0; dy < y; dy++) + memset(edata->frame_buffer + (dy * src_stride), 0, src_stride); + + for (dy = y + h; dy < edata->last_h; dy++) + memset(edata->frame_buffer + (dy * src_stride), 0, src_stride); } } @@ -5347,7 +5391,7 @@ _ecore_evas_x11_vnc_client_connection_new(rfbClientRec *client) ee = client->screen->screenData; edata = ee->engine.data; - if (!edata->accept_cb(edata->accept_cb_data, ee, client->host)) + if (edata->accept_cb && !edata->accept_cb(edata->accept_cb_data, ee, client->host)) return RFB_CLIENT_REFUSE; cdata = calloc(1, sizeof(Ecore_Evas_X11_Vnc_Client_Data)); diff --git a/src/modules/evas/engines/software_x11/evas_engine.c b/src/modules/evas/engines/software_x11/evas_engine.c index 08e151f107..44ad45ed58 100644 --- a/src/modules/evas/engines/software_x11/evas_engine.c +++ b/src/modules/evas/engines/software_x11/evas_engine.c @@ -9,6 +9,7 @@ #ifdef BUILD_ENGINE_SOFTWARE_XLIB # include "evas_xlib_outbuf.h" +# include "evas_xlib_buffer.h" # include "evas_xlib_swapbuf.h" # include "evas_xlib_color.h" # include "evas_xlib_image.h" @@ -20,6 +21,7 @@ # include "evas_xcb_color.h" # include "evas_xcb_xdefaults.h" # include "evas_xcb_image.h" +# include "evas_xcb_buffer.h" #endif #ifdef BUILD_ENGINE_SOFTWARE_XLIB @@ -33,6 +35,7 @@ #endif #include +#include Evas_Native_Tbm_Surface_Image_Set_Call glsym__evas_native_tbm_surface_image_set = NULL; Evas_Native_Tbm_Surface_Stride_Get_Call glsym__evas_native_tbm_surface_stride_get = NULL; @@ -56,6 +59,22 @@ struct _Render_Engine } egl; }; +typedef struct _Region_Push_Hook_Ctx { +#ifdef BUILD_ENGINE_SOFTWARE_XLIB + X_Output_Buffer *changed_pixels; +#else + Xcb_Output_Buffer *changed_pixels; +#endif + Outbuf *buf; + Eina_Spinlock *lock; + struct { + void (*cb)(Evas *evas, int x, int y, int w, int h, const void *pixels); + Evas *evas; + } region_push_hook; + int x; + int y; +} Region_Push_Hook_Ctx; + /* 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); @@ -66,8 +85,65 @@ static void eng_info_free(Evas *eo_e, void *info); static int eng_setup(Evas *eo_e, void *info); static void eng_output_free(void *data); +static Eina_List *_outbufs = NULL; + /* internal engine routines */ + +static void +_evas_software_x11_region_push_hook_call(void *data) +{ + Region_Push_Hook_Ctx *ctx = data; + + if (eina_list_data_find(_outbufs, ctx->buf)) + { +#ifdef BUILD_ENGINE_SOFTWARE_XLIB + ctx->region_push_hook.cb(ctx->region_push_hook.evas, ctx->x, ctx->y, + ctx->changed_pixels->xim->width, + ctx->changed_pixels->xim->height, + evas_software_xlib_x_output_buffer_data(ctx->changed_pixels, NULL)); + eina_spinlock_take(ctx->lock); + evas_software_xlib_x_output_buffer_unref(ctx->changed_pixels, 0); + eina_spinlock_release(ctx->lock); +#else + ctx->region_push_hook.cb(ctx->region_push_hook.evas, ctx->x, ctx->y, + ctx->changed_pixels->xim->width, + ctx->changed_pixels->xim->height, + evas_software_xcb_output_buffer_data(ctx->changed_pixels, NULL)); + eina_spinlock_take(ctx->lock); + evas_software_xcb_output_buffer_unref(ctx->changed_pixels, EINA_FALSE); + eina_spinlock_release(ctx->lock); +#endif + } + free(ctx); +} + +void +evas_software_x11_region_push_hook_call(Outbuf *buf, int x, int y, void *out_buf, + Eina_Spinlock *lock) +{ + Region_Push_Hook_Ctx *ctx; + + if (!buf->region_push_hook.cb) + return; + + ctx = malloc(sizeof(Region_Push_Hook_Ctx)); + EINA_SAFETY_ON_NULL_RETURN(ctx); + ctx->x = x; + ctx->y = y; + ctx->region_push_hook.cb = buf->region_push_hook.cb; + ctx->region_push_hook.evas = buf->region_push_hook.evas; +#ifdef BUILD_ENGINE_SOFTWARE_XLIB + ctx->changed_pixels = evas_software_xlib_x_output_buffer_ref(out_buf); +#else + ctx->changed_pixels = evas_software_xcb_output_buffer_ref(out_buf); +#endif + ctx->buf = buf; + ctx->lock = lock; + ecore_main_loop_thread_safe_call_async(_evas_software_x11_region_push_hook_call, + ctx); +} + #ifdef BUILD_ENGINE_SOFTWARE_XLIB /* @@ -135,23 +211,6 @@ _output_egl_setup(int w, int h, int rot, Display *disp, Drawable draw, } */ - -void -evas_software_x11_region_push_hook_call(Outbuf *buf, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, - const void *pixels EINA_UNUSED) -{ - /* int err; */ - - if (!buf->region_push_hook.cb) - return; -/* - err = ecore_thread_main_loop_begin(); - EINA_SAFETY_ON_TRUE_RETURN(err == -1); - buf->region_push_hook.cb(buf->region_push_hook.evas, x, y, w, h, pixels); - ecore_thread_main_loop_end(); - */ -} - static void _output_egl_shutdown(Render_Engine *re) { @@ -563,6 +622,8 @@ eng_setup(Evas *eo_e, void *in) info->info.mask, info->info.shape_dither, info->info.destination_alpha); re->outbuf_alpha_get = evas_software_xcb_outbuf_alpha_get; + re->generic.ob->region_push_hook.cb = info->func.region_push_hook; + re->generic.ob->region_push_hook.evas = eo_e; } #endif @@ -576,6 +637,8 @@ eng_setup(Evas *eo_e, void *in) re = e->engine.data.output; /* if ((re) && (re->ob)) ponebuf = re->ob->onebuf; */ + _outbufs = eina_list_remove(_outbufs, re->generic.ob); + #ifdef BUILD_ENGINE_SOFTWARE_XLIB if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB) { @@ -656,6 +719,7 @@ eng_setup(Evas *eo_e, void *in) } re = e->engine.data.output; + _outbufs = eina_list_append(_outbufs, re->generic.ob); return 1; } @@ -667,6 +731,7 @@ eng_output_free(void *data) if ((re = (Render_Engine *)data)) { + _outbufs = eina_list_remove(_outbufs, re->generic.ob); evas_render_engine_software_generic_clean(&re->generic); #ifdef BUILD_ENGINE_SOFTWARE_XLIB _output_egl_shutdown(re); diff --git a/src/modules/evas/engines/software_x11/evas_engine.h b/src/modules/evas/engines/software_x11/evas_engine.h index 5999e6823a..2be0966605 100644 --- a/src/modules/evas/engines/software_x11/evas_engine.h +++ b/src/modules/evas/engines/software_x11/evas_engine.h @@ -123,6 +123,6 @@ struct _Outbuf void evas_software_xlib_x_init(void); void evas_software_xcb_init(void); -void evas_software_x11_region_push_hook_call(Outbuf *buf, int x, int y, int w, int h, const void *pixels); +void evas_software_x11_region_push_hook_call(Outbuf *buf, int x, int y, void *out_buf, Eina_Spinlock *lock); #endif diff --git a/src/modules/evas/engines/software_x11/evas_xcb_buffer.c b/src/modules/evas/engines/software_x11/evas_xcb_buffer.c index ff90a6898c..6dbd579eca 100644 --- a/src/modules/evas/engines/software_x11/evas_xcb_buffer.c +++ b/src/modules/evas/engines/software_x11/evas_xcb_buffer.c @@ -243,7 +243,7 @@ evas_software_xcb_can_do_shm(xcb_connection_t *conn, xcb_screen_t *screen) cached_result = 0; else { - evas_software_xcb_output_buffer_free(xcbob, EINA_TRUE); + evas_software_xcb_output_buffer_unref(xcbob, EINA_TRUE); cached_result = 1; } } @@ -267,6 +267,7 @@ evas_software_xcb_output_buffer_new(xcb_connection_t *conn, xcb_visualtype_t *vi xcbob->shm_info = NULL; xcbob->w = w; xcbob->h = h; + xcbob->refcount = 1; if (try_shm > 0) { @@ -352,9 +353,23 @@ evas_software_xcb_output_buffer_new(xcb_connection_t *conn, xcb_visualtype_t *vi return xcbob; } -void -evas_software_xcb_output_buffer_free(Xcb_Output_Buffer *xcbob, Eina_Bool sync) +Xcb_Output_Buffer * +evas_software_xcb_output_buffer_ref(Xcb_Output_Buffer *xcbob) { + if (xcbob->refcount == UINT_MAX) + return NULL; + xcbob->refcount++; + return xcbob; +} + +void +evas_software_xcb_output_buffer_unref(Xcb_Output_Buffer *xcbob, Eina_Bool sync) +{ + if (!xcbob->refcount) + return; + xcbob->refcount--; + if (xcbob->refcount) + return; if (xcbob->shm_info) { if (sync) _xcbob_sync(xcbob->connection); diff --git a/src/modules/evas/engines/software_x11/evas_xcb_buffer.h b/src/modules/evas/engines/software_x11/evas_xcb_buffer.h index dc1f0b43cd..6e73e5a5dd 100644 --- a/src/modules/evas/engines/software_x11/evas_xcb_buffer.h +++ b/src/modules/evas/engines/software_x11/evas_xcb_buffer.h @@ -12,6 +12,7 @@ struct _Xcb_Output_Buffer xcb_shm_segment_info_t *shm_info; unsigned char *data; int w, h, bpl, psize; + unsigned int refcount; }; void evas_software_xcb_write_mask_line(Outbuf *buf, Xcb_Output_Buffer *xcbob, DATA32 *src, int w, int y); @@ -20,7 +21,8 @@ void evas_software_xcb_write_mask_line_vert(Outbuf *buf, Xcb_Output_Buffer *xcbo 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, int 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_unref(Xcb_Output_Buffer *xcbob, Eina_Bool sync); +Xcb_Output_Buffer *evas_software_xcb_output_buffer_ref(Xcb_Output_Buffer *xcbob); 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); diff --git a/src/modules/evas/engines/software_x11/evas_xcb_outbuf.c b/src/modules/evas/engines/software_x11/evas_xcb_outbuf.c index b376600fb3..dd8af98b6c 100644 --- a/src/modules/evas/engines/software_x11/evas_xcb_outbuf.c +++ b/src/modules/evas/engines/software_x11/evas_xcb_outbuf.c @@ -139,7 +139,7 @@ evas_software_xcb_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, xcb_co return NULL; } buf->priv.x11.xcb.imdepth = evas_software_xcb_output_buffer_depth(xob); - evas_software_xcb_output_buffer_free(xob, EINA_FALSE); + evas_software_xcb_output_buffer_unref(xob, EINA_FALSE); eina_array_step_set(&buf->priv.onebuf_regions, sizeof(Eina_Array), 8); @@ -368,7 +368,7 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w, if (!im) { - evas_software_xcb_output_buffer_free(obr->xcbob, EINA_FALSE); + evas_software_xcb_output_buffer_unref(obr->xcbob, EINA_FALSE); free(obr); eina_spinlock_release(&(buf->priv.lock)); return NULL; @@ -681,9 +681,8 @@ evas_software_xcb_outbuf_flush(Outbuf *buf, Tilebuf_Rect *surface_damage EINA_UN (const xcb_rectangle_t *)pixman_region_rectangles(&tmpr, NULL)); if (obr->xcbob) { - evas_software_x11_region_push_hook_call(buf, 0, 0, obr->xcbob->xim->width, - obr->xcbob->xim->height, - evas_software_xcb_output_buffer_data(obr->xcbob, NULL)); + evas_software_x11_region_push_hook_call(buf, 0, 0, obr->xcbob, + &shmpool_lock); evas_software_xcb_output_buffer_paste(obr->xcbob, buf->priv.x11.xcb.win, buf->priv.x11.xcb.gc, 0, 0, 0); @@ -716,9 +715,8 @@ evas_software_xcb_outbuf_flush(Outbuf *buf, Tilebuf_Rect *surface_damage EINA_UN if (obr->xcbob) { evas_software_x11_region_push_hook_call(buf, obr->x, obr->y, - obr->xcbob->xim->width, - obr->xcbob->xim->height, - evas_software_xcb_output_buffer_data(obr->xcbob, NULL)); + obr->xcbob, + &shmpool_lock); evas_software_xcb_output_buffer_paste(obr->xcbob, buf->priv.x11.xcb.win, buf->priv.x11.xcb.gc, @@ -796,10 +794,18 @@ evas_software_xcb_outbuf_idle_flush(Outbuf *buf) 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); + if (obr->xcbob) + { + SHMPOOL_LOCK(); + evas_software_xcb_output_buffer_unref(obr->xcbob, EINA_FALSE); + SHMPOOL_UNLOCK(); + } + if (obr->mask) + { + SHMPOOL_LOCK(); + evas_software_xcb_output_buffer_unref(obr->mask, EINA_FALSE); + SHMPOOL_UNLOCK(); + } free(obr); # ifdef EVAS_CSERVE2 if (evas_cserve2_use_get()) @@ -972,9 +978,8 @@ evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, in if (obr->xcbob) { evas_software_x11_region_push_hook_call(buf, obr->x, obr->y, - obr->xcbob->xim->width, - obr->xcbob->xim->height, - evas_software_xcb_output_buffer_data(obr->xcbob, NULL)); + obr->xcbob, + &shmpool_lock); evas_software_xcb_output_buffer_paste(obr->xcbob, buf->priv.x11.xcb.win, buf->priv.x11.xcb.gc, @@ -1269,12 +1274,16 @@ _unfind_xcbob(Xcb_Output_Buffer *xcbob, Eina_Bool sync) 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); + evas_software_xcb_output_buffer_unref(xcbob, sync); } SHMPOOL_UNLOCK(); } else - evas_software_xcb_output_buffer_free(xcbob, sync); + { + SHMPOOL_LOCK(); + evas_software_xcb_output_buffer_unref(xcbob, sync); + SHMPOOL_UNLOCK(); + } } static void @@ -1287,7 +1296,7 @@ _clear_xcbob(Eina_Bool sync) xcbob = _shmpool->data; _shmpool = eina_list_remove_list(_shmpool, _shmpool); - evas_software_xcb_output_buffer_free(xcbob, sync); + evas_software_xcb_output_buffer_unref(xcbob, sync); } _shmsize = 0; SHMPOOL_UNLOCK(); diff --git a/src/modules/evas/engines/software_x11/evas_xlib_buffer.c b/src/modules/evas/engines/software_x11/evas_xlib_buffer.c index 6ab127839f..b88571d8a1 100644 --- a/src/modules/evas/engines/software_x11/evas_xlib_buffer.c +++ b/src/modules/evas/engines/software_x11/evas_xlib_buffer.c @@ -244,7 +244,7 @@ evas_software_xlib_x_can_do_shm(Display *d) cached_result = 0; return 0; } - evas_software_xlib_x_output_buffer_free(xob, 1); + evas_software_xlib_x_output_buffer_unref(xob, 1); cached_result = 1; return 1; } @@ -275,6 +275,7 @@ evas_software_xlib_x_output_buffer_new(Display *d, Visual *v, int depth, int w, xob->shm_info = NULL; xob->w = w; xob->h = h; + xob->refcount = 1; if (try_shm > 0) { @@ -370,9 +371,23 @@ evas_software_xlib_x_output_buffer_new(Display *d, Visual *v, int depth, int w, return xob; } -void -evas_software_xlib_x_output_buffer_free(X_Output_Buffer *xob, int psync) +X_Output_Buffer * +evas_software_xlib_x_output_buffer_ref(X_Output_Buffer *xob) { + if (xob->refcount == UINT_MAX) + return NULL; + xob->refcount++; + return xob; +} + +void +evas_software_xlib_x_output_buffer_unref(X_Output_Buffer *xob, int psync) +{ + if (!xob->refcount) + return; + xob->refcount--; + if (xob->refcount) + return; if (xob->shm_info) { if (psync) XSync(xob->display, False); diff --git a/src/modules/evas/engines/software_x11/evas_xlib_buffer.h b/src/modules/evas/engines/software_x11/evas_xlib_buffer.h index 01c4db0320..703ddcbc38 100644 --- a/src/modules/evas/engines/software_x11/evas_xlib_buffer.h +++ b/src/modules/evas/engines/software_x11/evas_xlib_buffer.h @@ -18,6 +18,7 @@ struct _X_Output_Buffer int h; int bpl; int psize; + unsigned int refcount; }; void evas_software_xlib_x_write_mask_line (Outbuf *buf, X_Output_Buffer *xob, DATA32 *src, int w, int y); @@ -29,7 +30,9 @@ int evas_software_xlib_x_can_do_shm (Display *d); X_Output_Buffer *evas_software_xlib_x_output_buffer_new (Display *d, Visual *v, int depth, int w, int h, int try_shm, void *data); -void evas_software_xlib_x_output_buffer_free (X_Output_Buffer *xob, int sync); +void evas_software_xlib_x_output_buffer_unref (X_Output_Buffer *xob, int sync); + +X_Output_Buffer *evas_software_xlib_x_output_buffer_ref(X_Output_Buffer *xob); void evas_software_xlib_x_output_buffer_paste (X_Output_Buffer *xob, Drawable d, GC gc, int x, int y, int sync); diff --git a/src/modules/evas/engines/software_x11/evas_xlib_outbuf.c b/src/modules/evas/engines/software_x11/evas_xlib_outbuf.c index 0fb671c164..ce8388172b 100644 --- a/src/modules/evas/engines/software_x11/evas_xlib_outbuf.c +++ b/src/modules/evas/engines/software_x11/evas_xlib_outbuf.c @@ -124,12 +124,16 @@ _unfind_xob(X_Output_Buffer *xob, int psync) xob = xl->data; shmpool = eina_list_remove_list(shmpool, xl); shmsize -= xob->psize * xob->xim->depth / 8; - evas_software_xlib_x_output_buffer_free(xob, psync); + evas_software_xlib_x_output_buffer_unref(xob, psync); } SHMPOOL_UNLOCK(); } else - evas_software_xlib_x_output_buffer_free(xob, psync); + { + SHMPOOL_LOCK(); + evas_software_xlib_x_output_buffer_unref(xob, psync); + SHMPOOL_UNLOCK(); + } } static void @@ -142,7 +146,7 @@ _clear_xob(int psync) xob = shmpool->data; shmpool = eina_list_remove_list(shmpool, shmpool); - evas_software_xlib_x_output_buffer_free(xob, psync); + evas_software_xlib_x_output_buffer_unref(xob, psync); } shmsize = 0; SHMPOOL_UNLOCK(); @@ -318,12 +322,12 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth, /* FIXME: only alloc once per display+cmap */ buf->priv.pal = evas_software_xlib_x_color_allocate(disp, cmap, vis, pm); - if (!buf->priv.pal) - { - if (xob) evas_software_xlib_x_output_buffer_free(xob, 1); - free(buf); - return NULL; - } + if (!buf->priv.pal) + { + if (xob) evas_software_xlib_x_output_buffer_unref(xob, 1); + free(buf); + return NULL; + } } if (buf->priv.pal) { @@ -362,7 +366,7 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth, buf->rot); } buf->priv.x11.xlib.imdepth = evas_software_xlib_x_output_buffer_depth(xob); - evas_software_xlib_x_output_buffer_free(xob, 1); + evas_software_xlib_x_output_buffer_unref(xob, 1); if (!conv_func) { ERR("At depth: %i, RGB format mask: %08x %08x %08x, " @@ -479,7 +483,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w alpha, EVAS_COLORSPACE_ARGB8888); if (!im) { - evas_software_xlib_x_output_buffer_free(obr->xob, 0); + evas_software_xlib_x_output_buffer_unref(obr->xob, 0); free(obr); eina_spinlock_release(&(buf->priv.lock)); return NULL; @@ -819,9 +823,8 @@ evas_software_xlib_outbuf_flush(Outbuf *buf, Tilebuf_Rect *surface_damage EINA_U XSetRegion(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gc, tmpr); if (obr->xob) { - evas_software_x11_region_push_hook_call(buf, 0, 0, obr->xob->xim->width, - obr->xob->xim->height, - evas_software_xlib_x_output_buffer_data(obr->xob, NULL)); + evas_software_x11_region_push_hook_call(buf, 0, 0, obr->xob, + &shmpool_lock); evas_software_xlib_x_output_buffer_paste(obr->xob, buf->priv.x11.xlib.win, buf->priv.x11.xlib.gc, 0, 0, 0); @@ -850,9 +853,7 @@ evas_software_xlib_outbuf_flush(Outbuf *buf, Tilebuf_Rect *surface_damage EINA_U if (obr->xob) { evas_software_x11_region_push_hook_call(buf, obr->x, obr->y, - obr->xob->xim->width, - obr->xob->xim->height, - evas_software_xlib_x_output_buffer_data(obr->xob, NULL)); + obr->xob, &shmpool_lock); evas_software_xlib_x_output_buffer_paste(obr->xob, buf->priv.x11.xlib.win, buf->priv.x11.xlib.gc, obr->x, obr->y, 0); @@ -952,8 +953,18 @@ evas_software_xlib_outbuf_idle_flush(Outbuf *buf) im = buf->priv.onebuf; buf->priv.onebuf = NULL; obr = im->extended_info; - if (obr->xob) evas_software_xlib_x_output_buffer_free(obr->xob, 0); - if (obr->mxob) evas_software_xlib_x_output_buffer_free(obr->mxob, 0); + if (obr->xob) + { + SHMPOOL_LOCK(); + evas_software_xlib_x_output_buffer_unref(obr->xob, 0); + SHMPOOL_UNLOCK(); + } + if (obr->mxob) + { + SHMPOOL_LOCK(); + evas_software_xlib_x_output_buffer_unref(obr->mxob, 0); + SHMPOOL_UNLOCK(); + } free(obr); #ifdef EVAS_CSERVE2 if (evas_cserve2_use_get()) @@ -1137,9 +1148,7 @@ evas_software_xlib_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, i if (obr->xob) { evas_software_x11_region_push_hook_call(buf, obr->x, obr->y, - obr->xob->xim->width, - obr->xob->xim->height, - evas_software_xlib_x_output_buffer_data(obr->xob, NULL)); + obr->xob, &shmpool_lock); evas_software_xlib_x_output_buffer_paste(obr->xob, buf->priv.x11.xlib.win, buf->priv.x11.xlib.gc, obr->x, obr->y, 0);