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
devs/devilhorns/wayland_egl
Carsten Haitzler 13 years ago
parent 2133ccd144
commit eaad0eb095
  1. 2
      legacy/ecore/AUTHORS
  2. 2
      legacy/ecore/src/lib/ecore/ecore_private.h
  3. 48
      legacy/ecore/src/lib/ecore_evas/ecore_evas_x.c
  4. 3
      legacy/ecore/src/lib/ecore_x/xlib/ecore_x.c
  5. 2
      legacy/evas/AUTHORS
  6. 5
      legacy/evas/README.in
  7. 33
      legacy/evas/configure.ac
  8. 7
      legacy/evas/src/lib/Evas.h
  9. 3
      legacy/evas/src/lib/cache/evas_cache.h
  10. 211
      legacy/evas/src/lib/cache/evas_cache_image.c
  11. 19
      legacy/evas/src/lib/canvas/evas_main.c
  12. 52
      legacy/evas/src/lib/canvas/evas_object_gradient.c
  13. 21
      legacy/evas/src/lib/canvas/evas_object_gradient2.c
  14. 26
      legacy/evas/src/lib/canvas/evas_object_image.c
  15. 4
      legacy/evas/src/lib/canvas/evas_object_main.c
  16. 10
      legacy/evas/src/lib/canvas/evas_object_text.c
  17. 9
      legacy/evas/src/lib/canvas/evas_object_textblock.c
  18. 34
      legacy/evas/src/lib/canvas/evas_render.c
  19. 1
      legacy/evas/src/lib/engines/common/Makefile.am
  20. 30
      legacy/evas/src/lib/engines/common/evas_font_draw.c
  21. 49
      legacy/evas/src/lib/engines/common/evas_font_load.c
  22. 6
      legacy/evas/src/lib/engines/common/evas_font_main.c
  23. 81
      legacy/evas/src/lib/engines/common/evas_font_private.h
  24. 6
      legacy/evas/src/lib/engines/common/evas_font_query.c
  25. 9
      legacy/evas/src/lib/engines/common/evas_gradient2_main.c
  26. 9
      legacy/evas/src/lib/engines/common/evas_gradient_main.c
  27. 11
      legacy/evas/src/lib/engines/common/evas_image_main.c
  28. 88
      legacy/evas/src/lib/engines/common/evas_image_scalecache.c
  29. 9
      legacy/evas/src/lib/engines/common/evas_intl_utils.c
  30. 1432
      legacy/evas/src/lib/engines/common/evas_pipe.c
  31. 83
      legacy/evas/src/lib/engines/common/evas_pipe.h
  32. 56
      legacy/evas/src/lib/include/evas_common.h
  33. 3
      legacy/evas/src/modules/engines/buffer/Evas_Engine_Buffer.h
  34. 1
      legacy/evas/src/modules/engines/buffer/evas_engine.c
  35. 3
      legacy/evas/src/modules/engines/cairo_x11/Evas_Engine_Cairo_X11.h
  36. 1
      legacy/evas/src/modules/engines/cairo_x11/evas_engine.c
  37. 3
      legacy/evas/src/modules/engines/direct3d/Evas_Engine_Direct3D.h
  38. 1
      legacy/evas/src/modules/engines/direct3d/evas_engine.c
  39. 3
      legacy/evas/src/modules/engines/directfb/Evas_Engine_DirectFB.h
  40. 3
      legacy/evas/src/modules/engines/fb/Evas_Engine_FB.h
  41. 1
      legacy/evas/src/modules/engines/fb/evas_engine.c
  42. 3
      legacy/evas/src/modules/engines/gl_glew/Evas_Engine_GL_Glew.h
  43. 1
      legacy/evas/src/modules/engines/gl_glew/evas_engine.c
  44. 5
      legacy/evas/src/modules/engines/gl_x11/Evas_Engine_GL_X11.h
  45. 1
      legacy/evas/src/modules/engines/gl_x11/evas_engine.c
  46. 3
      legacy/evas/src/modules/engines/quartz/Evas_Engine_Quartz.h
  47. 1
      legacy/evas/src/modules/engines/quartz/evas_engine.c
  48. 3
      legacy/evas/src/modules/engines/software_16_ddraw/Evas_Engine_Software_16_DDraw.h
  49. 1
      legacy/evas/src/modules/engines/software_16_ddraw/evas_engine.c
  50. 3
      legacy/evas/src/modules/engines/software_16_sdl/Evas_Engine_SDL_16.h
  51. 3
      legacy/evas/src/modules/engines/software_16_wince/Evas_Engine_Software_16_WinCE.h
  52. 1
      legacy/evas/src/modules/engines/software_16_wince/evas_engine.c
  53. 3
      legacy/evas/src/modules/engines/software_16_x11/Evas_Engine_Software_16_X11.h
  54. 1
      legacy/evas/src/modules/engines/software_16_x11/evas_engine.c
  55. 3
      legacy/evas/src/modules/engines/software_ddraw/Evas_Engine_Software_DDraw.h
  56. 1
      legacy/evas/src/modules/engines/software_ddraw/evas_engine.c
  57. 3
      legacy/evas/src/modules/engines/software_gdi/Evas_Engine_Software_Gdi.h
  58. 59
      legacy/evas/src/modules/engines/software_generic/evas_engine.c
  59. 3
      legacy/evas/src/modules/engines/software_qtopia/Evas_Engine_Software_Qtopia.h
  60. 1
      legacy/evas/src/modules/engines/software_qtopia/evas_engine.c
  61. 3
      legacy/evas/src/modules/engines/software_sdl/Evas_Engine_SDL.h
  62. 2
      legacy/evas/src/modules/engines/software_x11/Evas_Engine_Software_X11.h
  63. 119
      legacy/evas/src/modules/engines/software_x11/evas_engine.c
  64. 4
      legacy/evas/src/modules/engines/software_x11/evas_engine.h
  65. 11
      legacy/evas/src/modules/engines/software_x11/evas_xlib_buffer.c
  66. 67
      legacy/evas/src/modules/engines/software_x11/evas_xlib_outbuf.c
  67. 5
      legacy/evas/src/modules/engines/software_x11/evas_xlib_outbuf.h
  68. 3
      legacy/evas/src/modules/engines/xrender_x11/Evas_Engine_XRender_X11.h
  69. 1
      legacy/evas/src/modules/engines/xrender_x11/evas_engine.c

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

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

@ -237,9 +237,21 @@ _ecore_evas_x_render(Ecore_Evas *ee)
EINA_LIST_FOREACH(updates, l, r)
ecore_x_window_area_clear(ee->prop.window, r->x, r->y, r->w, r->h);
if ((ee->shaped) && (updates))
ecore_x_window_shape_mask_set(ee->prop.window, ee->engine.x.mask);
// if ((ee->alpha) && (updates))
// ecore_x_window_shape_input_mask_set(ee->prop.window, ee->engine.x.mask);
{
#ifdef EVAS_FRAME_QUEUING
/* 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);
_ecore_evas_idle_timeout_update(ee);
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.override)))
{
updates = evas_render_updates(ee->evas);
if (updates)
{
if (ee->shaped)
ecore_x_window_shape_mask_set(ee->prop.window, ee->engine.x.mask);
// if (ee->alpha)
// ecore_x_window_shape_input_mask_set(ee->prop.window, ee->engine.x.mask);
{
#ifdef EVAS_FRAME_QUEUING
/* 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);
_ecore_evas_idle_timeout_update(ee);
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.connection = ecore_x_display_get();
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 */
einfo->info.drawable = ee->prop.window;
if (argb)

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

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

@ -275,3 +275,8 @@ NOTES:
For the arm optimizations you want to try:
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

@ -760,6 +760,38 @@ else
build_pipe_render="no"
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
build_async_events="auto"
@ -1453,6 +1485,7 @@ echo " MAGIC_DEBUG.............: $want_evas_magic_debug"
echo " Cache Server............: $want_evas_cserve"
echo
echo " Threaded Pipe Rendering.: $build_pipe_render"
echo " Async Pipe Rendering....: $build_async_render"
echo " Async Events............: $build_async_events"
echo " Async Image Preload.....: $build_async_preload"
echo

@ -373,6 +373,12 @@ typedef enum _Evas_Image_Scale_Hint
EVAS_IMAGE_SCALE_HINT_STATIC = 2
} 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
{
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 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 void evas_sync(Evas *e) EINA_ARG_NONNULL(1);
/**

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

@ -58,7 +58,13 @@ _evas_cache_image_make_dirty(Evas_Cache_Image *cache,
im->flags.dirty = 1;
im->flags.activ = 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));
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
if (im->cache_key)
{
@ -80,7 +86,13 @@ _evas_cache_image_make_activ(Evas_Cache_Image *cache,
im->flags.activ = 1;
im->flags.lru_nodata = 0;
im->flags.dirty = 0;
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
eina_hash_direct_add(cache->activ, key, im);
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
}
else
{
@ -98,9 +110,15 @@ _evas_cache_image_make_inactiv(Evas_Cache_Image *cache,
im->flags.activ = 0;
im->flags.dirty = 0;
im->flags.cached = 1;
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
eina_hash_direct_add(cache->inactiv, key, im);
cache->lru = eina_inlist_prepend(cache->lru, EINA_INLIST_GET(im));
cache->usage += cache->func.mem_size_get(im);
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
}
else
{
@ -115,9 +133,15 @@ _evas_cache_image_remove_lru_nodata(Evas_Cache_Image *cache,
if (im->flags.lru_nodata)
{
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->usage -= cache->func.mem_size_get(im);
}
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
}
}
static void
@ -126,8 +150,14 @@ _evas_cache_image_activ_lru_nodata(Evas_Cache_Image *cache,
{
im->flags.need_data = 0;
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->usage += cache->func.mem_size_get(im);
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
}
static void
@ -138,11 +168,20 @@ _evas_cache_image_remove_activ(Evas_Cache_Image *cache,
{
if (ie->flags.activ)
{
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
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);
}
else
{
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
if (ie->flags.dirty)
{
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->usage -= cache->func.mem_size_get(ie);
}
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
}
ie->flags.cached = 0;
ie->flags.dirty = 0;
@ -163,7 +205,8 @@ _evas_cache_image_remove_activ(Evas_Cache_Image *cache,
static void
_evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
{
if (!ie) return ;
if (!ie)
return ;
if (cache->func.debug)
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
LKD(ie->lock);
#endif
#ifdef EVAS_FRAME_QUEUING
LKD(ie->lock_references);
#endif
cache->func.dealloc(ie);
}
@ -237,6 +283,9 @@ _evas_cache_image_entry_new(Evas_Cache_Image *cache,
ie->allocated.w = 0;
ie->allocated.h = 0;
#ifdef EVAS_FRAME_QUEUING
LKI(ie->lock_references);
#endif
ie->references = 0;
ie->cache = cache;
@ -400,12 +449,18 @@ _evas_cache_image_async_cancel(void *data)
_evas_cache_image_async_end(ie);
}
#ifdef EVAS_FRAME_QUEUING
LKL(ie->lock_references);
#endif
if (ie->references == 0)
{
_evas_cache_image_remove_activ(ie->cache, ie);
_evas_cache_image_make_inactiv(ie->cache, ie, ie->cache_key);
evas_cache_image_flush(ie->cache);
}
#ifdef EVAS_FRAME_QUEUING
LKU(ie->lock_references);
#endif
}
static int
@ -500,9 +555,21 @@ EAPI void
evas_cache_image_set(Evas_Cache_Image *cache, int limit)
{
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;
evas_cache_image_flush(cache);
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
}
EAPI Evas_Cache_Image *
@ -530,6 +597,10 @@ evas_cache_image_init(const Evas_Cache_Image_Func *cb)
new->preload = NULL;
new->pending = NULL;
#ifdef EVAS_FRAME_QUEUING
LKI(new->lock);
#endif
return new;
}
@ -550,10 +621,18 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache)
Image_Entry *im;
assert(cache != NULL);
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
cache->references--;
if (cache->references > 0)
return ;
{
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
return ;
}
#ifdef BUILD_ASYNC_PRELOAD
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->inactiv);
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
LKD(cache->lock);
#endif
free(cache);
}
@ -711,7 +795,13 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *
hkey[size] = '\0';
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
im = eina_hash_find(cache->activ, hkey);
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
if (im)
{
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);
}
#ifdef EVAS_FRAME_QUEUING
LKL(cache->lock);
#endif
im = eina_hash_find(cache->inactiv, hkey);
#ifdef EVAS_FRAME_QUEUING
LKU(cache->lock);
#endif
if (im)
{
int ok;
@ -779,9 +875,15 @@ evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *
on_ok:
*error = EVAS_LOAD_ERROR_NONE;
#ifdef EVAS_FRAME_QUEUING
LKL(im->lock_references);
#endif
im->references++;
if (im->references > 1 && im->flags.lru_nodata)
_evas_cache_image_remove_lru_nodata(cache, im);
#ifdef EVAS_FRAME_QUEUING
LKU(im->lock_references);
#endif
return im;
@ -812,15 +914,37 @@ EAPI void
evas_cache_image_drop(Image_Entry *im)
{
Evas_Cache_Image *cache;
int references;
assert(im);
assert(im->cache);
#ifdef EVAS_FRAME_QUEUING
LKL(im->lock_references);
#endif
im->references--;
references = im->references;
#ifdef EVAS_FRAME_QUEUING
LKU(im->lock_references);
#endif
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
if (im->preload)
{
@ -845,13 +969,22 @@ EAPI void
evas_cache_image_data_not_needed(Image_Entry *im)
{
Evas_Cache_Image *cache;
int references;
assert(im);
assert(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 ;
_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;
Evas_Cache_Image *cache;
int references;
assert(im);
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;
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
// 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
#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;
*/
#ifdef EVAS_FRAME_QUEUING
LKL(im_dirty->lock_references);
#endif
im_dirty->references = 1;
#ifdef EVAS_FRAME_QUEUING
LKU(im_dirty->lock_references);
#endif
evas_cache_image_drop(im);
}
@ -927,12 +1075,21 @@ evas_cache_image_alone(Image_Entry *im)
{
Evas_Cache_Image *cache;
Image_Entry *im_dirty = im;
int references;
assert(im);
assert(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))
{
@ -967,7 +1124,13 @@ evas_cache_image_alone(Image_Entry *im)
if (error != 0) goto on_error;
*/
#ifdef EVAS_FRAME_QUEUING
LKL(im_dirty->lock_references);
#endif
im_dirty->references = 1;
#ifdef EVAS_FRAME_QUEUING
LKU(im_dirty->lock_references);
#endif
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);
return NULL;
}
#ifdef EVAS_FRAME_QUEUING
LKL(im->lock_references);
#endif
im->references = 1;
#ifdef EVAS_FRAME_QUEUING
LKU(im->lock_references);
#endif
if (cache->func.debug)
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);
return NULL;
}
#ifdef EVAS_FRAME_QUEUING
LKL(im->lock_references);
#endif
im->references = 1;
#ifdef EVAS_FRAME_QUEUING
LKU(im->lock_references);
#endif
if (cache->func.debug)
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->cache);
#ifdef EVAS_FRAME_QUEUING
LKL(im->lock_references);
#endif
assert(im->references > 0);
#ifdef EVAS_FRAME_QUEUING
LKU(im->lock_references);
#endif
if ((im->space == EVAS_COLORSPACE_YCBCR422P601_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);
if (error != 0) goto on_error;
#ifdef EVAS_FRAME_QUEUING
LKL(new->lock_references);
#endif
new->references = 1;
#ifdef EVAS_FRAME_QUEUING
LKU(new->lock_references);
#endif
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);
if (!im) return NULL;
#ifdef EVAS_FRAME_QUEUING
LKL(im->lock_references);
#endif
im->references = 1;
#ifdef EVAS_FRAME_QUEUING
LKU(im->lock_references);
#endif
return im;
}

@ -48,6 +48,9 @@ evas_init(void)
#ifdef BUILD_ASYNC_PRELOAD
_evas_preload_thread_init();
#endif
#ifdef EVAS_FRAME_QUEUING
evas_common_frameq_init();
#endif
return _evas_init_count;
@ -84,6 +87,13 @@ evas_shutdown(void)
if (--_evas_init_count != 0)
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
_evas_preload_thread_shutdown();
#endif
@ -180,6 +190,10 @@ evas_free(Evas *e)
return;
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) 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 < 1) w = 1;
if (h < 1) h = 1;
#ifdef EVAS_FRAME_QUEUING
evas_common_frameq_flush();
#endif
e->output.w = w;
e->output.h = h;
e->output.changed = 1;

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

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

@ -960,6 +960,9 @@ evas_object_image_data_set(Evas_Object *obj, void *data)
MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
return;
MAGIC_CHECK_END();
#ifdef EVAS_FRAME_QUEUING
evas_common_pipe_op_image_flush(o->engine_data);
#endif
p_data = o->engine_data;
if (data)
{
@ -1031,6 +1034,10 @@ evas_object_image_data_get(const Evas_Object *obj, Eina_Bool for_writing)
return NULL;
MAGIC_CHECK_END();
if (!o->engine_data) return NULL;
#ifdef EVAS_FRAME_QUEUING
evas_common_pipe_op_image_flush(o->engine_data);
#endif
data = NULL;
o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
o->engine_data,
@ -1202,9 +1209,14 @@ evas_object_image_alpha_set(Evas_Object *obj, Eina_Bool has_alpha)
return;
o->cur.has_alpha = has_alpha;
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->cur.has_alpha);
}
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);
}
@ -1810,6 +1822,13 @@ evas_object_image_colorspace_set(Evas_Object *obj, Evas_Colorspace cspace)
MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
return;
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;
if (o->engine_data)
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);
return;
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;
}

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

@ -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.y, 1, 1);
}
#ifdef EVAS_FRAME_QUEUING
if (o->engine_data)
evas_common_pipe_op_text_flush(o->engine_data);
#endif
/* DO IT */
if (o->engine_data)
{
@ -1102,6 +1108,7 @@ evas_font_hinting_set(Evas *e, Evas_Font_Hinting_Flags hinting)
MAGIC_CHECK_END();
if (e->hinting == hinting) return;
e->hinting = hinting;
EINA_INLIST_FOREACH(e->layers, lay)
{
Evas_Object *obj;
@ -1834,6 +1841,9 @@ _evas_object_text_rehint(Evas_Object *obj)
o = (Evas_Object_Text *)(obj->object_data);
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,
obj->layer->evas->hinting);
was = evas_object_is_in_output_rect(obj,

@ -6027,9 +6027,14 @@ _evas_object_textblock_rehint(Evas_Object *obj)
EINA_INLIST_FOREACH(ln->items, it)
{
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);
}
}
}
o->formatted.valid = 0;

@ -245,8 +245,13 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
obj->rect_del = 0;
obj->render_pre = 0;
#ifndef EVAS_FRAME_QUEUING
/* 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++;
/* If the object will be removed, we should not cache anything during this run. */
if (obj->delete_me != 0) clean_them = EINA_TRUE;
@ -1236,6 +1241,10 @@ evas_render_updates(Evas *e)
return NULL;
MAGIC_CHECK_END();
#ifdef EVAS_FRAME_QUEUING
evas_common_frameq_flush_ready ();
#endif
if (!e->changed) return NULL;
return evas_render_updates_internal(e, 1, 1);
}
@ -1254,6 +1263,10 @@ evas_render(Evas *e)
return;
MAGIC_CHECK_END();
#ifdef EVAS_FRAME_QUEUING
evas_common_frameq_flush_ready ();
#endif
if (!e->changed) return;
evas_render_updates_internal(e, 0, 1);
}
@ -1316,6 +1329,18 @@ evas_render_idle_flush(Evas *e)
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
* runtime.
@ -1393,12 +1418,19 @@ evas_render_object_recalc(Evas_Object *obj)
return;
MAGIC_CHECK_END();
#ifndef EVAS_FRAME_QUEUING
if ((!obj->changed) && (obj->delete_me < 2))
#else
if ((!obj->changed) )
#endif
{
Evas *e;
e = obj->layer->evas;
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);
obj->changed = 1;
}

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

@ -7,7 +7,23 @@
#include "evas_blend_private.h"
#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
_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);
// 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_RENDER | hintflags[fi->hinting]);
FTUNLOCK();
if (error)
{
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;
memset(fg, 0, (sizeof(struct _RGBA_Font_Glyph)));
FTLOCK();
error = FT_Get_Glyph(fi->src->ft.face->glyph, &(fg->glyph));
FTUNLOCK();
if (error)
{
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)
{
FTLOCK();
error = FT_Glyph_To_Bitmap(&(fg->glyph), FT_RENDER_MODE_NORMAL, 0, 1);
if (error)
{
FT_Done_Glyph(fg->glyph);
FTUNLOCK();
free(fg);
if (!fi->fash) fi->fash = _fash_gl_new();
if (fi->fash) _fash_gl_add(fi->fash, index, (void *)(-1));
return NULL;
}
FTUNLOCK();
}
fg->glyph_out = (FT_BitmapGlyph)fg->glyph;
fg->index = hindex;
@ -180,6 +203,7 @@ static FT_UInt
_evas_common_get_char_index(RGBA_Font_Int* fi, int gl)
{
Font_Char_Index result;
FT_UInt ret;
#ifdef HAVE_PTHREAD
/// 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);
// }
FTLOCK();
result.index = FT_Get_Char_Index(fi->src->ft.face, gl);
FTUNLOCK();
result.gl = gl;
// 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_h <= 0) return;
#ifndef EVAS_FRAME_QUEUING
LKL(fn->lock);
#endif
// evas_common_font_size_use(fn);