This series fixes two problems in the VNC implementation.

One deadlock and one segfault.

Patch 1:

Software X11 Evas Engine: Fix deadlock

Summary:
The patch bc6e8d2692 introduced a callback responsible to notify the pixels
that were sent to the X server. Since all EFL rendering is done by another
thread, the callback should be called from the main thread context.
To achieve this behaviour evas_software_x11_region_push_hook_call()
was using ecore_thread_main_loop_begin(), which may cause deadlocks, since
evas mainloop waits for the render thread and the render thread waits
the mainloop.

In order to fix this problem, the function
ecore_main_loop_thread_safe_call_async() will be used to
schedule the callback to run in the main loop context.

Since a callback is schedule to run in async manner, the pixels that
were sent to the X server must not be deleted until the user is informed.
In order to avoid more mallocs(), this patch adds the support for refcounts to the
X_Output_Buffer and Xcb_Output_Buffer.

Patch 2:

Ecore_Evas VNC: Use the image size to create the buffer.

In same cases they may differ and may lead to a segfault, since
memcpy() causes a buffer overrun.

Reviewers: bdilly, raster

Reviewed By: raster

Subscribers: cedric, jpeg

Differential Revision: https://phab.enlightenment.org/D4323
This commit is contained in:
Guilherme Iscaro 2016-10-21 13:56:00 +09:00 committed by Carsten Haitzler (Rasterman)
parent 094c9091b4
commit 8040d20f90
9 changed files with 240 additions and 78 deletions

View File

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

View File

@ -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 <Ecore.h>
#include <Eina.h>
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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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