#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)
}
/* 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;
{
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);
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
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)
{
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);
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;
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 *
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;
}
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
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));
#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)
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;
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)
{
if (!(data->map = _shm_pool_allocate(pool, len, &offset)))
{
ERR("Could not map leaf data");
- free(data);
- return NULL;
+ goto err;
}
if (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;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (ret) *ret = NULL;
+
if (alt_pool)
{
_shm_pool_reset(alt_pool);
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
}
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)
{
Shm_Surface *surf;
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;
}
}
_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__);
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
}
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 ((!leaf) || (leaf->valid))
+
+ if ((resize) && (!surface->leaf[i].resize_pool))
{
- leaf = &surface->leaf[i];
- break;
+ surface->leaf[i].resize_pool =
+ _shm_pool_create(surface->shm, 10 * 1024 * 1024);
}
- }
- if (!leaf)
- {
- CRI("All buffers held by server");
- return;
- }
-
- if ((!resize) && (leaf->resize_pool))
- {
- _shm_data_destroy(leaf->data);
- leaf->data = NULL;
-
- _shm_pool_destroy(leaf->resize_pool);
- leaf->resize_pool = NULL;
- }
-
- 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();
+ if (!_shm_leaf_create(surface, &surface->leaf[i], w, h))
+ {
+ 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;
+ Shm_Leaf *leaf = NULL;
+ int i = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
- if (!(leaf = surface->current))
+ for (; i < surface->num_buff; i++)
{
- ERR("No Current Leaf");
- return;
+ if (surface->leaf[i].busy) continue;
+ if ((!leaf) || (leaf->valid))
+ {
+ leaf = &surface->leaf[i];
+ break;
+ }
}
- if (!leaf->valid)
+ if (!leaf)
{
- ERR("Leaf Not Valid");
+ /* WRN("All buffers held by server"); */
return;
}
- rect = eina_rectangle_new(0, 0, 0, 0);
+ /* DBG("Current Leaf %d", (int)(leaf - &surface->leaf[0])); */
+
+ wl_surface_attach(surface->surface, leaf->data->buffer, 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;
-
- r.x = 0; r.y = 0;
- r.w = leaf->w; r.h = leaf->h;
+ wl_surface_damage(surface->surface, 0, 0, leaf->w, 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;
}
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);
}