From 6c167c3a6d08ed46402ab2dfc2ba6e963138ed1c Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Mon, 16 Jul 2007 07:25:35 +0000 Subject: [PATCH] cedric's sdl patch. SVN revision: 30845 --- legacy/evas/README.in | 7 + legacy/evas/configure.in | 60 + legacy/evas/src/lib/Makefile.am | 8 +- legacy/evas/src/lib/cache/.cvsignore | 6 + legacy/evas/src/lib/cache/Makefile.am | 18 + .../src/lib/cache/evas_cache_engine_image.c | 496 ++++++++ legacy/evas/src/lib/cache/evas_cache_image.c | 593 ++++++++++ legacy/evas/src/lib/canvas/evas_main.c | 3 + .../evas/src/lib/canvas/evas_object_image.c | 20 +- .../evas/src/lib/engines/common/Makefile.am | 1 + .../src/lib/engines/common/evas_image_data.c | 123 ++ .../src/lib/engines/common/evas_image_load.c | 110 +- .../src/lib/engines/common/evas_image_main.c | 470 ++------ .../evas/src/lib/engines/common/evas_pipe.c | 18 +- legacy/evas/src/lib/imaging/evas_imaging.c | 4 +- legacy/evas/src/lib/include/evas_common.h | 221 +++- legacy/evas/src/modules/engines/Makefile.am | 1 + .../src/modules/engines/buffer/evas_outbuf.c | 6 +- .../evas/src/modules/engines/fb/evas_outbuf.c | 8 +- .../modules/engines/gl_common/evas_gl_image.c | 29 +- .../engines/software_16/evas_soft16_main.c | 5 +- .../engines/software_generic/evas_engine.c | 155 +-- .../modules/engines/software_sdl/.cvsignore | 6 + .../engines/software_sdl/Evas_Engine_SDL.h | 24 + .../modules/engines/software_sdl/Makefile.am | 28 + .../engines/software_sdl/evas_engine_sdl.c | 1006 +++++++++++++++++ .../engines/software_sdl/evas_engine_sdl.h | 33 + .../engines/software_x11/evas_outbuf.c | 10 +- .../engines/software_xcb/evas_outbuf.c | 10 +- .../modules/engines/xrender_x11/evas_engine.c | 4 +- .../xrender_x11/evas_engine_gradient.c | 6 +- .../engines/xrender_x11/evas_engine_image.c | 10 +- .../engines/xrender_xcb/evas_engine_image.c | 22 +- 33 files changed, 2852 insertions(+), 669 deletions(-) create mode 100644 legacy/evas/src/lib/cache/.cvsignore create mode 100644 legacy/evas/src/lib/cache/Makefile.am create mode 100644 legacy/evas/src/lib/cache/evas_cache_engine_image.c create mode 100644 legacy/evas/src/lib/cache/evas_cache_image.c create mode 100644 legacy/evas/src/lib/engines/common/evas_image_data.c create mode 100644 legacy/evas/src/modules/engines/software_sdl/.cvsignore create mode 100644 legacy/evas/src/modules/engines/software_sdl/Evas_Engine_SDL.h create mode 100644 legacy/evas/src/modules/engines/software_sdl/Makefile.am create mode 100644 legacy/evas/src/modules/engines/software_sdl/evas_engine_sdl.c create mode 100644 legacy/evas/src/modules/engines/software_sdl/evas_engine_sdl.h diff --git a/legacy/evas/README.in b/legacy/evas/README.in index 2ff879201a..2973888117 100644 --- a/legacy/evas/README.in +++ b/legacy/evas/README.in @@ -14,6 +14,7 @@ Optional: X11R6 XCB DirectFB + SDL OpenGL (underway at the moment) Linux Qtopia @@ -127,6 +128,12 @@ really good. it may also be useful for embedded devices supported by directfb that offer acceleration (otherwise the fb driver will likely be faster). +--enable-sdl + +this is the sdl engine that uses sdl library (http://www.libsdl.org). This +library should work on many operating system. + + CPU: --enable-cpu-c diff --git a/legacy/evas/configure.in b/legacy/evas/configure.in index caaaedded3..cf0280237b 100644 --- a/legacy/evas/configure.in +++ b/legacy/evas/configure.in @@ -71,6 +71,8 @@ qt_dir="" qt_cflags="" qt_libs="" qt_moc="moc" +sdl_cflags="" +sdl_libs="" ##################################################################### @@ -356,6 +358,58 @@ if test "x$have_evas_directfb" = "xyes"; then fi AM_CONDITIONAL(BUILD_ENGINE_DIRECTFB, test "x$have_evas_directfb" = "xyes") +####################################### +## SDL +AC_ARG_WITH(sdl-config, [ --with-sdl-config=SDL_CONFIG use sdl-config specified], +[ SDL_CONFIG=$withval; + echo "using "$SDL_CONFIG" for sdl-config"; ], +[ if test -z "$SDL_CONFIG"; then + AC_PATH_PROG(SDL_CONFIG, "sdl-config", "", $PATH) + fi +]) +if test -z "$SDL_CONFIG" ; then SDL_CONFIG="sdl-config"; fi + +####################################### +## Check if we should build the sdl engine +have_evas_sdl="no"; +ENGINE_SDL_PRG=""; +## Automatic check... +AC_CHECK_HEADER(SDL/SDL.h, + [ have_evas_sdl="yes" ], + [ have_evas_sdl="no" ] +) + +# Manual override +AC_MSG_CHECKING(whether SDL backend is to be built) +AC_ARG_ENABLE(sdl, AC_HELP_STRING([--enable-sdl],[enable the SDL rendering backend]), [ + if test x"$enableval" = x"yes" ; then + AC_MSG_RESULT(yes) + have_evas_sdl="yes" + else + AC_MSG_RESULT(no) + have_evas_sdl="no" + fi + ], [ + AC_MSG_RESULT($have_evas_sdl) + ] +) +if test "x$have_evas_sdl" = "xyes"; then + if test "x$SDL_CONFIG" = "xno" ; then + have_evas_sdl= "no" + AM_CONDITIONAL(BUILD_ENGINE_SDL, false) + AC_MSG_RESULT(disabling sdl engine) + else + ENGINE_SDL_PRG="evas_sdl_test" + sdl_cflags=`$SDL_CONFIG --cflags` + sdl_libs=`$SDL_CONFIG --libs` + AM_CONDITIONAL(BUILD_ENGINE_SDL, true) + AC_DEFINE(BUILD_ENGINE_SDL, 1, [SDL Rendering Backend]) + fi +else + AM_CONDITIONAL(BUILD_ENGINE_SDL, false) + have_evas_sdl="no" +fi + ####################################### ## Check if we should build the fb engine have_evas_fb="no"; @@ -2017,6 +2071,9 @@ AC_SUBST(ddraw_libs) AC_SUBST(x_cflags) AC_SUBST(x_libs) +AC_SUBST(sdl_cflags) +AC_SUBST(sdl_libs) + AC_SUBST(xcb_cflags) AC_SUBST(xcb_libs) AC_SUBST(xcbrender_cflags) @@ -2068,6 +2125,7 @@ src/lib/canvas/Makefile src/lib/data/Makefile src/lib/file/Makefile src/lib/imaging/Makefile +src/lib/cache/Makefile src/lib/engines/Makefile src/lib/engines/common/Makefile src/lib/engines/common/evas_op_add/Makefile @@ -2093,6 +2151,7 @@ src/modules/engines/cairo_common/Makefile src/modules/engines/cairo_x11/Makefile src/modules/engines/xrender_x11/Makefile src/modules/engines/xrender_xcb/Makefile +src/modules/engines/software_sdl/Makefile src/modules/engines/glitz_x11/Makefile src/modules/engines/software_16/Makefile src/modules/engines/software_16_x11/Makefile @@ -2137,6 +2196,7 @@ echo " Software Framebuffer....: $have_evas_fb" echo " Software Qtopia.........: $have_evas_qtopia" echo " Software Memory Buffer..: $have_evas_buffer" echo " DirectFB................: $have_evas_directfb" +echo " SDL.....................: $have_evas_sdl" echo " OpenGL X11..............: $have_evas_gl_x11" echo " Cairo X11...............: $have_evas_cairo_x11" echo " XRender X11.............: $have_evas_xrender_x11" diff --git a/legacy/evas/src/lib/Makefile.am b/legacy/evas/src/lib/Makefile.am index 32e7e0dd81..034bd396a0 100644 --- a/legacy/evas/src/lib/Makefile.am +++ b/legacy/evas/src/lib/Makefile.am @@ -1,6 +1,6 @@ MAINTAINERCLEANFILES = Makefile.in -SUBDIRS = canvas data file engines imaging include +SUBDIRS = canvas data cache file engines imaging include AUTOMAKE_OPTIONS = 1.4 foreign @@ -24,6 +24,7 @@ libevas_la_LIBADD = \ canvas/libevas_canvas.la \ data/libevas_data.la \ file/libevas_file.la \ + cache/libevas_cache.la \ imaging/libevas_imaging.la \ engines/common/libevas_engine_common.la \ -lm \ @@ -39,6 +40,9 @@ libevas_la_DEPENDENCIES = \ canvas/libevas_canvas.la \ data/libevas_data.la \ file/libevas_file.la \ + cache/libevas_cache.la \ imaging/libevas_imaging.la \ - engines/common/libevas_engine_common.la + engines/common/libevas_engine_common.la + libevas_la_LDFLAGS = @create_shared_lib@ -version-info 1:0:0 + diff --git a/legacy/evas/src/lib/cache/.cvsignore b/legacy/evas/src/lib/cache/.cvsignore new file mode 100644 index 0000000000..b477e9cb01 --- /dev/null +++ b/legacy/evas/src/lib/cache/.cvsignore @@ -0,0 +1,6 @@ +Makefile.in +Makefile +.deps +.libs +*.la +*.lo diff --git a/legacy/evas/src/lib/cache/Makefile.am b/legacy/evas/src/lib/cache/Makefile.am new file mode 100644 index 0000000000..e74526954a --- /dev/null +++ b/legacy/evas/src/lib/cache/Makefile.am @@ -0,0 +1,18 @@ +## Process this file with automake to produce Makefile.in + +AUTOMAKE_OPTIONS = 1.4 foreign + +# A list of all the files in the current directory which can be regenerated +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = -I. \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib/include \ + @FREETYPE_CFLAGS@ + +noinst_LTLIBRARIES = libevas_cache.la +libevas_cache_la_SOURCES = \ +evas_cache_image.c \ +evas_cache_engine_image.c + +libevas_cache_la_DEPENDENCIES = $(top_builddir)/config.h diff --git a/legacy/evas/src/lib/cache/evas_cache_engine_image.c b/legacy/evas/src/lib/cache/evas_cache_engine_image.c new file mode 100644 index 0000000000..c25678c414 --- /dev/null +++ b/legacy/evas/src/lib/cache/evas_cache_engine_image.c @@ -0,0 +1,496 @@ +#include +#include + +#include "evas_common.h" +#include "evas_private.h" + +EAPI int +evas_cache_engine_image_usage_get(Evas_Cache_Engine_Image* cache) +{ + assert(cache != NULL); + + return cache->usage; +} + +EAPI int +evas_cache_engine_image_get(Evas_Cache_Engine_Image* cache) +{ + assert(cache != NULL); + + return cache->limit; +} + +EAPI void +evas_cache_engine_image_set(Evas_Cache_Engine_Image* cache, int limit) +{ + assert(cache != NULL); + + cache->limit = limit; +} + +EAPI Evas_Cache_Engine_Image* +evas_cache_engine_image_init(const Evas_Cache_Engine_Image_Func *cb, Evas_Cache_Image *parent) +{ + Evas_Cache_Engine_Image* new; + + new = malloc(sizeof (Evas_Cache_Engine_Image)); + if (!new) + return NULL; + + new->func = *cb; + + new->limit = -1; + new->usage = 0; + + new->dirty = NULL; + new->activ = NULL; + + new->parent = parent; + parent->references++; + + return new; +} + +static Evas_Bool +_evas_cache_engine_image_free_cb(Evas_Hash *hash, const char *key, void *data, void *fdata) +{ + Evas_Cache_Engine_Image* cache = fdata; + RGBA_Engine_Image* eim = data; + RGBA_Image* im; + + if (cache->func.debug) + cache->func.debug("shutdown-engine-activ", eim); + + evas_stringshare_del(eim->cache_key); + eim->cache_key = NULL; + + im = eim->src; + cache->func.destructor(eim); + if (im) evas_cache_image_drop(im); + free(eim); + + return 1; +} + +EAPI void +evas_cache_engine_image_shutdown(Evas_Cache_Engine_Image* cache) +{ + RGBA_Engine_Image* eim; + RGBA_Image* im; + + assert(cache != NULL); + + /* This is mad, I am about to destroy image still alive, but we need to prevent leak. */ + while (cache->dirty) + { + eim = (RGBA_Engine_Image*) cache->dirty; + im = eim->src; + + cache->dirty = evas_object_list_remove(cache->dirty, eim); + + if (cache->func.debug) + cache->func.debug("shutdown-engine-dirty", eim); + cache->func.destructor(eim); + if (im) evas_cache_image_drop(im); + free(eim); + } + + evas_hash_foreach(cache->activ, _evas_cache_engine_image_free_cb, cache); + evas_hash_free(cache->activ); +} + +EAPI RGBA_Engine_Image* +evas_cache_engine_image_request(Evas_Cache_Engine_Image *cache, const char *file, const char *key, + RGBA_Image_Loadopts *lo, void *data, int *error) +{ + RGBA_Engine_Image* eim; + RGBA_Image* im; + const char* ekey; + + assert(cache != NULL); + + im = evas_cache_image_request(cache->parent, file, key, lo, error); + if (!im) + { + *error = -1; + return NULL; + } + + if (cache->func.key) + ekey = cache->func.key(im, file, key, lo, data); + else + ekey = evas_stringshare_add(im->cache_key); + if (!ekey) + { + *error = -1; + evas_cache_image_drop(im); + return NULL; + } + + eim = evas_hash_find(cache->activ, ekey); + if (eim) goto on_ok; + + eim = malloc(sizeof(RGBA_Engine_Image)); + if (!eim) goto on_error; + + eim->src = im; + eim->engine_data = NULL; + eim->flags.dirty = 0; + eim->flags.loaded = 0; + eim->cache = cache; + eim->cache_key = ekey; + eim->references = 0; + + *error = cache->func.constructor(eim, data); + if (cache->func.debug) + cache->func.debug("constructor-engine", eim); + + if (*error != 0) goto on_error; + + cache->activ = evas_hash_add(cache->activ, ekey, eim); + cache->usage += strlen(eim->cache_key) + 1 + cache->func.mem_size_get(eim); + + on_ok: + eim->references++; + return eim; + + on_error: + evas_cache_image_drop(im); + evas_stringshare_del(ekey); + if (eim) free(eim); + return NULL; +} + +static void +_evas_cache_engine_image_free(Evas_Cache_Engine_Image* cache, RGBA_Engine_Image *eim) +{ + int size; + + size = cache->func.mem_size_get(eim); + cache->usage -= size; + + if (cache->func.debug) + cache->func.debug("drop-engine", eim); + cache->func.destructor(eim); + if (eim->src) evas_cache_image_drop(eim->src); + if (eim->cache_key) evas_stringshare_del(eim->cache_key); + free(eim); +} + +EAPI void +evas_cache_engine_image_drop(RGBA_Engine_Image *eim) +{ + Evas_Cache_Engine_Image* cache; + + assert(eim); + assert(eim->cache); + + eim->references--; + cache = eim->cache; + + if (eim->flags.dirty) + { + cache->dirty = evas_object_list_remove(cache->dirty, eim); + + _evas_cache_engine_image_free(cache, eim); + return ; + } + + if (eim->references == 0) + { + cache->activ = evas_hash_del(cache->activ, eim->cache_key, eim); + + _evas_cache_engine_image_free(cache, eim); + return ; + } +} + +EAPI RGBA_Engine_Image* +evas_cache_engine_image_dirty(RGBA_Engine_Image *eim, int x, int y, int w, int h) +{ + RGBA_Engine_Image* eim_dirty = eim; + RGBA_Image* im; + RGBA_Image* im_dirty; + Evas_Cache_Engine_Image* cache; + + assert(eim); + assert(eim->cache); + + cache = eim->cache; + if (!(eim->flags.dirty)) + { + im = eim->src; + im_dirty = evas_cache_image_dirty(im, x, y, w, h); + + /* If im == im_dirty, this meens that we have only one reference to the eim. */ + if (im != im_dirty) + { + if (eim->references == 1) + { + const char* hkey; + + hkey = eim->cache_key; + cache->activ = evas_hash_del(cache->activ, hkey, eim); + + cache->usage -= strlen(hkey) + 1; + + evas_stringshare_del(hkey); + + eim_dirty = eim; + eim_dirty->src = im_dirty; + } + else + { + int error; + + eim_dirty = malloc(sizeof(RGBA_Engine_Image)); + if (!eim_dirty) goto on_error; + + eim_dirty->src = im_dirty; + eim_dirty->engine_data = NULL; + eim_dirty->flags.dirty = 1; + eim_dirty->flags.loaded = 1; + eim_dirty->cache = cache; + eim_dirty->cache_key = NULL; + eim_dirty->references = 1; + + error = cache->func.dirty(eim_dirty, eim); + if (cache->func.debug) + cache->func.debug("dirty-engine", eim_dirty); + + if (error != 0) goto on_error; + + cache->usage += cache->func.mem_size_get(eim_dirty); + + evas_cache_engine_image_drop(eim); + } + + eim_dirty->cache_key = NULL; + eim_dirty->flags.dirty = 1; + + cache->dirty = evas_object_list_prepend(cache->dirty, eim_dirty); + } + } + + if (cache->func.dirty_region) + cache->func.dirty_region(eim_dirty, x, y, w, h); + if (cache->func.debug) + cache->func.debug("dirty-region-engine", eim_dirty); + + return eim_dirty; + + on_error: + if (eim) evas_cache_engine_image_drop(eim); + if (eim_dirty) + evas_cache_engine_image_drop(eim_dirty); + else + if (im_dirty) evas_cache_image_drop(im_dirty); + + return NULL; +} + +static RGBA_Engine_Image* +_evas_cache_engine_image_push_dirty(Evas_Cache_Engine_Image *cache, RGBA_Image *im, void* engine_data) +{ + RGBA_Engine_Image *eim; + int error; + + eim = malloc(sizeof(RGBA_Engine_Image)); + if (!eim) goto on_error; + + eim->src = im; + eim->engine_data = NULL; + eim->flags.dirty = 1; + eim->flags.loaded = 1; + eim->cache = cache; + eim->cache_key = NULL; + eim->references = 1; + + error = cache->func.update_data(eim, engine_data); + if (cache->func.debug) + cache->func.debug("dirty-update_data-engine", eim); + if (error != 0) goto on_error; + + cache->dirty = evas_object_list_prepend(cache->dirty, eim); + + return eim; + + on_error: + if (eim) + evas_cache_engine_image_drop(eim); + else + evas_cache_image_drop(im); + return NULL; +} + +EAPI RGBA_Engine_Image* +evas_cache_engine_image_copied_data(Evas_Cache_Engine_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace, void* engine_data) +{ + RGBA_Image *im; + + assert(cache); + + im = evas_cache_image_copied_data(cache->parent, w, h, image_data, alpha, cspace); + + return _evas_cache_engine_image_push_dirty(cache, im, engine_data); +} + +EAPI RGBA_Engine_Image* +evas_cache_engine_image_data(Evas_Cache_Engine_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace, void* engine_data) +{ + RGBA_Image *im; + + assert(cache); + + im = evas_cache_image_data(cache->parent, w, h, image_data, alpha, cspace); + + return _evas_cache_engine_image_push_dirty(cache, im, engine_data); +} + +EAPI RGBA_Engine_Image* +evas_cache_engine_image_size_set(RGBA_Engine_Image *eim, int w, int h) +{ + Evas_Cache_Engine_Image* cache; + RGBA_Engine_Image* new; + RGBA_Image* im; + int error; + + assert(eim); + assert(eim->src); + assert(eim->cache); + assert(eim->references > 0); + + if (eim->src->image->w == w + && eim->src->image->h == h) + return eim; + + cache = eim->cache; + + im = evas_cache_image_size_set(eim->src, w, h); + /* Good idea to call update_data ? */ + if (im == eim->src) return eim; + eim->src = NULL; + + new = malloc(sizeof(RGBA_Engine_Image)); + if (!new) goto on_error; + + new->src = im; + new->engine_data = NULL; + new->flags = eim->flags; + new->flags.loaded = 1; + new->cache = cache; + new->cache_key = NULL; + new->references = 1; + + error = cache->func.size_set(new, eim); + if (error) goto on_error; + + assert(new->engine_data != eim->engine_data); + + cache->usage += cache->func.mem_size_get(new); + + if (new->flags.dirty || eim->references > 1) + { + new->flags.dirty = 1; + cache->dirty = evas_object_list_prepend(cache->dirty, new); + } + else + { + char* cache_key = NULL; + + cache_key = eim->cache_key ? evas_stringshare_add(eim->cache_key) : NULL; + new->cache_key = cache_key; + + cache->activ = evas_hash_add(cache->activ, cache_key, new); + cache->usage += strlen(new->cache_key) + 1; + } + + evas_cache_engine_image_drop(eim); + return new; + + on_error: + if (new) + evas_cache_engine_image_drop(new); + else + if (im) + evas_cache_image_drop(im); + evas_cache_engine_image_drop(eim); + + return NULL; +} + +EAPI void +evas_cache_engine_image_load_data(RGBA_Engine_Image *eim) +{ + Evas_Cache_Engine_Image* cache; + int size; + + assert(eim); + assert(eim->src); + assert(eim->cache); + + if (eim->flags.loaded) return ; + + evas_cache_image_load_data(eim->src); + + cache = eim->cache; + if (cache->func.debug) + cache->func.debug("load-engine", eim); + + size = cache->func.mem_size_get(eim); + cache = eim->cache; + cache->func.load(eim, eim->src); + cache->usage += cache->func.mem_size_get(eim) - size; + + eim->flags.loaded = 1; +} + +EAPI RGBA_Engine_Image* +evas_cache_engine_image_engine(Evas_Cache_Engine_Image *cache, void *engine_data) +{ + RGBA_Engine_Image* eim; + int error; + + eim = malloc(sizeof(RGBA_Engine_Image)); + if (!eim) goto on_error; + + eim->src = evas_cache_image_empty(cache->parent); + if (!eim->src) goto on_error; + + eim->engine_data = NULL; + eim->flags.dirty = 1; + eim->flags.loaded = 1; + eim->cache = cache; + eim->cache_key = NULL; + eim->references = 1; + + error = cache->func.update_data(eim, engine_data); + if (cache->func.debug) + cache->func.debug("update_data-engine", eim); + + if (error != 0) goto on_error; + + cache->dirty = evas_object_list_prepend(cache->dirty, eim); + + return eim; + + on_error: + if (eim) + evas_cache_engine_image_drop(eim); + return NULL; +} + +EAPI void +evas_cache_engine_image_colorspace(RGBA_Engine_Image* eim, int cspace, void* engine_data) +{ + Evas_Cache_Engine_Image* cache = eim->cache; + + assert(cache); + + cache->func.destructor(eim); + evas_cache_image_colorspace(eim->src, cspace); + cache->func.constructor(eim, engine_data); + if (cache->func.debug) + cache->func.debug("cosntructor-colorspace-engine", eim); +} + diff --git a/legacy/evas/src/lib/cache/evas_cache_image.c b/legacy/evas/src/lib/cache/evas_cache_image.c new file mode 100644 index 0000000000..6fc4cf8496 --- /dev/null +++ b/legacy/evas/src/lib/cache/evas_cache_image.c @@ -0,0 +1,593 @@ +#include +#include +#include + +#include "evas_common.h" +#include "evas_private.h" + +EAPI int +evas_cache_image_usage_get(Evas_Cache_Image *cache) +{ + assert(cache != NULL); + + return cache->usage; +} + +EAPI int +evas_cache_image_get(Evas_Cache_Image *cache) +{ + assert(cache != NULL); + + return cache->limit; +} + +EAPI void +evas_cache_image_set(Evas_Cache_Image *cache, int limit) +{ + assert(cache != NULL); + + cache->limit = limit; +} + +EAPI Evas_Cache_Image* +evas_cache_image_init(const Evas_Cache_Image_Func *cb) +{ + Evas_Cache_Image* new; + + new = malloc(sizeof (Evas_Cache_Image)); + if (!new) + return NULL; + + new->func = *cb; + + new->limit = -1; + new->usage = 0; + + new->dirty = NULL; + new->lru = NULL; + new->inactiv = NULL; + new->activ = NULL; + + new->references = 1; + + return new; +} + +static Evas_Bool +_evas_cache_image_free_cb(Evas_Hash *hash, const char *key, void *data, void *fdata) +{ + Evas_Cache_Image* cache = fdata; + RGBA_Image* im = data; + + if (cache->func.debug) + cache->func.debug("shutdown-activ", im); + + free(im->cache_key); + im->cache_key = NULL; + + cache->func.destructor(im); + evas_common_image_delete(im); + return 1; +} + +EAPI void +evas_cache_image_shutdown(Evas_Cache_Image *cache) +{ + RGBA_Image* im; + + assert(cache != NULL); + cache->references--; + + if (cache->references > 0) + return ; + + while (cache->lru) + { + im = (RGBA_Image*) cache->lru; + cache->lru = evas_object_list_remove(cache->lru, im); + + free(im->cache_key); + im->cache_key = NULL; + + if (cache->func.debug) + cache->func.debug("shutdown-lru", im); + cache->func.destructor(im); + evas_common_image_delete(im); + } + + /* This is mad, I am about to destroy image still alive, but we need to prevent leak. */ + while (cache->dirty) + { + im = (RGBA_Image*) cache->dirty; + cache->dirty = evas_object_list_remove(cache->dirty, im); + + if (cache->func.debug) + cache->func.debug("shutdown-dirty", im); + cache->func.destructor(im); + evas_common_image_delete(im); + } + + evas_hash_foreach(cache->activ, _evas_cache_image_free_cb, cache); + evas_hash_free(cache->activ); + evas_hash_free(cache->inactiv); + + free(cache); +} + +EAPI RGBA_Image* +evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *key, RGBA_Image_Loadopts *lo, int *error) +{ + const char* format; + char* hkey; + RGBA_Image* im; + Evas_Image_Load_Opts prevent; + int size; + struct stat st; + + assert(cache != NULL); + + if (!file && !key) return NULL; + if (!file) return NULL; + if ((!lo) || + (lo && + (lo->scale_down_by == 0) && + (lo->dpi = 0.0) && + ((lo->w == 0) || (lo->h == 0)))) + { + lo = &prevent; + if (key) + format = "%s//://%s"; + else + format = "%s//://%p"; + } + else + { + if (key) + format = "%s//://%s//@/%i/%1.5f/%ix%i"; + else + format = "%s//://%p//@/%i/%1.5f/%ix%i"; + } + size = strlen(file) + (key ? strlen(key) : 6) + 64; + hkey = alloca(sizeof (char) * size); + snprintf(hkey, size, format, file, key, lo->scale_down_by, lo->dpi, lo->w, lo->h); + + if (stat(file, &st) < 0) return NULL; + /* FIXME: Handle timestamp correctly. */ + + im = evas_hash_find(cache->activ, hkey); + if (im) + goto on_ok; + + im = evas_hash_find(cache->inactiv, hkey); + if (im) + { + cache->lru = evas_object_list_remove(cache->lru, im); + cache->inactiv = evas_hash_del(cache->inactiv, hkey, im); + cache->activ = evas_hash_add(cache->activ, hkey, im); + + goto on_ok; + } + + im = evas_common_image_new(); + if (!im) + { + *error = -1; + return NULL; + } + + im->timestamp = st.st_mtime; + im->laststat = time(NULL); + + if (lo) im->load_opts = *lo; + + im->info.file = (char *) evas_stringshare_add(file); + if (key) im->info.key = (char *) evas_stringshare_add(key); + + *error = cache->func.constructor(im); + if (*error != 0) + { + evas_common_image_delete(im); + return NULL; + } + + if (cache->func.debug) + cache->func.debug("request", im); + + cache->activ = evas_hash_add(cache->activ, hkey, im); + + im->references = 0; + im->cache_key = strdup(hkey); + im->cache = cache; + + cache->usage += strlen(im->cache_key) + 1 + cache->func.mem_size_get(im); + + on_ok: + *error = 0; + im->references++; + return im; +} + +EAPI void +evas_cache_image_drop(RGBA_Image *im) +{ + Evas_Cache_Image* cache; + char* hkey; + + assert(im); + assert(im->cache); + + im->references--; + cache = im->cache; + + if ((im->flags & RGBA_IMAGE_IS_DIRTY) == RGBA_IMAGE_IS_DIRTY) + { + int size; + + size = cache->func.mem_size_get(im); + cache->usage -= size; + cache->dirty = evas_object_list_remove(cache->dirty, im); + if (cache->func.debug) + cache->func.debug("drop", im); + + cache->func.destructor(im); + evas_common_image_delete(im); + + return ; + } + + if (im->references == 0) + { + hkey = im->cache_key; + + cache->activ = evas_hash_del(cache->activ, hkey, im); + cache->inactiv = evas_hash_add(cache->inactiv, hkey, im); + cache->lru = evas_object_list_prepend(cache->lru, im); + + /* FIXME: Enforce cache limit. */ + } +} + +EAPI RGBA_Image* +evas_cache_image_dirty(RGBA_Image *im, int x, int y, int w, int h) +{ + RGBA_Image* im_dirty = im; + Evas_Cache_Image* cache; + char* hkey; + + assert(im); + assert(im->cache); + + cache = im->cache; + if (!(im->flags & RGBA_IMAGE_IS_DIRTY)) + { + if (im->references == 1) + { + hkey = im->cache_key; + cache->activ = evas_hash_del(cache->activ, hkey, im); + + cache->usage -= strlen(hkey) + 1; + + free(hkey); + + im_dirty = im; + } + else + { + int error; + + im_dirty = evas_common_image_new(); + if (!im_dirty) goto on_error; + im_dirty->image = evas_common_image_surface_new(im); + if (!im_dirty->image) goto on_error; + im_dirty->image->w = w; + im_dirty->image->h = h; + + if (cache->func.debug) + cache->func.debug("dirty-src", im); + error = cache->func.dirty(im_dirty, im); + if (cache->func.debug) + cache->func.debug("dirty-out", im_dirty); + + if (error != 0) goto on_error; + + im_dirty->cache = cache; + im_dirty->references = 1; + + cache->usage += cache->func.mem_size_get(im_dirty); + + evas_cache_image_drop(im); + } + + im_dirty->cache_key = NULL; + im_dirty->flags |= RGBA_IMAGE_IS_DIRTY; + + cache->dirty = evas_object_list_prepend(cache->dirty, im_dirty); + } + + if (cache->func.debug) + cache->func.debug("dirty-region", im_dirty); + if (cache->func.dirty_region) + cache->func.dirty_region(im_dirty, x, y, w, h); + + return im_dirty; + + on_error: + if (im_dirty) evas_common_image_delete(im_dirty); + evas_cache_image_drop(im); + return NULL; +} + +EAPI RGBA_Image* +evas_cache_image_alone(RGBA_Image *im) +{ + RGBA_Image* im_dirty = im; + Evas_Cache_Image* cache; + char* hkey; + + assert(im); + assert(im->cache); + + cache = im->cache; + if (im->references == 1) + { + if (!(im->flags & RGBA_IMAGE_IS_DIRTY)) + { + hkey = im->cache_key; + cache->activ = evas_hash_del(cache->activ, hkey, im); + + cache->usage -= strlen(hkey) + 1; + free(hkey); + + im_dirty->cache_key = NULL; + im_dirty->flags |= RGBA_IMAGE_IS_DIRTY; + + cache->dirty = evas_object_list_prepend(cache->dirty, im_dirty); + } + } + else + { + int error; + + im_dirty = evas_common_image_new(); + if (!im_dirty) goto on_error; + im_dirty->image = evas_common_image_surface_new(im); + if (!im_dirty->image) goto on_error; + im_dirty->image->w = im->image->w; + im_dirty->image->h = im->image->h; + + if (cache->func.debug) + cache->func.debug("dirty-src", im); + error = cache->func.dirty(im_dirty, im); + if (cache->func.debug) + cache->func.debug("dirty-out", im_dirty); + + if (error != 0) goto on_error; + + im_dirty->cache_key = NULL; + im_dirty->flags |= RGBA_IMAGE_IS_DIRTY; + im_dirty->references = 1; + + cache->dirty = evas_object_list_prepend(cache->dirty, im_dirty); + + evas_cache_image_drop(im); + } + + return im_dirty; + + on_error: + if (im_dirty) evas_common_image_delete(im_dirty); + evas_cache_image_drop(im); + return NULL; +} + +static RGBA_Image* +_evas_cache_image_push_dirty(Evas_Cache_Image *cache, RGBA_Image* im) +{ + cache->dirty = evas_object_list_prepend(cache->dirty, im); + + im->flags |= RGBA_IMAGE_IS_DIRTY; + im->cache_key = NULL; + im->cache = cache; + + return im; +} + +EAPI RGBA_Image* +evas_cache_image_copied_data(Evas_Cache_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace) +{ + RGBA_Image* im; + + assert(cache); + + if (cspace != EVAS_COLORSPACE_ARGB8888) + w &= ~0x1; + + im = evas_common_image_create(w, h); + if (!im) return NULL; + + if (cache->func.copied_data(im, w, h, image_data, alpha, cspace) != 0) + { + evas_common_image_delete(im); + return NULL; + } + + return _evas_cache_image_push_dirty(cache, im); +} + +EAPI RGBA_Image* +evas_cache_image_data(Evas_Cache_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace) +{ + RGBA_Image* im; + + assert(cache); + + im = evas_common_image_new(); + if (!im) return NULL; + im->image = evas_common_image_surface_new(im); + if (!im->image) + { + evas_common_image_delete(im); + return NULL; + } + + if (cache->func.data(im, w, h, image_data, alpha, cspace) != 0) + { + evas_common_image_delete(im); + return NULL; + } + + return _evas_cache_image_push_dirty(cache, im); +} + +EAPI RGBA_Image* +evas_cache_image_size_set(RGBA_Image *im, int w, int h) +{ + Evas_Cache_Image* cache; + RGBA_Image* new; + int error; + + assert(im); + assert(im->image); + assert(im->cache); + assert(im->references > 0); + + if (im->image->w == w + && im->image->h == h) + return im; + + cache = im->cache; + + new = evas_common_image_new(); + if (!new) goto on_error; + new->image = evas_common_image_surface_new(im); + if (!new->image) goto on_error; + new->image->w = w; + new->image->h = h; + + if (cache->func.debug) + cache->func.debug("size_set-in", im); + error = cache->func.size_set(new, im, w, h); + if (cache->func.debug) + cache->func.debug("size_set-out", new); + + if (error != 0) goto on_error; + + new->cache = cache; + new->cache_key = NULL; + + new->references = 1; + cache->usage += cache->func.mem_size_get(new); + + if ((im->flags & RGBA_IMAGE_IS_DIRTY) == RGBA_IMAGE_IS_DIRTY + || im->references > 1) + { + new->flags |= RGBA_IMAGE_IS_DIRTY; + cache->dirty = evas_object_list_prepend(cache->dirty, new); + } + else + { + char* cache_key = NULL; + + cache_key = im->cache_key ? strdup(im->cache_key) : NULL; + new->cache_key = cache_key; + + cache->activ = evas_hash_add(cache->activ, cache_key, new); + cache->usage += strlen(new->cache_key) + 1; + } + + evas_cache_image_drop(im); + + return new; + + on_error: + if (new) evas_common_image_delete(new); + evas_cache_image_drop(im); + return NULL; +} + +EAPI void +evas_cache_image_load_data(RGBA_Image *im) +{ + Evas_Cache_Image* cache; + int size; + + assert(im); + assert(im->image); + assert(im->cache); + + if ((im->flags & RGBA_IMAGE_LOADED) == RGBA_IMAGE_LOADED) return ; + + cache = im->cache; + if (cache->func.debug) + cache->func.debug("load", im); + + size = cache->func.mem_size_get(im); + cache->func.load(im); + cache->usage += cache->func.mem_size_get(im) - size; + + im->flags |= RGBA_IMAGE_LOADED; + + assert(im->image->data); +} + +EAPI int +evas_cache_image_flush(Evas_Cache_Image *cache) +{ + assert(cache); + + if (cache->limit == -1) + return -1; + + while (cache->lru && cache->limit < cache->usage) + { + RGBA_Image* im; + + im = (RGBA_Image*) cache->lru->last; + cache->lru = evas_object_list_remove(cache->lru, im); + cache->inactiv = evas_hash_del(cache->inactiv, im->cache_key, im); + + cache->usage -= strlen(im->cache_key) + 1; + cache->usage -= cache->func.mem_size_get(im); + + free(im->cache_key); + im->cache_key = NULL; + + cache->func.destructor(im); + evas_common_image_delete(im); + } + return cache->usage; +} + +EAPI RGBA_Image* +evas_cache_image_empty(Evas_Cache_Image* cache) +{ + RGBA_Image* new; + + new = evas_common_image_new(); + if (!new) goto on_error; + new->image = evas_common_image_surface_new(new); + if (!new->image) goto on_error; + + new->cache = cache; + new->references = 1; + + new->cache_key = NULL; + new->flags |= RGBA_IMAGE_IS_DIRTY; + + cache->dirty = evas_object_list_prepend(cache->dirty, new); + + return new; + + on_error: + if (new) evas_common_image_delete(new); + return NULL; +} + +EAPI void +evas_cache_image_colorspace(RGBA_Image* im, int cspace) +{ + if (!im) return ; + if (im->cs.space == cspace) return ; + + evas_common_image_colorspace_set(im, cspace); +} diff --git a/legacy/evas/src/lib/canvas/evas_main.c b/legacy/evas/src/lib/canvas/evas_main.c index 8d397032b0..1d584ab044 100644 --- a/legacy/evas/src/lib/canvas/evas_main.c +++ b/legacy/evas/src/lib/canvas/evas_main.c @@ -742,6 +742,9 @@ evas_render_method_list(void) #ifdef BUILD_ENGINE_SOFTWARE_QTOPIA methods = evas_list_append(methods, strdup("software_qtopia")); #endif +#ifdef BUILD_ENGINE_SDL + methods = evas_list_append(methods, strdup("software_sdl")); +#endif return methods; } diff --git a/legacy/evas/src/lib/canvas/evas_object_image.c b/legacy/evas/src/lib/canvas/evas_object_image.c index 1a38197ae9..f7e816b274 100644 --- a/legacy/evas/src/lib/canvas/evas_object_image.c +++ b/legacy/evas/src/lib/canvas/evas_object_image.c @@ -1061,20 +1061,18 @@ evas_object_image_save(Evas_Object *obj, const char *file, const char *key, cons else break; } } - im = evas_common_image_new(); + im = evas_cache_image_empty(evas_common_image_cache_get()); if (im) { if (o->cur.has_alpha) im->flags |= RGBA_IMAGE_HAS_ALPHA; - im->image = evas_common_image_surface_new(im); - if (im->image) - { - im->image->data = data; - im->image->w = o->cur.image.w; - im->image->h = o->cur.image.h; - im->image->no_free = 1; - ok = evas_common_save_image_to_file(im, file, key, quality, compress); - } - evas_common_image_free(im); + + im->image->data = data; + im->image->w = o->cur.image.w; + im->image->h = o->cur.image.h; + im->image->no_free = 1; + ok = evas_common_save_image_to_file(im, file, key, quality, compress); + + evas_cache_image_drop(im); } return ok; } diff --git a/legacy/evas/src/lib/engines/common/Makefile.am b/legacy/evas/src/lib/engines/common/Makefile.am index dfb8721004..c15675b772 100644 --- a/legacy/evas/src/lib/engines/common/Makefile.am +++ b/legacy/evas/src/lib/engines/common/Makefile.am @@ -45,6 +45,7 @@ evas_gradient_sinusoidal.c \ evas_image_load.c \ evas_image_save.c \ evas_image_main.c \ +evas_image_data.c \ evas_line_main.c \ evas_polygon_main.c \ evas_rectangle_main.c \ diff --git a/legacy/evas/src/lib/engines/common/evas_image_data.c b/legacy/evas/src/lib/engines/common/evas_image_data.c new file mode 100644 index 0000000000..3fcab35ad0 --- /dev/null +++ b/legacy/evas/src/lib/engines/common/evas_image_data.c @@ -0,0 +1,123 @@ +#include "evas_common.h" +#include "evas_private.h" + +#include + +EAPI int +evas_common_image_from_data(RGBA_Image* dst, int w, int h, DATA32 *image_data, int alpha, int cspace) +{ + switch (cspace) + { + case EVAS_COLORSPACE_ARGB8888: + dst->image->w = w; + dst->image->h = h; + dst->image->data = image_data; + dst->image->no_free = 1; + if (alpha) + dst->flags |= RGBA_IMAGE_HAS_ALPHA; + else + dst->flags &= ~RGBA_IMAGE_HAS_ALPHA; + break; + case EVAS_COLORSPACE_YCBCR422P601_PL: + case EVAS_COLORSPACE_YCBCR422P709_PL: + w &= ~0x1; + dst->image->w = w; + dst->image->h = h; + evas_common_image_surface_alloc(dst->image); + dst->cs.data = image_data; + dst->cs.no_free = 1; + break; + default: + abort(); + break; + } + dst->cs.space = cspace; + evas_common_image_colorspace_dirty(dst); + return 0; +} + +EAPI int +evas_common_image_from_copied_data(RGBA_Image* dst, int w, int h, DATA32 *image_data, int alpha, int cspace) +{ + switch (cspace) + { + case EVAS_COLORSPACE_ARGB8888: + if (alpha) + dst->flags |= RGBA_IMAGE_HAS_ALPHA; + else + dst->flags &= ~RGBA_IMAGE_HAS_ALPHA; + if (image_data) + memcpy(dst->image->data, image_data, w * h * sizeof(DATA32)); + break; + case EVAS_COLORSPACE_YCBCR422P601_PL: + case EVAS_COLORSPACE_YCBCR422P709_PL: + dst->cs.data = calloc(1, dst->image->h * sizeof(unsigned char*) * 2); + if (image_data && (dst->cs.data)) + memcpy(dst->cs.data, image_data, dst->image->h * sizeof(unsigned char*) * 2); + break; + default: + abort(); + break; + } + + dst->cs.space = cspace; + evas_common_image_colorspace_dirty(dst); + return 0; +} + +EAPI int +evas_common_image_size_set(RGBA_Image* dst, const RGBA_Image* im, int w, int h) +{ + if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) || + (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL)) + w &= ~0x1; + + dst->cs.space = im->cs.space; + dst->flags = im->flags; + dst->cs.no_free = 0; + if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) || + (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL)) + dst->cs.data = calloc(1, dst->image->h * sizeof(unsigned char *) * 2); + evas_common_image_surface_alloc(dst->image); + evas_common_image_colorspace_dirty(dst); + + return 0; +} + +EAPI int +evas_common_image_colorspace_set(RGBA_Image* dst, int cspace) +{ + switch (cspace) + { + case EVAS_COLORSPACE_ARGB8888: + if (dst->cs.data) + { + if (!dst->cs.no_free) free(dst->cs.data); + dst->cs.data = NULL; + dst->cs.no_free = 0; + } + break; + case EVAS_COLORSPACE_YCBCR422P601_PL: + case EVAS_COLORSPACE_YCBCR422P709_PL: + if (dst->image->no_free) + { + dst->image->data = NULL; + dst->image->no_free = 0; + evas_common_image_surface_alloc(dst->image); + } + if (dst->cs.data) + { + if (!dst->cs.no_free) free(dst->cs.data); + } + dst->cs.data = calloc(1, dst->image->h * sizeof(unsigned char *) * 2); + dst->cs.no_free = 0; + break; + default: + abort(); + break; + } + dst->cs.space = cspace; + evas_common_image_colorspace_dirty(dst); + + return 0; +} diff --git a/legacy/evas/src/lib/engines/common/evas_image_load.c b/legacy/evas/src/lib/engines/common/evas_image_load.c index 29d8945000..3cb7fcbab2 100644 --- a/legacy/evas/src/lib/engines/common/evas_image_load.c +++ b/legacy/evas/src/lib/engines/common/evas_image_load.c @@ -3,58 +3,50 @@ extern Evas_List *evas_modules; -EAPI RGBA_Image * -evas_common_load_image_from_file(const char *file, const char *key, RGBA_Image_Loadopts *lo) +struct ext_loader_s { + const char* extention; + const char* loader; +}; + +static struct ext_loader_s loaders[] = { + { "png", "png" }, + { "jpg", "jpeg" }, + { "jpeg", "jpeg" }, + { "jfif", "jpeg" }, + { "eet", "eet" }, + { "edj", "eet" }, + { "eap", "eet" }, + { "edb", "edb" }, + { "xpm", "xpm" }, + { "tiff", "tiff" }, + { "tif", "tiff" }, + { "svg", "svg" }, + { "svgz", "svg" } +}; + +EAPI int +evas_common_load_image_module_from_file(RGBA_Image *im) { Evas_Image_Load_Func *evas_image_load_func = NULL; - Evas_List *l; - RGBA_Image *im; - char *p; - char *loader = NULL; - Evas_Module *em; - struct stat st; - - if (file == NULL) return NULL; + const char *loader = NULL; + char *dot; + Evas_List *l; + Evas_Module *em; + int i; - im = evas_common_image_find(file, key, 0, lo); - if (im) + dot = strrchr (im->info.file, '.'); + if (dot) { - evas_common_image_ref(im); - return im; - } - if (stat(file, &st) < 0) return NULL; - - im = evas_common_image_new(); - if (!im) return NULL; - - im->timestamp = st.st_mtime; - im->laststat = time(NULL); - - if (lo) im->load_opts = *lo; - - p = strrchr(file, '.'); - if (p) - { - p++; - if (!strcasecmp(p, "png")) - loader = "png"; - else if ((!strcasecmp(p, "jpg")) || (!strcasecmp(p, "jpeg")) || - (!strcasecmp(p, "jfif"))) - loader = "jpeg"; - else if ((!strcasecmp(p, "eet")) || (!strcasecmp(p, "edj")) || - (!strcasecmp(p, "eap"))) - loader = "eet"; - else if (!strcasecmp(p, "edb")) - loader = "edb"; - else if ((!strcasecmp(p, "tiff")) || (!strcasecmp(p, "tif"))) - loader = "tiff"; - else if (!strcasecmp(p, "xpm")) - loader = "xpm"; - else if (!strcasecmp(p, "svg")) - loader = "svg"; - else if (!strcasecmp(p, "svgz")) - loader = "svg"; + for (i = 0, ++dot; i < (sizeof (loaders) / sizeof (struct ext_loader_s)); ++i) + { + if (!strcasecmp (dot, loaders[i].extention)) + { + loader = loaders[i].loader; + break; + } + } } + if (loader) { em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader); @@ -64,7 +56,7 @@ evas_common_load_image_from_file(const char *file, const char *key, RGBA_Image_L { evas_module_use(em); evas_image_load_func = em->functions; - if (evas_image_load_func->file_head(im, file, key)) + if (evas_image_load_func->file_head(im, im->info.file, im->info.key)) goto ok; } } @@ -77,7 +69,7 @@ evas_common_load_image_from_file(const char *file, const char *key, RGBA_Image_L if (!evas_module_load(em)) continue; evas_image_load_func = em->functions; evas_module_use(em); - if (evas_image_load_func->file_head(im, file, key)) + if (evas_image_load_func->file_head(im, im->info.file, im->info.key)) { if (evas_modules != l) { @@ -86,33 +78,30 @@ evas_common_load_image_from_file(const char *file, const char *key, RGBA_Image_L goto ok; } } - - evas_common_image_free(im); - return NULL; - ok: + evas_common_image_delete(im); + return -1; + + ok: im->info.module = (void *)em; im->info.loader = (void *)evas_image_load_func; - im->info.file = (char *)evas_stringshare_add(file); - if (key) im->info.key = (char *)evas_stringshare_add(key); evas_module_ref((Evas_Module *)im->info.module); - evas_common_image_ref(im); - return im; + return 0; } EAPI void evas_common_load_image_data_from_file(RGBA_Image *im) { Evas_Image_Load_Func *evas_image_load_func = NULL; - - if (im->image->data) return; + + if ((im->flags & RGBA_IMAGE_LOADED) == RGBA_IMAGE_LOADED) return ; if (!im->info.module) return; evas_image_load_func = im->info.loader; evas_module_use((Evas_Module *)im->info.module); if (!evas_image_load_func->file_data(im, im->info.file, im->info.key)) { - evas_common_image_surface_alloc(im->image); + if (!im->image->data) evas_common_image_surface_alloc(im->image); if (!im->image->data) { const DATA32 pixel = 0xffffffff; @@ -128,4 +117,5 @@ evas_common_load_image_data_from_file(RGBA_Image *im) evas_module_unref((Evas_Module *)im->info.module); im->info.module = NULL; } + im->flags |= RGBA_IMAGE_LOADED; } diff --git a/legacy/evas/src/lib/engines/common/evas_image_main.c b/legacy/evas/src/lib/engines/common/evas_image_main.c index 35fdd1bf55..53c92537cc 100644 --- a/legacy/evas/src/lib/engines/common/evas_image_main.c +++ b/legacy/evas/src/lib/engines/common/evas_image_main.c @@ -9,70 +9,50 @@ #include #endif -static Evas_Hash * images = NULL; -static Evas_Object_List * cache = NULL; -static int cache_size = 0; -static int cache_usage = 0; +static Evas_Cache_Image * eci = NULL; +static int reference = 0; -static RGBA_Image *evas_rgba_line_buffer = NULL; +/* static RGBA_Image *evas_rgba_line_buffer = NULL; */ #define EVAS_RGBA_LINE_BUFFER_MIN_LEN 256 #define EVAS_RGBA_LINE_BUFFER_MAX_LEN 2048 -static RGBA_Image *evas_alpha_line_buffer = NULL; +/* static RGBA_Image *evas_alpha_line_buffer = NULL; */ #define EVAS_ALPHA_LINE_BUFFER_MIN_LEN 256 #define EVAS_ALPHA_LINE_BUFFER_MAX_LEN 2048 -#if 0 -int -image_debug_hash_cb(Evas_Hash *hash, const char *key, void *data, void *fdata) +/* The cache is doing the allocation and deallocation, you must just do the rest. */ +static void _evas_common_image_unload(RGBA_Image* im); + +static void _evas_common_image_dirty_region(RGBA_Image* im, int x, int y, int w, int h); + +/* Only called when references > 0. Need to provide a fresh copie of im. */ +/* The destination surface does have a surface, but no allocated pixel data. */ +static int _evas_common_image_dirty(RGBA_Image* dst, const RGBA_Image* src); + +static const Evas_Cache_Image_Func _evas_common_image_func = { - RGBA_Image *im; - - im = data; - printf(" [%i] %3ix%3i %6i %6i [%2x %2x] %i %s\n", - im->references, - im->image->w, im->image->h, - im->image->w * im->image->h * 4, - evas_common_image_ram_usage(im), - im->flags & RGBA_IMAGE_IS_DIRTY, - im->flags & RGBA_IMAGE_INDEXED, - im->info.format, - im->info.file); -} - -static void -image_debug(void) -{ - Evas_Object_List *l; - - printf("active images:\n"); - evas_hash_foreach(images, image_debug_hash_cb, NULL); - printf("cache size: %i\n", cache_size); - printf("cache usage: %i\n", cache_usage); - printf("cached images:\n"); - for (l = cache; l; l = l->next) - { - RGBA_Image *im; - - im = l; - printf(" [%i] %3ix%3i %6i %6i [%2x %2x] %i %s\n", - im->references, - im->image->w, im->image->h, - im->image->w * im->image->h * 4, - evas_common_image_ram_usage(im), - im->flags & RGBA_IMAGE_IS_DIRTY, - im->flags & RGBA_IMAGE_INDEXED, - im->info.format, - im->info.file); - } -} -#endif + .constructor = evas_common_load_image_module_from_file, + .destructor = _evas_common_image_unload, + .dirty_region = _evas_common_image_dirty_region, + .dirty = _evas_common_image_dirty, + .copied_data = evas_common_image_from_copied_data, + .color_space = evas_common_image_colorspace_set, + .data = evas_common_image_from_data, + .size_set = evas_common_image_size_set, + .load = evas_common_load_image_data_from_file, + .mem_size_get = evas_common_image_ram_usage, + .debug = NULL +}; EAPI void evas_common_image_init(void) { + if (!eci) + eci = evas_cache_image_init(&_evas_common_image_func); + reference++; + #ifdef BUILD_LOADER_EET eet_init(); #endif @@ -81,11 +61,69 @@ evas_common_image_init(void) EAPI void evas_common_image_shutdown(void) { + if (--reference == 0) + { + evas_cache_image_shutdown(eci); + eci = NULL; + } + #ifdef BUILD_LOADER_EET eet_shutdown(); #endif } +static void +_evas_common_image_unload(RGBA_Image* im) +{ +} + +static void +_evas_common_image_dirty_region(RGBA_Image* im, int x, int y, int w, int h) +{ +} + +void +evas_common_image_delete(RGBA_Image* im) +{ + if ((im->cs.data) && (im->image->data)) + { + if (im->cs.data != im->image->data) + { + if (!im->cs.no_free) free(im->cs.data); + } + } + else if (im->cs.data) + { + if (!im->cs.no_free) free(im->cs.data); + } + + im->cs.data = NULL; + evas_common_pipe_free(im); + if (im->image) evas_common_image_surface_free(im->image); + if (im->info.file) evas_stringshare_del(im->info.file); + if (im->info.key) evas_stringshare_del(im->info.key); + if (im->info.module) evas_module_unref((Evas_Module *)im->info.module); + /* memset the image to 0x99 because i recently saw a segv where an + * seemed to be used BUT its contents were wrong - it looks like it was + * overwritten by something from efreet - as there was an execute command + * for a command there and some other signs - but to make sure, I am + * going to empty this struct out in case this happens again so i know + * that something else is overwritign this struct - or not */ + memset(im, 0x99, sizeof(im)); + free(im); +} + +/* Only called when references > 0. Need to provide a fresh copie of im. */ +static int +_evas_common_image_dirty(RGBA_Image* dst, const RGBA_Image* src) +{ + evas_common_image_colorspace_normalize(dst); + evas_common_blit_rectangle(src, dst, 0, 0, src->image->w, src->image->h, 0, 0); + evas_common_cpu_end_opt(); + + return 0; +} + #if 0 void evas_common_image_surface_alpha_tiles_calc(RGBA_Surface *is, int tsize) @@ -174,6 +212,8 @@ evas_common_image_surface_alloc(RGBA_Surface *is) { size_t siz = 0; + if (is->data) return ; + if (is->im->flags & RGBA_IMAGE_ALPHA_ONLY) siz = is->w * is->h * sizeof(DATA8); else @@ -206,7 +246,7 @@ evas_common_image_create(int w, int h) im->image = evas_common_image_surface_new(im); if (!im->image) { - evas_common_image_free(im); + evas_common_image_delete(im); return NULL; } im->image->w = w; @@ -214,7 +254,7 @@ evas_common_image_create(int w, int h) evas_common_image_surface_alloc(im->image); if (!im->image->data) { - evas_common_image_free(im); + evas_common_image_delete(im); return NULL; } im->flags = RGBA_IMAGE_IS_DIRTY; @@ -232,7 +272,7 @@ evas_common_image_alpha_create(int w, int h) im->image = evas_common_image_surface_new(im); if (!im->image) { - evas_common_image_free(im); + evas_common_image_delete(im); return NULL; } im->image->w = w; @@ -241,7 +281,7 @@ evas_common_image_alpha_create(int w, int h) evas_common_image_surface_alloc(im->image); if (!im->image->data) { - evas_common_image_free(im); + evas_common_image_delete(im); return NULL; } im->flags = RGBA_IMAGE_IS_DIRTY; @@ -262,72 +302,6 @@ evas_common_image_new(void) return im; } -EAPI void -evas_common_image_free(RGBA_Image *im) -{ - im->ref--; - if (im->ref > 0) return; - if ((im->cs.data) && (im->image->data)) - { - if (im->cs.data != im->image->data) - { - if (!im->cs.no_free) free(im->cs.data); - } - } - else if (im->cs.data) - { - if (!im->cs.no_free) free(im->cs.data); - } - - im->cs.data = NULL; - evas_common_pipe_free(im); - if (im->image) evas_common_image_surface_free(im->image); - if (im->info.file) evas_stringshare_del(im->info.file); -// if (im->info.real_file) evas_stringshare_del(im->info.real_file); - if (im->info.key) evas_stringshare_del(im->info.key); -// if (im->info.comment) evas_stringshare_del(im->info.comment); - if (im->info.module) evas_module_unref((Evas_Module *)im->info.module); - /* memset the image to 0x99 because i recently saw a segv where an - * seemed to be used BUT its contents were wrong - it looks like it was - * overwritten by something from efreet - as there was an execute command - * for a command there and some other signs - but to make sure, I am - * going to empty this struct out in case this happens again so i know - * that something else is overwritign this struct - or not */ - memset(im, 0x99, sizeof(im)); - free(im); -} - -EAPI void -evas_common_image_ref(RGBA_Image *im) -{ - im->references++; - if (im->references == 1) /* we were in cache - take us out */ - { - evas_common_image_uncache(im); - evas_common_image_store(im); - } -} - -EAPI void -evas_common_image_unref(RGBA_Image *im) -{ - im->references--; - if (im->references <= 0) /* we were are now in cache - put us in */ - { - evas_common_image_unstore(im); - if ((cache_size > 0) && - (!(im->flags & RGBA_IMAGE_IS_DIRTY))) - { - evas_common_image_cache(im); - evas_common_image_flush_cache(); - } - else - { - evas_common_image_free(im); - } - } -} - EAPI void evas_common_image_colorspace_normalize(RGBA_Image *im) { @@ -345,7 +319,7 @@ evas_common_image_colorspace_normalize(RGBA_Image *im) case EVAS_COLORSPACE_YCBCR422P601_PL: #ifdef BUILD_CONVERT_YUV if ((im->image->data) && (*((unsigned char **)im->cs.data))) - evas_common_convert_yuv_420p_601_rgba(im->cs.data, im->image->data, + evas_common_convert_yuv_420p_601_rgba(im->cs.data, (DATA8*) im->image->data, im->image->w, im->image->h); #endif break; @@ -361,237 +335,27 @@ evas_common_image_colorspace_dirty(RGBA_Image *im) im->cs.dirty = 1; } -EAPI void -evas_common_image_cache(RGBA_Image *im) -{ - int ram; - - if (im->flags & RGBA_IMAGE_INDEXED) return; - im->flags |= RGBA_IMAGE_INDEXED; - cache = evas_object_list_prepend(cache, im); - ram = evas_common_image_ram_usage(im); - cache_usage += ram; - evas_common_image_flush_cache(); -} - -EAPI void -evas_common_image_uncache(RGBA_Image *im) -{ - int ram; - - if (!(im->flags & RGBA_IMAGE_INDEXED)) return; - im->flags &= ~RGBA_IMAGE_INDEXED; - cache = evas_object_list_remove(cache, im); - ram = evas_common_image_ram_usage(im); - cache_usage -= ram; -} - -EAPI void -evas_common_image_flush_cache(void) -{ - Evas_Object_List *l, *l_next; - - if (!cache) return; - if (cache_usage < cache_size) return; - - for (l = cache->last; l;) - { - RGBA_Image *im; - - l_next = l->prev; - im = (RGBA_Image *)l; - evas_common_image_uncache(im); - evas_common_image_free(im); - if (cache_usage <= cache_size) return; - l = l_next; - } -} - EAPI void evas_common_image_set_cache(int size) { - cache_size = size; - evas_common_image_flush_cache(); + if (eci != NULL) + evas_cache_image_set(eci, size); } - EAPI int evas_common_image_get_cache(void) { - return cache_size; -} - -EAPI void -evas_common_image_store(RGBA_Image *im) -{ - char buf[4096 + 1024]; - - if (im->flags & RGBA_IMAGE_IS_DIRTY) return; - if (im->flags & RGBA_IMAGE_INDEXED) return; - if ((!im->info.file) && (!im->info.key)) return; - if ((im->load_opts.scale_down_by == 0) && - (im->load_opts.dpi == 0.0) && - ((im->load_opts.w == 0) || (im->load_opts.h == 0))) - { - if (im->info.key) - snprintf(buf, sizeof(buf), "%s//://%s", im->info.file, im->info.key); - else - snprintf(buf, sizeof(buf), "%s", im->info.file); - } - else - { - if (im->info.key) - snprintf(buf, sizeof(buf), "//@/%i/%1.5f/%ix%i//%s//://%s", im->load_opts.scale_down_by, im->load_opts.dpi, im->load_opts.w, im->load_opts.h, im->info.file, im->info.key); - else - snprintf(buf, sizeof(buf), "//@/%i/%1.5f/%ix%i//%s", im->load_opts.scale_down_by, im->load_opts.dpi, im->load_opts.w, im->load_opts.h, im->info.file); - } - images = evas_hash_add(images, buf, im); - im->flags |= RGBA_IMAGE_INDEXED; -} - -EAPI void -evas_common_image_unstore(RGBA_Image *im) -{ - char buf[4096 + 1024]; - - if (!(im->flags & RGBA_IMAGE_INDEXED)) return; - if ((!im->info.file) && (!im->info.key)) return; - if ((im->load_opts.scale_down_by == 0) && - (im->load_opts.dpi == 0.0) && - ((im->load_opts.w == 0) || (im->load_opts.h == 0))) - { - if (im->info.key) - snprintf(buf, sizeof(buf), "%s//://%s", im->info.file, im->info.key); - else - snprintf(buf, sizeof(buf), "%s", im->info.file); - } - else - { - if (im->info.key) - snprintf(buf, sizeof(buf), "//@/%i/%1.5f/%ix%i//%s//://%s", im->load_opts.scale_down_by, im->load_opts.dpi, im->load_opts.w, im->load_opts.h, im->info.file, im->info.key); - else - snprintf(buf, sizeof(buf), "//@/%i/%1.5f/%ix%i//%s", im->load_opts.scale_down_by, im->load_opts.dpi, im->load_opts.w, im->load_opts.h, im->info.file); - } - images = evas_hash_del(images, buf, im); - im->flags &= ~RGBA_IMAGE_INDEXED; + return evas_cache_image_get(eci); } #define STAT_GAP 2 EAPI RGBA_Image * -evas_common_image_find(const char *file, const char *key, DATA64 timestamp, RGBA_Image_Loadopts *lo) +evas_common_load_image_from_file(const char *file, const char *key, RGBA_Image_Loadopts *lo) { - RGBA_Image_Loadopts *lo2; - RGBA_Image *im; - char buf[4096 + 1024]; - Evas_Object_List *l; - struct stat st; - static time_t laststat = 0; - time_t t, mt = 0; + int error; - if ((!file) && (!key)) return NULL; - if (!file) return NULL; - if ((!lo) || - ((lo) && - (lo->scale_down_by == 0) && - (lo->dpi == 0.0) && - ((lo->w == 0) || (lo->h == 0)))) - { - if (key) - snprintf(buf, sizeof(buf), "%s//://%s", file, key); - else - snprintf(buf, sizeof(buf), "%s", file); - } - else - { - if (key) - snprintf(buf, sizeof(buf), "//@/%i/%1.5f/%ix%i//%s//://%s", lo->scale_down_by, lo->dpi, lo->w, lo->h, file, key); - else - snprintf(buf, sizeof(buf), "//@/%i/%1.5f/%ix%i//%s", lo->scale_down_by, lo->dpi, lo->w, lo->h, file); - } - im = evas_hash_find(images, buf); - t = time(NULL); - if (im) - { - if ((t - im->laststat) < STAT_GAP) - return im; - else - { - struct stat st; - - if (stat(file, &st) < 0) return NULL; - mt = st.st_mtime; - if (mt == im->timestamp) - { - im->laststat = t; - laststat = t; - return im; - } - } - } - for (l = cache; l; l = l->next) - { - int ok; - - im = (RGBA_Image *)l; - lo2 = &(im->load_opts); - ok = 0; - if ((file) && (im->info.file) && - (!strcmp(file, im->info.file))) - ok++; - else if ((!file) && (!im->info.file)) - ok++; - else continue; - - if ((key) && (im->info.key) && - (!strcmp(key, im->info.key))) - ok++; - else if ((!key) && (!im->info.key)) - ok++; - else continue; - - if ((lo->scale_down_by == lo2->scale_down_by) && - (lo->dpi == lo2->dpi) && (lo->w == lo2->w) && - (lo->h == lo2->h)) - ok++; - else continue; - - if ((t - im->laststat) >= STAT_GAP) - { - if (stat(file, &st) < 0) continue; - mt = st.st_mtime; - if (im->timestamp == mt) - ok++; - else continue; - } - else ok++; - - laststat = t; - im->laststat = t; - return im; - } -/* - for (l = cache; l; l = l->next) - { - int ok; - - im = (RGBA_Image *)l; - ok = 0; - if ((file) && (im->info.file) && - (!strcmp(file, im->info.file))) - ok++; - if ((!file) && (!im->info.file)) - ok++; - if ((key) && (im->info.key) && - (!strcmp(key, im->info.key))) - ok++; - if ((!key) && (!im->info.key)) - ok++; -// if (im->timestamp == timestamp) -// ok++; - if (ok >= 2) return im; - } - */ - return NULL; + if (file == NULL) return NULL; + return evas_cache_image_request(eci, file, key, lo, &error); } EAPI int @@ -609,19 +373,18 @@ evas_common_image_ram_usage(RGBA_Image *im) return ram; } -EAPI void -evas_common_image_dirty(RGBA_Image *im) -{ - evas_common_image_unstore(im); - im->flags |= RGBA_IMAGE_IS_DIRTY; -} - EAPI void evas_common_image_cache_free(void) { evas_common_image_set_cache(0); } +EAPI Evas_Cache_Image* +evas_common_image_cache_get(void) +{ + return eci; +} + EAPI RGBA_Image * evas_common_image_line_buffer_obtain(int len) { @@ -653,7 +416,7 @@ evas_common_image_line_buffer_obtain(int len) EAPI void evas_common_image_line_buffer_release(RGBA_Image *im) { - evas_common_image_free(im); + evas_common_image_delete(im); /* if (!evas_rgba_line_buffer) return; if (EVAS_RGBA_LINE_BUFFER_MAX_LEN < evas_rgba_line_buffer->image->w) @@ -673,7 +436,7 @@ evas_common_image_line_buffer_release(RGBA_Image *im) EAPI void evas_common_image_line_buffer_free(RGBA_Image *im) { - evas_common_image_free(im); + evas_common_image_delete(im); /* if (!evas_rgba_line_buffer) return; evas_common_image_free(evas_rgba_line_buffer); @@ -711,7 +474,7 @@ evas_common_image_alpha_line_buffer_obtain(int len) EAPI void evas_common_image_alpha_line_buffer_release(RGBA_Image *im) { - evas_common_image_free(im); + evas_common_image_delete(im); /* if (!evas_alpha_line_buffer) return; if (EVAS_ALPHA_LINE_BUFFER_MAX_LEN < evas_alpha_line_buffer->image->w) @@ -728,17 +491,6 @@ evas_common_image_alpha_line_buffer_release(RGBA_Image *im) */ } -EAPI void -evas_common_image_alpha_line_buffer_free(RGBA_Image *im) -{ - evas_common_image_free(im); -/* - if (!evas_alpha_line_buffer) return; - evas_common_image_free(evas_alpha_line_buffer); - evas_alpha_line_buffer = NULL; - */ -} - EAPI void evas_common_image_premul(RGBA_Image *im) { diff --git a/legacy/evas/src/lib/engines/common/evas_pipe.c b/legacy/evas/src/lib/engines/common/evas_pipe.c index 2eadf69483..56a7866103 100644 --- a/legacy/evas/src/lib/engines/common/evas_pipe.c +++ b/legacy/evas/src/lib/engines/common/evas_pipe.c @@ -483,7 +483,9 @@ evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, static void evas_common_pipe_op_image_free(RGBA_Pipe_Op *op) { - evas_common_image_free(op->op.image.src); + op->op.image.src->ref--; + if (op->op.image.src->ref == 0) + evas_cache_image_drop(op->op.image.src); evas_common_pipe_op_free(op); } @@ -493,15 +495,15 @@ evas_common_pipe_image_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thre if (info) { RGBA_Draw_Context context; - + memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); #ifdef EVAS_SLI evas_common_draw_context_set_sli(&(context), info->y, info->h); -#else +#else evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h); -#endif +#endif if (op->op.image.smooth) - evas_common_scale_rgba_in_to_out_clip_smooth(op->op.image.src, + evas_common_scale_rgba_in_to_out_clip_smooth(op->op.image.src, dst, &(context), op->op.image.sx, op->op.image.sy, @@ -512,7 +514,7 @@ evas_common_pipe_image_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thre op->op.image.dw, op->op.image.dh); else - evas_common_scale_rgba_in_to_out_clip_sample(op->op.image.src, + evas_common_scale_rgba_in_to_out_clip_sample(op->op.image.src, dst, &(context), op->op.image.sx, op->op.image.sy, @@ -526,7 +528,7 @@ evas_common_pipe_image_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thre else { if (op->op.image.smooth) - evas_common_scale_rgba_in_to_out_clip_smooth(op->op.image.src, + evas_common_scale_rgba_in_to_out_clip_smooth(op->op.image.src, dst, &(op->context), op->op.image.sx, op->op.image.sy, @@ -537,7 +539,7 @@ evas_common_pipe_image_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thre op->op.image.dw, op->op.image.dh); else - evas_common_scale_rgba_in_to_out_clip_sample(op->op.image.src, + evas_common_scale_rgba_in_to_out_clip_sample(op->op.image.src, dst, &(op->context), op->op.image.sx, op->op.image.sy, diff --git a/legacy/evas/src/lib/imaging/evas_imaging.c b/legacy/evas/src/lib/imaging/evas_imaging.c index 9ca8f3e518..6d00778f53 100644 --- a/legacy/evas/src/lib/imaging/evas_imaging.c +++ b/legacy/evas/src/lib/imaging/evas_imaging.c @@ -20,7 +20,7 @@ evas_imaging_image_load(const char *file, const char *key) im = calloc(1, sizeof(Evas_Imaging_Image)); if (!im) { - evas_common_image_free(image); + evas_cache_image_drop(image); return NULL; } im->image = image; @@ -31,7 +31,7 @@ EAPI void evas_imaging_image_free(Evas_Imaging_Image *im) { if (!im) return; - evas_common_image_unref(im->image); + evas_cache_image_drop(im->image); free(im); } diff --git a/legacy/evas/src/lib/include/evas_common.h b/legacy/evas/src/lib/include/evas_common.h index a8480f0d1b..0725149c4f 100644 --- a/legacy/evas/src/lib/include/evas_common.h +++ b/legacy/evas/src/lib/include/evas_common.h @@ -109,27 +109,28 @@ /*****************************************************************************/ #ifndef _WIN32_WCE -typedef unsigned long long DATA64; +typedef unsigned long long DATA64; #else -typedef unsigned __int64 DATA64; +typedef unsigned __int64 DATA64; #define strdup _strdup #define snprintf _snprintf #define rewind(f) fseek(f, 0, SEEK_SET) #endif -typedef unsigned int DATA32; -typedef unsigned short DATA16; -typedef unsigned char DATA8; +typedef unsigned int DATA32; +typedef unsigned short DATA16; +typedef unsigned char DATA8; -typedef struct _Evas_Object_List Evas_Object_List; +typedef struct _Evas_Object_List Evas_Object_List; -typedef struct _Evas_Hash_El Evas_Hash_El; +typedef struct _Evas_Hash_El Evas_Hash_El; typedef struct _RGBA_Image_Loadopts RGBA_Image_Loadopts; typedef struct _RGBA_Pipe_Op RGBA_Pipe_Op; typedef struct _RGBA_Pipe RGBA_Pipe; typedef struct _RGBA_Pipe_Thread_Info RGBA_Pipe_Thread_Info; typedef struct _RGBA_Image RGBA_Image; +typedef struct _RGBA_Engine_Image RGBA_Engine_Image; typedef struct _RGBA_Surface RGBA_Surface; typedef struct _RGBA_Image_Span RGBA_Image_Span; typedef struct _RGBA_Draw_Context RGBA_Draw_Context; @@ -147,19 +148,25 @@ typedef struct _RGBA_Gfx_Compositor RGBA_Gfx_Compositor; typedef struct _Cutout_Rect Cutout_Rect; typedef struct _Cutout_Rects Cutout_Rects; -typedef struct _Convert_Pal Convert_Pal; +typedef struct _Convert_Pal Convert_Pal; -typedef struct _Tilebuf Tilebuf; -typedef struct _Tilebuf_Tile Tilebuf_Tile; -typedef struct _Tilebuf_Rect Tilebuf_Rect; +typedef struct _Tilebuf Tilebuf; +typedef struct _Tilebuf_Tile Tilebuf_Tile; +typedef struct _Tilebuf_Rect Tilebuf_Rect; -typedef struct _Evas_Array_Hash Evas_Array_Hash; +typedef struct _Evas_Array_Hash Evas_Array_Hash; +typedef struct _Evas_Array_Hash Evas_Array_Double_Hash; /* typedef struct _Regionbuf Regionbuf; typedef struct _Regionspan Regionspan; */ +typedef struct _Evas_Cache_Image Evas_Cache_Image; +typedef struct _Evas_Cache_Image_Func Evas_Cache_Image_Func; +typedef struct _Evas_Cache_Engine_Image Evas_Cache_Engine_Image; +typedef struct _Evas_Cache_Engine_Image_Func Evas_Cache_Engine_Image_Func; + typedef void (*RGBA_Gfx_Func) (DATA32 *src, DATA8 *mask, DATA32 col, DATA32 *dst, int len); typedef void (*RGBA_Gfx_Pt_Func) (DATA32 src, DATA8 mask, DATA32 col, DATA32 *dst); typedef void (*Gfx_Func_Copy) (DATA32 *src, DATA32 *dst, int len); @@ -181,7 +188,8 @@ typedef enum _RGBA_Image_Flags RGBA_IMAGE_INDEXED = (1 << 2), RGBA_IMAGE_ALPHA_ONLY = (1 << 3), RGBA_IMAGE_ALPHA_TILES = (1 << 4), - RGBA_IMAGE_ALPHA_SPARSE = (1 << 5) + RGBA_IMAGE_ALPHA_SPARSE = (1 << 5), + RGBA_IMAGE_LOADED = (1 << 6) } RGBA_Image_Flags; typedef enum _Convert_Pal_Mode @@ -364,11 +372,16 @@ struct _RGBA_Image char *comment; // int format; } info; + void *extended_info; RGBA_Pipe *pipe; int references; RGBA_Image_Loadopts load_opts; + unsigned char scale; + int ref; + + /* Colorspace stuff. */ time_t timestamp; time_t laststat; struct { @@ -377,7 +390,32 @@ struct _RGBA_Image unsigned char no_free : 1; unsigned char dirty : 1; } cs; - unsigned char scale; + + /* Cache stuff. */ + Evas_Cache_Image *cache; + char *cache_key; +}; + +struct _RGBA_Engine_Image +{ + Evas_Object_List _list_data; + + /* Engine specific data. */ + void *engine_data; + + /* Upper Engine data. */ + RGBA_Image *src; + + /* Cache stuff. */ + int references; + struct + { + int dirty : 1; + int loaded : 1; + } flags; + + Evas_Cache_Engine_Image *cache; + const char *cache_key; }; struct _RGBA_Gradient_Color_Stop @@ -659,6 +697,82 @@ struct _Convert_Pal void *data; }; +/****/ +struct _Evas_Cache_Image_Func +{ + /* The cache is doing the allocation and deallocation, you must just do the rest. */ + int (*constructor)(RGBA_Image* im); + void (*destructor)(RGBA_Image* im); + + void (*dirty_region)(RGBA_Image* im, int x, int y, int w, int h); + /* Only called when references > 0. Need to provide a fresh copie of im. */ + /* The destination surface does have a surface, but no allocated pixel data. */ + int (*dirty)(RGBA_Image* dst, const RGBA_Image* src); + /* Only called when references == 1. We will call drop on `im'. */ + /* The destination surface does not have any surface. */ + int (*size_set)(RGBA_Image* dst, const RGBA_Image* src, int w, int h); + + /* The destination surface does not have any surface. */ + int (*copied_data)(RGBA_Image* dst, int w, int h, DATA32 *image_data, int alpha, int cspace); + /* The destination surface does not have any surface. */ + int (*data)(RGBA_Image* dst, int w, int h, DATA32 *image_data, int alpha, int cspace); + int (*color_space)(RGBA_Image* dst, int cspace); + + void (*load)(RGBA_Image* im); + int (*mem_size_get)(RGBA_Image* im); + void (*debug)(const char* context, RGBA_Image* im); +}; + +struct _Evas_Cache_Image +{ + int usage; + int limit; + int references; + + Evas_Cache_Image_Func func; + + Evas_Object_List* dirty; + + Evas_Object_List* lru; + Evas_Hash* inactiv; + Evas_Hash* activ; +}; + +struct _Evas_Cache_Engine_Image_Func +{ + /* Must return a char* allocated with evas_stringshare_add. */ + char* (*key)(RGBA_Image *im, const char *file, const char *key, RGBA_Image_Loadopts *lo, int *error); + + int (*constructor)(RGBA_Engine_Image*, void* data); + void (*destructor)(RGBA_Engine_Image *eim); + + void (*dirty_region)(RGBA_Engine_Image *eim, int x, int y, int w, int h); + /* Only called when references > 0. Need to provide a fresh copie of im. */ + int (*dirty)(RGBA_Engine_Image *dst, const RGBA_Engine_Image *src); + /* Only called when references == 1. We will call drop on `im'. */ + int (*size_set)(RGBA_Engine_Image *dst, const RGBA_Engine_Image *src); + + int (*update_data)(RGBA_Engine_Image* dst, void* data); + + void (*load)(RGBA_Engine_Image *eim, const RGBA_Image* im); + int (*mem_size_get)(RGBA_Engine_Image *eim); + void (*debug)(const char* context, RGBA_Engine_Image *eim); +}; + +struct _Evas_Cache_Engine_Image +{ + int usage; + int limit; + + Evas_Cache_Engine_Image_Func func; + + Evas_Object_List* dirty; + + Evas_Hash* activ; + + Evas_Cache_Image* parent; +}; + /*****************************************************************************/ #include "evas_macros.h" @@ -906,45 +1020,38 @@ EAPI void evas_common_image_surface_free (RGBA_Surface *is);/*2*/ EAPI void evas_common_image_surface_alloc (RGBA_Surface *is);/*2*/ EAPI void evas_common_image_surface_dealloc (RGBA_Surface *is);/*2*/ EAPI void evas_common_image_colorspace_normalize(RGBA_Image *im); -EAPI void evas_common_image_colorspace_dirty (RGBA_Image *im); -EAPI void evas_common_image_cache (RGBA_Image *im); /*2*/ -EAPI void evas_common_image_uncache (RGBA_Image *im); /*2*/ -EAPI void evas_common_image_store (RGBA_Image *im); /*2*/ -EAPI void evas_common_image_unstore (RGBA_Image *im); /*2*/ -EAPI RGBA_Image *evas_common_image_find (const char *file, const char *key, DATA64 timestamp, RGBA_Image_Loadopts *lo); /*2*/ +EAPI void evas_common_image_colorspace_dirty (RGBA_Image *im); EAPI void evas_common_image_cache_free (void); /*2*/ -EAPI void evas_common_image_premul (RGBA_Image *im); /*2*/ -EAPI void evas_common_image_set_alpha_sparse (RGBA_Image *im); /*2*/ - -/*done*/ +EAPI void evas_common_image_premul (RGBA_Image *im); /*2*/ +EAPI void evas_common_image_set_alpha_sparse (RGBA_Image *im); /*2*/ EAPI RGBA_Image *evas_common_image_alpha_create (int w, int h); EAPI RGBA_Image *evas_common_image_create (int w, int h); EAPI RGBA_Image *evas_common_image_new (void); +EAPI void evas_common_image_delete (RGBA_Image *im); +EAPI Evas_Cache_Image* evas_common_image_cache_get (void); +EAPI int evas_common_load_image_module_from_file (RGBA_Image *im); +EAPI void evas_common_load_image_data_from_file (RGBA_Image *im); +EAPI int evas_common_image_colorspace_set (RGBA_Image* dst, int cspace); -EAPI void evas_common_image_free (RGBA_Image *im); -EAPI void evas_common_image_ref (RGBA_Image *im); -EAPI void evas_common_image_unref (RGBA_Image *im); -EAPI void evas_common_image_flush_cache (void); +EAPI int evas_common_image_size_set (RGBA_Image* dst, const RGBA_Image* im, int w, int h); +EAPI int evas_common_image_from_copied_data (RGBA_Image* dst, int w, int h, DATA32 *image_data, int alpha, int cspace); +EAPI int evas_common_image_from_data (RGBA_Image* dst, int w, int h, DATA32 *image_data, int alpha, int cspace); + +/*done*/ EAPI void evas_common_image_set_cache (int size); EAPI int evas_common_image_get_cache (void); EAPI int evas_common_image_ram_usage (RGBA_Image *im); -EAPI void evas_common_image_dirty (RGBA_Image *im); EAPI RGBA_Image *evas_common_image_line_buffer_obtain (int len); EAPI void evas_common_image_line_buffer_release (RGBA_Image *im); -EAPI void evas_common_image_line_buffer_free (RGBA_Image *im); EAPI RGBA_Image *evas_common_image_alpha_line_buffer_obtain (int len); EAPI void evas_common_image_alpha_line_buffer_release (RGBA_Image *im); EAPI void evas_common_image_alpha_line_buffer_free (RGBA_Image *im); /*done*/ -EAPI RGBA_Image *evas_common_load_image_from_file (const char *file, const char *key, RGBA_Image_Loadopts *lo); -EAPI void evas_common_load_image_data_from_file(RGBA_Image *im); -EAPI int evas_common_save_image_to_file (RGBA_Image *im, const char *file, const char *key, int quality, int compress); - - - +EAPI RGBA_Image *evas_common_load_image_from_file (const char *file, const char *key, RGBA_Image_Loadopts *lo); +EAPI int evas_common_save_image_to_file (RGBA_Image *im, const char *file, const char *key, int quality, int compress); /****/ EAPI void evas_common_rectangle_init (void); @@ -1115,7 +1222,47 @@ int evas_common_array_hash_search (Evas_Array_Hash *hash, int key); void evas_stringshare_init(void); void evas_stringshare_shutdown(void); - + +/****/ +Evas_Cache_Image* evas_cache_image_init(const Evas_Cache_Image_Func* cb); +void evas_cache_image_shutdown(Evas_Cache_Image* cache); +RGBA_Image* evas_cache_image_request(Evas_Cache_Image* cache, const char* file, const char* key, RGBA_Image_Loadopts* lo, int* error); +void evas_cache_image_drop(RGBA_Image* im); +int evas_cache_image_flush(Evas_Cache_Image* cache); + +int evas_cache_image_usage_get(Evas_Cache_Image* cache); +int evas_cache_image_get(Evas_Cache_Image* cache); +void evas_cache_image_set(Evas_Cache_Image* cache, int size); + +RGBA_Image* evas_cache_image_alone(RGBA_Image *im); +RGBA_Image* evas_cache_image_dirty(RGBA_Image* im, int x, int y, int w, int h); +void evas_cache_image_load_data(RGBA_Image* im); +RGBA_Image* evas_cache_image_copied_data(Evas_Cache_Image* cache, int w, int h, DATA32* image_data, int alpha, int cspace); +RGBA_Image* evas_cache_image_data(Evas_Cache_Image* cache, int w, int h, DATA32* image_data, int alpha, int cspace); +void evas_cache_image_colorspace(RGBA_Image* im, int cspace); +RGBA_Image* evas_cache_image_empty(Evas_Cache_Image* cache); + +RGBA_Image* evas_cache_image_size_set(RGBA_Image* im, int w, int h); +/****/ +Evas_Cache_Engine_Image* evas_cache_engine_image_init(const Evas_Cache_Engine_Image_Func *cb, Evas_Cache_Image *parent); +void evas_cache_engine_image_shutdown(Evas_Cache_Engine_Image* cache); + +int evas_cache_engine_image_usage_get(Evas_Cache_Engine_Image* cache); +int evas_cache_engine_image_get(Evas_Cache_Engine_Image* cache); +void evas_cache_engine_image_set(Evas_Cache_Engine_Image* cache, int limit); + +RGBA_Engine_Image* evas_cache_engine_image_request(Evas_Cache_Engine_Image *cache, const char *file, const char *key, + RGBA_Image_Loadopts *lo, void *engine_data, int *error); +RGBA_Engine_Image* evas_cache_engine_image_engine(Evas_Cache_Engine_Image *cache, void *engine_data); +void evas_cache_engine_image_drop(RGBA_Engine_Image *eim); +RGBA_Engine_Image* evas_cache_engine_image_dirty(RGBA_Engine_Image *eim, int x, int y, int w, int h); +RGBA_Engine_Image* evas_cache_engine_image_copied_data(Evas_Cache_Engine_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace, void* engine_data); +RGBA_Engine_Image* evas_cache_engine_image_data(Evas_Cache_Engine_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace, void* engine_data); +void evas_cache_engine_colorspace(RGBA_Engine_Image *eim, int cspace, void* engine_data); +RGBA_Engine_Image* evas_cache_engine_image_size_set(RGBA_Engine_Image *eim, int w, int h); + +void evas_cache_engine_image_load_data(RGBA_Engine_Image *eim); + /*****************************************************************************/ #ifdef __cplusplus diff --git a/legacy/evas/src/modules/engines/Makefile.am b/legacy/evas/src/modules/engines/Makefile.am index deaeee32af..cf1a6d3545 100644 --- a/legacy/evas/src/modules/engines/Makefile.am +++ b/legacy/evas/src/modules/engines/Makefile.am @@ -16,6 +16,7 @@ software_x11 \ software_xcb \ xrender_x11 \ xrender_xcb \ +software_sdl \ glitz_x11 \ software_16 \ software_16_x11 diff --git a/legacy/evas/src/modules/engines/buffer/evas_outbuf.c b/legacy/evas/src/modules/engines/buffer/evas_outbuf.c index 0318ce3a70..c97751d41f 100644 --- a/legacy/evas/src/modules/engines/buffer/evas_outbuf.c +++ b/legacy/evas/src/modules/engines/buffer/evas_outbuf.c @@ -12,7 +12,7 @@ evas_buffer_outbuf_buf_free(Outbuf *buf) { if (buf->priv.back_buf) { - evas_common_image_free(buf->priv.back_buf); + evas_common_image_delete(buf->priv.back_buf); } free(buf); } @@ -119,7 +119,7 @@ evas_buffer_outbuf_buf_new_region_for_update(Outbuf *buf, int x, int y, int w, i void evas_buffer_outbuf_buf_free_region_for_update(Outbuf *buf, RGBA_Image *update) { - if (update != buf->priv.back_buf) evas_common_image_free(update); + if (update != buf->priv.back_buf) evas_common_image_delete(update); } void @@ -263,7 +263,7 @@ evas_buffer_outbuf_buf_push_updated_region(Outbuf *buf, RGBA_Image *update, int { DATA32 *dest, *src, *dst; int yy, row_bytes; - + row_bytes = buf->dest_row_bytes; dest = (DATA8 *)(buf->dest) + (y * row_bytes) + (x * 4); if (buf->func.new_update_region) diff --git a/legacy/evas/src/modules/engines/fb/evas_outbuf.c b/legacy/evas/src/modules/engines/fb/evas_outbuf.c index f5b7c26cb8..fc50de6358 100644 --- a/legacy/evas/src/modules/engines/fb/evas_outbuf.c +++ b/legacy/evas/src/modules/engines/fb/evas_outbuf.c @@ -14,7 +14,7 @@ evas_fb_outbuf_fb_free(Outbuf *buf) /* FIXME: impliment */ printf("destroying fb info.. not implemented!!!! WARNING. LEAK!\n"); if (buf->priv.back_buf) - evas_common_image_free(buf->priv.back_buf); + evas_common_image_delete(buf->priv.back_buf); free(buf); } @@ -231,7 +231,7 @@ evas_fb_outbuf_fb_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, void evas_fb_outbuf_fb_free_region_for_update(Outbuf *buf, RGBA_Image *update) { - if (update != buf->priv.back_buf) evas_common_image_free(update); + if (update != buf->priv.back_buf) evas_common_image_delete(update); } void @@ -333,7 +333,7 @@ evas_fb_outbuf_fb_reconfigure(Outbuf *buf, int w, int h, int rot, Outbuf_Depth d return; if (buf->priv.back_buf) { - evas_common_image_free(buf->priv.back_buf); + evas_common_image_delete(buf->priv.back_buf); buf->priv.back_buf = NULL; } if (buf->priv.fb.fb) @@ -382,7 +382,7 @@ evas_fb_outbuf_fb_set_have_backbuf(Outbuf *buf, int have_backbuf) if (buf->priv.back_buf) { if (have_backbuf) return; - evas_common_image_free(buf->priv.back_buf); + evas_common_image_delete(buf->priv.back_buf); buf->priv.back_buf = NULL; } else diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c index 5ba1174049..e2df893c9d 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c @@ -15,7 +15,7 @@ evas_gl_common_image_load(Evas_GL_Context *gc, const char *file, const char *key im = l->data; if (im->im == im_im) { - evas_common_image_unref(im_im); + evas_cache_image_drop(im_im); gc->images = evas_list_remove_list(gc->images, l); gc->images = evas_list_prepend(gc->images, im); im->references++; @@ -63,19 +63,12 @@ evas_gl_common_image_new_from_data(Evas_GL_Context *gc, int w, int h, int *data, im = calloc(1, sizeof(Evas_GL_Image)); if (!im) return NULL; im->references = 1; - im->im = evas_common_image_new(); + im->im = evas_cache_image_empty(evas_common_image_cache_get()); if (!im->im) { free(im); return NULL; } - im->im->image = evas_common_image_surface_new(im->im); - if (!im->im->image) - { - evas_common_image_free(im->im); - free(im); - return NULL; - } im->gc = gc; im->im->image->w = w; im->im->image->h = h; @@ -117,12 +110,14 @@ evas_gl_common_image_new_from_copied_data(Evas_GL_Context *gc, int w, int h, int im = calloc(1, sizeof(Evas_GL_Image)); if (!im) return NULL; im->references = 1; - im->im = evas_common_image_create(w, h); + im->im = evas_cache_image_empty(evas_common_image_cache_get()); if (!im->im) { free(im); return NULL; } + im->im->image->w = w; + im->im->image->h = h; im->gc = gc; im->cs.space = cspace; if (alpha) @@ -132,13 +127,12 @@ evas_gl_common_image_new_from_copied_data(Evas_GL_Context *gc, int w, int h, int switch (cspace) { case EVAS_COLORSPACE_ARGB8888: + evas_common_image_surface_alloc(im->im->image); if (data) memcpy(im->im->image->data, data, w * h * sizeof(DATA32)); break; case EVAS_COLORSPACE_YCBCR422P601_PL: case EVAS_COLORSPACE_YCBCR422P709_PL: - evas_common_image_surface_dealloc(im->im->image); - im->im->image->data = NULL; if (im->tex) evas_gl_common_texture_free(im->tex); im->tex = NULL; im->cs.no_free = 0; @@ -161,12 +155,14 @@ evas_gl_common_image_new(Evas_GL_Context *gc, int w, int h, int alpha, int cspac im = calloc(1, sizeof(Evas_GL_Image)); if (!im) return NULL; im->references = 1; - im->im = evas_common_image_create(w, h); + im->im = evas_cache_image_empty(evas_common_image_cache_get()); if (!im->im) { free(im); return NULL; } + im->im->image->w = w; + im->im->image->h = h; im->gc = gc; im->cs.space = cspace; if (alpha) @@ -176,6 +172,7 @@ evas_gl_common_image_new(Evas_GL_Context *gc, int w, int h, int alpha, int cspac switch (cspace) { case EVAS_COLORSPACE_ARGB8888: + evas_common_image_surface_alloc(im->im->image); // if (data) // memcpy(im->im->image->data, data, w * h * sizeof(DATA32)); break; @@ -208,7 +205,7 @@ evas_gl_common_image_free(Evas_GL_Image *im) if (!im->cs.no_free) free(im->cs.data); } if (im->cached) im->gc->images = evas_list_remove(im->gc->images, im); - if (im->im) evas_common_image_unref(im->im); + if (im->im) evas_cache_image_drop(im->im); if (im->tex) evas_gl_common_texture_free(im->tex); free(im); } @@ -216,7 +213,7 @@ evas_gl_common_image_free(Evas_GL_Image *im) void evas_gl_common_image_dirty(Evas_GL_Image *im) { - evas_common_image_dirty(im->im); + im->im = evas_cache_image_dirty(im->im, 0, 0, im->im->image->w, im->im->image->h); im->dirty = 1; } @@ -242,11 +239,11 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy { r = g = b = a = 255; } - evas_common_load_image_data_from_file(im->im); /* leak in this switch */ switch (im->cs.space) { case EVAS_COLORSPACE_ARGB8888: + evas_cache_image_load_data(im->im); if ((im->tex) && (im->dirty)) { evas_gl_common_texture_update(im->tex, im->im, im->tex->smooth); diff --git a/legacy/evas/src/modules/engines/software_16/evas_soft16_main.c b/legacy/evas/src/modules/engines/software_16/evas_soft16_main.c index 7fdfa84ef0..20594c0431 100644 --- a/legacy/evas/src/modules/engines/software_16/evas_soft16_main.c +++ b/legacy/evas/src/modules/engines/software_16/evas_soft16_main.c @@ -163,7 +163,7 @@ soft16_image_load_new(const char *file, const char *key, _calc_stride(sim->image->w), have_alpha, 0); if (!im) { - evas_common_image_unref(sim); + evas_cache_image_drop(sim); return NULL; } @@ -263,7 +263,8 @@ soft16_image_load_data(Soft16_Image *im) if (!im->pixels) soft16_image_alloc_pixels(im); if (im->pixels) _soft16_image_rgba32_import(im, im->source_im->image->data); } - evas_common_image_unref(im->source_im); + done: + evas_cache_image_drop(im->source_im); im->source_im = NULL; } diff --git a/legacy/evas/src/modules/engines/software_generic/evas_engine.c b/legacy/evas/src/modules/engines/software_generic/evas_engine.c index 9a80fcb9e9..7bfc94c83a 100644 --- a/legacy/evas/src/modules/engines/software_generic/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_generic/evas_engine.c @@ -349,7 +349,7 @@ eng_image_alpha_get(void *data, void *image) static int eng_image_colorspace_get(void *data, void *image) { - RGBA_Image *im; + RGBA_Image *im; if (!image) return EVAS_COLORSPACE_ARGB8888; im = image; @@ -368,24 +368,9 @@ eng_image_alpha_set(void *data, void *image, int has_alpha) im->flags &= ~RGBA_IMAGE_HAS_ALPHA; return im; } - if (im->references > 1) - { - RGBA_Image *im_new; + im = evas_cache_image_alone(im); + evas_common_image_colorspace_dirty(im); - im_new = evas_common_image_create(im->image->w, im->image->h); - if (!im_new) return im; - evas_common_load_image_data_from_file(im); - evas_common_image_colorspace_normalize(im); - evas_common_blit_rectangle(im, im_new, 0, 0, im->image->w, im->image->h, 0, 0); - evas_common_cpu_end_opt(); - evas_common_image_unref(im); - im = im_new; - } - else - { - evas_common_image_dirty(im); - evas_common_image_colorspace_dirty(im); - } if (has_alpha) im->flags |= RGBA_IMAGE_HAS_ALPHA; else @@ -488,84 +473,19 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I static void * eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) { - RGBA_Image *im; - - im = evas_common_image_new(); - if (!im) return NULL; - im->image = evas_common_image_surface_new(im); - if (!im->image) - { - evas_common_image_free(im); - return NULL; - } - switch (cspace) - { - case EVAS_COLORSPACE_ARGB8888: - im->image->w = w; - im->image->h = h; - im->image->data = image_data; - im->image->no_free = 1; - if (alpha) - im->flags |= RGBA_IMAGE_HAS_ALPHA; - else - im->flags &= ~RGBA_IMAGE_HAS_ALPHA; - break; - case EVAS_COLORSPACE_YCBCR422P601_PL: - case EVAS_COLORSPACE_YCBCR422P709_PL: - w &= ~0x1; - im->image->w = w; - im->image->h = h; - evas_common_image_surface_alloc(im->image); - im->cs.data = image_data; - im->cs.no_free = 1; - break; - default: - abort(); - break; - } - im->cs.space = cspace; - evas_common_image_colorspace_dirty(im); - return im; + return evas_cache_image_data(evas_common_image_cache_get(), w, h, image_data, alpha, cspace); } static void * eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) { - RGBA_Image *im; - - switch (cspace) - { - case EVAS_COLORSPACE_ARGB8888: - im = evas_common_image_create(w, h); - if (!im) return NULL; - if (alpha) - im->flags |= RGBA_IMAGE_HAS_ALPHA; - else - im->flags &= ~RGBA_IMAGE_HAS_ALPHA; - if (image_data) - memcpy(im->image->data, image_data, w * h * sizeof(DATA32)); - break; - case EVAS_COLORSPACE_YCBCR422P601_PL: - case EVAS_COLORSPACE_YCBCR422P709_PL: - w &= ~0x1; - im = evas_common_image_create(w, h); - im->cs.data = calloc(1, im->image->h * sizeof(unsigned char *) * 2); - if ((image_data) && (im->cs.data)) - memcpy(im->cs.data, image_data, im->image->h * sizeof(unsigned char *) * 2); - break; - default: - abort(); - break; - } - im->cs.space = cspace; - evas_common_image_colorspace_dirty(im); - return im; + return evas_cache_image_copied_data(evas_common_image_cache_get(), w, h, image_data, alpha, cspace); } static void eng_image_free(void *data, void *image) { - evas_common_image_unref(image); + evas_cache_image_drop(image); } static void @@ -581,46 +501,20 @@ eng_image_size_get(void *data, void *image, int *w, int *h) static void * eng_image_size_set(void *data, void *image, int w, int h) { - RGBA_Image *im, *im_old; + RGBA_Image *im; - im_old = image; - if ((im_old->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) || - (im_old->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL)) - w &= ~0x1; - if ((im_old) && (im_old->image->w == w) && (im_old->image->h == h)) - return image; - im = evas_common_image_create(w, h); - if (!im) return im_old; - if (im_old) - { - im->cs.space = im_old->cs.space; - im->flags = im_old->flags; - im->cs.no_free = 0; - if ((im_old->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) || - (im_old->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL)) - im->cs.data = calloc(1, im->image->h * sizeof(unsigned char *) * 2); - /* - evas_common_load_image_data_from_file(im_old); - evas_common_image_colorspace_normalize(im); - if (im_old->image->data) - { - evas_common_blit_rectangle(im_old, im, 0, 0, w, h, 0, 0); - evas_common_cpu_end_opt(); - } - */ - evas_common_image_unref(im_old); - evas_common_image_colorspace_dirty(im); - } - return im; + im = image; + return evas_cache_image_size_set(image, w, h); } static void * eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h) { + RGBA_Image* im = image; + if (!image) return NULL; - evas_common_image_dirty(image); - evas_common_image_colorspace_dirty(image); - return image; + im = evas_cache_image_dirty(im, x, y, w, h); + return im; } static void * @@ -639,22 +533,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data) { case EVAS_COLORSPACE_ARGB8888: if (to_write) - { - if (im->references > 1) - { - RGBA_Image *im_new; - - im_new = evas_common_image_create(im->image->w, im->image->h); - if (!im_new) return im; - evas_common_image_colorspace_normalize(im); - evas_common_blit_rectangle(im, im_new, 0, 0, im->image->w, im->image->h, 0, 0); - evas_common_cpu_end_opt(); - evas_common_image_unref(im); - im = im_new; - } - else - evas_common_image_dirty(im); - } + im = evas_cache_image_alone(im); *image_data = im->image->data; break; case EVAS_COLORSPACE_YCBCR422P601_PL: @@ -681,13 +560,13 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data) if (image_data != im->image->data) { int w, h; - + w = im->image->w; h = im->image->h; im2 = eng_image_new_from_data(data, w, h, image_data, eng_image_alpha_get(data, image), eng_image_colorspace_get(data, image)); - evas_common_image_unref(im); + evas_cache_image_drop(im); im = im2; } break; @@ -714,7 +593,7 @@ static void eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth) { RGBA_Image *im; - + if (!image) return; im = image; if (im->cs.space == EVAS_COLORSPACE_ARGB8888) diff --git a/legacy/evas/src/modules/engines/software_sdl/.cvsignore b/legacy/evas/src/modules/engines/software_sdl/.cvsignore new file mode 100644 index 0000000000..a51c9665e0 --- /dev/null +++ b/legacy/evas/src/modules/engines/software_sdl/.cvsignore @@ -0,0 +1,6 @@ +.deps +.libs +Makefile +Makefile.in +*.lo +*.la \ No newline at end of file diff --git a/legacy/evas/src/modules/engines/software_sdl/Evas_Engine_SDL.h b/legacy/evas/src/modules/engines/software_sdl/Evas_Engine_SDL.h new file mode 100644 index 0000000000..86260c43a5 --- /dev/null +++ b/legacy/evas/src/modules/engines/software_sdl/Evas_Engine_SDL.h @@ -0,0 +1,24 @@ +#ifndef _EVAS_ENGINE_SDL_H +#define _EVAS_ENGINE_SDL_H + +#include + +typedef struct _Evas_Engine_Info_SDL Evas_Engine_Info_SDL; + +struct _Evas_Engine_Info_SDL +{ + /* PRIVATE - don't mess with this baby or evas will poke its tongue out */ + /* at you and make nasty noises */ + Evas_Engine_Info magic; + + struct { + SDL_Surface *surface; + int fullscreen : 1; + int hwsurface : 1; + int noframe : 1; + int alpha : 1; + } info; +}; +#endif + + diff --git a/legacy/evas/src/modules/engines/software_sdl/Makefile.am b/legacy/evas/src/modules/engines/software_sdl/Makefile.am new file mode 100644 index 0000000000..9a93cb0955 --- /dev/null +++ b/legacy/evas/src/modules/engines/software_sdl/Makefile.am @@ -0,0 +1,28 @@ +AUTOMAKE_OPTIONS = 1.4 foreign + +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = -I. -I$(top_srcdir)/src/lib -I$(top_srcdir)/src/lib/include @FREETYPE_CFLAGS@ @sdl_cflags@ + +if BUILD_ENGINE_SDL + +pkgdir = $(libdir)/evas/modules/engines/software_sdl/$(MODULE_ARCH) + +pkg_LTLIBRARIES = module.la + +module_la_SOURCES = \ +evas_engine_sdl.c \ +evas_engine_sdl.h + +module_la_LIBADD = @sdl_libs@ $(top_builddir)/src/lib/libevas.la +module_la_LDFLAGS = -module -avoid-version -L$(top_builddir)/src/lib -L$(top_builddir)/src/lib/.libs +module_la_DEPENDENCIES = $(top_builddir)/config.h + +include_HEADERS = Evas_Engine_SDL.h + +endif + +EXTRA_DIST = \ +evas_engine_sdl.c \ +evas_engine_sdl.h \ +Evas_Engine_SDL.h diff --git a/legacy/evas/src/modules/engines/software_sdl/evas_engine_sdl.c b/legacy/evas/src/modules/engines/software_sdl/evas_engine_sdl.c new file mode 100644 index 0000000000..5a5727bf16 --- /dev/null +++ b/legacy/evas/src/modules/engines/software_sdl/evas_engine_sdl.c @@ -0,0 +1,1006 @@ +#include +#include +#include +#include +#include +#include + +#include "evas_engine_sdl.h" + +/* #define DEBUG_SDL */ + +extern Evas_List* evas_modules; + +static Evas_Func func = {}; +static Evas_Func pfunc = {}; + +static void* _sdl_output_setup (int w, int h, int fullscreen, int noframe, int alpha, int hwsurface); +static void _sdl_stretch_blit (const RGBA_Engine_Image* from, RGBA_Engine_Image* to, int w, int h); + +static int _sdl_image_constructor (RGBA_Engine_Image*, void* data); +static void _sdl_image_destructor (RGBA_Engine_Image *eim); + +static void _sdl_image_dirty_region (RGBA_Engine_Image *eim, int x, int y, int w, int h); + +static int _sdl_image_dirty (RGBA_Engine_Image *dst, const RGBA_Engine_Image *src); + +static int _sdl_image_size_set (RGBA_Engine_Image *dst, const RGBA_Engine_Image *src); + +static int _sdl_image_update_data (RGBA_Engine_Image* dst, void* engine_data); + +static void _sdl_image_load (RGBA_Engine_Image *eim, const RGBA_Image* im); +static int _sdl_image_mem_size_get (RGBA_Engine_Image *eim); + +#ifdef DEBUG_SDL +static void _sdl_image_debug(const char* context, RGBA_Engine_Image* im); +#endif + +static const Evas_Cache_Engine_Image_Func _sdl_cache_engine_image_cb = { + .key = NULL, + .constructor = _sdl_image_constructor, + .destructor = _sdl_image_destructor, + .dirty_region = _sdl_image_dirty_region, + .dirty = _sdl_image_dirty, + .size_set = _sdl_image_size_set, + .update_data = _sdl_image_update_data, + .load = _sdl_image_load, + .mem_size_get = _sdl_image_mem_size_get, +#ifdef DEBUG_SDL + .debug = _sdl_image_debug +#else + .debug = NULL +#endif +}; + +#define _SDL_UPDATE_PIXELS(EIM) ; +/* EIM->src->image->data = ((SDL_Surface*) EIM->engine_data)->pixels; */ + +#define RMASK 0x00ff0000 +#define GMASK 0x0000ff00 +#define BMASK 0x000000ff +#define AMASK 0xff000000 + +/* SDL engine info function */ +static void* +evas_engine_sdl_info (Evas* e) +{ + Evas_Engine_Info_SDL* info = calloc(1, sizeof (Evas_Engine_Info_SDL)); + + if (!info) + return NULL; + + info->magic.magic = rand(); + + return info; +} + +static void +evas_engine_sdl_info_free (Evas* e, void* info) +{ + Evas_Engine_Info_SDL* in = (Evas_Engine_Info_SDL*) info; + + free(in); + in = NULL; +} + +/* SDL engine output manipulation function */ +static void +evas_engine_sdl_setup (Evas* e, void* in) +{ + Evas_Engine_Info_SDL* info = (Evas_Engine_Info_SDL*) in; + + /* if we arent set to sdl, why the hell do we get called?! */ + if (evas_output_method_get(e) != evas_render_method_lookup("software_sdl")) + return ; + + SDL_Init(SDL_INIT_NOPARACHUTE); + + if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) + { + fprintf(stderr, "SDL_Init failed with %s\n", SDL_GetError()); + exit(-1); + } + + /* lets just set up */ + e->engine.data.output = _sdl_output_setup(e->output.w, e->output.h, + info->info.fullscreen, + info->info.noframe, + info->info.alpha, + info->info.hwsurface); + + if (!e->engine.data.output) + return; + + e->engine.func = &func; + e->engine.data.context = e->engine.func->context_new(e->engine.data.output); + info->info.surface = ((Render_Engine*) e->engine.data.output)->surface; +} + +static void +evas_engine_sdl_output_free (void *data) +{ + Render_Engine* re = (Render_Engine*) data; + + if (re->cache) + evas_cache_engine_image_shutdown(re->cache); + + evas_common_tilebuf_free(re->tb); + if (re->rects) + evas_common_tilebuf_free_render_rects(re->rects); + + if (re->update_rects) + free(re->update_rects); + memset(re, sizeof (Render_Engine), 0); + free(re); + + evas_common_font_shutdown(); + evas_common_image_shutdown(); + + SDL_QuitSubSystem(SDL_INIT_VIDEO); +} + +static void +evas_engine_sdl_output_resize (void *data, int w, int h) +{ + /* FIXME */ + Render_Engine* re = (Render_Engine*) data; + RGBA_Engine_Image* eim = NULL; + + if (w == re->tb->outbuf_w && h == re->tb->outbuf_h) + return; + + eim = re->rgba_engine_image; + + /* Rebuil tilebuf */ + evas_common_tilebuf_free(re->tb); + re->tb = evas_common_tilebuf_new(w, h); + if (re->tb) + evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + + /* Build the new screen */ + re->surface = SDL_SetVideoMode(w, h, 32, + (re->hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE) + | (re->fullscreen ? SDL_FULLSCREEN : 0) + | (re->noframe ? SDL_NOFRAME : 0) + | (re->alpha ? SDL_SRCALPHA : 0)); + + if (!re->surface) + { + fprintf(stderr, "Unable to change the resolution to : %ix%i\n", w, h); + exit(-1); + } + re->rgba_engine_image = evas_cache_engine_image_engine(re->cache, re->surface); + if (!re->rgba_engine_image) + { + fprintf(stderr, "RGBA_Image allocation from SDL failed\n"); + exit(-1); + } + + /* Destroy the copy */ + evas_cache_engine_image_drop(eim); +} + +static void +evas_engine_sdl_output_tile_size_set (void *data, int w, int h) +{ + Render_Engine* re = (Render_Engine*) data; + + evas_common_tilebuf_set_tile_size(re->tb, w, h); +} + +static void +evas_engine_sdl_output_redraws_rect_add (void *data, int x, int y, int w, int h) +{ + Render_Engine* re = (Render_Engine*) data; + + evas_common_tilebuf_add_redraw(re->tb, x, y, w, h); +} + +static void +evas_engine_sdl_output_redraws_rect_del (void *data, int x, int y, int w, int h) +{ + Render_Engine* re = (Render_Engine*) data; + + evas_common_tilebuf_del_redraw(re->tb, x, y, w, h); +} + +static void +evas_engine_sdl_output_redraws_clear (void *data) +{ + Render_Engine* re = (Render_Engine*) data; + + evas_common_tilebuf_clear(re->tb); +} + +static void* +evas_engine_sdl_output_redraws_next_update_get (void *data, + int *x, int *y, int *w, int *h, + int *cx, int *cy, int *cw, int *ch) +{ + Render_Engine* re = (Render_Engine*) data; + Tilebuf_Rect* tb_rect = NULL; + + if (re->end) + { + re->end = 0; + return NULL; + } + if (!re->rects) + { + re->rects = evas_common_tilebuf_get_render_rects(re->tb); + re->cur_rect = (Evas_Object_List *) re->rects; + } + if (!re->cur_rect) + return NULL; + + tb_rect = (Tilebuf_Rect*) re->cur_rect; + *cx = *x = tb_rect->x; + *cy = *y = tb_rect->y; + *cw = *w = tb_rect->w; + *ch = *h = tb_rect->h; + re->cur_rect = re->cur_rect->next; + if (!re->cur_rect) + { + evas_common_tilebuf_free_render_rects(re->rects); + re->rects = NULL; + re->end = 1; + } + + /* Return the "fake" surface so it is passed to the drawing routines. */ + return re->rgba_engine_image; +} + +static void +evas_engine_sdl_output_redraws_next_update_push (void *data, void *surface, + int x, int y, int w, int h) +{ + Render_Engine *re = (Render_Engine *) data; + + if (re->update_rects_count + 1 > re->update_rects_limit) + { + re->update_rects_limit += 8; + re->update_rects = realloc(re->update_rects, sizeof (SDL_Rect) * re->update_rects_limit); + } + + re->update_rects[re->update_rects_count].x = x; + re->update_rects[re->update_rects_count].y = y; + re->update_rects[re->update_rects_count].w = w; + re->update_rects[re->update_rects_count].h = h; + + ++re->update_rects_count; + + evas_common_cpu_end_opt(); +} + +static void +_sdl_image_dirty_region(RGBA_Engine_Image *eim, int x, int y, int w, int h) +{ + SDL_UpdateRect((SDL_Surface*) eim->engine_data, x, y, w, h); +} + +static void +evas_engine_sdl_output_flush (void *data) +{ + Render_Engine *re = (Render_Engine *) data; + + if (re->update_rects_count > 0) + SDL_UpdateRects(re->surface, re->update_rects_count, re->update_rects); + + re->update_rects_count = 0; +} + + +static void +evas_engine_sdl_output_idle_flush (void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; +} + +/* + * Image objects + */ + +static void* +evas_engine_sdl_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo) +{ + Render_Engine* re = (Render_Engine*) data;; + + *error = 0; + return evas_cache_engine_image_request(re->cache, file, key, lo, NULL, error); +} + +static int +evas_engine_sdl_image_alpha_get(void *data, void *image) +{ + RGBA_Engine_Image *eim = image; + + if (!eim) return 1; + switch (eim->src->cs.space) + { + case EVAS_COLORSPACE_ARGB8888: + if (eim->src->flags & RGBA_IMAGE_HAS_ALPHA) return 1; + default: + break; + } + return 0; +} + +static void +evas_engine_sdl_image_size_get(void *data, void *image, int *w, int *h) +{ + RGBA_Engine_Image* eim; + + eim = image; + if (w) *w = eim->src->image->w; + if (h) *h = eim->src->image->h; +} + +static int +evas_engine_sdl_image_colorspace_get(void *data, void *image) +{ + RGBA_Engine_Image *eim = image; + + if (!eim) return EVAS_COLORSPACE_ARGB8888; + return eim->src->cs.space; +} + +static void +evas_engine_sdl_image_colorspace_set(void *data, void *image, int cspace) +{ + RGBA_Engine_Image *eim = (RGBA_Engine_Image*) image; + + if (!eim) return; + if (eim->src->cs.space == cspace) return; + + evas_cache_engine_colorspace(eim, cspace, NULL); +} + +static void* +evas_engine_sdl_image_new_from_copied_data(void *data, + int w, int h, + DATA32* image_data, + int alpha, int cspace) +{ + Render_Engine *re = (Render_Engine*) data; + + return evas_cache_engine_image_copied_data(re->cache, w, h, image_data, alpha, cspace, NULL); +} + +static void* +evas_engine_sdl_image_new_from_data(void *data, int w, int h, DATA32* image_data, int alpha, int cspace) +{ + Render_Engine *re = (Render_Engine*) data; + + return evas_cache_engine_image_data(re->cache, w, h, image_data, alpha, cspace, NULL); +} + +static void +evas_engine_sdl_image_free(void *data, void *image) +{ + RGBA_Engine_Image* eim = (RGBA_Engine_Image*) image; + + (void) data; + + evas_cache_engine_image_drop(eim); +} + +static void* +evas_engine_sdl_image_size_set(void *data, void *image, int w, int h) +{ + RGBA_Engine_Image* eim = (RGBA_Engine_Image*) image; + + (void) data; + + return evas_cache_engine_image_size_set(eim, w, h); +} + +void* +evas_engine_sdl_image_dirty_region(void *data, + void *image, + int x, int y, int w, int h) +{ + RGBA_Engine_Image* eim = (RGBA_Engine_Image*) image; + + (void) data; + + return evas_cache_engine_image_dirty(eim, x, y, w, h); +} + +void* +evas_engine_sdl_image_data_get(void *data, void *image, + int to_write, DATA32** image_data) +{ + RGBA_Engine_Image* eim = (RGBA_Engine_Image*) image; + + (void) data; + + if (!eim) + { + *image_data = NULL; + return NULL; + } + + switch (eim->src->cs.space) + { + case EVAS_COLORSPACE_ARGB8888: + if (to_write) + eim = evas_cache_engine_image_dirty(eim, 0, 0, eim->src->image->w, eim->src->image->h); + + evas_cache_engine_image_load_data(eim); + *image_data = eim->src->image->data; + break; + case EVAS_COLORSPACE_YCBCR422P709_PL: + case EVAS_COLORSPACE_YCBCR422P601_PL: + *image_data = eim->src->cs.data; + break; + default: + abort(); + break; + } + return eim; +} + +void* +evas_engine_sdl_image_data_put(void *data, void *image, DATA32* image_data) +{ + Render_Engine* re = (Render_Engine*) data; + RGBA_Engine_Image* eim = (RGBA_Engine_Image*) image; + + if (!eim) return NULL; + + switch (eim->src->cs.space) + { + case EVAS_COLORSPACE_ARGB8888: + if (image_data != eim->src->image->data) + { + evas_cache_engine_image_drop(eim); + eim = evas_cache_engine_image_data(re->cache, + eim->src->image->w, eim->src->image->h, + image_data, + func.image_alpha_get(data, eim), + func.image_colorspace_get(data, eim), + NULL); + } + break; + case EVAS_COLORSPACE_YCBCR422P601_PL: + case EVAS_COLORSPACE_YCBCR422P709_PL: + if (image_data != eim->src->cs.data) + { + if (eim->src->cs.data) + if (!eim->src->cs.no_free) + free(eim->src->cs.data); + eim->src->cs.data = image_data; + evas_common_image_colorspace_dirty(eim->src); + } + break; + default: + abort(); + break; + } + return eim; +} + +void* +evas_engine_sdl_image_alpha_set(void *data, void *image, int has_alpha) +{ + RGBA_Engine_Image* eim = (RGBA_Engine_Image*) image; + + (void) data; + + if (!eim) return NULL; + if (eim->src->cs.space != EVAS_COLORSPACE_ARGB8888) + { + eim->src->flags &= ~RGBA_IMAGE_HAS_ALPHA; + return eim; + } + + eim = evas_cache_engine_image_dirty(eim, 0, 0, eim->src->image->w, eim->src->image->h); + + /* FIXME: update SDL_Surface flags */ + if (has_alpha) + eim->src->flags |= RGBA_IMAGE_HAS_ALPHA; + else + eim->src->flags &= ~RGBA_IMAGE_HAS_ALPHA; + return eim; +} + +void* +evas_engine_sdl_image_border_set(void *data, void *image, int l, int r, int t, int b) +{ + return image; +} + +void +evas_engine_sdl_image_border_get(void *data, void *image, int *l, int *r, int *t, int *b) +{ + /* FIXME: need to know what evas expect from this call */ +} + +void +evas_engine_sdl_image_draw(void *data, void *context, void *surface, void *image, + int src_region_x, int src_region_y, int src_region_w, int src_region_h, + int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h, + int smooth) +{ + Render_Engine* re = data; + RGBA_Engine_Image* eim = (RGBA_Engine_Image*) image; + RGBA_Engine_Image* dst = (RGBA_Engine_Image*) surface; + RGBA_Draw_Context* dc = (RGBA_Draw_Context*) context; + int mustlock_im = 0; + int mustlock_dst = 0; + + (void) data; + + if (eim->src->cs.space == EVAS_COLORSPACE_ARGB8888) + evas_cache_engine_image_load_data(eim); + + /* Fallback to software method */ + if (SDL_MUSTLOCK(((SDL_Surface*) dst->engine_data))) + { + mustlock_dst = 1; + SDL_LockSurface(dst->engine_data); + _SDL_UPDATE_PIXELS(dst); + } + + if (eim->engine_data && SDL_MUSTLOCK(((SDL_Surface*) eim->engine_data))) + { + mustlock_im = 1; + SDL_LockSurface(eim->engine_data); + _SDL_UPDATE_PIXELS(eim); + } + + evas_common_image_colorspace_normalize(eim->src); + + if (smooth) + evas_common_scale_rgba_in_to_out_clip_smooth(eim->src, dst->src, dc, + src_region_x, src_region_y, src_region_w, src_region_h, + dst_region_x, dst_region_y, dst_region_w, dst_region_h); + else + evas_common_scale_rgba_in_to_out_clip_sample(eim->src, dst->src, dc, + src_region_x, src_region_y, src_region_w, src_region_h, + dst_region_x, dst_region_y, dst_region_w, dst_region_h); + evas_common_cpu_end_opt (); + + if (mustlock_im) + SDL_UnlockSurface(eim->engine_data); + + if (mustlock_dst) + SDL_UnlockSurface(dst->engine_data); +} + +void +evas_engine_sdl_image_cache_flush(void *data) +{ + Render_Engine* re = (Render_Engine*) data; + int size; + + size = evas_cache_engine_image_get(re->cache); + evas_cache_engine_image_set(re->cache, 0); + evas_cache_engine_image_set(re->cache, size); +} + +void +evas_engine_sdl_image_cache_set(void *data, int bytes) +{ + Render_Engine* re = (Render_Engine*) data; + + evas_cache_engine_image_set(re->cache, bytes); +} + +int +evas_engine_sdl_image_cache_get(void *data) +{ + Render_Engine* re = (Render_Engine*) data; + + return evas_cache_engine_image_get(re->cache); +} + +char* +evas_engine_sdl_image_comment_get(void *data, void *image, char *key) +{ + RGBA_Engine_Image *eim = (RGBA_Engine_Image*) image; + + return eim->src->info.comment; +} + +char* +evas_engine_sdl_image_format_get(void *data, void *image) +{ + /* FIXME: need to know what evas expect from this call */ + return NULL; +} + +static void +evas_engine_sdl_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text) +{ + RGBA_Engine_Image* eim = (RGBA_Engine_Image*) surface; + int mustlock_im = 0; + + if (eim->engine_data && SDL_MUSTLOCK(((SDL_Surface*) eim->engine_data))) + { + mustlock_im = 1; + SDL_LockSurface(eim->engine_data); + _SDL_UPDATE_PIXELS(eim); + } + + evas_common_font_draw(eim->src, context, font, x, y, text); + evas_common_cpu_end_opt(); + + if (mustlock_im) + SDL_UnlockSurface(eim->engine_data); +} + +static void +evas_engine_sdl_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2) +{ + RGBA_Engine_Image* eim = (RGBA_Engine_Image*) surface; + int mustlock_im = 0; + + if (eim->engine_data && SDL_MUSTLOCK(((SDL_Surface*) eim->engine_data))) + { + mustlock_im = 1; + SDL_LockSurface(eim->engine_data); + _SDL_UPDATE_PIXELS(eim); + } + + evas_common_line_draw(eim->src, context, x1, y1, x2, y2); + evas_common_cpu_end_opt(); + + if (mustlock_im) + SDL_UnlockSurface(eim->engine_data); +} + +static void +evas_engine_sdl_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h) +{ + RGBA_Engine_Image* eim = (RGBA_Engine_Image*) surface; + int mustlock_im = 0; + + if (eim->engine_data && SDL_MUSTLOCK(((SDL_Surface*) eim->engine_data))) + { + mustlock_im = 1; + SDL_LockSurface(eim->engine_data); + _SDL_UPDATE_PIXELS(eim); + } + + evas_common_rectangle_draw(eim->src, context, x, y, w, h); + evas_common_cpu_end_opt(); + + if (mustlock_im) + SDL_UnlockSurface(eim->engine_data); +} + +static void +evas_engine_sdl_polygon_draw(void *data, void *context, void *surface, void *polygon) +{ + RGBA_Engine_Image* eim = (RGBA_Engine_Image*) surface; + int mustlock_im = 0; + + if (eim->engine_data && SDL_MUSTLOCK(((SDL_Surface*) eim->engine_data))) + { + mustlock_im = 1; + SDL_LockSurface(eim->engine_data); + _SDL_UPDATE_PIXELS(eim); + } + + evas_common_polygon_draw(eim->src, context, polygon); + evas_common_cpu_end_opt(); + + if (mustlock_im) + SDL_UnlockSurface(eim->engine_data); +} + +static void +evas_engine_sdl_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h) +{ + RGBA_Engine_Image* eim = (RGBA_Engine_Image*) surface; + int mustlock_im = 0; + + if (eim->engine_data && SDL_MUSTLOCK(((SDL_Surface*) eim->engine_data))) + { + mustlock_im = 1; + SDL_LockSurface(eim->engine_data); + _SDL_UPDATE_PIXELS(eim); + } + + evas_common_gradient_draw(eim->src, context, x, y, w, h, gradient); + evas_common_cpu_end_opt(); + + if (mustlock_im) + SDL_UnlockSurface(eim->engine_data); +} + +EAPI int module_open(Evas_Module *em) +{ + if (!em) return 0; + /* get whatever engine module we inherit from */ + if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0; + /* store it for later use */ + func = pfunc; + /* now to override methods */ +#define ORD(f) EVAS_API_OVERRIDE(f, &func, evas_engine_sdl_) + ORD(info); + ORD(info_free); + ORD(setup); + ORD(output_free); + ORD(output_resize); + ORD(output_tile_size_set); + ORD(output_redraws_rect_add); + ORD(output_redraws_rect_del); + ORD(output_redraws_clear); + ORD(output_redraws_next_update_get); + ORD(output_redraws_next_update_push); + ORD(output_flush); + ORD(output_idle_flush); + ORD(image_load); + ORD(image_new_from_data); + ORD(image_new_from_copied_data); + ORD(image_colorspace_set); + ORD(image_colorspace_get); + ORD(image_free); + ORD(image_size_set); + ORD(image_size_get); + ORD(image_dirty_region); + ORD(image_data_get); + ORD(image_data_put); + ORD(image_alpha_set); + ORD(image_alpha_get); + ORD(image_border_set); + ORD(image_border_get); + ORD(image_draw); + ORD(image_comment_get); + ORD(image_format_get); + ORD(image_cache_flush); + ORD(image_cache_set); + ORD(image_cache_get); + ORD(font_draw); + ORD(line_draw); + ORD(rectangle_draw); + ORD(polygon_draw); + ORD(gradient_draw); + /* now advertise out own api */ + em->functions = (void *)(&func); + return 1; +} + +EAPI void module_close(void) +{ + +} + +EAPI Evas_Module_Api evas_modapi = +{ + EVAS_MODULE_API_VERSION, + EVAS_MODULE_TYPE_ENGINE, + "software_sdl", + "none" +}; + +/* Private routines. */ + +static void* +_sdl_output_setup (int w, int h, int fullscreen, int noframe, int alpha, int hwsurface) +{ + Render_Engine *re = calloc(1, sizeof(Render_Engine)); + + /* if we haven't initialized - init (automatic abort if already done) */ + evas_common_cpu_init(); + evas_common_blend_init(); + evas_common_image_init(); + evas_common_convert_init(); + evas_common_scale_init(); + evas_common_rectangle_init(); + evas_common_gradient_init(); + evas_common_polygon_init(); + evas_common_line_init(); + evas_common_font_init(); + evas_common_draw_init(); + evas_common_tilebuf_init(); + + re->cache = evas_cache_engine_image_init(&_sdl_cache_engine_image_cb, evas_common_image_cache_get()); + if (!re->cache) + { + fprintf(stderr, "Evas_Cache_Engine_Image allocation failed!\n"); + exit(-1); + } + + re->tb = evas_common_tilebuf_new(w, h); + /* in preliminary tests 16x16 gave highest framerates */ + evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + re->surface = SDL_SetVideoMode(w, h, 32, + (hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE) + | (fullscreen ? SDL_FULLSCREEN : 0) + | (noframe ? SDL_NOFRAME : 0) + | (alpha ? SDL_SRCALPHA : 0)); + + if (!re->surface) + return NULL; + + SDL_SetAlpha(re->surface, SDL_SRCALPHA | SDL_RLEACCEL, 0); + + /* We create a "fake" RGBA_Image which points to the SDL surface. Each access + * to that surface is wrapped in Lock / Unlock calls whenever the data is + * manipulated directly. */ + re->rgba_engine_image = evas_cache_engine_image_engine(re->cache, re->surface); + if (!re->rgba_engine_image) + { + fprintf(stderr, "RGBA_Image allocation from SDL failed\n"); + exit(-1); + } + + re->alpha = alpha; + re->hwsurface = hwsurface; + re->fullscreen = fullscreen; + re->noframe = noframe; + return re; +} + +static void +_sdl_stretch_blit (const RGBA_Engine_Image* from, + RGBA_Engine_Image* to, + int w, int h) +{ + int mustlock_from = 0; + int mustlock_to = 0; + + if (from->engine_data) + if (SDL_MUSTLOCK(((SDL_Surface*) from->engine_data))) + mustlock_from = 1; + + if (to->engine_data) + if (SDL_MUSTLOCK(((SDL_Surface*) to->engine_data))) + mustlock_to = 1; + + if (mustlock_from) + { + SDL_LockSurface(from->engine_data); + _SDL_UPDATE_PIXELS(from); + } + + if (mustlock_to) + { + SDL_LockSurface(to->engine_data); + _SDL_UPDATE_PIXELS(to); + } + + evas_common_blit_rectangle(from->src, to->src, 0, 0, w, h, 0, 0); + + if (mustlock_to) + SDL_UnlockSurface(to->engine_data); + + if (mustlock_from) + SDL_UnlockSurface(from->engine_data); + + evas_common_cpu_end_opt(); +} + +static int +_sdl_image_constructor(RGBA_Engine_Image* eim, void* data) +{ + SDL_Surface *sdl = NULL; + + if (eim->src->image->data) + { + /* FIXME: Take care of CSPACE */ + sdl = SDL_CreateRGBSurfaceFrom(eim->src->image->data, + eim->src->image->w, eim->src->image->h, + 32, eim->src->image->w * 4, + RMASK, GMASK, BMASK, AMASK); + eim->engine_data = sdl; + } + + return 0; +} + +static void +_sdl_image_destructor(RGBA_Engine_Image *eim) +{ + if (eim->engine_data) + SDL_FreeSurface(eim->engine_data); + eim->engine_data = NULL; +} + +static int +_sdl_image_dirty(RGBA_Engine_Image *dst, const RGBA_Engine_Image *src) +{ + SDL_Surface *sdl = NULL; + + /* FIXME: Take care of CSPACE */ + sdl = SDL_CreateRGBSurfaceFrom(dst->src->image->data, + dst->src->image->w, dst->src->image->h, + 32, dst->src->image->w * 4, + 0xff0000, 0xff00, 0xff, 0xff000000); + dst->engine_data = sdl; + + return 0; +} + +static int +_sdl_image_update_data(RGBA_Engine_Image *dst, void* engine_data) +{ + SDL_Surface *sdl = NULL; + + if (engine_data) + { + sdl = engine_data; + + dst->src->image->data = sdl->pixels; + dst->src->image->no_free = 1; + dst->src->image->w = sdl->w; + dst->src->image->h = sdl->h; + dst->src->flags |= RGBA_IMAGE_HAS_ALPHA; + } + else + /* FIXME: Take care of CSPACE */ + sdl = SDL_CreateRGBSurfaceFrom(dst->src->image->data, + dst->src->image->w, dst->src->image->h, + 32, dst->src->image->w * 4, + RMASK, GMASK, BMASK, AMASK); + + dst->engine_data = sdl; + + return 0; +} + +static int +_sdl_image_size_set(RGBA_Engine_Image *dst, const RGBA_Engine_Image *src) +{ + SDL_Surface* sdl; + + sdl = SDL_CreateRGBSurfaceFrom(dst->src->image->data, + dst->src->image->w, dst->src->image->h, + 32, dst->src->image->w * 4, + RMASK, GMASK, BMASK, AMASK); + + dst->engine_data = sdl; + +/* _sdl_stretch_blit(src, dst, dst->src->image->w, dst->src->image->h); */ + + return 0; +} + +static void +_sdl_image_load(RGBA_Engine_Image *eim, const RGBA_Image *im) +{ + SDL_Surface* sdl; + + if (!eim->engine_data) + { + sdl = SDL_CreateRGBSurfaceFrom(eim->src->image->data, + eim->src->image->w, eim->src->image->h, + 32, eim->src->image->w * 4, + RMASK, GMASK, BMASK, AMASK); + eim->engine_data = sdl; + } +} + +static int +_sdl_image_mem_size_get(RGBA_Engine_Image *eim) +{ + int size = 0; + + if (eim->engine_data) + size = sizeof (SDL_Surface) + sizeof (SDL_PixelFormat) + (eim->src ? evas_common_image_ram_usage(eim->src) : 0); + + return size; +} + +#ifdef DEBUG_SDL +static void +_sdl_image_debug(const char* context, RGBA_Engine_Image* eim) +{ + printf ("*** %s image (%p) ***\n", context, eim); + if (eim) + { + printf ("* W: %i\n* H: %i\n", eim->src->image->w, eim->src->image->h); + printf ("* Pixels: %p\n* SDL Surface: %p\n", eim->src->image->data, eim->engine_data); + printf ("* Surface->pixels: %p\n", ((SDL_Surface*) eim->engine_data)->pixels); + printf ("* Flags: %i\n", eim->src->flags); + printf ("* Filename: %s\n* Key: %s\n", eim->src->info.file, eim->src->info.key); + printf ("* Reference: %i\n", eim->references); + } + printf ("*** ***\n"); +} +#endif diff --git a/legacy/evas/src/modules/engines/software_sdl/evas_engine_sdl.h b/legacy/evas/src/modules/engines/software_sdl/evas_engine_sdl.h new file mode 100644 index 0000000000..31df3c0dea --- /dev/null +++ b/legacy/evas/src/modules/engines/software_sdl/evas_engine_sdl.h @@ -0,0 +1,33 @@ +#ifndef EVAS_ENGINE_SDL_H +#define EVAS_ENGINE_SDL_H + +#include "evas_common.h" +#include "evas_private.h" +#include "Evas_Engine_SDL.h" + +typedef struct _Render_Engine Render_Engine; + +struct _Render_Engine +{ + RGBA_Engine_Image* rgba_engine_image; + SDL_Surface* surface; + + Tilebuf* tb; + Tilebuf_Rect* rects; + Evas_Object_List* cur_rect; + + Evas_Cache_Engine_Image* cache; + + SDL_Rect* update_rects; + int update_rects_count; + int update_rects_limit; + + int fullscreen:1; + int noframe:1; + int alpha:1; + int hwsurface:1; + + int end:1; +}; + +#endif diff --git a/legacy/evas/src/modules/engines/software_x11/evas_outbuf.c b/legacy/evas/src/modules/engines/software_x11/evas_outbuf.c index 61b6e37cab..ece0f90f12 100644 --- a/legacy/evas/src/modules/engines/software_x11/evas_outbuf.c +++ b/legacy/evas/src/modules/engines/software_x11/evas_outbuf.c @@ -237,8 +237,7 @@ evas_software_x11_outbuf_new_region_for_update(Outbuf * buf, int x, int y, int w (buf->priv.mask.g == 0x00ff00) && (buf->priv.mask.b == 0x0000ff)) { - im = evas_common_image_new(); - im->image = evas_common_image_surface_new(im); + im = evas_cache_image_empty(evas_common_image_cache_get()); im->image->w = w; im->image->h = h; im->image->data = NULL; @@ -260,7 +259,10 @@ evas_software_x11_outbuf_new_region_for_update(Outbuf * buf, int x, int y, int w } else { - im = evas_common_image_create(w, h); + im = evas_cache_image_empty(evas_common_image_cache_get()); + im->image->w = w; + im->image->h = h; + evas_common_image_surface_alloc(im->image); im->extended_info = obr; if ((buf->rot == 0) || (buf->rot == 180)) obr->xob = evas_software_x11_x_output_buffer_new(buf->priv.x.disp, @@ -333,7 +335,7 @@ evas_software_x11_outbuf_flush(Outbuf *buf) im = buf->priv.pending_writes->data; buf->priv.pending_writes = evas_list_remove_list(buf->priv.pending_writes, buf->priv.pending_writes); obr = im->extended_info; - evas_common_image_free(im); + evas_cache_image_drop(im); if (obr->xob) evas_software_x11_x_output_buffer_free(obr->xob, 0); if (obr->mxob) evas_software_x11_x_output_buffer_free(obr->mxob, 0); free(obr); diff --git a/legacy/evas/src/modules/engines/software_xcb/evas_outbuf.c b/legacy/evas/src/modules/engines/software_xcb/evas_outbuf.c index 7b5d177557..cefe5889e5 100644 --- a/legacy/evas/src/modules/engines/software_xcb/evas_outbuf.c +++ b/legacy/evas/src/modules/engines/software_xcb/evas_outbuf.c @@ -281,8 +281,7 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, (buf->priv.mask.g == 0x00ff00) && (buf->priv.mask.b == 0x0000ff)) { - im = evas_common_image_new(); - im->image = evas_common_image_surface_new(im); + im = evas_cache_image_empty(evas_common_image_cache_get()); im->image->w = w; im->image->h = h; im->image->data = NULL; @@ -305,7 +304,10 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, } else { - im = evas_common_image_create(w, h); + im = evas_cache_image_empty(evas_common_image_cache_get()); + im->image->w = w; + im->image->h = h; + evas_common_image_surface_alloc(im->image); im->extended_info = obr; if ((buf->rot == 0) || (buf->rot == 180)) obr->xcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, @@ -391,7 +393,7 @@ evas_software_xcb_outbuf_flush(Outbuf *buf) buf->priv.pending_writes = evas_list_remove_list(buf->priv.pending_writes, buf->priv.pending_writes); obr = im->extended_info; - evas_common_image_free(im); + evas_cache_image_drop(im); if (obr->xcbob) evas_software_xcb_x_output_buffer_free(obr->xcbob, 0); if (obr->mxcbob) evas_software_xcb_x_output_buffer_free(obr->mxcbob, 0); free(obr); diff --git a/legacy/evas/src/modules/engines/xrender_x11/evas_engine.c b/legacy/evas/src/modules/engines/xrender_x11/evas_engine.c index 4591a4f011..967c68595f 100644 --- a/legacy/evas/src/modules/engines/xrender_x11/evas_engine.c +++ b/legacy/evas/src/modules/engines/xrender_x11/evas_engine.c @@ -560,14 +560,14 @@ eng_image_colorspace_set(void *data, void *image, int cspace) im->cs.data = NULL; im->cs.no_free = 0; } - if (im->im) evas_common_image_unref(im->im); + if (im->im) evas_cache_image_drop(im->im); im->im = NULL; break; case EVAS_COLORSPACE_YCBCR422P601_PL: case EVAS_COLORSPACE_YCBCR422P709_PL: if ((im->free_data) && (im->data)) free(im->data); im->data = NULL; - if (im->im) evas_common_image_unref(im->im); + if (im->im) evas_cache_image_drop(im->im); im->im = NULL; if (im->cs.data) { diff --git a/legacy/evas/src/modules/engines/xrender_x11/evas_engine_gradient.c b/legacy/evas/src/modules/engines/xrender_x11/evas_engine_gradient.c index 3c0470481b..3b53567be9 100644 --- a/legacy/evas/src/modules/engines/xrender_x11/evas_engine_gradient.c +++ b/legacy/evas/src/modules/engines/xrender_x11/evas_engine_gradient.c @@ -170,7 +170,7 @@ _xre_gradient_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, im->image = evas_common_image_surface_new(im); if (!im->image) { - evas_common_image_free(im); + evas_common_image_delete(im); _xr_render_surface_free(gr->surface); gr->surface = NULL; return; @@ -178,7 +178,7 @@ _xre_gradient_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, xim = _xr_image_new(gr->xinf, w, h, gr->surface->depth); if (!xim) { - evas_common_image_free(im); + evas_common_image_delete(im); _xr_render_surface_free(gr->surface); gr->surface = NULL; return; @@ -204,7 +204,7 @@ _xre_gradient_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, } } _xr_image_put(xim, gr->surface->draw, 0, 0, w, h); - evas_common_image_free(im); + evas_common_image_delete(im); dc->render_op = op; dc->clip.use = cuse; } diff --git a/legacy/evas/src/modules/engines/xrender_x11/evas_engine_image.c b/legacy/evas/src/modules/engines/xrender_x11/evas_engine_image.c index fae111b09b..34c8136bb1 100644 --- a/legacy/evas/src/modules/engines/xrender_x11/evas_engine_image.c +++ b/legacy/evas/src/modules/engines/xrender_x11/evas_engine_image.c @@ -235,7 +235,7 @@ __xre_image_real_free(XR_Image *im) if (im->file) evas_stringshare_del(im->file); if (im->key) evas_stringshare_del(im->key); if (im->fkey) free(im->fkey); - if (im->im) evas_common_image_unref(im->im); + if (im->im) evas_cache_image_drop(im->im); if ((im->data) && (im->dirty)) __xre_image_dirty_hash_del(im); if ((im->free_data) && (im->data)) free(im->data); if (im->surface) _xr_render_surface_free(im->surface); @@ -334,7 +334,7 @@ _xre_image_resize(XR_Image *im, int w, int h) } else if (im->im) { - evas_common_image_unref(im->im); + evas_cache_image_drop(im->im); im->im = NULL; if (im->free_data) { @@ -360,7 +360,7 @@ _xre_image_resize(XR_Image *im, int w, int h) } if (im->im) { - evas_common_image_unref(im->im); + evas_cache_image_drop(im->im); im->im = NULL; } if (!im->cs.no_free) @@ -421,7 +421,7 @@ _xre_image_data_put(XR_Image *im, void *data) if (im->im) { if (data == im->im->image->data) return; - evas_common_image_unref(im->im); + evas_cache_image_drop(im->im); im->im = NULL; } if (im->cs.data == data) return; @@ -636,7 +636,7 @@ _xre_image_surface_gen(XR_Image *im) im->w + 2, 1); if ((im->im) && (!im->dirty)) { - evas_common_image_unref(im->im); + evas_cache_image_drop(im->im); im->im = NULL; } if (tdata) free(tdata); diff --git a/legacy/evas/src/modules/engines/xrender_xcb/evas_engine_image.c b/legacy/evas/src/modules/engines/xrender_xcb/evas_engine_image.c index db4ab23799..517c8c90a3 100644 --- a/legacy/evas/src/modules/engines/xrender_xcb/evas_engine_image.c +++ b/legacy/evas/src/modules/engines/xrender_xcb/evas_engine_image.c @@ -199,7 +199,7 @@ __xre_image_real_free(XR_Image *im) if (im->file) evas_stringshare_del(im->file); if (im->key) evas_stringshare_del(im->key); if (im->fkey) free(im->fkey); - if (im->im) evas_common_image_unref(im->im); + if (im->im) evas_cache_image_drop(im->im); if ((im->data) && (im->dirty)) __xre_image_dirty_hash_del(im); if ((im->free_data) && (im->data)) free(im->data); if (im->surface) _xr_render_surface_free(im->surface); @@ -272,7 +272,7 @@ _xre_image_copy(XR_Image *im) if (im2) im2->alpha = im->alpha; if ((im->im) && (!im->dirty)) { - evas_common_image_unref(im->im); + evas_cache_image_drop(im->im); im->im = NULL; } return im2; @@ -335,9 +335,9 @@ _xre_image_resize(XR_Image *im, int w, int h) else if (im->im) { RGBA_Image *im_old; - + im_old = im->im; - im->im = evas_common_image_create(w, h); + im->im = evas_cache_image_empty(evas_common_image_cache_get()); if (!im->im) { im->im = im_old; @@ -348,22 +348,26 @@ _xre_image_resize(XR_Image *im, int w, int h) } return; } + im->im->image->w = w; + im->im->image->h = h; + evas_common_image_surface_alloc(im->im->image); evas_common_load_image_data_from_file(im_old); if (im_old->image->data) { int x = 0, y = 0, ww, hh; - + ww = w; hh = h; RECTS_CLIP_TO_RECT(x, y, ww, hh, 0, 0, im->w, im->h); evas_common_blit_rectangle(im_old, im->im, 0, 0, ww, hh, 0, 0); evas_common_cpu_end_opt(); } im->free_data = 1; + /* FIXME: Hum ? */ im->data = im->im->image->data; im->im->image->data = NULL; - evas_common_image_unref(im->im); + evas_cache_image_drop(im->im); im->im = NULL; - evas_common_image_unref(im_old); + evas_cache_image_drop(im_old); __xre_image_dirty_hash_add(im); } else @@ -426,7 +430,7 @@ _xre_image_data_put(XR_Image *im, void *data) if (data == imdata) return; if (im->im) { - evas_common_image_unref(im->im); + evas_cache_image_drop(im->im); im->im = NULL; } } @@ -580,7 +584,7 @@ _xre_image_surface_gen(XR_Image *im) 1, 1); if ((im->im) && (!im->dirty)) { - evas_common_image_unref(im->im); + evas_cache_image_drop(im->im); im->im = NULL; } }