big patch from Samsung SAIT (Advanced research group) for async multi-frame

rendering. to turn on:

1.
configure with --enable-async-render
2.
export EVAS_RENDER_MODE=non-blocking
  
presto. necessitates some api swizzling (thus the expedite. ecore etc. changes)

the kind of results you get on a desktop:

http://www.rasterman.com/files/evas-async-vs-none.html



SVN revision: 49087
This commit is contained in:
Carsten Haitzler 2010-05-21 07:10:45 +00:00
parent 2133ccd144
commit eaad0eb095
69 changed files with 2399 additions and 293 deletions

View File

@ -29,3 +29,5 @@ Lars Munch <lars@segv.dk>
Andre Dieb <andre.dieb@gmail.com> Andre Dieb <andre.dieb@gmail.com>
Mathieu Taillefumier <mathieu.taillefumier@free.fr> Mathieu Taillefumier <mathieu.taillefumier@free.fr>
Rui Miguel Silva Seabra <rms@1407.org> Rui Miguel Silva Seabra <rms@1407.org>
Saumsung Electronics <tbd>
Samsung SAIT <tbd>

View File

@ -57,6 +57,8 @@ extern int _ecore_log_dom ;
# define CLAMP(x, min, max) (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x))) # define CLAMP(x, min, max) (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x)))
#endif #endif
#define EVAS_FRAME_QUEUING 1 /* for test */
#define READBUFSIZ 65536 #define READBUFSIZ 65536
#define ECORE_MAGIC_NONE 0x1234fedc #define ECORE_MAGIC_NONE 0x1234fedc

View File

@ -237,9 +237,21 @@ _ecore_evas_x_render(Ecore_Evas *ee)
EINA_LIST_FOREACH(updates, l, r) EINA_LIST_FOREACH(updates, l, r)
ecore_x_window_area_clear(ee->prop.window, r->x, r->y, r->w, r->h); ecore_x_window_area_clear(ee->prop.window, r->x, r->y, r->w, r->h);
if ((ee->shaped) && (updates)) if ((ee->shaped) && (updates))
ecore_x_window_shape_mask_set(ee->prop.window, ee->engine.x.mask); {
// if ((ee->alpha) && (updates)) #ifdef EVAS_FRAME_QUEUING
// ecore_x_window_shape_input_mask_set(ee->prop.window, ee->engine.x.mask); /* wait until ee->engine.x.mask being updated */
evas_sync(ee->evas);
#endif
ecore_x_window_shape_mask_set(ee->prop.window, ee->engine.x.mask);
}
if ((ee->alpha) && (updates))
{
#ifdef EVAS_FRAME_QUEUING
/* wait until ee->engine.x.mask being updated */
// evas_sync(ee->evas);
#endif
// ecore_x_window_shape_input_mask_set(ee->prop.window, ee->engine.x.mask);
}
evas_render_updates_free(updates); evas_render_updates_free(updates);
_ecore_evas_idle_timeout_update(ee); _ecore_evas_idle_timeout_update(ee);
rend = 1; rend = 1;
@ -351,14 +363,25 @@ _ecore_evas_x_render(Ecore_Evas *ee)
((ee->should_be_visible) && (ee->prop.fullscreen)) || ((ee->should_be_visible) && (ee->prop.fullscreen)) ||
((ee->should_be_visible) && (ee->prop.override))) ((ee->should_be_visible) && (ee->prop.override)))
{ {
updates = evas_render_updates(ee->evas); updates = evas_render_updates(ee->evas);
if (updates) if (updates)
{ {
if (ee->shaped) if (ee->shaped)
ecore_x_window_shape_mask_set(ee->prop.window, ee->engine.x.mask); {
// if (ee->alpha) #ifdef EVAS_FRAME_QUEUING
// ecore_x_window_shape_input_mask_set(ee->prop.window, ee->engine.x.mask); /* wait until ee->engine.x.mask being updated */
evas_sync(ee->evas);
#endif
ecore_x_window_shape_mask_set(ee->prop.window, ee->engine.x.mask);
}
if (ee->alpha)
{
#ifdef EVAS_FRAME_QUEUING
/* wait until ee->engine.x.mask being updated */
// evas_sync(ee->evas);
#endif
// ecore_x_window_shape_input_mask_set(ee->prop.window, ee->engine.x.mask);
}
evas_render_updates_free(updates); evas_render_updates_free(updates);
_ecore_evas_idle_timeout_update(ee); _ecore_evas_idle_timeout_update(ee);
rend = 1; rend = 1;
@ -2829,6 +2852,17 @@ ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent,
einfo->info.backend = EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB; einfo->info.backend = EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB;
einfo->info.connection = ecore_x_display_get(); einfo->info.connection = ecore_x_display_get();
einfo->info.screen = NULL; einfo->info.screen = NULL;
#ifdef EVAS_FRAME_QUEUING
{
char *render_mode;
render_mode = getenv("EVAS_RENDER_MODE");
if (render_mode && !strcmp(render_mode, "non-blocking"))
{
einfo->render_mode = EVAS_RENDER_MODE_NONBLOCKING;
}
}
#endif
# endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */ # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
einfo->info.drawable = ee->prop.window; einfo->info.drawable = ee->prop.window;
if (argb) if (argb)

View File

@ -254,6 +254,9 @@ ecore_x_init(const char *name)
_ecore_xlib_log_dom = -1; _ecore_xlib_log_dom = -1;
return --_ecore_x_init_count; return --_ecore_x_init_count;
} }
#ifdef EVAS_FRAME_QUEUING
XInitThreads();
#endif
_ecore_x_disp = XOpenDisplay((char *)name); _ecore_x_disp = XOpenDisplay((char *)name);
if (!_ecore_x_disp) if (!_ecore_x_disp)
goto shutdown_ecore_event; goto shutdown_ecore_event;

View File

@ -18,3 +18,5 @@ Tom Hacohen <tom@stosb.com>
Mathieu Taillefumier <mathieu.taillefumier@free.fr> Mathieu Taillefumier <mathieu.taillefumier@free.fr>
Iván Briano <ivan@profusion.mobi> Iván Briano <ivan@profusion.mobi>
Gustavo Lima Chaves <glima@profusion.mobi> Gustavo Lima Chaves <glima@profusion.mobi>
Saumsung Electronics <tbd>
Samsung SAIT <tbd>

View File

@ -275,3 +275,8 @@ NOTES:
For the arm optimizations you want to try: For the arm optimizations you want to try:
export CFLAGS="-O2 -march=armv5te -mcpu=arm1136jf-s -fomit-frame-pointer" export CFLAGS="-O2 -march=armv5te -mcpu=arm1136jf-s -fomit-frame-pointer"
To enable the async renderer compile with:
--enable-async-render
and also runtime set this environment variable:
export EVAS_RENDER_MODE=non-blocking

View File

@ -760,6 +760,38 @@ else
build_pipe_render="no" build_pipe_render="no"
fi fi
#######################################
## Async Renderer
build_async_render="no"
AC_MSG_CHECKING(whether to build Asynchronously Threaded Pipe Rendering support)
AC_ARG_ENABLE(async-render,
AC_HELP_STRING([--enable-async-render], [enable asynchronously threaded pipe rendering support]),
[ build_async_render=$enableval ]
)
AC_MSG_RESULT($build_async_render)
AC_MSG_CHECKING(whether we can build Asynchronously Threaded Pipe Rendering support)
if test \( "x$build_async_render" = "xyes" \); then
AC_MSG_RESULT(yes)
AC_DEFINE(EVAS_FRAME_QUEUING, 1, [Build async render support])
build_async_render="yes"
AC_DEFINE(BUILD_PIPE_RENDER, 1, [Build pipe render support])
build_pipe_render="yes"
need_pthreads="yes"
PKG_CHECK_MODULES([XEXT],
[xext < 1.1.1],
[ build_avoid_libXext_bug=yes ],
[ build_avoid_libXext_bug=no ]
)
if test \( "x$build_avoid_libXext_bug" = "xyes" \); then
AC_DEFINE(LIBXEXT_VERSION_LOW, 1, [To avoid bug on old libXext version])
fi
else
AC_MSG_RESULT(no)
build_async_render="no"
fi
####################################### #######################################
## Async events ## Async events
build_async_events="auto" build_async_events="auto"
@ -1453,6 +1485,7 @@ echo " MAGIC_DEBUG.............: $want_evas_magic_debug"
echo " Cache Server............: $want_evas_cserve" echo " Cache Server............: $want_evas_cserve"
echo echo
echo " Threaded Pipe Rendering.: $build_pipe_render" echo " Threaded Pipe Rendering.: $build_pipe_render"
echo " Async Pipe Rendering....: $build_async_render"
echo " Async Events............: $build_async_events" echo " Async Events............: $build_async_events"
echo " Async Image Preload.....: $build_async_preload" echo " Async Image Preload.....: $build_async_preload"
echo echo

View File

@ -373,6 +373,12 @@ typedef enum _Evas_Image_Scale_Hint
EVAS_IMAGE_SCALE_HINT_STATIC = 2 EVAS_IMAGE_SCALE_HINT_STATIC = 2
} Evas_Image_Scale_Hint; } Evas_Image_Scale_Hint;
typedef enum _Evas_Engine_Render_Mode
{
EVAS_RENDER_MODE_BLOCKING = 0,
EVAS_RENDER_MODE_NONBLOCKING = 1,
} Evas_Engine_Render_Mode;
typedef enum _Evas_Image_Content_Hint typedef enum _Evas_Image_Content_Hint
{ {
EVAS_IMAGE_CONTENT_HINT_NONE = 0, EVAS_IMAGE_CONTENT_HINT_NONE = 0,
@ -721,6 +727,7 @@ extern "C" {
EAPI void evas_pointer_canvas_xy_get (const Evas *e, Evas_Coord *x, Evas_Coord *y) EINA_ARG_NONNULL(1); EAPI void evas_pointer_canvas_xy_get (const Evas *e, Evas_Coord *x, Evas_Coord *y) EINA_ARG_NONNULL(1);
EAPI int evas_pointer_button_down_mask_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); EAPI int evas_pointer_button_down_mask_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
EAPI Eina_Bool evas_pointer_inside_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); EAPI Eina_Bool evas_pointer_inside_get (const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
EAPI void evas_sync(Evas *e) EINA_ARG_NONNULL(1);
/** /**

View File

@ -60,6 +60,9 @@ struct _Evas_Cache_Image
int usage; int usage;
int limit; int limit;
int references; int references;
#ifdef EVAS_FRAME_QUEUING
LK(lock);
#endif
}; };
struct _Evas_Cache_Engine_Image_Func struct _Evas_Cache_Engine_Image_Func

View File

@ -58,7 +58,13 @@ _evas_cache_image_make_dirty(Evas_Cache_Image *cache,
im->flags.dirty = 1; im->flags.dirty = 1;
im->flags.activ = 0; im->flags.activ = 0;
im->flags.lru_nodata = 0; im->flags.lru_nodata = 0;
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
cache->dirty = eina_inlist_prepend(cache->dirty, EINA_INLIST_GET(im)); cache->dirty = eina_inlist_prepend(cache->dirty, EINA_INLIST_GET(im));
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
if (im->cache_key) if (im->cache_key)
{ {
@ -80,7 +86,13 @@ _evas_cache_image_make_activ(Evas_Cache_Image *cache,
im->flags.activ = 1; im->flags.activ = 1;
im->flags.lru_nodata = 0; im->flags.lru_nodata = 0;
im->flags.dirty = 0; im->flags.dirty = 0;
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
eina_hash_direct_add(cache->activ, key, im); eina_hash_direct_add(cache->activ, key, im);
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
} }
else else
{ {
@ -98,9 +110,15 @@ _evas_cache_image_make_inactiv(Evas_Cache_Image *cache,
im->flags.activ = 0; im->flags.activ = 0;
im->flags.dirty = 0; im->flags.dirty = 0;
im->flags.cached = 1; im->flags.cached = 1;
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
eina_hash_direct_add(cache->inactiv, key, im); eina_hash_direct_add(cache->inactiv, key, im);
cache->lru = eina_inlist_prepend(cache->lru, EINA_INLIST_GET(im)); cache->lru = eina_inlist_prepend(cache->lru, EINA_INLIST_GET(im));
cache->usage += cache->func.mem_size_get(im); cache->usage += cache->func.mem_size_get(im);
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
} }
else else
{ {
@ -115,9 +133,15 @@ _evas_cache_image_remove_lru_nodata(Evas_Cache_Image *cache,
if (im->flags.lru_nodata) if (im->flags.lru_nodata)
{ {
im->flags.lru_nodata = 0; im->flags.lru_nodata = 0;
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
cache->lru_nodata = eina_inlist_remove(cache->lru_nodata, EINA_INLIST_GET(im)); cache->lru_nodata = eina_inlist_remove(cache->lru_nodata, EINA_INLIST_GET(im));
cache->usage -= cache->func.mem_size_get(im); cache->usage -= cache->func.mem_size_get(im);
} #ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
}
} }
static void static void
@ -126,8 +150,14 @@ _evas_cache_image_activ_lru_nodata(Evas_Cache_Image *cache,
{ {
im->flags.need_data = 0; im->flags.need_data = 0;
im->flags.lru_nodata = 1; im->flags.lru_nodata = 1;
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
cache->lru_nodata = eina_inlist_prepend(cache->lru_nodata, EINA_INLIST_GET(im)); cache->lru_nodata = eina_inlist_prepend(cache->lru_nodata, EINA_INLIST_GET(im));
cache->usage += cache->func.mem_size_get(im); cache->usage += cache->func.mem_size_get(im);
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
} }
static void static void
@ -138,11 +168,20 @@ _evas_cache_image_remove_activ(Evas_Cache_Image *cache,
{ {
if (ie->flags.activ) if (ie->flags.activ)
{ {
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
eina_hash_del(cache->activ, ie->cache_key, ie); eina_hash_del(cache->activ, ie->cache_key, ie);
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
_evas_cache_image_remove_lru_nodata(cache, ie); _evas_cache_image_remove_lru_nodata(cache, ie);
} }
else else
{ {
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
if (ie->flags.dirty) if (ie->flags.dirty)
{ {
cache->dirty = eina_inlist_remove(cache->dirty, EINA_INLIST_GET(ie)); cache->dirty = eina_inlist_remove(cache->dirty, EINA_INLIST_GET(ie));
@ -153,6 +192,9 @@ _evas_cache_image_remove_activ(Evas_Cache_Image *cache,
cache->lru = eina_inlist_remove(cache->lru, EINA_INLIST_GET(ie)); cache->lru = eina_inlist_remove(cache->lru, EINA_INLIST_GET(ie));
cache->usage -= cache->func.mem_size_get(ie); cache->usage -= cache->func.mem_size_get(ie);
} }
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
} }
ie->flags.cached = 0; ie->flags.cached = 0;
ie->flags.dirty = 0; ie->flags.dirty = 0;
@ -163,7 +205,8 @@ _evas_cache_image_remove_activ(Evas_Cache_Image *cache,
static void static void
_evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie) _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
{ {
if (!ie) return ; if (!ie)
return ;
if (cache->func.debug) if (cache->func.debug)
cache->func.debug("deleting", ie); cache->func.debug("deleting", ie);
@ -201,6 +244,9 @@ _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
#ifdef BUILD_ASYNC_PRELOAD #ifdef BUILD_ASYNC_PRELOAD
LKD(ie->lock); LKD(ie->lock);
#endif #endif
#ifdef EVAS_FRAME_QUEUING
LKD(ie->lock_references);
#endif
cache->func.dealloc(ie); cache->func.dealloc(ie);
} }
@ -237,6 +283,9 @@ _evas_cache_image_entry_new(Evas_Cache_Image *cache,
ie->allocated.w = 0; ie->allocated.w = 0;
ie->allocated.h = 0; ie->allocated.h = 0;
#ifdef EVAS_FRAME_QUEUING
LKI(ie->lock_references);
#endif
ie->references = 0; ie->references = 0;
ie->cache = cache; ie->cache = cache;
@ -400,12 +449,18 @@ _evas_cache_image_async_cancel(void *data)
_evas_cache_image_async_end(ie); _evas_cache_image_async_end(ie);
} }
#ifdef EVAS_FRAME_QUEUING
LKL(ie->lock_references);
#endif
if (ie->references == 0) if (ie->references == 0)
{ {
_evas_cache_image_remove_activ(ie->cache, ie); _evas_cache_image_remove_activ(ie->cache, ie);
_evas_cache_image_make_inactiv(ie->cache, ie, ie->cache_key); _evas_cache_image_make_inactiv(ie->cache, ie, ie->cache_key);
evas_cache_image_flush(ie->cache); evas_cache_image_flush(ie->cache);
} }
#ifdef EVAS_FRAME_QUEUING
LKU(ie->lock_references);
#endif
} }
static int static int
@ -500,9 +555,21 @@ EAPI void
evas_cache_image_set(Evas_Cache_Image *cache, int limit) evas_cache_image_set(Evas_Cache_Image *cache, int limit)
{ {
assert(cache != NULL); assert(cache != NULL);
if (cache->limit == limit) return; #ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
if (cache->limit == limit)
{
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
return;
}
cache->limit = limit; cache->limit = limit;
evas_cache_image_flush(cache); evas_cache_image_flush(cache);
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
} }
EAPI Evas_Cache_Image * EAPI Evas_Cache_Image *
@ -530,6 +597,10 @@ evas_cache_image_init(const Evas_Cache_Image_Func *cb)
new->preload = NULL; new->preload = NULL;
new->pending = NULL; new->pending = NULL;
#ifdef EVAS_FRAME_QUEUING
LKI(new->lock);
#endif
return new; return new;
} }
@ -550,10 +621,18 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache)
Image_Entry *im; Image_Entry *im;
assert(cache != NULL); assert(cache != NULL);
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
cache->references--; cache->references--;
if (cache->references > 0) if (cache->references > 0)
return ; {
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
return ;
}
#ifdef BUILD_ASYNC_PRELOAD #ifdef BUILD_ASYNC_PRELOAD
EINA_LIST_FREE(cache->preload, im) EINA_LIST_FREE(cache->preload, im)
@ -610,6 +689,11 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache)
eina_hash_free(cache->activ); eina_hash_free(cache->activ);
eina_hash_free(cache->inactiv); eina_hash_free(cache->inactiv);
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
LKD(cache->lock);
#endif
free(cache); free(cache);
} }
@ -711,7 +795,13 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *
hkey[size] = '\0'; hkey[size] = '\0';
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
im = eina_hash_find(cache->activ, hkey); im = eina_hash_find(cache->activ, hkey);
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
if (im) if (im)
{ {
time_t t; time_t t;
@ -733,7 +823,13 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *
_evas_cache_image_make_dirty(cache, im); _evas_cache_image_make_dirty(cache, im);
} }
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
im = eina_hash_find(cache->inactiv, hkey); im = eina_hash_find(cache->inactiv, hkey);
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
if (im) if (im)
{ {
int ok; int ok;
@ -779,9 +875,15 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *
on_ok: on_ok:
*error = EVAS_LOAD_ERROR_NONE; *error = EVAS_LOAD_ERROR_NONE;
#ifdef EVAS_FRAME_QUEUING
LKL(im->lock_references);
#endif
im->references++; im->references++;
if (im->references > 1 && im->flags.lru_nodata) if (im->references > 1 && im->flags.lru_nodata)
_evas_cache_image_remove_lru_nodata(cache, im); _evas_cache_image_remove_lru_nodata(cache, im);
#ifdef EVAS_FRAME_QUEUING
LKU(im->lock_references);
#endif
return im; return im;
@ -812,15 +914,37 @@ EAPI void
evas_cache_image_drop(Image_Entry *im) evas_cache_image_drop(Image_Entry *im)
{ {
Evas_Cache_Image *cache; Evas_Cache_Image *cache;
int references;
assert(im); assert(im);
assert(im->cache); assert(im->cache);
#ifdef EVAS_FRAME_QUEUING
LKL(im->lock_references);
#endif
im->references--; im->references--;
references = im->references;
#ifdef EVAS_FRAME_QUEUING
LKU(im->lock_references);
#endif
cache = im->cache; cache = im->cache;
if (im->references == 0) if (references == 0)
{ {
#ifdef EVAS_FRAME_QUEUING
LKL(((RGBA_Image *)im)->ref_fq_add);
LKL(((RGBA_Image *)im)->ref_fq_del);
if (((RGBA_Image *)im)->ref_fq[0] != ((RGBA_Image *)im)->ref_fq[1])
{
LKU(((RGBA_Image *)im)->ref_fq_add);
LKU(((RGBA_Image *)im)->ref_fq_del);
return;
}
LKU(((RGBA_Image *)im)->ref_fq_add);
LKU(((RGBA_Image *)im)->ref_fq_del);
#endif
#ifdef BUILD_ASYNC_PRELOAD #ifdef BUILD_ASYNC_PRELOAD
if (im->preload) if (im->preload)
{ {
@ -845,13 +969,22 @@ EAPI void
evas_cache_image_data_not_needed(Image_Entry *im) evas_cache_image_data_not_needed(Image_Entry *im)
{ {
Evas_Cache_Image *cache; Evas_Cache_Image *cache;
int references;
assert(im); assert(im);
assert(im->cache); assert(im->cache);
cache = im->cache; cache = im->cache;
if (im->references > 1) return ; #ifdef EVAS_FRAME_QUEUING
LKL(im->lock_references);
#endif
references = im->references;
#ifdef EVAS_FRAME_QUEUING
LKU(im->lock_references);
#endif
if (references > 1) return ;
if (im->flags.dirty || !im->flags.need_data) return ; if (im->flags.dirty || !im->flags.need_data) return ;
_evas_cache_image_activ_lru_nodata(cache, im); _evas_cache_image_activ_lru_nodata(cache, im);
@ -862,6 +995,7 @@ evas_cache_image_dirty(Image_Entry *im, int x, int y, int w, int h)
{ {
Image_Entry *im_dirty = im; Image_Entry *im_dirty = im;
Evas_Cache_Image *cache; Evas_Cache_Image *cache;
int references;
assert(im); assert(im);
assert(im->cache); assert(im->cache);
@ -869,9 +1003,17 @@ evas_cache_image_dirty(Image_Entry *im, int x, int y, int w, int h)
cache = im->cache; cache = im->cache;
if (!(im->flags.dirty)) if (!(im->flags.dirty))
{ {
#ifdef EVAS_FRAME_QUEUING
LKL(im->lock_references);
#endif
references = im->references;
#ifdef EVAS_FRAME_QUEUING
LKU(im->lock_references);
#endif
#ifndef EVAS_CSERVE #ifndef EVAS_CSERVE
// if ref 1 also copy if using shared cache as its read-only // if ref 1 also copy if using shared cache as its read-only
if (im->references == 1) im_dirty = im; if (references == 1) im_dirty = im;
else else
#endif #endif
{ {
@ -900,7 +1042,13 @@ evas_cache_image_dirty(Image_Entry *im, int x, int y, int w, int h)
if (error != 0) goto on_error; if (error != 0) goto on_error;
*/ */
#ifdef EVAS_FRAME_QUEUING
LKL(im_dirty->lock_references);
#endif
im_dirty->references = 1; im_dirty->references = 1;
#ifdef EVAS_FRAME_QUEUING
LKU(im_dirty->lock_references);
#endif
evas_cache_image_drop(im); evas_cache_image_drop(im);
} }
@ -927,12 +1075,21 @@ evas_cache_image_alone(Image_Entry *im)
{ {
Evas_Cache_Image *cache; Evas_Cache_Image *cache;
Image_Entry *im_dirty = im; Image_Entry *im_dirty = im;
int references;
assert(im); assert(im);
assert(im->cache); assert(im->cache);
cache = im->cache; cache = im->cache;
if (im->references == 1) #ifdef EVAS_FRAME_QUEUING
LKL(im->lock_references);
#endif
references = im->references;
#ifdef EVAS_FRAME_QUEUING
LKU(im->lock_references);
#endif
if (references == 1)
{ {
if (!(im->flags.dirty)) if (!(im->flags.dirty))
{ {
@ -967,7 +1124,13 @@ evas_cache_image_alone(Image_Entry *im)
if (error != 0) goto on_error; if (error != 0) goto on_error;
*/ */
#ifdef EVAS_FRAME_QUEUING
LKL(im_dirty->lock_references);
#endif
im_dirty->references = 1; im_dirty->references = 1;
#ifdef EVAS_FRAME_QUEUING
LKU(im_dirty->lock_references);
#endif
evas_cache_image_drop(im); evas_cache_image_drop(im);
} }
@ -1004,7 +1167,13 @@ evas_cache_image_copied_data(Evas_Cache_Image *cache, int w, int h, DATA32 *imag
_evas_cache_image_entry_delete(cache, im); _evas_cache_image_entry_delete(cache, im);
return NULL; return NULL;
} }
#ifdef EVAS_FRAME_QUEUING
LKL(im->lock_references);
#endif
im->references = 1; im->references = 1;
#ifdef EVAS_FRAME_QUEUING
LKU(im->lock_references);
#endif
if (cache->func.debug) if (cache->func.debug)
cache->func.debug("copied-data", im); cache->func.debug("copied-data", im);
@ -1032,7 +1201,13 @@ evas_cache_image_data(Evas_Cache_Image *cache, int w, int h, DATA32 *image_data,
_evas_cache_image_entry_delete(cache, im); _evas_cache_image_entry_delete(cache, im);
return NULL; return NULL;
} }
#ifdef EVAS_FRAME_QUEUING
LKL(im->lock_references);
#endif
im->references = 1; im->references = 1;
#ifdef EVAS_FRAME_QUEUING
LKU(im->lock_references);
#endif
if (cache->func.debug) if (cache->func.debug)
cache->func.debug("data", im); cache->func.debug("data", im);
@ -1068,7 +1243,13 @@ evas_cache_image_size_set(Image_Entry *im, int w, int h)
assert(im); assert(im);
assert(im->cache); assert(im->cache);
#ifdef EVAS_FRAME_QUEUING
LKL(im->lock_references);
#endif
assert(im->references > 0); assert(im->references > 0);
#ifdef EVAS_FRAME_QUEUING
LKU(im->lock_references);
#endif
if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) || if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
(im->space == EVAS_COLORSPACE_YCBCR422P709_PL)) (im->space == EVAS_COLORSPACE_YCBCR422P709_PL))
@ -1091,7 +1272,13 @@ evas_cache_image_size_set(Image_Entry *im, int w, int h)
error = cache->func.size_set(new, im, w, h); error = cache->func.size_set(new, im, w, h);
if (error != 0) goto on_error; if (error != 0) goto on_error;
#ifdef EVAS_FRAME_QUEUING
LKL(new->lock_references);
#endif
new->references = 1; new->references = 1;
#ifdef EVAS_FRAME_QUEUING
LKU(new->lock_references);
#endif
evas_cache_image_drop(im); evas_cache_image_drop(im);
@ -1314,7 +1501,13 @@ evas_cache_image_empty(Evas_Cache_Image *cache)
im = _evas_cache_image_entry_new(cache, NULL, 0, NULL, NULL, NULL, NULL); im = _evas_cache_image_entry_new(cache, NULL, 0, NULL, NULL, NULL, NULL);
if (!im) return NULL; if (!im) return NULL;
#ifdef EVAS_FRAME_QUEUING
LKL(im->lock_references);
#endif
im->references = 1; im->references = 1;
#ifdef EVAS_FRAME_QUEUING
LKU(im->lock_references);
#endif
return im; return im;
} }

View File

@ -48,6 +48,9 @@ evas_init(void)
#ifdef BUILD_ASYNC_PRELOAD #ifdef BUILD_ASYNC_PRELOAD
_evas_preload_thread_init(); _evas_preload_thread_init();
#endif #endif
#ifdef EVAS_FRAME_QUEUING
evas_common_frameq_init();
#endif
return _evas_init_count; return _evas_init_count;
@ -84,6 +87,13 @@ evas_shutdown(void)
if (--_evas_init_count != 0) if (--_evas_init_count != 0)
return _evas_init_count; return _evas_init_count;
#ifdef EVAS_FRAME_QUEUING
if (evas_common_frameq_enabled())
{
evas_common_frameq_finish();
evas_common_frameq_destroy();
}
#endif
#ifdef BUILD_ASYNC_EVENTS #ifdef BUILD_ASYNC_EVENTS
_evas_preload_thread_shutdown(); _evas_preload_thread_shutdown();
#endif #endif
@ -180,6 +190,10 @@ evas_free(Evas *e)
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
#ifdef EVAS_FRAME_QUEUING
evas_common_frameq_flush();
#endif
if (e->walking_list == 0) evas_render_idle_flush(e); if (e->walking_list == 0) evas_render_idle_flush(e);
if (e->walking_list > 0) return; if (e->walking_list > 0) return;
@ -424,6 +438,11 @@ evas_output_size_set(Evas *e, int w, int h)
if ((w == e->output.w) && (h == e->output.h)) return; if ((w == e->output.w) && (h == e->output.h)) return;
if (w < 1) w = 1; if (w < 1) w = 1;
if (h < 1) h = 1; if (h < 1) h = 1;
#ifdef EVAS_FRAME_QUEUING
evas_common_frameq_flush();
#endif
e->output.w = w; e->output.w = w;
e->output.h = h; e->output.h = h;
e->output.changed = 1; e->output.changed = 1;

View File

@ -147,9 +147,15 @@ evas_object_gradient_color_stop_add(Evas_Object *obj, int r, int g, int b, int a
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
if (o->engine_data) if (o->engine_data)
obj->layer->evas->engine.func->gradient_color_stop_add(obj->layer->evas->engine.data.output, {
o->engine_data, #ifdef EVAS_FRAME_QUEUING
r, g, b, a, delta); evas_common_pipe_op_grad_flush(o->engine_data);
#endif
obj->layer->evas->engine.func->gradient_color_stop_add(obj->layer->evas->engine.data.output,
o->engine_data,
r, g, b, a, delta);
}
o->gradient_changed = 1; o->gradient_changed = 1;
o->changed = 1; o->changed = 1;
evas_object_change(obj); evas_object_change(obj);
@ -180,8 +186,13 @@ evas_object_gradient_alpha_stop_add(Evas_Object *obj, int a, int delta)
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
if (o->engine_data) if (o->engine_data)
obj->layer->evas->engine.func->gradient_alpha_stop_add(obj->layer->evas->engine.data.output, {
o->engine_data, a, delta); #ifdef EVAS_FRAME_QUEUING
evas_common_pipe_op_grad_flush(o->engine_data);
#endif
obj->layer->evas->engine.func->gradient_alpha_stop_add(obj->layer->evas->engine.data.output,
o->engine_data, a, delta);
}
o->gradient_changed = 1; o->gradient_changed = 1;
o->changed = 1; o->changed = 1;
evas_object_change(obj); evas_object_change(obj);
@ -204,8 +215,13 @@ evas_object_gradient_clear(Evas_Object *obj)
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
if (o->engine_data) if (o->engine_data)
obj->layer->evas->engine.func->gradient_clear(obj->layer->evas->engine.data.output, {
o->engine_data); #ifdef EVAS_FRAME_QUEUING
evas_common_pipe_op_grad_flush(o->engine_data);
#endif
obj->layer->evas->engine.func->gradient_clear(obj->layer->evas->engine.data.output,
o->engine_data);
}
o->gradient_changed = 1; o->gradient_changed = 1;
o->changed = 1; o->changed = 1;
o->cur.gradient_opaque = 0; o->cur.gradient_opaque = 0;
@ -236,9 +252,14 @@ evas_object_gradient_color_data_set(Evas_Object *obj, void *data, int len, Eina_
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
if (o->engine_data) if (o->engine_data)
obj->layer->evas->engine.func->gradient_color_data_set(obj->layer->evas->engine.data.output, {
o->engine_data, #ifdef EVAS_FRAME_QUEUING
data, len, has_alpha); evas_common_pipe_op_grad_flush(o->engine_data);
#endif
obj->layer->evas->engine.func->gradient_color_data_set(obj->layer->evas->engine.data.output,
o->engine_data,
data, len, has_alpha);
}
o->gradient_changed = 1; o->gradient_changed = 1;
o->changed = 1; o->changed = 1;
evas_object_change(obj); evas_object_change(obj);
@ -267,9 +288,14 @@ evas_object_gradient_alpha_data_set(Evas_Object *obj, void *data, int len)
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
if (o->engine_data) if (o->engine_data)
obj->layer->evas->engine.func->gradient_alpha_data_set(obj->layer->evas->engine.data.output, {
o->engine_data, #ifdef EVAS_FRAME_QUEUING
data, len); evas_common_pipe_op_grad_flush(o->engine_data);
#endif
obj->layer->evas->engine.func->gradient_alpha_data_set(obj->layer->evas->engine.data.output,
o->engine_data,
data, len);
}
o->gradient_changed = 1; o->gradient_changed = 1;
o->changed = 1; o->changed = 1;
evas_object_change(obj); evas_object_change(obj);

View File

@ -53,9 +53,15 @@ evas_object_gradient2_color_np_stop_insert(Evas_Object *obj, int r, int g, int b
MAGIC_CHECK_END(); MAGIC_CHECK_END();
engine_data = obj->func->engine_data_get(obj); engine_data = obj->func->engine_data_get(obj);
if (engine_data) if (engine_data)
obj->layer->evas->engine.func->gradient2_color_np_stop_insert(obj->layer->evas->engine.data.output, {
engine_data, #ifdef EVAS_FRAME_QUEUING
r, g, b, a, pos); evas_common_pipe_op_grad2_flush(engine_data);
#endif
obj->layer->evas->engine.func->gradient2_color_np_stop_insert(obj->layer->evas->engine.data.output,
engine_data,
r, g, b, a, pos);
}
og->gradient_changed = 1; og->gradient_changed = 1;
evas_object_change(obj); evas_object_change(obj);
} }
@ -79,8 +85,13 @@ evas_object_gradient2_clear(Evas_Object *obj)
MAGIC_CHECK_END(); MAGIC_CHECK_END();
engine_data = obj->func->engine_data_get(obj); engine_data = obj->func->engine_data_get(obj);
if (engine_data) if (engine_data)
obj->layer->evas->engine.func->gradient2_clear(obj->layer->evas->engine.data.output, {
engine_data); #ifdef EVAS_FRAME_QUEUING
evas_common_pipe_op_grad2_flush(engine_data);
#endif
obj->layer->evas->engine.func->gradient2_clear(obj->layer->evas->engine.data.output,
engine_data);
}
og->gradient_changed = 1; og->gradient_changed = 1;
og->cur.gradient_opaque = 0; og->cur.gradient_opaque = 0;
evas_object_change(obj); evas_object_change(obj);

View File

@ -960,6 +960,9 @@ evas_object_image_data_set(Evas_Object *obj, void *data)
MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE); MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
#ifdef EVAS_FRAME_QUEUING
evas_common_pipe_op_image_flush(o->engine_data);
#endif
p_data = o->engine_data; p_data = o->engine_data;
if (data) if (data)
{ {
@ -1031,6 +1034,10 @@ evas_object_image_data_get(const Evas_Object *obj, Eina_Bool for_writing)
return NULL; return NULL;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
if (!o->engine_data) return NULL; if (!o->engine_data) return NULL;
#ifdef EVAS_FRAME_QUEUING
evas_common_pipe_op_image_flush(o->engine_data);
#endif
data = NULL; data = NULL;
o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output, o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
o->engine_data, o->engine_data,
@ -1202,9 +1209,14 @@ evas_object_image_alpha_set(Evas_Object *obj, Eina_Bool has_alpha)
return; return;
o->cur.has_alpha = has_alpha; o->cur.has_alpha = has_alpha;
if (o->engine_data) if (o->engine_data)
o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output, {
#ifdef EVAS_FRAME_QUEUING
evas_common_pipe_op_image_flush(o->engine_data);
#endif
o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
o->engine_data, o->engine_data,
o->cur.has_alpha); o->cur.has_alpha);
}
evas_object_image_data_update_add(obj, 0, 0, o->cur.image.w, o->cur.image.h); evas_object_image_data_update_add(obj, 0, 0, o->cur.image.w, o->cur.image.h);
EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o); EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
} }
@ -1810,6 +1822,13 @@ evas_object_image_colorspace_set(Evas_Object *obj, Evas_Colorspace cspace)
MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE); MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
#ifdef EVAS_FRAME_QUEUING
if (o->cur.cspace != cspace)
if (o->engine_data)
evas_common_pipe_op_image_flush(o->engine_data);
#endif
o->cur.cspace = cspace; o->cur.cspace = cspace;
if (o->engine_data) if (o->engine_data)
obj->layer->evas->engine.func->image_colorspace_set(obj->layer->evas->engine.data.output, obj->layer->evas->engine.func->image_colorspace_set(obj->layer->evas->engine.data.output,
@ -1913,6 +1932,11 @@ evas_object_image_scale_hint_set(Evas_Object *obj, Evas_Image_Scale_Hint hint)
MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE); MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
#ifdef EVAS_FRAME_QUEUING
if (o->scale_hint != hint)
if (o->engine_data)
evas_common_pipe_op_image_flush(o->engine_data);
#endif
o->scale_hint = hint; o->scale_hint = hint;
} }

View File

@ -368,6 +368,10 @@ evas_object_del(Evas_Object *obj)
if (obj->delete_me) return; if (obj->delete_me) return;
#ifdef EVAS_FRAME_QUEUING
evas_common_frameq_flush();
#endif
_evas_object_event_new(); _evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_DEL, NULL); evas_object_event_callback_call(obj, EVAS_CALLBACK_DEL, NULL);

View File

@ -195,6 +195,12 @@ evas_object_text_font_set(Evas_Object *obj, const char *font, Evas_Font_Size siz
obj->layer->evas->pointer.x, obj->layer->evas->pointer.x,
obj->layer->evas->pointer.y, 1, 1); obj->layer->evas->pointer.y, 1, 1);
} }
#ifdef EVAS_FRAME_QUEUING
if (o->engine_data)
evas_common_pipe_op_text_flush(o->engine_data);
#endif
/* DO IT */ /* DO IT */
if (o->engine_data) if (o->engine_data)
{ {
@ -1102,6 +1108,7 @@ evas_font_hinting_set(Evas *e, Evas_Font_Hinting_Flags hinting)
MAGIC_CHECK_END(); MAGIC_CHECK_END();
if (e->hinting == hinting) return; if (e->hinting == hinting) return;
e->hinting = hinting; e->hinting = hinting;
EINA_INLIST_FOREACH(e->layers, lay) EINA_INLIST_FOREACH(e->layers, lay)
{ {
Evas_Object *obj; Evas_Object *obj;
@ -1834,6 +1841,9 @@ _evas_object_text_rehint(Evas_Object *obj)
o = (Evas_Object_Text *)(obj->object_data); o = (Evas_Object_Text *)(obj->object_data);
if (!o->engine_data) return; if (!o->engine_data) return;
#ifdef EVAS_FRAME_QUEUING
evas_common_pipe_op_text_flush(o->engine_data);
#endif
evas_font_load_hinting_set(obj->layer->evas, o->engine_data, evas_font_load_hinting_set(obj->layer->evas, o->engine_data,
obj->layer->evas->hinting); obj->layer->evas->hinting);
was = evas_object_is_in_output_rect(obj, was = evas_object_is_in_output_rect(obj,

View File

@ -6027,9 +6027,14 @@ _evas_object_textblock_rehint(Evas_Object *obj)
EINA_INLIST_FOREACH(ln->items, it) EINA_INLIST_FOREACH(ln->items, it)
{ {
if (it->format->font.font) if (it->format->font.font)
evas_font_load_hinting_set(obj->layer->evas, {
it->format->font.font, #ifdef EVAS_FRAME_QUEUING
evas_common_pipe_op_text_flush(it->format->font.font);
#endif
evas_font_load_hinting_set(obj->layer->evas,
it->format->font.font,
obj->layer->evas->hinting); obj->layer->evas->hinting);
}
} }
} }
o->formatted.valid = 0; o->formatted.valid = 0;

View File

@ -245,8 +245,13 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
obj->rect_del = 0; obj->rect_del = 0;
obj->render_pre = 0; obj->render_pre = 0;
#ifndef EVAS_FRAME_QUEUING
/* because of clip objects - delete 2 cycles later */ /* because of clip objects - delete 2 cycles later */
if (obj->delete_me == 2) eina_array_push(delete_objects, obj); if (obj->delete_me == 2)
#else
if (obj->delete_me == evas_common_frameq_get_frameq_sz() + 2)
#endif
eina_array_push(delete_objects, obj);
else if (obj->delete_me != 0) obj->delete_me++; else if (obj->delete_me != 0) obj->delete_me++;
/* If the object will be removed, we should not cache anything during this run. */ /* If the object will be removed, we should not cache anything during this run. */
if (obj->delete_me != 0) clean_them = EINA_TRUE; if (obj->delete_me != 0) clean_them = EINA_TRUE;
@ -1236,6 +1241,10 @@ evas_render_updates(Evas *e)
return NULL; return NULL;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
#ifdef EVAS_FRAME_QUEUING
evas_common_frameq_flush_ready ();
#endif
if (!e->changed) return NULL; if (!e->changed) return NULL;
return evas_render_updates_internal(e, 1, 1); return evas_render_updates_internal(e, 1, 1);
} }
@ -1254,6 +1263,10 @@ evas_render(Evas *e)
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
#ifdef EVAS_FRAME_QUEUING
evas_common_frameq_flush_ready ();
#endif
if (!e->changed) return; if (!e->changed) return;
evas_render_updates_internal(e, 0, 1); evas_render_updates_internal(e, 0, 1);
} }
@ -1316,6 +1329,18 @@ evas_render_idle_flush(Evas *e)
e->invalidate = 1; e->invalidate = 1;
} }
EAPI void
evas_sync(Evas *e)
{
#ifdef EVAS_FRAME_QUEUING
MAGIC_CHECK(e, Evas, MAGIC_EVAS);
return;
MAGIC_CHECK_END();
evas_common_frameq_flush ();
#endif
}
/** /**
* Make the canvas discard as much data as possible used by the engine at * Make the canvas discard as much data as possible used by the engine at
* runtime. * runtime.
@ -1393,12 +1418,19 @@ evas_render_object_recalc(Evas_Object *obj)
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
#ifndef EVAS_FRAME_QUEUING
if ((!obj->changed) && (obj->delete_me < 2)) if ((!obj->changed) && (obj->delete_me < 2))
#else
if ((!obj->changed) )
#endif
{ {
Evas *e; Evas *e;
e = obj->layer->evas; e = obj->layer->evas;
if ((!e) || (e->cleanup)) return; if ((!e) || (e->cleanup)) return;
#ifdef EVAS_FRAME_QUEUING
if (obj->delete_me >= evas_common_frameq_get_frameq_sz() + 2) return;
#endif
eina_array_push(&e->pending_objects, obj); eina_array_push(&e->pending_objects, obj);
obj->changed = 1; obj->changed = 1;
} }

View File

@ -90,6 +90,7 @@ evas_convert_rgb_8.h \
evas_convert_yuv.h \ evas_convert_yuv.h \
evas_draw.h \ evas_draw.h \
evas_font.h \ evas_font.h \
evas_font_private.h \
evas_gradient.h \ evas_gradient.h \
evas_gradient_private.h \ evas_gradient_private.h \
evas_image.h \ evas_image.h \

View File

@ -7,7 +7,23 @@
#include "evas_blend_private.h" #include "evas_blend_private.h"
#include "evas_intl_utils.h" /*defines INTERNATIONAL_SUPPORT if possible */ #include "evas_intl_utils.h" /*defines INTERNATIONAL_SUPPORT if possible */
#include "evas_font_private.h" /* for Frame-Queuing support */
#ifdef EVAS_FRAME_QUEUING
EAPI void
evas_common_font_draw_init(void)
{
LKI(lock_font_draw);
LKI(lock_fribidi);
}
EAPI void
evas_common_font_draw_finish(void)
{
LKD(lock_font_draw);
LKD(lock_fribidi);
}
#endif
static void static void
_fash_int_free(Fash_Int *fash) _fash_int_free(Fash_Int *fash)
@ -123,9 +139,11 @@ evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt index)
// fg = eina_hash_find(fi->glyphs, &hindex); // fg = eina_hash_find(fi->glyphs, &hindex);
// if (fg) return fg; // if (fg) return fg;
FTLOCK();
// error = FT_Load_Glyph(fi->src->ft.face, index, FT_LOAD_NO_BITMAP); // error = FT_Load_Glyph(fi->src->ft.face, index, FT_LOAD_NO_BITMAP);
error = FT_Load_Glyph(fi->src->ft.face, index, error = FT_Load_Glyph(fi->src->ft.face, index,
FT_LOAD_RENDER | hintflags[fi->hinting]); FT_LOAD_RENDER | hintflags[fi->hinting]);
FTUNLOCK();
if (error) if (error)
{ {
if (!fi->fash) fi->fash = _fash_gl_new(); if (!fi->fash) fi->fash = _fash_gl_new();
@ -137,7 +155,9 @@ evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt index)
if (!fg) return NULL; if (!fg) return NULL;
memset(fg, 0, (sizeof(struct _RGBA_Font_Glyph))); memset(fg, 0, (sizeof(struct _RGBA_Font_Glyph)));
FTLOCK();
error = FT_Get_Glyph(fi->src->ft.face->glyph, &(fg->glyph)); error = FT_Get_Glyph(fi->src->ft.face->glyph, &(fg->glyph));
FTUNLOCK();
if (error) if (error)
{ {
free(fg); free(fg);
@ -147,15 +167,18 @@ evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt index)
} }
if (fg->glyph->format != FT_GLYPH_FORMAT_BITMAP) if (fg->glyph->format != FT_GLYPH_FORMAT_BITMAP)
{ {
FTLOCK();
error = FT_Glyph_To_Bitmap(&(fg->glyph), FT_RENDER_MODE_NORMAL, 0, 1); error = FT_Glyph_To_Bitmap(&(fg->glyph), FT_RENDER_MODE_NORMAL, 0, 1);
if (error) if (error)
{ {
FT_Done_Glyph(fg->glyph); FT_Done_Glyph(fg->glyph);
FTUNLOCK();
free(fg); free(fg);
if (!fi->fash) fi->fash = _fash_gl_new(); if (!fi->fash) fi->fash = _fash_gl_new();
if (fi->fash) _fash_gl_add(fi->fash, index, (void *)(-1)); if (fi->fash) _fash_gl_add(fi->fash, index, (void *)(-1));
return NULL; return NULL;
} }
FTUNLOCK();
} }
fg->glyph_out = (FT_BitmapGlyph)fg->glyph; fg->glyph_out = (FT_BitmapGlyph)fg->glyph;
fg->index = hindex; fg->index = hindex;
@ -180,6 +203,7 @@ static FT_UInt
_evas_common_get_char_index(RGBA_Font_Int* fi, int gl) _evas_common_get_char_index(RGBA_Font_Int* fi, int gl)
{ {
Font_Char_Index result; Font_Char_Index result;
FT_UInt ret;
#ifdef HAVE_PTHREAD #ifdef HAVE_PTHREAD
/// pthread_mutex_lock(&fi->ft_mutex); /// pthread_mutex_lock(&fi->ft_mutex);
@ -197,7 +221,9 @@ _evas_common_get_char_index(RGBA_Font_Int* fi, int gl)
// return FT_Get_Char_Index(fi->src->ft.face, gl); // return FT_Get_Char_Index(fi->src->ft.face, gl);
// } // }
FTLOCK();
result.index = FT_Get_Char_Index(fi->src->ft.face, gl); result.index = FT_Get_Char_Index(fi->src->ft.face, gl);
FTUNLOCK();
result.gl = gl; result.gl = gl;
// eina_hash_direct_add(fi->indexes, &result->gl, result); // eina_hash_direct_add(fi->indexes, &result->gl, result);
@ -583,7 +609,9 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
if (ext_w <= 0) return; if (ext_w <= 0) return;
if (ext_h <= 0) return; if (ext_h <= 0) return;
#ifndef EVAS_FRAME_QUEUING
LKL(fn->lock); LKL(fn->lock);
#endif
// evas_common_font_size_use(fn); // evas_common_font_size_use(fn);
use_kerning = FT_HAS_KERNING(fi->src->ft.face); use_kerning = FT_HAS_KERNING(fi->src->ft.face);
func = evas_common_gfx_func_composite_mask_color_span_get(dc->col.col, dst, 1, dc->render_op); func = evas_common_gfx_func_composite_mask_color_span_get(dc->col.col, dst, 1, dc->render_op);
@ -616,5 +644,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
} }
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch; dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
} }
#ifndef EVAS_FRAME_QUEUING
LKU(fn->lock); LKU(fn->lock);
#endif
} }

View File

@ -7,6 +7,8 @@
#include <assert.h> #include <assert.h>
#include "evas_font_private.h" /* for Frame-Queuing support */
extern FT_Library evas_ft_lib; extern FT_Library evas_ft_lib;
static int font_cache_usage = 0; static int font_cache_usage = 0;
@ -45,7 +47,9 @@ _evas_font_cache_int_hash(const RGBA_Font_Int *key, int key_length __UNUSED__)
static void static void
_evas_common_font_source_free(RGBA_Font_Source *fs) _evas_common_font_source_free(RGBA_Font_Source *fs)
{ {
FTLOCK();
FT_Done_Face(fs->ft.face); FT_Done_Face(fs->ft.face);
FTUNLOCK();
#if 0 /* FIXME: Disable as it is only used by dead code using deprecated datatype. */ #if 0 /* FIXME: Disable as it is only used by dead code using deprecated datatype. */
// if (fs->charmap) evas_array_hash_free(fs->charmap); // if (fs->charmap) evas_array_hash_free(fs->charmap);
#endif #endif
@ -59,7 +63,9 @@ font_flush_free_glyph_cb(const Eina_Hash *hash, const void *key, void *data, voi
RGBA_Font_Glyph *fg; RGBA_Font_Glyph *fg;
fg = data; fg = data;
FTLOCK();
FT_Done_Glyph(fg->glyph); FT_Done_Glyph(fg->glyph);
FTUNLOCK();
// extension calls // extension calls
if (fg->ext_dat_free) fg->ext_dat_free(fg->ext_dat); if (fg->ext_dat_free) fg->ext_dat_free(fg->ext_dat);
free(fg); free(fg);
@ -137,7 +143,9 @@ evas_common_font_source_memory_load(const char *name, const void *data, int data
fs->data_size = data_size; fs->data_size = data_size;
fs->current_size = 0; fs->current_size = 0;
memcpy(fs->data, data, data_size); memcpy(fs->data, data, data_size);
FTLOCK();
error = FT_New_Memory_Face(evas_ft_lib, fs->data, fs->data_size, 0, &(fs->ft.face)); error = FT_New_Memory_Face(evas_ft_lib, fs->data, fs->data_size, 0, &(fs->ft.face));
FTUNLOCK();
if (error) if (error)
{ {
free(fs); free(fs);
@ -145,7 +153,9 @@ evas_common_font_source_memory_load(const char *name, const void *data, int data
} }
fs->name = eina_stringshare_add(name); fs->name = eina_stringshare_add(name);
fs->file = NULL; fs->file = NULL;
FTLOCK();
error = FT_Select_Charmap(fs->ft.face, ft_encoding_unicode); error = FT_Select_Charmap(fs->ft.face, ft_encoding_unicode);
FTUNLOCK();
fs->ft.orig_upem = fs->ft.face->units_per_EM; fs->ft.orig_upem = fs->ft.face->units_per_EM;
fs->references = 1; fs->references = 1;
@ -183,9 +193,11 @@ evas_common_font_source_load_complete(RGBA_Font_Source *fs)
{ {
int error; int error;
FTLOCK();
error = FT_New_Face(evas_ft_lib, fs->file, 0, &(fs->ft.face)); error = FT_New_Face(evas_ft_lib, fs->file, 0, &(fs->ft.face));
if (error) if (error)
{ {
FTUNLOCK();
fs->ft.face = NULL; fs->ft.face = NULL;
return error; return error;
} }
@ -194,10 +206,12 @@ evas_common_font_source_load_complete(RGBA_Font_Source *fs)
if (error) if (error)
{ {
FT_Done_Face(fs->ft.face); FT_Done_Face(fs->ft.face);
FTUNLOCK();
fs->ft.face = NULL; fs->ft.face = NULL;
return error; return error;
} }
FTUNLOCK();
fs->ft.orig_upem = fs->ft.face->units_per_EM; fs->ft.orig_upem = fs->ft.face->units_per_EM;
return error; return error;
} }
@ -236,7 +250,9 @@ evas_common_font_size_use(RGBA_Font *fn)
{ {
if (fi->src->current_size != fi->size) if (fi->src->current_size != fi->size)
{ {
FTLOCK();
FT_Activate_Size(fi->ft.size); FT_Activate_Size(fi->ft.size);
FTUNLOCK();
fi->src->current_size = fi->size; fi->src->current_size = fi->size;
} }
} }
@ -369,6 +385,7 @@ evas_common_font_int_load_complete(RGBA_Font_Int *fi)
int ret; int ret;
int error; int error;
FTLOCK();
error = FT_New_Size(fi->src->ft.face, &(fi->ft.size)); error = FT_New_Size(fi->src->ft.face, &(fi->ft.size));
if (!error) if (!error)
{ {
@ -381,6 +398,7 @@ evas_common_font_int_load_complete(RGBA_Font_Int *fi)
fi->real_size = fi->size; fi->real_size = fi->size;
error = FT_Set_Pixel_Sizes(fi->src->ft.face, 0, fi->real_size); error = FT_Set_Pixel_Sizes(fi->src->ft.face, 0, fi->real_size);
} }
FTUNLOCK();
if (error) if (error)
{ {
int i; int i;
@ -405,7 +423,9 @@ evas_common_font_int_load_complete(RGBA_Font_Int *fi)
if (d == 0) break; if (d == 0) break;
} }
fi->real_size = chosen_size; fi->real_size = chosen_size;
FTLOCK();
error = FT_Set_Pixel_Sizes(fi->src->ft.face, chosen_width, fi->real_size); error = FT_Set_Pixel_Sizes(fi->src->ft.face, chosen_width, fi->real_size);
FTUNLOCK();
if (error) if (error)
{ {
/* couldn't choose the size anyway... what now? */ /* couldn't choose the size anyway... what now? */
@ -457,6 +477,11 @@ evas_common_font_memory_load(const char *name, int size, const void *data, int d
fi->hinting = fn->hinting; fi->hinting = fn->hinting;
fn->references = 1; fn->references = 1;
LKI(fn->lock); LKI(fn->lock);
#ifdef EVAS_FRAME_QUEUING
LKI(fn->ref_fq_add);
LKI(fn->ref_fq_del);
pthread_cond_init(&(fn->cond_fq_del), NULL);
#endif
return fn; return fn;
} }
@ -506,6 +531,11 @@ evas_common_font_load(const char *name, int size)
fi->hinting = fn->hinting; fi->hinting = fn->hinting;
fn->references = 1; fn->references = 1;
LKI(fn->lock); LKI(fn->lock);
#ifdef EVAS_FRAME_QUEUING
LKI(fn->ref_fq_add);
LKI(fn->ref_fq_del);
pthread_cond_init(&(fn->cond_fq_del), NULL);
#endif
return fn; return fn;
} }
@ -552,6 +582,19 @@ evas_common_font_free(RGBA_Font *fn)
if (!fn) return; if (!fn) return;
fn->references--; fn->references--;
if (fn->references > 0) return; if (fn->references > 0) return;
#ifdef EVAS_FRAME_QUEUING
LKL(fn->ref_fq_add);
LKL(fn->ref_fq_del);
if (fn->ref_fq[0] != fn->ref_fq[1])
{
LKU(fn->ref_fq_add);
LKU(fn->ref_fq_del);
return;
}
LKU(fn->ref_fq_add);
LKU(fn->ref_fq_del);
#endif
EINA_LIST_FOREACH(fn->fonts, l, fi) EINA_LIST_FOREACH(fn->fonts, l, fi)
{ {
fi->references--; fi->references--;
@ -565,6 +608,12 @@ evas_common_font_free(RGBA_Font *fn)
eina_list_free(fn->fonts); eina_list_free(fn->fonts);
if (fn->fash) fn->fash->freeme(fn->fash); if (fn->fash) fn->fash->freeme(fn->fash);
LKD(fn->lock); LKD(fn->lock);
#ifdef EVAS_FRAME_QUEUING
LKD(fn->ref_fq_add);
LKD(fn->ref_fq_del);
pthread_cond_destroy(&(fn->cond_fq_del));
#endif
free(fn); free(fn);
} }

View File

@ -17,6 +17,9 @@ evas_common_font_init(void)
error = FT_Init_FreeType(&evas_ft_lib); error = FT_Init_FreeType(&evas_ft_lib);
if (error) return; if (error) return;
evas_common_font_load_init(); evas_common_font_load_init();
#ifdef EVAS_FRAME_QUEUING
evas_common_font_draw_init();
#endif
} }
EAPI void EAPI void
@ -33,6 +36,9 @@ evas_common_font_shutdown(void)
evas_common_font_flush(); evas_common_font_flush();
error = FT_Done_FreeType(evas_ft_lib); error = FT_Done_FreeType(evas_ft_lib);
#ifdef EVAS_FRAME_QUEUING
evas_common_font_draw_finish();
#endif
evas_ft_lib = 0; evas_ft_lib = 0;
} }

View File

@ -0,0 +1,81 @@
#ifndef _EVAS_FONT_PRIVATE_H
#define _EVAS_FONT_PRIVATE_H
LK(lock_font_draw); // for freetype2 API calls
LK(lock_fribidi); // for fribidi API calls
#ifdef EVAS_FRAME_QUEUING
#define FTLOCK() LKL(lock_font_draw)
#define FTUNLOCK() LKU(lock_font_draw)
#define FBDLOCK() LKL(lock_fribidi)
#define FBDUNLOCK() LKU(lock_fribidi)
#else
#define FTLOCK(x)
#define FTUNLOCK(x)
#define FBDLOCK()
#define FBDUNLOCK()
#endif
#endif /* !_EVAS_FONT_PRIVATE_H */
#ifndef _EVAS_FONT_PRIVATE_H
#define _EVAS_FONT_PRIVATE_H
LK(lock_font_draw); // for freetype2 API calls
LK(lock_fribidi); // for fribidi API calls
#ifdef EVAS_FRAME_QUEUING
#define FTLOCK() LKL(lock_font_draw)
#define FTUNLOCK() LKU(lock_font_draw)
#define FBDLOCK() LKL(lock_fribidi)
#define FBDUNLOCK() LKU(lock_fribidi)
#else
#define FTLOCK(x)
#define FTUNLOCK(x)
#define FBDLOCK()
#define FBDUNLOCK()
#endif
#endif /* !_EVAS_FONT_PRIVATE_H */
#ifndef _EVAS_FONT_PRIVATE_H
#define _EVAS_FONT_PRIVATE_H
LK(lock_font_draw); // for freetype2 API calls
LK(lock_fribidi); // for fribidi API calls
#ifdef EVAS_FRAME_QUEUING
#define FTLOCK() LKL(lock_font_draw)
#define FTUNLOCK() LKU(lock_font_draw)
#define FBDLOCK() LKL(lock_fribidi)
#define FBDUNLOCK() LKU(lock_fribidi)
#else
#define FTLOCK(x)
#define FTUNLOCK(x)
#define FBDLOCK()
#define FBDUNLOCK()
#endif
#endif /* !_EVAS_FONT_PRIVATE_H */
#ifndef _EVAS_FONT_PRIVATE_H
#define _EVAS_FONT_PRIVATE_H
LK(lock_font_draw);
#ifdef EVAS_FRAME_QUEUING
#define FTLOCK() LKL(lock_font_draw)
#define FTUNLOCK() LKU(lock_font_draw)
#else
#define FTLOCK(x)
#define FTUNLOCK(x)
#endif
#endif /* !_EVAS_FONT_PRIVATE_H */

View File

@ -1,5 +1,6 @@
#include "evas_common.h" #include "evas_common.h"
#include "evas_intl_utils.h" /*defines INTERNATIONAL_SUPPORT if possible */ #include "evas_intl_utils.h" /*defines INTERNATIONAL_SUPPORT if possible */
#include "evas_font_private.h" /* for Frame-Queuing support */
EAPI int EAPI int
evas_common_font_query_kerning(RGBA_Font_Int* fi, evas_common_font_query_kerning(RGBA_Font_Int* fi,
@ -26,12 +27,14 @@ evas_common_font_query_kerning(RGBA_Font_Int* fi,
* values to kern by - given same font, same size and same * values to kern by - given same font, same size and same
* prev_index and index. auto/bytecode or none hinting doesnt * prev_index and index. auto/bytecode or none hinting doesnt
* matter */ * matter */
FTLOCK();
if (FT_Get_Kerning(fi->src->ft.face, if (FT_Get_Kerning(fi->src->ft.face,
key[0], key[1], key[0], key[1],
ft_kerning_default, &delta) == 0) ft_kerning_default, &delta) == 0)
{ {
int *push; int *push;
FTUNLOCK();
*kerning = delta.x >> 6; *kerning = delta.x >> 6;
push = malloc(sizeof (int) * 3); push = malloc(sizeof (int) * 3);
@ -46,6 +49,7 @@ evas_common_font_query_kerning(RGBA_Font_Int* fi,
goto on_correct; goto on_correct;
} }
FTUNLOCK();
error = 0; error = 0;
on_correct: on_correct:
@ -188,7 +192,9 @@ evas_common_font_query_advance(RGBA_Font *fn, const char *text, int *h_adv, int
pen_x = 0; pen_x = 0;
pen_y = 0; pen_y = 0;
// evas_common_font_size_use(fn); // evas_common_font_size_use(fn);
FTLOCK();
use_kerning = FT_HAS_KERNING(fi->src->ft.face); use_kerning = FT_HAS_KERNING(fi->src->ft.face);
FTUNLOCK();
prev_index = 0; prev_index = 0;
for (chr = 0; text[chr];) for (chr = 0; text[chr];)
{ {

View File

@ -68,6 +68,15 @@ evas_common_gradient2_free(RGBA_Gradient2 *gr)
if (!gr) return; if (!gr) return;
gr->references--; gr->references--;
if (gr->references > 0) return; if (gr->references > 0) return;
#ifdef EVAS_FRAME_QUEUING
LKL(gr->ref_fq_add); LKL(gr->ref_fq_del);
if (gr->ref_fq[0] != gr->ref_fq[1])
{
LKU(gr->ref_fq_add); LKU(gr->ref_fq_del);
return;
}
LKU(gr->ref_fq_add); LKU(gr->ref_fq_del);
#endif
evas_common_gradient2_clear(gr); evas_common_gradient2_clear(gr);
if (gr->stops.cdata) free(gr->stops.cdata); if (gr->stops.cdata) free(gr->stops.cdata);
if (gr->stops.adata) free(gr->stops.adata); if (gr->stops.adata) free(gr->stops.adata);

View File

@ -160,6 +160,15 @@ evas_common_gradient_free(RGBA_Gradient *gr)
if (!gr) return; if (!gr) return;
gr->references--; gr->references--;
if (gr->references > 0) return; if (gr->references > 0) return;
#ifdef EVAS_FRAME_QUEUING
LKL(gr->ref_fq_add); LKL(gr->ref_fq_del);
if (gr->ref_fq[0] != gr->ref_fq[1])
{
LKU(gr->ref_fq_add); LKU(gr->ref_fq_del);
return;
}
LKU(gr->ref_fq_add); LKU(gr->ref_fq_del);
#endif
evas_common_gradient_clear(gr); evas_common_gradient_clear(gr);
if (gr->type.name) free(gr->type.name); if (gr->type.name) free(gr->type.name);
if (gr->type.params) free(gr->type.params); if (gr->type.params) free(gr->type.params);

View File

@ -141,6 +141,12 @@ _evas_common_rgba_image_new(void)
if (!im) return NULL; if (!im) return NULL;
im->flags = RGBA_IMAGE_NOTHING; im->flags = RGBA_IMAGE_NOTHING;
im->ref = 1; im->ref = 1;
#ifdef EVAS_FRAME_QUEUING
LKI(im->ref_fq_add);
LKI(im->ref_fq_del);
pthread_cond_init(&(im->cond_fq_del), NULL);
#endif
evas_common_rgba_image_scalecache_init(&im->cache_entry); evas_common_rgba_image_scalecache_init(&im->cache_entry);
return &im->cache_entry; return &im->cache_entry;
} }
@ -152,6 +158,11 @@ _evas_common_rgba_image_delete(Image_Entry *ie)
#ifdef BUILD_PIPE_RENDER #ifdef BUILD_PIPE_RENDER
evas_common_pipe_free(im); evas_common_pipe_free(im);
# ifdef EVAS_FRAME_QUEUING
LKD(im->ref_fq_add);
LKD(im->ref_fq_del);
pthread_cond_destroy(&(im->cond_fq_del));
# endif
#endif #endif
evas_common_rgba_image_scalecache_shutdown(&im->cache_entry); evas_common_rgba_image_scalecache_shutdown(&im->cache_entry);
if (ie->info.module) evas_module_unref((Evas_Module *)ie->info.module); if (ie->info.module) evas_module_unref((Evas_Module *)ie->info.module);

View File

@ -40,6 +40,9 @@ struct _Scaleitem
int dst_w, dst_h; int dst_w, dst_h;
int flop; int flop;
int size_adjust; int size_adjust;
#ifdef EVAS_FRAME_QUEUING
RWLK(lock);
#endif
Eina_Bool forced_unload : 1; Eina_Bool forced_unload : 1;
Eina_Bool smooth : 1; Eina_Bool smooth : 1;
Eina_Bool populate_me : 1; Eina_Bool populate_me : 1;
@ -90,7 +93,8 @@ evas_common_scalecache_shutdown(void)
{ {
#ifdef SCALECACHE #ifdef SCALECACHE
init--; init--;
LKD(cache_lock); if (init ==0)
LKD(cache_lock);
#endif #endif
} }
@ -123,6 +127,9 @@ evas_common_rgba_image_scalecache_dirty(Image_Entry *ie)
{ {
Scaleitem *sci; Scaleitem *sci;
sci = im->cache.list->data; sci = im->cache.list->data;
#ifdef EVAS_FRAME_QUEUING
WRLKL(sci->lock);
#endif
im->cache.list = eina_list_remove(im->cache.list, sci); im->cache.list = eina_list_remove(im->cache.list, sci);
if (sci->im) if (sci->im)
{ {
@ -136,6 +143,10 @@ evas_common_rgba_image_scalecache_dirty(Image_Entry *ie)
cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci); cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci);
LKU(cache_lock); LKU(cache_lock);
} }
#ifdef EVAS_FRAME_QUEUING
RWLKU(sci->lock);
RWLKD(sci->lock);
#endif
free(sci); free(sci);
} }
LKU(im->cache.lock); LKU(im->cache.lock);
@ -230,6 +241,9 @@ _sci_find(RGBA_Image *im,
{ {
l = eina_list_last(im->cache.list); l = eina_list_last(im->cache.list);
sci = l->data; sci = l->data;
#ifdef EVAS_FRAME_QUEUING
WRLKL(sci->lock);
#endif
im->cache.list = eina_list_remove_list(im->cache.list, l); im->cache.list = eina_list_remove_list(im->cache.list, l);
if ((sci->usage == im->cache.newest_usage) || if ((sci->usage == im->cache.newest_usage) ||
(sci->usage_count == im->cache.newest_usage_count)) (sci->usage_count == im->cache.newest_usage_count))
@ -244,6 +258,9 @@ _sci_find(RGBA_Image *im,
// INF(" 1- %i", sci->dst_w * sci->dst_h * 4); // INF(" 1- %i", sci->dst_w * sci->dst_h * 4);
cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci); cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci);
} }
#ifdef EVAS_FRAME_QUEUING
RWLKU(sci->lock);
#endif
if (max_scale_items < 1) return NULL; if (max_scale_items < 1) return NULL;
} }
else else
@ -255,6 +272,9 @@ _sci_find(RGBA_Image *im,
sci = malloc(sizeof(Scaleitem)); sci = malloc(sizeof(Scaleitem));
memset(sci, 0, sizeof(Eina_Inlist)); memset(sci, 0, sizeof(Eina_Inlist));
sci->parent_im = im; sci->parent_im = im;
#ifdef EVAS_FRAME_QUEUING
RWLKI(sci->lock);
#endif
} }
sci->usage = 0; sci->usage = 0;
sci->usage_count = 0; sci->usage_count = 0;
@ -288,6 +308,9 @@ _cache_prune(Scaleitem *notsci, Eina_Bool copies_only)
if (!sci) return; if (!sci) return;
} }
if (sci == notsci) return; if (sci == notsci) return;
#ifdef EVAS_FRAME_QUEUING
WRLKL(sci->lock);
#endif
if (sci->im) if (sci->im)
{ {
evas_common_rgba_image_free(&sci->im->cache_entry); evas_common_rgba_image_free(&sci->im->cache_entry);
@ -303,6 +326,10 @@ _cache_prune(Scaleitem *notsci, Eina_Bool copies_only)
cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci); cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci);
memset(sci, 0, sizeof(Eina_Inlist)); memset(sci, 0, sizeof(Eina_Inlist));
} }
#ifdef EVAS_FRAME_QUEUING
RWLKU(sci->lock);
#endif
// INF("FLUSH %i > %i", cache_size, max_cache_size); // INF("FLUSH %i > %i", cache_size, max_cache_size);
} }
} }
@ -467,9 +494,14 @@ evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst,
LKL(im->cache.lock); LKL(im->cache.lock);
if ((src_region_w == dst_region_w) && (src_region_h == dst_region_h)) if ((src_region_w == dst_region_w) && (src_region_h == dst_region_h))
{ {
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888) #ifdef EVAS_FRAME_QUEUING
evas_cache_image_load_data(&im->cache_entry); if (!evas_common_frameq_enabled())
evas_common_image_colorspace_normalize(im); #endif
{
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
evas_cache_image_load_data(&im->cache_entry);
evas_common_image_colorspace_normalize(im);
}
// noscales++; // noscales++;
LKU(im->cache.lock); LKU(im->cache.lock);
if (im->image.data) if (im->image.data)
@ -496,9 +528,14 @@ evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst,
LKU(cache_lock); LKU(cache_lock);
if (!sci) if (!sci)
{ {
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888) #ifdef EVAS_FRAME_QUEUING
evas_cache_image_load_data(&im->cache_entry); if (!evas_common_frameq_enabled())
evas_common_image_colorspace_normalize(im); #endif
{
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
evas_cache_image_load_data(&im->cache_entry);
evas_common_image_colorspace_normalize(im);
}
// misses++; // misses++;
LKU(im->cache.lock); LKU(im->cache.lock);
if (im->image.data) if (im->image.data)
@ -656,6 +693,9 @@ evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst,
if (sci->flop > 0) sci->flop -= FLOP_DEL; if (sci->flop > 0) sci->flop -= FLOP_DEL;
} }
// INF("use cached!"); // INF("use cached!");
#ifdef EVAS_FRAME_QUEUING
RDLKL(sci->lock);
#endif
LKU(im->cache.lock); LKU(im->cache.lock);
evas_common_scale_rgba_in_to_out_clip_sample evas_common_scale_rgba_in_to_out_clip_sample
(sci->im, dst, dc, (sci->im, dst, dc,
@ -663,11 +703,22 @@ evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst,
dst_region_w, dst_region_h, dst_region_w, dst_region_h,
dst_region_x, dst_region_y, dst_region_x, dst_region_y,
dst_region_w, dst_region_h); dst_region_w, dst_region_h);
#ifdef EVAS_FRAME_QUEUING
RWLKU(sci->lock);
#endif
// hits++; // hits++;
// INF("check %p %i < %i", // INF("check %p %i < %i",
// im, // im,
// (int)im->cache.orig_usage, // (int)im->cache.orig_usage,
// (int)im->cache.newest_usage); // (int)im->cache.newest_usage);
#ifndef EVAS_FRAME_QUEUING
/* while framequeuing is applied,
* original image data is loaded by the main thread
* just before enqueuing the rendering op into the pipe.
* so unloading the original image data here
* causes only speed-down side-effect and no memory usage gain;
* it will be loaded again for the very next rendering for this image.
*/
if ((dounload) || if ((dounload) ||
((im->cache_entry.flags.loaded) && ((im->cache_entry.flags.loaded) &&
((!im->cs.no_free) ((!im->cs.no_free)
@ -683,12 +734,18 @@ evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst,
evas_common_rgba_image_unload(&im->cache_entry); evas_common_rgba_image_unload(&im->cache_entry);
} }
} }
#endif
} }
else else
{ {
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888) #ifdef EVAS_FRAME_QUEUING
evas_cache_image_load_data(&im->cache_entry); if (!evas_common_frameq_enabled())
evas_common_image_colorspace_normalize(im); #endif
{
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
evas_cache_image_load_data(&im->cache_entry);
evas_common_image_colorspace_normalize(im);
}
// misses++; // misses++;
LKU(im->cache.lock); LKU(im->cache.lock);
if (im->image.data) if (im->image.data)
@ -709,9 +766,14 @@ evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst,
} }
#else #else
RGBA_Image *im = (RGBA_Image *)ie; RGBA_Image *im = (RGBA_Image *)ie;
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888) #ifdef EVAS_FRAME_QUEUING
evas_cache_image_load_data(&im->cache_entry); if (!evas_common_frameq_enabled())
evas_common_image_colorspace_normalize(im); #endif
{
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
evas_cache_image_load_data(&im->cache_entry);
evas_common_image_colorspace_normalize(im);
}
if (im->image.data) if (im->image.data)
{ {
if (smooth) if (smooth)

View File

@ -4,6 +4,8 @@
#include "evas_common.h" #include "evas_common.h"
#include "evas_intl_utils.h" #include "evas_intl_utils.h"
#include "evas_font_private.h"
#ifdef INTERNATIONAL_SUPPORT #ifdef INTERNATIONAL_SUPPORT
#include <fribidi/fribidi.h> #include <fribidi/fribidi.h>
@ -41,10 +43,12 @@ evas_intl_utf8_to_visual(const char *text,
if (!unicode_in) if (!unicode_in)
{ {
len = -1; len = -1;
goto error1; goto error1;
} }
FBDLOCK();
len = fribidi_utf8_to_unicode(text, byte_len, unicode_in); len = fribidi_utf8_to_unicode(text, byte_len, unicode_in);
FBDUNLOCK();
unicode_in[len] = 0; unicode_in[len] = 0;
unicode_out = (FriBidiChar *)alloca(sizeof(FriBidiChar) * (len + 1)); unicode_out = (FriBidiChar *)alloca(sizeof(FriBidiChar) * (len + 1));
@ -109,7 +113,8 @@ evas_intl_utf8_to_visual(const char *text,
} }
fribidi_unicode_to_utf8(unicode_out, len, text_out); fribidi_unicode_to_utf8(unicode_out, len, text_out);
FBDUNLOCK();
*ret_len = len; *ret_len = len;
return text_out; return text_out;

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,82 @@
#ifndef _EVAS_PIPE_H #ifndef _EVAS_PIPE_H
#define _EVAS_PIPE_H #define _EVAS_PIPE_H
#ifdef BUILD_PTHREAD
typedef struct _Thinfo
{
int thread_num;
pthread_t thread_id;
pthread_barrier_t *barrier;
RGBA_Pipe_Thread_Info *info;
#ifdef EVAS_FRAME_QUEUING
void *fq_info;
#endif
} Thinfo;
#endif
#ifdef EVAS_FRAME_QUEUING
struct _Evas_Surface
{
EINA_INLIST;
RGBA_Image *im;
int x, y, w, h;
int dontpush; // dont push the surface out after drawing done
};
typedef struct _Evas_Surface Evas_Surface;
struct _Evas_Frame
{
EINA_INLIST;
Evas_Surface *surfaces;
void *data;
int in_process;
int ready;
int dont_schedule;
struct timeval ready_time;
void (*output_redraws_next_update_push) (void *data, void *surface, int x, int y, int w, int h);
void (*output_flush) (void *data);
void (*output_set_priv)(void *data, void *cur, void *prev);
};
typedef struct _Evas_Frame Evas_Frame;
struct _Evas_FrameQ
{
int initialised;
Evas_Frame *frames;
pthread_cond_t cond_new;
pthread_cond_t cond_ready;
pthread_cond_t cond_done;
LK(mutex);
int thread_num;
Thinfo thinfo[TH_MAX];
int frameq_sz;
Evas_Frame *cur_frame;
};
typedef struct _Evas_FrameQ Evas_FrameQ;
#define FRAMEQ_SZ_PER_THREAD 2
struct _Evas_Frameq_Thread_Info
{
Evas_FrameQ *frameq;
};
typedef struct _Evas_Frameq_Thread_Info Evas_Frameq_Thread_Info;
EAPI Evas_Surface *evas_common_frameq_new_surface (void *surface, int x, int y, int w, int h);
EAPI void evas_common_frameq_add_surface(Evas_Surface *surface);
EAPI void evas_common_frameq_set_frame_data(void *data,
void (*fn_output_redraws_next_update_push) (void *data, void *surface, int x, int y, int w, int h),
void (*fn_output_flush) (void *data),
void (*fn_output_set_priv)(void *data, void *cur, void *prev));
EAPI void evas_common_frameq_prepare_frame();
EAPI void evas_common_frameq_ready_frame();
EAPI void evas_common_frameq_init();
EAPI void evas_common_frameq_flush();
EAPI void evas_common_frameq_flush_ready ();
#endif
/* image rendering pipelines... new optional system - non-immediate and /* image rendering pipelines... new optional system - non-immediate and
* threadable * threadable
@ -19,4 +95,11 @@ EAPI void evas_common_pipe_map4_draw(RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc, RGBA_Map_Point *p, RGBA_Draw_Context *dc, RGBA_Map_Point *p,
int smooth, int level); int smooth, int level);
#ifdef EVAS_FRAME_QUEUING
EAPI void evas_common_pipe_op_grad_flush(RGBA_Gradient *gr);
EAPI void evas_common_pipe_op_grad2_flush(RGBA_Gradient2 *gr);
EAPI void evas_common_pipe_op_text_flush(RGBA_Font *fn);
EAPI void evas_common_pipe_op_image_flush(RGBA_Image *im);
#endif
#endif /* _EVAS_PIPE_H */ #endif /* _EVAS_PIPE_H */

View File

@ -136,7 +136,14 @@ extern EAPI int _evas_log_dom_global;
# include <pthread.h> # include <pthread.h>
# include <sched.h> # include <sched.h>
# define LK(x) pthread_mutex_t x # define LK(x) pthread_mutex_t x
#ifndef EVAS_FRAME_QUEUING
# define LKI(x) pthread_mutex_init(&(x), NULL); # define LKI(x) pthread_mutex_init(&(x), NULL);
#else
# define LKI(x) {pthread_mutexattr_t attr;\
pthread_mutexattr_init(&attr); \
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); \
pthread_mutex_init(&(x), &attr);}
#endif
# define LKD(x) pthread_mutex_destroy(&(x)); # define LKD(x) pthread_mutex_destroy(&(x));
# define LKL(x) pthread_mutex_lock(&(x)); # define LKL(x) pthread_mutex_lock(&(x));
# define LKT(x) pthread_mutex_trylock(&(x)); # define LKT(x) pthread_mutex_trylock(&(x));
@ -145,6 +152,15 @@ extern EAPI int _evas_log_dom_global;
# define THI(x) int x # define THI(x) int x
# define TH_MAX 8 # define TH_MAX 8
/* for rwlocks */
#define RWLK(x) pthread_rwlock_t x
#define RWLKI(x) pthread_rwlock_init(&(x), NULL);
#define RWLKD(x) pthread_rwlock_destroy(&(x));
#define RDLKL(x) pthread_rwlock_rdlock(&(x));
#define WRLKL(x) pthread_rwlock_wrlock(&(x));
#define RWLKU(x) pthread_rwlock_unlock(&(x));
// even though in theory having every Nth rendered line done by a different // even though in theory having every Nth rendered line done by a different
// thread might even out load across threads - it actually slows things down. // thread might even out load across threads - it actually slows things down.
//#define EVAS_SLI 1 //#define EVAS_SLI 1
@ -159,6 +175,15 @@ extern EAPI int _evas_log_dom_global;
# define TH(x) # define TH(x)
# define THI(x) # define THI(x)
# define TH_MAX 0 # define TH_MAX 0
/* for rwlocks */
#define RWLK(x)
#define RWLKI(x)
#define RWLKD(x)
#define RDLKL(x)
#define WRLKL(x)
#define RWLKU(x)
#endif #endif
#ifdef HAVE_ALLOCA_H #ifdef HAVE_ALLOCA_H
@ -521,6 +546,9 @@ struct _Image_Entry
time_t laststat; time_t laststat;
int references; int references;
#ifdef EVAS_FRAME_QUEUING
LK(lock_references); // needed for accessing references
#endif
unsigned char scale; unsigned char scale;
@ -630,6 +658,8 @@ struct _RGBA_Draw_Context
}; };
#ifdef BUILD_PIPE_RENDER #ifdef BUILD_PIPE_RENDER
#include "../engines/common/evas_map_image.h"
struct _RGBA_Pipe_Op struct _RGBA_Pipe_Op
{ {
RGBA_Draw_Context context; RGBA_Draw_Context context;
@ -707,6 +737,12 @@ struct _RGBA_Image
void *extended_info; void *extended_info;
#ifdef BUILD_PIPE_RENDER #ifdef BUILD_PIPE_RENDER
RGBA_Pipe *pipe; RGBA_Pipe *pipe;
#ifdef EVAS_FRAME_QUEUING
LK(ref_fq_add);
LK(ref_fq_del);
pthread_cond_t cond_fq_del;
int ref_fq[2]; // ref_fq[0] is for addition, ref_fq[1] is for deletion
#endif
#endif #endif
int ref; int ref;
@ -790,6 +826,13 @@ struct _RGBA_Gradient
} type; } type;
int references; int references;
#ifdef EVAS_FRAME_QUEUING
LK(ref_fq_add);
LK(ref_fq_del);
pthread_cond_t cond_fq_del;
int ref_fq[2]; //ref_fq[0] is for addition,
//ref_fq[1] is for deletion
#endif
Eina_Bool imported_data : 1; Eina_Bool imported_data : 1;
Eina_Bool has_alpha : 1; Eina_Bool has_alpha : 1;
@ -847,6 +890,13 @@ struct _RGBA_Gradient2
} type; } type;
int references; int references;
#ifdef EVAS_FRAME_QUEUING
LK(ref_fq_add);
LK(ref_fq_del);
pthread_cond_t cond_fq_del;
int ref_fq[2]; //ref_fq[0] is for addition,
//ref_fq[1] is for deletion
#endif
Eina_Bool has_alpha : 1; Eina_Bool has_alpha : 1;
}; };
@ -922,6 +972,12 @@ struct _RGBA_Font
Fash_Int *fash; Fash_Int *fash;
unsigned char sizeok : 1; unsigned char sizeok : 1;
LK(lock); LK(lock);
#ifdef EVAS_FRAME_QUEUING
LK(ref_fq_add);
LK(ref_fq_del);
pthread_cond_t cond_fq_del;
int ref_fq[2]; //ref_fq[0] is for addition, ref_fq[1] is for deletion
#endif
}; };
struct _RGBA_Font_Int struct _RGBA_Font_Int

View File

@ -31,6 +31,9 @@ struct _Evas_Engine_Info_Buffer
void (*free_update_region) (int x, int y, int w, int h, void *data); void (*free_update_region) (int x, int y, int w, int h, void *data);
} func; } func;
} info; } info;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };
#endif #endif

View File

@ -126,6 +126,7 @@ eng_info(Evas *e)
info = calloc(1, sizeof(Evas_Engine_Info_Buffer)); info = calloc(1, sizeof(Evas_Engine_Info_Buffer));
if (!info) return NULL; if (!info) return NULL;
info->magic.magic = rand(); info->magic.magic = rand();
info->render_mode = EVAS_RENDER_MODE_BLOCKING;
return info; return info;
e = NULL; e = NULL;
} }

View File

@ -21,6 +21,9 @@ struct _Evas_Engine_Info_Cairo_X11
} info; } info;
/* engine specific function calls to query stuff about the destination */ /* engine specific function calls to query stuff about the destination */
/* engine (what visual & colormap & depth to use, performance info etc. */ /* engine (what visual & colormap & depth to use, performance info etc. */
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };
#endif #endif

View File

@ -267,6 +267,7 @@ eng_info(Evas *e)
info = calloc(1, sizeof(Evas_Engine_Info_Cairo_X11)); info = calloc(1, sizeof(Evas_Engine_Info_Cairo_X11));
if (!info) return NULL; if (!info) return NULL;
info->magic.magic = rand(); info->magic.magic = rand();
info->render_mode = EVAS_RENDER_MODE_BLOCKING;
return info; return info;
e = NULL; e = NULL;
} }

View File

@ -27,6 +27,9 @@ struct _Evas_Engine_Info_Direct3D
unsigned short height; unsigned short height;
unsigned char *mask; unsigned char *mask;
} *shape; } *shape;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };

View File

@ -77,6 +77,7 @@ eng_info(Evas *e)
if (!info) return NULL; if (!info) return NULL;
info->magic.magic = rand(); info->magic.magic = rand();
memset(&info->info, 0, sizeof(info->info)); memset(&info->info, 0, sizeof(info->info));
info->render_mode = EVAS_RENDER_MODE_BLOCKING;
return info; return info;
e = NULL; e = NULL;
} }

View File

@ -16,6 +16,9 @@ struct _Evas_Engine_Info_DirectFB
IDirectFB *dfb; IDirectFB *dfb;
IDirectFBSurface *surface; IDirectFBSurface *surface;
} info; } info;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };
#endif #endif

View File

@ -16,6 +16,9 @@ struct _Evas_Engine_Info_FB
int refresh; int refresh;
int rotation; int rotation;
} info; } info;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };
#endif #endif

View File

@ -81,6 +81,7 @@ eng_info(Evas *e)
info = calloc(1, sizeof(Evas_Engine_Info_FB)); info = calloc(1, sizeof(Evas_Engine_Info_FB));
if (!info) return NULL; if (!info) return NULL;
info->magic.magic = rand(); info->magic.magic = rand();
info->render_mode = EVAS_RENDER_MODE_BLOCKING;
return info; return info;
e = NULL; e = NULL;
} }

View File

@ -20,6 +20,9 @@ struct _Evas_Engine_Info_GL_Glew
HWND window; HWND window;
int depth; int depth;
} info; } info;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };

View File

@ -20,6 +20,7 @@ eng_info(Evas *e __UNUSED__)
info = calloc(1, sizeof(Evas_Engine_Info_GL_Glew)); info = calloc(1, sizeof(Evas_Engine_Info_GL_Glew));
if (!info) return NULL; if (!info) return NULL;
info->magic.magic = rand(); info->magic.magic = rand();
info->render_mode = EVAS_RENDER_MODE_BLOCKING;
return info; return info;
} }

View File

@ -29,13 +29,16 @@ struct _Evas_Engine_Info_GL_X11
Colormap (*best_colormap_get) (Evas_Engine_Info_GL_X11 *einfo); Colormap (*best_colormap_get) (Evas_Engine_Info_GL_X11 *einfo);
int (*best_depth_get) (Evas_Engine_Info_GL_X11 *einfo); int (*best_depth_get) (Evas_Engine_Info_GL_X11 *einfo);
} func; } func;
struct { struct {
void (*pre_swap) (void *data, Evas *e); void (*pre_swap) (void *data, Evas *e);
void (*post_swap) (void *data, Evas *e); void (*post_swap) (void *data, Evas *e);
void *data; // data for callback calls void *data; // data for callback calls
} callback; } callback;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
unsigned char vsync : 1; // does nothing right now unsigned char vsync : 1; // does nothing right now
unsigned char indirect : 1; // use indirect rendering unsigned char indirect : 1; // use indirect rendering

View File

@ -184,6 +184,7 @@ eng_info(Evas *e)
info->func.best_visual_get = eng_best_visual_get; info->func.best_visual_get = eng_best_visual_get;
info->func.best_colormap_get = eng_best_colormap_get; info->func.best_colormap_get = eng_best_colormap_get;
info->func.best_depth_get = eng_best_depth_get; info->func.best_depth_get = eng_best_depth_get;
info->render_mode = EVAS_RENDER_MODE_BLOCKING;
return info; return info;
e = NULL; e = NULL;
} }

View File

@ -15,6 +15,9 @@ struct _Evas_Engine_Info_Quartz
struct { struct {
CGContextRef context; CGContextRef context;
} info; } info;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };
#endif #endif

View File

@ -44,6 +44,7 @@ eng_info(Evas *e)
info = calloc(1, sizeof(Evas_Engine_Info_Quartz)); info = calloc(1, sizeof(Evas_Engine_Info_Quartz));
if (!info) return NULL; if (!info) return NULL;
info->magic.magic = rand(); info->magic.magic = rand();
info->render_mode = EVAS_RENDER_MODE_BLOCKING;
return info; return info;
} }

View File

@ -23,6 +23,9 @@ struct _Evas_Engine_Info_Software_16_DDraw
int rotation; int rotation;
} info; } info;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };

View File

@ -54,6 +54,7 @@ eng_info(Evas *e)
info = calloc(1, sizeof(Evas_Engine_Info_Software_16_DDraw)); info = calloc(1, sizeof(Evas_Engine_Info_Software_16_DDraw));
if (!info) return NULL; if (!info) return NULL;
info->magic.magic = rand(); info->magic.magic = rand();
info->render_mode = EVAS_RENDER_MODE_BLOCKING;
return info; return info;
e = NULL; e = NULL;
} }

View File

@ -17,6 +17,9 @@ struct _Evas_Engine_Info_SDL_16
int noframe : 1; int noframe : 1;
int alpha : 1; int alpha : 1;
} info; } info;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };
#endif #endif

View File

@ -26,6 +26,9 @@ struct _Evas_Engine_Info_Software_16_WinCE
int (*suspend) (int backend); int (*suspend) (int backend);
int (*resume) (int backend); int (*resume) (int backend);
} func; } func;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };

View File

@ -95,6 +95,7 @@ eng_info(Evas *e)
info->magic.magic = rand(); info->magic.magic = rand();
info->func.suspend = _suspend; info->func.suspend = _suspend;
info->func.resume = _resume; info->func.resume = _resume;
info->render_mode = EVAS_RENDER_MODE_BLOCKING;
return info; return info;
e = NULL; e = NULL;
} }

View File

@ -17,6 +17,9 @@ struct _Evas_Engine_Info_Software_16_X11
Drawable drawable; Drawable drawable;
int rotation; int rotation;
} info; } info;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };
#endif #endif

View File

@ -103,6 +103,7 @@ eng_info(Evas *e)
info = calloc(1, sizeof(Evas_Engine_Info_Software_16_X11)); info = calloc(1, sizeof(Evas_Engine_Info_Software_16_X11));
if (!info) return NULL; if (!info) return NULL;
info->magic.magic = rand(); info->magic.magic = rand();
info->render_mode = EVAS_RENDER_MODE_BLOCKING;
return info; return info;
e = NULL; e = NULL;
} }

View File

@ -21,6 +21,9 @@ struct _Evas_Engine_Info_Software_DDraw
int rotation; int rotation;
unsigned int fullscreen : 1; unsigned int fullscreen : 1;
} info; } info;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };

View File

@ -97,6 +97,7 @@ eng_info(Evas *e)
info = calloc(1, sizeof(Evas_Engine_Info_Software_DDraw)); info = calloc(1, sizeof(Evas_Engine_Info_Software_DDraw));
if (!info) return NULL; if (!info) return NULL;
info->magic.magic = rand(); info->magic.magic = rand();
info->render_mode = EVAS_RENDER_MODE_BLOCKING;
return info; return info;
e = NULL; e = NULL;
} }

View File

@ -23,6 +23,9 @@ struct _Evas_Engine_Info_Software_Gdi
unsigned int layered : 1; unsigned int layered : 1;
unsigned int fullscreen : 1; unsigned int fullscreen : 1;
} info; } info;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };

View File

@ -150,7 +150,11 @@ static void
eng_rectangle_draw(void *data __UNUSED__, void *context, void *surface, int x, int y, int w, int h) eng_rectangle_draw(void *data __UNUSED__, void *context, void *surface, int x, int y, int w, int h)
{ {
#ifdef BUILD_PIPE_RENDER #ifdef BUILD_PIPE_RENDER
if (cpunum > 1) if ((cpunum > 1)
#ifdef EVAS_FRAME_QUEUING
&& evas_common_frameq_enabled()
#endif
)
evas_common_pipe_rectangle_draw(surface, context, x, y, w, h); evas_common_pipe_rectangle_draw(surface, context, x, y, w, h);
else else
#endif #endif
@ -164,8 +168,12 @@ static void
eng_line_draw(void *data __UNUSED__, void *context, void *surface, int x1, int y1, int x2, int y2) eng_line_draw(void *data __UNUSED__, void *context, void *surface, int x1, int y1, int x2, int y2)
{ {
#ifdef BUILD_PIPE_RENDER #ifdef BUILD_PIPE_RENDER
if (cpunum > 1) if ((cpunum > 1)
evas_common_pipe_line_draw(surface, context, x1, y1, x2, y2); #ifdef EVAS_FRAME_QUEUING
&& evas_common_frameq_enabled()
#endif
)
evas_common_pipe_line_draw(surface, context, x1, y1, x2, y2);
else else
#endif #endif
{ {
@ -190,7 +198,11 @@ static void
eng_polygon_draw(void *data __UNUSED__, void *context, void *surface, void *polygon, int x, int y) eng_polygon_draw(void *data __UNUSED__, void *context, void *surface, void *polygon, int x, int y)
{ {
#ifdef BUILD_PIPE_RENDER #ifdef BUILD_PIPE_RENDER
if (cpunum > 1) if ((cpunum > 1)
#ifdef EVAS_FRAME_QUEUING
&& evas_common_frameq_enabled()
#endif
)
evas_common_pipe_poly_draw(surface, context, polygon, x, y); evas_common_pipe_poly_draw(surface, context, polygon, x, y);
else else
#endif #endif
@ -284,7 +296,11 @@ static void
eng_gradient2_linear_draw(void *data __UNUSED__, void *context, void *surface, void *linear_gradient, int x, int y, int w, int h) eng_gradient2_linear_draw(void *data __UNUSED__, void *context, void *surface, void *linear_gradient, int x, int y, int w, int h)
{ {
#ifdef BUILD_PIPE_RENDER #ifdef BUILD_PIPE_RENDER
if (cpunum > 1) if ((cpunum > 1)
#ifdef EVAS_FRAME_QUEUING
&& evas_common_frameq_enabled()
#endif
)
evas_common_pipe_grad2_draw(surface, context, x, y, w, h, linear_gradient); evas_common_pipe_grad2_draw(surface, context, x, y, w, h, linear_gradient);
else else
#endif #endif
@ -351,7 +367,11 @@ static void
eng_gradient2_radial_draw(void *data __UNUSED__, void *context, void *surface, void *radial_gradient, int x, int y, int w, int h) eng_gradient2_radial_draw(void *data __UNUSED__, void *context, void *surface, void *radial_gradient, int x, int y, int w, int h)
{ {
#ifdef BUILD_PIPE_RENDER #ifdef BUILD_PIPE_RENDER
if (cpunum > 1) if ((cpunum > 1)
#ifdef EVAS_FRAME_QUEUING
&& evas_common_frameq_enabled()
#endif
)
evas_common_pipe_grad2_draw(surface, context, x, y, w, h, radial_gradient); evas_common_pipe_grad2_draw(surface, context, x, y, w, h, radial_gradient);
else else
#endif #endif
@ -484,7 +504,11 @@ static void
eng_gradient_draw(void *data __UNUSED__, void *context, void *surface, void *gradient, int x, int y, int w, int h) eng_gradient_draw(void *data __UNUSED__, void *context, void *surface, void *gradient, int x, int y, int w, int h)
{ {
#ifdef BUILD_PIPE_RENDER #ifdef BUILD_PIPE_RENDER
if (cpunum > 1) if ((cpunum > 1)
#ifdef EVAS_FRAME_QUEUING
&& evas_common_frameq_enabled()
#endif
)
evas_common_pipe_grad_draw(surface, context, x, y, w, h, gradient); evas_common_pipe_grad_draw(surface, context, x, y, w, h, gradient);
else else
#endif #endif
@ -745,7 +769,11 @@ eng_image_draw(void *data __UNUSED__, void *context, void *surface, void *image,
if (!image) return; if (!image) return;
im = image; im = image;
#ifdef BUILD_PIPE_RENDER #ifdef BUILD_PIPE_RENDER
if (cpunum > 1) if ((cpunum > 1)
#ifdef EVAS_FRAME_QUEUING
&& evas_common_frameq_enabled()
#endif
)
{ {
evas_common_rgba_image_scalecache_prepare(im, surface, context, smooth, evas_common_rgba_image_scalecache_prepare(im, surface, context, smooth,
src_x, src_y, src_w, src_h, src_x, src_y, src_w, src_h,
@ -810,7 +838,7 @@ eng_image_map4_draw(void *data __UNUSED__, void *context, void *surface, void *i
(p[3].col == 0xffffffff)) (p[3].col == 0xffffffff))
{ {
int dx, dy, dw, dh; int dx, dy, dw, dh;
dx = p[0].x >> FP; dx = p[0].x >> FP;
dy = p[0].y >> FP; dy = p[0].y >> FP;
dw = (p[2].x >> FP) - dx; dw = (p[2].x >> FP) - dx;
@ -823,13 +851,18 @@ eng_image_map4_draw(void *data __UNUSED__, void *context, void *surface, void *i
else else
{ {
#ifdef BUILD_PIPE_RENDER #ifdef BUILD_PIPE_RENDER
if (cpunum > 1) if ((cpunum > 1)
# ifdef EVAS_FRAME_QUEUING
&& evas_common_frameq_enabled()
# endif
)
evas_common_pipe_map4_draw(im, surface, context, p, smooth, level); evas_common_pipe_map4_draw(im, surface, context, p, smooth, level);
else else
#endif #endif
evas_common_map4_rgba(im, surface, context, p, smooth, level); evas_common_map4_rgba(im, surface, context, p, smooth, level);
} }
evas_common_cpu_end_opt(); evas_common_cpu_end_opt();
} }
static void * static void *
@ -1000,7 +1033,11 @@ static void
eng_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const char *text) eng_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const char *text)
{ {
#ifdef BUILD_PIPE_RENDER #ifdef BUILD_PIPE_RENDER
if (cpunum > 1) if ((cpunum > 1)
#ifdef EVAS_FRAME_QUEUING
&& evas_common_frameq_enabled()
#endif
)
evas_common_pipe_text_draw(surface, context, font, x, y, text); evas_common_pipe_text_draw(surface, context, font, x, y, text);
else else
#endif #endif

View File

@ -25,6 +25,9 @@ struct _Evas_Engine_Info_Software_Qtopia
QWidget *target; QWidget *target;
int rotation; int rotation;
} info; } info;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };
#endif #endif

View File

@ -90,6 +90,7 @@ eng_info(Evas *e)
info = calloc(1, sizeof(Evas_Engine_Info_Software_Qtopia)); info = calloc(1, sizeof(Evas_Engine_Info_Software_Qtopia));
if (!info) return NULL; if (!info) return NULL;
info->magic.magic = rand(); info->magic.magic = rand();
info->render_mode = EVAS_RENDER_MODE_BLOCKING;
return info; return info;
e = NULL; e = NULL;
} }

View File

@ -18,6 +18,9 @@ struct _Evas_Engine_Info_SDL
int noframe : 1; int noframe : 1;
int alpha : 1; int alpha : 1;
} info; } info;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };
#endif #endif

View File

@ -53,6 +53,8 @@ struct _Evas_Engine_Info_Software_X11
} func; } func;
int mask_changed; int mask_changed;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };
#endif #endif

View File

@ -84,7 +84,10 @@ struct _Render_Engine
int dpi; // xres - dpi int dpi; // xres - dpi
} xr; // xres - dpi } xr; // xres - dpi
#endif #endif
#ifdef EVAS_FRAME_QUEUING
Evas_Engine_Render_Mode render_mode;
#endif
void (*outbuf_free)(Outbuf *ob); void (*outbuf_free)(Outbuf *ob);
void (*outbuf_reconfigure)(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth); void (*outbuf_reconfigure)(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth);
int (*outbuf_get_rot)(Outbuf *ob); int (*outbuf_get_rot)(Outbuf *ob);
@ -94,6 +97,9 @@ struct _Render_Engine
void (*outbuf_flush)(Outbuf *ob); void (*outbuf_flush)(Outbuf *ob);
void (*outbuf_idle_flush)(Outbuf *ob); void (*outbuf_idle_flush)(Outbuf *ob);
Eina_Bool (*outbuf_alpha_get)(Outbuf *ob); Eina_Bool (*outbuf_alpha_get)(Outbuf *ob);
#ifdef EVAS_FRAME_QUEUING
void (*outbuf_set_priv)(Outbuf *ob, void *cur, void *prev);
#endif
}; };
/* prototypes we will use here */ /* prototypes we will use here */
@ -441,6 +447,7 @@ eng_info(Evas *e __UNUSED__)
info->func.best_visual_get = _best_visual_get; info->func.best_visual_get = _best_visual_get;
info->func.best_colormap_get = _best_colormap_get; info->func.best_colormap_get = _best_colormap_get;
info->func.best_depth_get = _best_depth_get; info->func.best_depth_get = _best_depth_get;
info->render_mode = EVAS_RENDER_MODE_BLOCKING;
return info; return info;
} }
@ -502,6 +509,10 @@ eng_setup(Evas *e, void *in)
re->outbuf_flush = evas_software_xlib_outbuf_flush; re->outbuf_flush = evas_software_xlib_outbuf_flush;
re->outbuf_idle_flush = evas_software_xlib_outbuf_idle_flush; re->outbuf_idle_flush = evas_software_xlib_outbuf_idle_flush;
re->outbuf_alpha_get = evas_software_xlib_outbuf_alpha_get; re->outbuf_alpha_get = evas_software_xlib_outbuf_alpha_get;
#ifdef EVAS_FRAME_QUEUING
re->outbuf_set_priv = evas_software_xlib_outbuf_set_priv;
re->render_mode = info->render_mode;
#endif
} }
#endif #endif
@ -542,6 +553,9 @@ eng_setup(Evas *e, void *in)
{ {
int ponebuf = 0; int ponebuf = 0;
#ifdef EVAS_FRAME_QUEUING
evas_common_frameq_flush ();
#endif
re = e->engine.data.output; re = e->engine.data.output;
ponebuf = re->ob->onebuf; ponebuf = re->ob->onebuf;
@ -564,6 +578,9 @@ eng_setup(Evas *e, void *in)
info->info.shape_dither, info->info.shape_dither,
info->info.destination_alpha); info->info.destination_alpha);
evas_software_xlib_outbuf_debug_set(re->ob, info->info.debug); evas_software_xlib_outbuf_debug_set(re->ob, info->info.debug);
#ifdef EVAS_FRAME_QUEUING
re->render_mode = info->render_mode;
#endif
} }
#endif #endif
@ -714,23 +731,112 @@ static void
eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h) eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
{ {
Render_Engine *re; Render_Engine *re;
#ifdef EVAS_FRAME_QUEUING
Evas_Surface *e_surface;
#endif
re = (Render_Engine *)data; re = (Render_Engine *)data;
#ifdef BUILD_PIPE_RENDER #if defined(BUILD_PIPE_RENDER) && !defined(EVAS_FRAME_QUEUING)
evas_common_pipe_map4_begin(surface); evas_common_pipe_map4_begin(surface);
#endif #endif /* BUILD_PIPE_RENDER && !EVAS_FRAME_QUEUING*/
#ifdef EVAS_FRAME_QUEUING
if (re->render_mode == EVAS_RENDER_MODE_NONBLOCKING)
{
/* create a new frame if this is the first surface of this frame */
evas_common_frameq_prepare_frame();
/* add surface into the frame */
e_surface = evas_common_frameq_new_surface(surface, x, y, w, h);
evas_common_frameq_add_surface(e_surface);
return;
}
#endif
re->outbuf_push_updated_region(re->ob, surface, x, y, w, h); re->outbuf_push_updated_region(re->ob, surface, x, y, w, h);
re->outbuf_free_region_for_update(re->ob, surface); re->outbuf_free_region_for_update(re->ob, surface);
evas_common_cpu_end_opt(); evas_common_cpu_end_opt();
} }
#ifdef EVAS_FRAME_QUEUING
static void *
eng_image_map_surface_new(void *data , int w, int h, int alpha)
{
void *surface;
DATA32 *pixels;
Render_Engine *re;
Evas_Surface *e_surface;
re = (Render_Engine *)data;
surface = evas_cache_image_copied_data(evas_common_image_cache_get(),
w, h, NULL, alpha,
EVAS_COLORSPACE_ARGB8888);
pixels = evas_cache_image_pixels(surface);
if (re->render_mode == EVAS_RENDER_MODE_NONBLOCKING)
{
/* create a new frame if this is the first surface of this frame */
evas_common_frameq_prepare_frame();
/* add surface into the frame */
e_surface = evas_common_frameq_new_surface (surface, 0, 0, w, h);
e_surface->dontpush = 1; // this surface is not going to be pushed to screen
evas_common_frameq_add_surface(e_surface);
}
return surface;
}
static void
eng_output_frameq_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
{
Render_Engine *re;
re = (Render_Engine *)data;
re->outbuf_push_updated_region(re->ob, surface, x, y, w, h);
re->outbuf_free_region_for_update(re->ob, surface);
evas_common_cpu_end_opt();
}
static void
eng_output_frameq_flush(void *data)
{
Render_Engine *re;
re = (Render_Engine *)data;
re->outbuf_flush(re->ob);
}
static void
eng_output_frameq_set_priv(void *data, void *cur, void *prev)
{
Render_Engine *re;
re = (Render_Engine *)data;
re->outbuf_set_priv(re->ob, cur, prev);
}
#endif
static void static void
eng_output_flush(void *data) eng_output_flush(void *data)
{ {
Render_Engine *re; Render_Engine *re;
re = (Render_Engine *)data; re = (Render_Engine *)data;
re->outbuf_flush(re->ob); #ifdef EVAS_FRAME_QUEUING
if (re->render_mode == EVAS_RENDER_MODE_NONBLOCKING)
{
evas_common_frameq_set_frame_data(data,
eng_output_frameq_redraws_next_update_push,
eng_output_frameq_flush,
eng_output_frameq_set_priv);
evas_common_frameq_ready_frame();
evas_common_frameq_begin();
}
else
#endif
{
re->outbuf_flush(re->ob);
}
} }
static void static void
@ -751,6 +857,7 @@ eng_canvas_alpha_get(void *data, void *context __UNUSED__)
return (re->ob->priv.destination_alpha) || (re->outbuf_alpha_get(re->ob)); return (re->ob->priv.destination_alpha) || (re->outbuf_alpha_get(re->ob));
} }
/* module advertising code */ /* module advertising code */
static int static int
module_open(Evas_Module *em) module_open(Evas_Module *em)
@ -793,6 +900,10 @@ module_open(Evas_Module *em)
ORD(output_flush); ORD(output_flush);
ORD(output_idle_flush); ORD(output_idle_flush);
/* now advertise out own api */ /* now advertise out own api */
#ifdef EVAS_FRAME_QUEUING
ORD(image_map_surface_new);
#endif
em->functions = (void *)(&func); em->functions = (void *)(&func);
return 1; return 1;
} }

View File

@ -113,6 +113,10 @@ struct _Outbuf
Eina_List *pending_writes; Eina_List *pending_writes;
/* a list of previous frame pending regions to write to the target */ /* a list of previous frame pending regions to write to the target */
Eina_List *prev_pending_writes; Eina_List *prev_pending_writes;
#ifdef EVAS_FRAME_QUEUING
/* protecting prev_pending_writes */
LK(lock);
#endif
unsigned char mask_dither : 1; unsigned char mask_dither : 1;
unsigned char destination_alpha : 1; unsigned char destination_alpha : 1;

View File

@ -305,7 +305,18 @@ evas_software_xlib_x_output_buffer_new(Display *d, Visual *v, int depth, int w,
ph = XSetErrorHandler((XErrorHandler) ph = XSetErrorHandler((XErrorHandler)
x_output_tmp_x_err); x_output_tmp_x_err);
} }
#if defined(EVAS_FRAME_QUEUING) && defined(LIBXEXT_VERSION_LOW)
/* workaround for libXext of lower then 1.1.1 */
if (evas_common_frameq_enabled())
XLockDisplay(d);
#endif
XShmAttach(d, xob->shm_info); XShmAttach(d, xob->shm_info);
#if defined(EVAS_FRAME_QUEUING) && defined(LIBXEXT_VERSION_LOW)
/* workaround for libXext of lower then 1.1.1 */
if (evas_common_frameq_enabled())
XUnlockDisplay(d);
#endif
if (try_shm == 2) // only needed during testing if (try_shm == 2) // only needed during testing
{ {
XSync(d, False); XSync(d, False);

View File

@ -25,6 +25,15 @@ static int shmsize = 0;
static int shmmemlimit = 10 * 1024 * 1024; static int shmmemlimit = 10 * 1024 * 1024;
static int shmcountlimit = 32; static int shmcountlimit = 32;
#ifdef EVAS_FRAME_QUEUING
static LK(lock_shmpool);
#define SHMPOOL_LOCK() LKL(lock_shmpool)
#define SHMPOOL_UNLOCK() LKU(lock_shmpool)
#else
#define SHMPOOL_LOCK()
#define SHMPOOL_UNLOCK()
#endif
static X_Output_Buffer * static X_Output_Buffer *
_find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data) _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
{ {
@ -46,6 +55,7 @@ _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
else else
lbytes = ((w + 31) / 32) * 4; lbytes = ((w + 31) / 32) * 4;
sz = lbytes * h; sz = lbytes * h;
SHMPOOL_LOCK();
EINA_LIST_FOREACH(shmpool, l, xob2) EINA_LIST_FOREACH(shmpool, l, xob2)
{ {
int szdif; int szdif;
@ -69,8 +79,12 @@ _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
} }
} }
if ((fitness > (100 * 100)) || (!xob)) if ((fitness > (100 * 100)) || (!xob))
return evas_software_xlib_x_output_buffer_new(d, v, depth, w, h, shm, data); {
SHMPOOL_UNLOCK();
xob = evas_software_xlib_x_output_buffer_new(d, v, depth, w, h, shm, data);
return xob;
}
have_xob: have_xob:
shmpool = eina_list_remove_list(shmpool, xl); shmpool = eina_list_remove_list(shmpool, xl);
xob->w = w; xob->w = w;
@ -80,6 +94,7 @@ _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
xob->xim->height = xob->h; xob->xim->height = xob->h;
xob->xim->bytes_per_line = xob->bpl; xob->xim->bytes_per_line = xob->bpl;
shmsize -= xob->psize * (xob->xim->depth / 8); shmsize -= xob->psize * (xob->xim->depth / 8);
SHMPOOL_UNLOCK();
return xob; return xob;
} }
@ -89,6 +104,7 @@ _unfind_xob(X_Output_Buffer *xob, int sync)
// evas_software_xlib_x_output_buffer_free(xob, sync); return; // evas_software_xlib_x_output_buffer_free(xob, sync); return;
if (xob->shm_info) if (xob->shm_info)
{ {
SHMPOOL_LOCK();
shmpool = eina_list_prepend(shmpool, xob); shmpool = eina_list_prepend(shmpool, xob);
shmsize += xob->psize * xob->xim->depth / 8; shmsize += xob->psize * xob->xim->depth / 8;
while ((shmsize > (shmmemlimit)) || while ((shmsize > (shmmemlimit)) ||
@ -103,9 +119,11 @@ _unfind_xob(X_Output_Buffer *xob, int sync)
break; break;
} }
xob = xl->data; xob = xl->data;
shmpool = eina_list_remove_list(shmpool, xl); shmpool = eina_list_remove_list(shmpool, xl);
shmsize -= xob->psize * xob->xim->depth / 8;
evas_software_xlib_x_output_buffer_free(xob, sync); evas_software_xlib_x_output_buffer_free(xob, sync);
} }
SHMPOOL_UNLOCK();
} }
else else
evas_software_xlib_x_output_buffer_free(xob, sync); evas_software_xlib_x_output_buffer_free(xob, sync);
@ -114,6 +132,7 @@ _unfind_xob(X_Output_Buffer *xob, int sync)
static void static void
_clear_xob(int sync) _clear_xob(int sync)
{ {
SHMPOOL_LOCK();
while (shmpool) while (shmpool)
{ {
X_Output_Buffer *xob; X_Output_Buffer *xob;
@ -123,16 +142,23 @@ _clear_xob(int sync)
evas_software_xlib_x_output_buffer_free(xob, sync); evas_software_xlib_x_output_buffer_free(xob, sync);
} }
shmsize = 0; shmsize = 0;
SHMPOOL_UNLOCK();
} }
void void
evas_software_xlib_outbuf_init(void) evas_software_xlib_outbuf_init(void)
{ {
#ifdef EVAS_FRAME_QUEUING
LKI(lock_shmpool);
#endif
} }
void void
evas_software_xlib_outbuf_free(Outbuf *buf) evas_software_xlib_outbuf_free(Outbuf *buf)
{ {
#ifdef EVAS_FRAME_QUEUING
LKL(buf->priv.lock);
#endif
while (buf->priv.pending_writes) while (buf->priv.pending_writes)
{ {
RGBA_Image *im; RGBA_Image *im;
@ -146,6 +172,9 @@ evas_software_xlib_outbuf_free(Outbuf *buf)
if (obr->mxob) _unfind_xob(obr->mxob, 0); if (obr->mxob) _unfind_xob(obr->mxob, 0);
free(obr); free(obr);
} }
#ifdef EVAS_FRAME_QUEUING
LKU(buf->priv.lock);
#endif
evas_software_xlib_outbuf_idle_flush(buf); evas_software_xlib_outbuf_idle_flush(buf);
evas_software_xlib_outbuf_flush(buf); evas_software_xlib_outbuf_flush(buf);
if (buf->priv.x11.xlib.gc) if (buf->priv.x11.xlib.gc)
@ -155,6 +184,9 @@ evas_software_xlib_outbuf_free(Outbuf *buf)
if (buf->priv.pal) if (buf->priv.pal)
evas_software_xlib_x_color_deallocate(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.cmap, evas_software_xlib_x_color_deallocate(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.cmap,
buf->priv.x11.xlib.vis, buf->priv.pal); buf->priv.x11.xlib.vis, buf->priv.pal);
#ifdef EVAS_FRAME_QUEUING
LKD(buf->priv.lock);
#endif
free(buf); free(buf);
_clear_xob(0); _clear_xob(0);
} }
@ -331,6 +363,9 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
evas_software_xlib_outbuf_drawable_set(buf, draw); evas_software_xlib_outbuf_drawable_set(buf, draw);
evas_software_xlib_outbuf_mask_set(buf, mask); evas_software_xlib_outbuf_mask_set(buf, mask);
} }
#ifdef EVAS_FRAME_QUEUING
LKI(buf->priv.lock);
#endif
return buf; return buf;
} }
@ -578,7 +613,10 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
/* FIXME: faster memset! */ /* FIXME: faster memset! */
memset(im->image.data, 0, w * h * sizeof(DATA32)); memset(im->image.data, 0, w * h * sizeof(DATA32));
buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im); #ifdef EVAS_FRAME_QUEUING
if (!evas_common_frameq_enabled())
#endif
buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im);
return im; return im;
} }
@ -653,6 +691,9 @@ evas_software_xlib_outbuf_flush(Outbuf *buf)
buf->priv.x11.xlib.gcm, buf->priv.x11.xlib.gcm,
obr->x, obr->y, 0); obr->x, obr->y, 0);
} }
#ifdef EVAS_FRAME_QUEUING
LKL(buf->priv.lock);
#endif
while (buf->priv.prev_pending_writes) while (buf->priv.prev_pending_writes)
{ {
im = buf->priv.prev_pending_writes->data; im = buf->priv.prev_pending_writes->data;
@ -670,6 +711,9 @@ evas_software_xlib_outbuf_flush(Outbuf *buf)
free(obr); free(obr);
} }
buf->priv.prev_pending_writes = buf->priv.pending_writes; buf->priv.prev_pending_writes = buf->priv.pending_writes;
#ifdef EVAS_FRAME_QUEUING
LKU(buf->priv.lock);
#endif
buf->priv.pending_writes = NULL; buf->priv.pending_writes = NULL;
XFlush(buf->priv.x11.xlib.disp); XFlush(buf->priv.x11.xlib.disp);
#else #else
@ -734,6 +778,9 @@ evas_software_xlib_outbuf_idle_flush(Outbuf *buf)
} }
else else
{ {
#ifdef EVAS_FRAME_QUEUING
LKL(buf->priv.lock);
#endif
if (buf->priv.prev_pending_writes) XSync(buf->priv.x11.xlib.disp, False); if (buf->priv.prev_pending_writes) XSync(buf->priv.x11.xlib.disp, False);
while (buf->priv.prev_pending_writes) while (buf->priv.prev_pending_writes)
{ {
@ -750,6 +797,9 @@ evas_software_xlib_outbuf_idle_flush(Outbuf *buf)
if (obr->mxob) _unfind_xob(obr->mxob, 0); if (obr->mxob) _unfind_xob(obr->mxob, 0);
free(obr); free(obr);
} }
#ifdef EVAS_FRAME_QUEUING
LKU(buf->priv.lock);
#endif
_clear_xob(0); _clear_xob(0);
} }
} }
@ -1036,3 +1086,12 @@ evas_software_xlib_outbuf_alpha_get(Outbuf *buf)
{ {
return buf->priv.x11.xlib.mask; return buf->priv.x11.xlib.mask;
} }
#ifdef EVAS_FRAME_QUEUING
void
evas_software_xlib_outbuf_set_priv(Outbuf *buf, void *cur, void *prev)
{
buf->priv.pending_writes = (Eina_List *)cur;
}
#endif

View File

@ -83,5 +83,10 @@ void evas_software_xlib_outbuf_debug_show (Outbuf *buf,
int h); int h);
Eina_Bool evas_software_xlib_outbuf_alpha_get (Outbuf *buf); Eina_Bool evas_software_xlib_outbuf_alpha_get (Outbuf *buf);
#ifdef EVAS_FRAME_QUEUING
void evas_software_xlib_outbuf_set_priv (Outbuf *buf,
void *cur,
void *prev);
#endif
#endif #endif

View File

@ -37,5 +37,8 @@ struct _Evas_Engine_Info_XRender_X11
void *visual; void *visual;
unsigned char destination_alpha : 1; unsigned char destination_alpha : 1;
} info; } info;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
}; };
#endif #endif

View File

@ -462,6 +462,7 @@ eng_info(Evas *e __UNUSED__)
info = calloc(1, sizeof(Evas_Engine_Info_XRender_X11)); info = calloc(1, sizeof(Evas_Engine_Info_XRender_X11));
if (!info) return NULL; if (!info) return NULL;
info->magic.magic = rand(); info->magic.magic = rand();
info->render_mode = EVAS_RENDER_MODE_BLOCKING;
return info; return info;
} }