forked from enlightenment/efl
evas-wayland-shm: Fix redrawing issues that were causing 'flashing' in latest engine code.
Summary: As reported by derek & zmike, the previous engine refactor left some issues where the app would 'flash' during redraws due to buffer handling. This commit fixes that issue along with flashing during resize. @fix Signed-off-by: Chris Michael <cp.michael@samsung.com>
This commit is contained in:
parent
2725a248c9
commit
57bdbf6793
|
@ -67,6 +67,7 @@ struct _Shm_Leaf
|
|||
Shm_Data *data;
|
||||
Shm_Pool *resize_pool;
|
||||
Eina_Bool valid : 1;
|
||||
Eina_Bool reconfigure : 1;
|
||||
};
|
||||
|
||||
typedef struct _Shm_Surface Shm_Surface;
|
||||
|
@ -79,6 +80,8 @@ struct _Shm_Surface
|
|||
int w, h;
|
||||
int dx, dy;
|
||||
int num_buff;
|
||||
int last_buff;
|
||||
int curr_buff;
|
||||
|
||||
Shm_Leaf leaf[MAX_BUFFERS];
|
||||
Shm_Leaf *current;
|
||||
|
@ -116,9 +119,9 @@ struct _Outbuf
|
|||
} priv;
|
||||
};
|
||||
|
||||
Shm_Surface *_evas_shm_surface_create(struct wl_shm *shm, struct wl_surface *surface, int w, int h, Eina_Bool alpha);
|
||||
Shm_Surface *_evas_shm_surface_create(struct wl_shm *shm, struct wl_surface *surface, int w, int h, int num_buff, Eina_Bool alpha);
|
||||
void _evas_shm_surface_destroy(Shm_Surface *surface);
|
||||
void _evas_shm_surface_prepare(Shm_Surface *surface, int dx, int dy, int w, int h, int num_buff, uint32_t flags);
|
||||
void _evas_shm_surface_reconfigure(Shm_Surface *surface, int dx, int dy, int w, int h, int num_buff, uint32_t flags);
|
||||
void _evas_shm_surface_swap(Shm_Surface *surface, Eina_Rectangle *rects, unsigned int count);
|
||||
void *_evas_shm_surface_data_get(Shm_Surface *surface, int *w, int *h);
|
||||
void _evas_shm_surface_redraw(Shm_Surface *surface);
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
#endif
|
||||
#include "evas_engine.h"
|
||||
|
||||
#define RED_MASK 0x00ff0000
|
||||
#define GREEN_MASK 0x0000ff00
|
||||
#define BLUE_MASK 0x000000ff
|
||||
#define RED_MASK 0xff0000
|
||||
#define GREEN_MASK 0x00ff00
|
||||
#define BLUE_MASK 0x0000ff
|
||||
|
||||
Outbuf *
|
||||
_evas_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *shm, struct wl_surface *surface)
|
||||
|
@ -43,13 +43,10 @@ _evas_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, Eina_Bool alpha, s
|
|||
}
|
||||
|
||||
/* try to create the outbuf surface */
|
||||
if (!(ob->surface = _evas_shm_surface_create(shm, surface, w, h, alpha)))
|
||||
if (!(ob->surface =
|
||||
_evas_shm_surface_create(shm, surface, w, h, ob->num_buff, alpha)))
|
||||
goto surf_err;
|
||||
|
||||
/* call prepare function to setup first buffer */
|
||||
_evas_shm_surface_prepare(ob->surface, 0, 0, w, h,
|
||||
ob->num_buff, ob->surface->flags);
|
||||
|
||||
eina_array_step_set(&ob->priv.onebuf_regions, sizeof(Eina_Array), 8);
|
||||
|
||||
return ob;
|
||||
|
@ -64,6 +61,27 @@ _evas_outbuf_free(Outbuf *ob)
|
|||
{
|
||||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
while (ob->priv.pending_writes)
|
||||
{
|
||||
RGBA_Image *img;
|
||||
Eina_Rectangle *rect;
|
||||
|
||||
img = ob->priv.pending_writes->data;
|
||||
ob->priv.pending_writes =
|
||||
eina_list_remove_list(ob->priv.pending_writes, ob->priv.pending_writes);
|
||||
|
||||
rect = img->extended_info;
|
||||
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
evas_cache2_image_close(&img->cache_entry);
|
||||
else
|
||||
#endif
|
||||
evas_cache_image_drop(&img->cache_entry);
|
||||
|
||||
eina_rectangle_free(rect);
|
||||
}
|
||||
|
||||
_evas_outbuf_flush(ob, NULL, MODE_FULL);
|
||||
_evas_outbuf_idle_flush(ob);
|
||||
|
||||
|
@ -77,7 +95,43 @@ _evas_outbuf_free(Outbuf *ob)
|
|||
void
|
||||
_evas_outbuf_idle_flush(Outbuf *ob)
|
||||
{
|
||||
_evas_shm_surface_redraw(ob->surface);
|
||||
RGBA_Image *img;
|
||||
Eina_Rectangle *rect;
|
||||
|
||||
if (ob->priv.onebuf)
|
||||
{
|
||||
img = ob->priv.onebuf;
|
||||
ob->priv.onebuf = NULL;
|
||||
|
||||
rect = img->extended_info;
|
||||
eina_rectangle_free(rect);
|
||||
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
evas_cache2_image_close(&img->cache_entry);
|
||||
else
|
||||
#endif
|
||||
evas_cache_image_drop(&img->cache_entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (ob->priv.prev_pending_writes)
|
||||
{
|
||||
img = ob->priv.prev_pending_writes->data;
|
||||
ob->priv.prev_pending_writes =
|
||||
eina_list_remove_list(ob->priv.prev_pending_writes,
|
||||
ob->priv.prev_pending_writes);
|
||||
rect = img->extended_info;
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
evas_cache2_image_close(&img->cache_entry);
|
||||
else
|
||||
#endif
|
||||
evas_cache_image_drop(&img->cache_entry);
|
||||
|
||||
eina_rectangle_free(rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -91,12 +145,6 @@ _evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode
|
|||
|
||||
if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return;
|
||||
|
||||
if (!ob->surface->current)
|
||||
{
|
||||
WRN("Cannot Flush. No Current Leaf !!");
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for pending writes */
|
||||
if (!ob->priv.pending_writes)
|
||||
{
|
||||
|
@ -114,6 +162,8 @@ _evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode
|
|||
EINA_ARRAY_ITER_NEXT(&ob->priv.onebuf_regions, i, rect, it)
|
||||
result[i] = *rect;
|
||||
|
||||
_evas_shm_surface_redraw(ob->surface);
|
||||
|
||||
/* force a buffer swap */
|
||||
_evas_shm_surface_swap(ob->surface, result, n);
|
||||
|
||||
|
@ -197,27 +247,25 @@ _evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode
|
|||
i++;
|
||||
}
|
||||
|
||||
_evas_shm_surface_redraw(ob->surface);
|
||||
|
||||
/* force a buffer swap */
|
||||
_evas_shm_surface_swap(ob->surface, result, n);
|
||||
}
|
||||
|
||||
_evas_shm_surface_redraw(ob->surface);
|
||||
}
|
||||
|
||||
Render_Engine_Swap_Mode
|
||||
_evas_outbuf_swapmode_get(Outbuf *ob)
|
||||
{
|
||||
int i = 0, count = 0;
|
||||
int i = 0;
|
||||
|
||||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
for (; i < ob->num_buff; i++)
|
||||
{
|
||||
if (ob->surface->leaf[i].busy)
|
||||
count++;
|
||||
}
|
||||
i = (ob->surface->last_buff - ob->surface->curr_buff +
|
||||
(ob->surface->last_buff > ob->surface->last_buff ?
|
||||
0 : ob->surface->num_buff)) % ob->surface->num_buff;
|
||||
|
||||
switch (count)
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
return MODE_COPY;
|
||||
|
@ -263,8 +311,10 @@ _evas_outbuf_reconfigure(Outbuf *ob, int x, int y, int w, int h, int rot, Outbuf
|
|||
else
|
||||
ob->surface->flags = 0;
|
||||
|
||||
_evas_shm_surface_prepare(ob->surface, x, y, w, h,
|
||||
ob->num_buff, ob->surface->flags);
|
||||
_evas_shm_surface_reconfigure(ob->surface, x, y, w, h,
|
||||
ob->num_buff, ob->surface->flags);
|
||||
|
||||
_evas_outbuf_idle_flush(ob);
|
||||
}
|
||||
|
||||
void *
|
||||
|
@ -287,7 +337,7 @@ _evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx,
|
|||
|
||||
if (!(data = _evas_shm_surface_data_get(ob->surface, &bw, &bh)))
|
||||
{
|
||||
ERR("Could not get surface data");
|
||||
/* ERR("Could not get surface data"); */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -360,6 +410,8 @@ _evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
img->cache_entry.w = w;
|
||||
img->cache_entry.h = h;
|
||||
img->cache_entry.flags.alpha |= ob->priv.destination_alpha ? 1 : 0;
|
||||
|
||||
#ifdef EVAS_CSERVE2
|
||||
|
@ -462,7 +514,11 @@ _evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, in
|
|||
if (bpp <= 0) return;
|
||||
|
||||
/* check for valid desination data */
|
||||
if (!(dst = _evas_shm_surface_data_get(ob->surface, &ww, &hh))) return;
|
||||
if (!(dst = _evas_shm_surface_data_get(ob->surface, &ww, &hh)))
|
||||
{
|
||||
/* ERR("Could not get surface data"); */
|
||||
return;
|
||||
}
|
||||
|
||||
bpl = (ww * sizeof(int));
|
||||
|
||||
|
|
|
@ -1,30 +1,10 @@
|
|||
#include "evas_common_private.h"
|
||||
#include "evas_private.h"
|
||||
#ifdef EVAS_CSERVE2
|
||||
# include "evas_cs2_private.h"
|
||||
#endif
|
||||
#include "evas_engine.h"
|
||||
#include <sys/mman.h>
|
||||
|
||||
static void
|
||||
_evas_shm_surface_cb_frame(void *data, struct wl_callback *callback, uint32_t timestamp EINA_UNUSED)
|
||||
{
|
||||
Shm_Surface *surf;
|
||||
|
||||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
if (!(surf = data)) return;
|
||||
if (callback != surf->frame_cb) return;
|
||||
|
||||
wl_callback_destroy(callback);
|
||||
surf->frame_cb = NULL;
|
||||
surf->redraw = EINA_FALSE;
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener _frame_listener =
|
||||
{
|
||||
_evas_shm_surface_cb_frame
|
||||
};
|
||||
static Eina_Bool _shm_leaf_create(Shm_Surface *surface, Shm_Leaf *leaf, int w, int h);
|
||||
static void _shm_leaf_release(Shm_Leaf *leaf);
|
||||
|
||||
static struct wl_shm_pool *
|
||||
_shm_pool_make(struct wl_shm *shm, int size, void **data)
|
||||
|
@ -132,7 +112,10 @@ _shm_pool_allocate(Shm_Pool *pool, size_t size, int *offset)
|
|||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
if ((pool->used + size) > pool->size)
|
||||
return NULL;
|
||||
{
|
||||
WRN("Shm Pool Too Small");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*offset = pool->used;
|
||||
pool->used += size;
|
||||
|
@ -148,6 +131,26 @@ _shm_pool_reset(Shm_Pool *pool)
|
|||
pool->used = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_shm_frame_release(void *data, struct wl_callback *callback, uint32_t timestamp EINA_UNUSED)
|
||||
{
|
||||
Shm_Surface *surf;
|
||||
|
||||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
if (!(surf = data)) return;
|
||||
if (callback != surf->frame_cb) return;
|
||||
|
||||
wl_callback_destroy(surf->frame_cb);
|
||||
surf->frame_cb = NULL;
|
||||
surf->redraw = EINA_FALSE;
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener _shm_frame_listener =
|
||||
{
|
||||
_shm_frame_release
|
||||
};
|
||||
|
||||
static Shm_Data *
|
||||
_shm_data_create_from_pool(Shm_Pool *pool, int w, int h, Eina_Bool alpha)
|
||||
{
|
||||
|
@ -170,8 +173,7 @@ _shm_data_create_from_pool(Shm_Pool *pool, int w, int h, Eina_Bool alpha)
|
|||
if (!(data->map = _shm_pool_allocate(pool, len, &offset)))
|
||||
{
|
||||
ERR("Could not map leaf data");
|
||||
free(data);
|
||||
return NULL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (alpha)
|
||||
|
@ -183,14 +185,17 @@ _shm_data_create_from_pool(Shm_Pool *pool, int w, int h, Eina_Bool alpha)
|
|||
if (!data->buffer)
|
||||
{
|
||||
ERR("Could not create buffer from pool: %m");
|
||||
free(data);
|
||||
return NULL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
err:
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
_shm_data_create(Shm_Pool *alt_pool, Shm_Data **ret, Shm_Surface *surface, int w, int h)
|
||||
{
|
||||
Shm_Pool *pool;
|
||||
|
@ -198,6 +203,8 @@ _shm_data_create(Shm_Pool *alt_pool, Shm_Data **ret, Shm_Surface *surface, int w
|
|||
|
||||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
if (ret) *ret = NULL;
|
||||
|
||||
if (alt_pool)
|
||||
{
|
||||
_shm_pool_reset(alt_pool);
|
||||
|
@ -208,23 +215,20 @@ _shm_data_create(Shm_Pool *alt_pool, Shm_Data **ret, Shm_Surface *surface, int w
|
|||
if (!(pool = _shm_pool_create(surface->shm, ((w * sizeof(int)) * h))))
|
||||
{
|
||||
ERR("Could not create shm pool");
|
||||
goto err;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(data = _shm_data_create_from_pool(pool, w, h, surface->alpha)))
|
||||
{
|
||||
ERR("Could not create data from pool");
|
||||
_shm_pool_destroy(pool);
|
||||
goto err;
|
||||
return;
|
||||
}
|
||||
|
||||
data->pool = pool;
|
||||
|
||||
out:
|
||||
if (ret) *ret = data;
|
||||
return;
|
||||
err:
|
||||
if (ret) *ret = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -237,16 +241,6 @@ _shm_data_destroy(Shm_Data *data)
|
|||
free(data);
|
||||
}
|
||||
|
||||
static void
|
||||
_shm_leaf_release(Shm_Leaf *leaf)
|
||||
{
|
||||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
if (leaf->data) _shm_data_destroy(leaf->data);
|
||||
if (leaf->resize_pool) _shm_pool_destroy(leaf->resize_pool);
|
||||
memset(leaf, 0, sizeof(*leaf));
|
||||
}
|
||||
|
||||
static void
|
||||
_shm_buffer_release(void *data, struct wl_buffer *buffer)
|
||||
{
|
||||
|
@ -257,13 +251,20 @@ _shm_buffer_release(void *data, struct wl_buffer *buffer)
|
|||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
surf = data;
|
||||
|
||||
for (; i < surf->num_buff; i++)
|
||||
{
|
||||
leaf = &surf->leaf[i];
|
||||
if ((leaf->data) && (leaf->data->buffer == buffer))
|
||||
{
|
||||
// DBG("Buffer Released: %d", (int)(leaf - &surf->leaf[0]));
|
||||
leaf->busy = 0;
|
||||
|
||||
if (leaf->reconfigure)
|
||||
{
|
||||
_shm_leaf_release(leaf);
|
||||
_shm_leaf_create(surf, leaf, surf->w, surf->h);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -274,10 +275,43 @@ static const struct wl_buffer_listener _shm_buffer_listener =
|
|||
_shm_buffer_release
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
_shm_leaf_create(Shm_Surface *surface, Shm_Leaf *leaf, int w, int h)
|
||||
{
|
||||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
_shm_data_create(leaf->resize_pool, &leaf->data, surface, w, h);
|
||||
if (!leaf->data)
|
||||
{
|
||||
CRI("Failed to create leaf data");
|
||||
abort();
|
||||
}
|
||||
|
||||
leaf->w = w;
|
||||
leaf->h = h;
|
||||
leaf->valid = EINA_TRUE;
|
||||
|
||||
wl_buffer_add_listener(leaf->data->buffer, &_shm_buffer_listener, surface);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_shm_leaf_release(Shm_Leaf *leaf)
|
||||
{
|
||||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
if (leaf->data) _shm_data_destroy(leaf->data);
|
||||
if (leaf->resize_pool) _shm_pool_destroy(leaf->resize_pool);
|
||||
memset(leaf, 0, sizeof(*leaf));
|
||||
leaf->valid = EINA_FALSE;
|
||||
}
|
||||
|
||||
Shm_Surface *
|
||||
_evas_shm_surface_create(struct wl_shm *shm, struct wl_surface *surface, int w, int h, Eina_Bool alpha)
|
||||
_evas_shm_surface_create(struct wl_shm *shm, struct wl_surface *surface, int w, int h, int num_buff, Eina_Bool alpha)
|
||||
{
|
||||
Shm_Surface *surf;
|
||||
int i = 0;
|
||||
|
||||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
|
@ -289,10 +323,25 @@ _evas_shm_surface_create(struct wl_shm *shm, struct wl_surface *surface, int w,
|
|||
surf->h = h;
|
||||
surf->shm = shm;
|
||||
surf->surface = surface;
|
||||
surf->num_buff = num_buff;
|
||||
surf->alpha = alpha;
|
||||
surf->flags = 0;
|
||||
|
||||
/* create surface buffers */
|
||||
for (; i < surf->num_buff; i++)
|
||||
{
|
||||
if (!_shm_leaf_create(surf, &(surf->leaf[i]), w, h))
|
||||
{
|
||||
ERR("Could not create surface leaf");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
return surf;
|
||||
|
||||
err:
|
||||
_evas_shm_surface_destroy(surf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -309,23 +358,61 @@ _evas_shm_surface_destroy(Shm_Surface *surface)
|
|||
}
|
||||
|
||||
void
|
||||
_evas_shm_surface_prepare(Shm_Surface *surface, int dx, int dy, int w, int h, int num_buff, uint32_t flags)
|
||||
_evas_shm_surface_reconfigure(Shm_Surface *surface, int dx, int dy, int w, int h, int num_buff, uint32_t flags)
|
||||
{
|
||||
Shm_Leaf *leaf = NULL;
|
||||
int i = 0, resize = 0;
|
||||
|
||||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
resize = !!(flags & SURFACE_HINT_RESIZING);
|
||||
|
||||
/* update surface properties */
|
||||
for (; i < surface->num_buff; i++)
|
||||
{
|
||||
/* don't resize any busy leafs */
|
||||
if (surface->leaf[i].busy)
|
||||
{
|
||||
surface->leaf[i].reconfigure = EINA_TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* clear this leaf */
|
||||
_shm_leaf_release(&surface->leaf[i]);
|
||||
}
|
||||
|
||||
surface->w = w;
|
||||
surface->h = h;
|
||||
surface->dx = dx;
|
||||
surface->dy = dy;
|
||||
surface->flags = flags;
|
||||
surface->num_buff = num_buff;
|
||||
|
||||
for (; i < num_buff; i++)
|
||||
for (i = 0; i < surface->num_buff; i++)
|
||||
{
|
||||
if (surface->leaf[i].busy) continue;
|
||||
|
||||
if ((resize) && (!surface->leaf[i].resize_pool))
|
||||
{
|
||||
surface->leaf[i].resize_pool =
|
||||
_shm_pool_create(surface->shm, 10 * 1024 * 1024);
|
||||
}
|
||||
|
||||
if (!_shm_leaf_create(surface, &surface->leaf[i], w, h))
|
||||
{
|
||||
CRI("Failed to create leaf data");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_evas_shm_surface_swap(Shm_Surface *surface, Eina_Rectangle *rects, unsigned int count)
|
||||
{
|
||||
Shm_Leaf *leaf = NULL;
|
||||
int i = 0;
|
||||
|
||||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
for (; i < surface->num_buff; i++)
|
||||
{
|
||||
if (surface->leaf[i].busy) continue;
|
||||
if ((!leaf) || (leaf->valid))
|
||||
|
@ -337,124 +424,67 @@ _evas_shm_surface_prepare(Shm_Surface *surface, int dx, int dy, int w, int h, in
|
|||
|
||||
if (!leaf)
|
||||
{
|
||||
CRI("All buffers held by server");
|
||||
/* WRN("All buffers held by server"); */
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!resize) && (leaf->resize_pool))
|
||||
{
|
||||
_shm_data_destroy(leaf->data);
|
||||
leaf->data = NULL;
|
||||
/* DBG("Current Leaf %d", (int)(leaf - &surface->leaf[0])); */
|
||||
|
||||
_shm_pool_destroy(leaf->resize_pool);
|
||||
leaf->resize_pool = NULL;
|
||||
}
|
||||
wl_surface_attach(surface->surface, leaf->data->buffer, 0, 0);
|
||||
|
||||
if (leaf->valid)
|
||||
{
|
||||
if ((leaf->w == w) && (leaf->h == h)) goto out;
|
||||
}
|
||||
|
||||
if (leaf->data) _shm_data_destroy(leaf->data);
|
||||
leaf->data = NULL;
|
||||
|
||||
if ((resize) && (!leaf->resize_pool))
|
||||
{
|
||||
leaf->resize_pool =
|
||||
_shm_pool_create(surface->shm, 6 * 1024 * 1024);
|
||||
}
|
||||
|
||||
_shm_data_create(leaf->resize_pool, &leaf->data, surface, w, h);
|
||||
if (!leaf->data)
|
||||
{
|
||||
CRI("Failed to create leaf data");
|
||||
abort();
|
||||
}
|
||||
|
||||
leaf->w = w;
|
||||
leaf->h = h;
|
||||
leaf->valid = EINA_TRUE;
|
||||
|
||||
wl_buffer_add_listener(leaf->data->buffer, &_shm_buffer_listener, surface);
|
||||
|
||||
out:
|
||||
surface->current = leaf;
|
||||
}
|
||||
|
||||
void
|
||||
_evas_shm_surface_swap(Shm_Surface *surface, Eina_Rectangle *rects, unsigned int count)
|
||||
{
|
||||
Shm_Leaf *leaf;
|
||||
Eina_Rectangle *rect;
|
||||
|
||||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
if (!(leaf = surface->current))
|
||||
{
|
||||
ERR("No Current Leaf");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!leaf->valid)
|
||||
{
|
||||
ERR("Leaf Not Valid");
|
||||
return;
|
||||
}
|
||||
|
||||
rect = eina_rectangle_new(0, 0, 0, 0);
|
||||
if ((rects) && (count > 0))
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
for (; i < count; i++)
|
||||
eina_rectangle_union(rect, &rects[i]);
|
||||
wl_surface_damage(surface->surface,
|
||||
rects[i].x, rects[i].y,
|
||||
rects[i].w, rects[i].h);
|
||||
}
|
||||
else
|
||||
{
|
||||
Eina_Rectangle r;
|
||||
wl_surface_damage(surface->surface, 0, 0, leaf->w, leaf->h);
|
||||
|
||||
r.x = 0; r.y = 0;
|
||||
r.w = leaf->w; r.h = leaf->h;
|
||||
|
||||
eina_rectangle_union(rect, &r);
|
||||
}
|
||||
|
||||
wl_surface_attach(surface->surface, leaf->data->buffer, 0, 0);
|
||||
wl_surface_damage(surface->surface, rect->x, rect->y, rect->w, rect->h);
|
||||
wl_surface_commit(surface->surface);
|
||||
|
||||
eina_rectangle_free(rect);
|
||||
|
||||
leaf->busy = 1;
|
||||
surface->dx = 0;
|
||||
surface->dy = 0;
|
||||
surface->redraw = EINA_TRUE;
|
||||
surface->last_buff = surface->curr_buff;
|
||||
surface->curr_buff = (int)(leaf - &surface->leaf[0]);
|
||||
}
|
||||
|
||||
void *
|
||||
_evas_shm_surface_data_get(Shm_Surface *surface, int *bw, int *bh)
|
||||
_evas_shm_surface_data_get(Shm_Surface *surface, int *w, int *h)
|
||||
{
|
||||
Shm_Leaf *leaf;
|
||||
Shm_Leaf *leaf = NULL;
|
||||
int i = 0;
|
||||
|
||||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
if (bw) *bw = 0;
|
||||
if (bh) *bh = 0;
|
||||
if (w) *w = 0;
|
||||
if (h) *h = 0;
|
||||
|
||||
if (!(leaf = surface->current))
|
||||
for (; i < surface->num_buff; i++)
|
||||
{
|
||||
_evas_shm_surface_prepare(surface, 0, 0, surface->w, surface->h,
|
||||
surface->num_buff, surface->flags);
|
||||
|
||||
if (!(leaf = surface->current))
|
||||
if (surface->leaf[i].busy) continue;
|
||||
if ((!leaf) || (leaf->valid))
|
||||
{
|
||||
CRI("NO Current Surface");
|
||||
return NULL;
|
||||
leaf = &surface->leaf[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bw) *bw = leaf->w;
|
||||
if (bh) *bh = leaf->h;
|
||||
if (!leaf)
|
||||
{
|
||||
/* WRN("All buffers held by server"); */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* DBG("Leaf Data Get %d", (int)(leaf - &surface->leaf[0])); */
|
||||
|
||||
if (w) *w = leaf->w;
|
||||
if (h) *h = leaf->h;
|
||||
|
||||
return leaf->data->map;
|
||||
}
|
||||
|
@ -473,5 +503,5 @@ _evas_shm_surface_redraw(Shm_Surface *surface)
|
|||
if (!surface->surface) return;
|
||||
|
||||
surface->frame_cb = wl_surface_frame(surface->surface);
|
||||
wl_callback_add_listener(surface->frame_cb, &_frame_listener, surface);
|
||||
wl_callback_add_listener(surface->frame_cb, &_shm_frame_listener, surface);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue