cedric's sdl patch.

SVN revision: 30845
This commit is contained in:
Carsten Haitzler 2007-07-16 07:25:35 +00:00
parent 64171b5ca6
commit 6c167c3a6d
33 changed files with 2852 additions and 669 deletions

View File

@ -14,6 +14,7 @@ Optional:
X11R6 X11R6
XCB XCB
DirectFB DirectFB
SDL
OpenGL (underway at the moment) OpenGL (underway at the moment)
Linux Linux
Qtopia 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 directfb that offer acceleration (otherwise the fb driver will likely be
faster). 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: CPU:
--enable-cpu-c --enable-cpu-c

View File

@ -71,6 +71,8 @@ qt_dir=""
qt_cflags="" qt_cflags=""
qt_libs="" qt_libs=""
qt_moc="moc" qt_moc="moc"
sdl_cflags=""
sdl_libs=""
##################################################################### #####################################################################
@ -356,6 +358,58 @@ if test "x$have_evas_directfb" = "xyes"; then
fi fi
AM_CONDITIONAL(BUILD_ENGINE_DIRECTFB, test "x$have_evas_directfb" = "xyes") 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 ## Check if we should build the fb engine
have_evas_fb="no"; have_evas_fb="no";
@ -2017,6 +2071,9 @@ AC_SUBST(ddraw_libs)
AC_SUBST(x_cflags) AC_SUBST(x_cflags)
AC_SUBST(x_libs) AC_SUBST(x_libs)
AC_SUBST(sdl_cflags)
AC_SUBST(sdl_libs)
AC_SUBST(xcb_cflags) AC_SUBST(xcb_cflags)
AC_SUBST(xcb_libs) AC_SUBST(xcb_libs)
AC_SUBST(xcbrender_cflags) AC_SUBST(xcbrender_cflags)
@ -2068,6 +2125,7 @@ src/lib/canvas/Makefile
src/lib/data/Makefile src/lib/data/Makefile
src/lib/file/Makefile src/lib/file/Makefile
src/lib/imaging/Makefile src/lib/imaging/Makefile
src/lib/cache/Makefile
src/lib/engines/Makefile src/lib/engines/Makefile
src/lib/engines/common/Makefile src/lib/engines/common/Makefile
src/lib/engines/common/evas_op_add/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/cairo_x11/Makefile
src/modules/engines/xrender_x11/Makefile src/modules/engines/xrender_x11/Makefile
src/modules/engines/xrender_xcb/Makefile src/modules/engines/xrender_xcb/Makefile
src/modules/engines/software_sdl/Makefile
src/modules/engines/glitz_x11/Makefile src/modules/engines/glitz_x11/Makefile
src/modules/engines/software_16/Makefile src/modules/engines/software_16/Makefile
src/modules/engines/software_16_x11/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 Qtopia.........: $have_evas_qtopia"
echo " Software Memory Buffer..: $have_evas_buffer" echo " Software Memory Buffer..: $have_evas_buffer"
echo " DirectFB................: $have_evas_directfb" echo " DirectFB................: $have_evas_directfb"
echo " SDL.....................: $have_evas_sdl"
echo " OpenGL X11..............: $have_evas_gl_x11" echo " OpenGL X11..............: $have_evas_gl_x11"
echo " Cairo X11...............: $have_evas_cairo_x11" echo " Cairo X11...............: $have_evas_cairo_x11"
echo " XRender X11.............: $have_evas_xrender_x11" echo " XRender X11.............: $have_evas_xrender_x11"

View File

@ -1,6 +1,6 @@
MAINTAINERCLEANFILES = Makefile.in MAINTAINERCLEANFILES = Makefile.in
SUBDIRS = canvas data file engines imaging include SUBDIRS = canvas data cache file engines imaging include
AUTOMAKE_OPTIONS = 1.4 foreign AUTOMAKE_OPTIONS = 1.4 foreign
@ -24,6 +24,7 @@ libevas_la_LIBADD = \
canvas/libevas_canvas.la \ canvas/libevas_canvas.la \
data/libevas_data.la \ data/libevas_data.la \
file/libevas_file.la \ file/libevas_file.la \
cache/libevas_cache.la \
imaging/libevas_imaging.la \ imaging/libevas_imaging.la \
engines/common/libevas_engine_common.la \ engines/common/libevas_engine_common.la \
-lm \ -lm \
@ -39,6 +40,9 @@ libevas_la_DEPENDENCIES = \
canvas/libevas_canvas.la \ canvas/libevas_canvas.la \
data/libevas_data.la \ data/libevas_data.la \
file/libevas_file.la \ file/libevas_file.la \
cache/libevas_cache.la \
imaging/libevas_imaging.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 libevas_la_LDFLAGS = @create_shared_lib@ -version-info 1:0:0

6
legacy/evas/src/lib/cache/.cvsignore vendored Normal file
View File

@ -0,0 +1,6 @@
Makefile.in
Makefile
.deps
.libs
*.la
*.lo

18
legacy/evas/src/lib/cache/Makefile.am vendored Normal file
View File

@ -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

View File

@ -0,0 +1,496 @@
#include <assert.h>
#include <Evas.h>
#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);
}

View File

@ -0,0 +1,593 @@
#include <stdlib.h>
#include <assert.h>
#include <Evas.h>
#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);
}

View File

@ -742,6 +742,9 @@ evas_render_method_list(void)
#ifdef BUILD_ENGINE_SOFTWARE_QTOPIA #ifdef BUILD_ENGINE_SOFTWARE_QTOPIA
methods = evas_list_append(methods, strdup("software_qtopia")); methods = evas_list_append(methods, strdup("software_qtopia"));
#endif #endif
#ifdef BUILD_ENGINE_SDL
methods = evas_list_append(methods, strdup("software_sdl"));
#endif
return methods; return methods;
} }

View File

@ -1061,20 +1061,18 @@ evas_object_image_save(Evas_Object *obj, const char *file, const char *key, cons
else break; else break;
} }
} }
im = evas_common_image_new(); im = evas_cache_image_empty(evas_common_image_cache_get());
if (im) if (im)
{ {
if (o->cur.has_alpha) im->flags |= RGBA_IMAGE_HAS_ALPHA; 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->data = data; im->image->h = o->cur.image.h;
im->image->w = o->cur.image.w; im->image->no_free = 1;
im->image->h = o->cur.image.h; ok = evas_common_save_image_to_file(im, file, key, quality, compress);
im->image->no_free = 1;
ok = evas_common_save_image_to_file(im, file, key, quality, compress); evas_cache_image_drop(im);
}
evas_common_image_free(im);
} }
return ok; return ok;
} }

View File

@ -45,6 +45,7 @@ evas_gradient_sinusoidal.c \
evas_image_load.c \ evas_image_load.c \
evas_image_save.c \ evas_image_save.c \
evas_image_main.c \ evas_image_main.c \
evas_image_data.c \
evas_line_main.c \ evas_line_main.c \
evas_polygon_main.c \ evas_polygon_main.c \
evas_rectangle_main.c \ evas_rectangle_main.c \

View File

@ -0,0 +1,123 @@
#include "evas_common.h"
#include "evas_private.h"
#include <assert.h>
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;
}

View File

@ -3,58 +3,50 @@
extern Evas_List *evas_modules; extern Evas_List *evas_modules;
EAPI RGBA_Image * struct ext_loader_s {
evas_common_load_image_from_file(const char *file, const char *key, RGBA_Image_Loadopts *lo) 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_Image_Load_Func *evas_image_load_func = NULL;
Evas_List *l; const char *loader = NULL;
RGBA_Image *im; char *dot;
char *p; Evas_List *l;
char *loader = NULL; Evas_Module *em;
Evas_Module *em; int i;
struct stat st;
if (file == NULL) return NULL;
im = evas_common_image_find(file, key, 0, lo); dot = strrchr (im->info.file, '.');
if (im) if (dot)
{ {
evas_common_image_ref(im); for (i = 0, ++dot; i < (sizeof (loaders) / sizeof (struct ext_loader_s)); ++i)
return im; {
} if (!strcasecmp (dot, loaders[i].extention))
if (stat(file, &st) < 0) return NULL; {
loader = loaders[i].loader;
im = evas_common_image_new(); break;
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";
} }
if (loader) if (loader)
{ {
em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, 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_module_use(em);
evas_image_load_func = em->functions; 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; 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; if (!evas_module_load(em)) continue;
evas_image_load_func = em->functions; evas_image_load_func = em->functions;
evas_module_use(em); 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) 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; 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.module = (void *)em;
im->info.loader = (void *)evas_image_load_func; 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_module_ref((Evas_Module *)im->info.module);
evas_common_image_ref(im); return 0;
return im;
} }
EAPI void EAPI void
evas_common_load_image_data_from_file(RGBA_Image *im) evas_common_load_image_data_from_file(RGBA_Image *im)
{ {
Evas_Image_Load_Func *evas_image_load_func = NULL; 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; if (!im->info.module) return;
evas_image_load_func = im->info.loader; evas_image_load_func = im->info.loader;
evas_module_use((Evas_Module *)im->info.module); evas_module_use((Evas_Module *)im->info.module);
if (!evas_image_load_func->file_data(im, im->info.file, im->info.key)) 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) if (!im->image->data)
{ {
const DATA32 pixel = 0xffffffff; 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); evas_module_unref((Evas_Module *)im->info.module);
im->info.module = NULL; im->info.module = NULL;
} }
im->flags |= RGBA_IMAGE_LOADED;
} }

View File

@ -9,70 +9,50 @@
#include <memcheck.h> #include <memcheck.h>
#endif #endif
static Evas_Hash * images = NULL; static Evas_Cache_Image * eci = NULL;
static Evas_Object_List * cache = NULL; static int reference = 0;
static int cache_size = 0;
static int cache_usage = 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_MIN_LEN 256
#define EVAS_RGBA_LINE_BUFFER_MAX_LEN 2048 #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_MIN_LEN 256
#define EVAS_ALPHA_LINE_BUFFER_MAX_LEN 2048 #define EVAS_ALPHA_LINE_BUFFER_MAX_LEN 2048
#if 0 /* The cache is doing the allocation and deallocation, you must just do the rest. */
int static void _evas_common_image_unload(RGBA_Image* im);
image_debug_hash_cb(Evas_Hash *hash, const char *key, void *data, void *fdata)
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; .constructor = evas_common_load_image_module_from_file,
.destructor = _evas_common_image_unload,
im = data; .dirty_region = _evas_common_image_dirty_region,
printf(" [%i] %3ix%3i %6i %6i [%2x %2x] %i %s\n", .dirty = _evas_common_image_dirty,
im->references, .copied_data = evas_common_image_from_copied_data,
im->image->w, im->image->h, .color_space = evas_common_image_colorspace_set,
im->image->w * im->image->h * 4, .data = evas_common_image_from_data,
evas_common_image_ram_usage(im), .size_set = evas_common_image_size_set,
im->flags & RGBA_IMAGE_IS_DIRTY, .load = evas_common_load_image_data_from_file,
im->flags & RGBA_IMAGE_INDEXED, .mem_size_get = evas_common_image_ram_usage,
im->info.format, .debug = NULL
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
EAPI void EAPI void
evas_common_image_init(void) evas_common_image_init(void)
{ {
if (!eci)
eci = evas_cache_image_init(&_evas_common_image_func);
reference++;
#ifdef BUILD_LOADER_EET #ifdef BUILD_LOADER_EET
eet_init(); eet_init();
#endif #endif
@ -81,11 +61,69 @@ evas_common_image_init(void)
EAPI void EAPI void
evas_common_image_shutdown(void) evas_common_image_shutdown(void)
{ {
if (--reference == 0)
{
evas_cache_image_shutdown(eci);
eci = NULL;
}
#ifdef BUILD_LOADER_EET #ifdef BUILD_LOADER_EET
eet_shutdown(); eet_shutdown();
#endif #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 #if 0
void void
evas_common_image_surface_alpha_tiles_calc(RGBA_Surface *is, int tsize) 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; size_t siz = 0;
if (is->data) return ;
if (is->im->flags & RGBA_IMAGE_ALPHA_ONLY) if (is->im->flags & RGBA_IMAGE_ALPHA_ONLY)
siz = is->w * is->h * sizeof(DATA8); siz = is->w * is->h * sizeof(DATA8);
else else
@ -206,7 +246,7 @@ evas_common_image_create(int w, int h)
im->image = evas_common_image_surface_new(im); im->image = evas_common_image_surface_new(im);
if (!im->image) if (!im->image)
{ {
evas_common_image_free(im); evas_common_image_delete(im);
return NULL; return NULL;
} }
im->image->w = w; im->image->w = w;
@ -214,7 +254,7 @@ evas_common_image_create(int w, int h)
evas_common_image_surface_alloc(im->image); evas_common_image_surface_alloc(im->image);
if (!im->image->data) if (!im->image->data)
{ {
evas_common_image_free(im); evas_common_image_delete(im);
return NULL; return NULL;
} }
im->flags = RGBA_IMAGE_IS_DIRTY; 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); im->image = evas_common_image_surface_new(im);
if (!im->image) if (!im->image)
{ {
evas_common_image_free(im); evas_common_image_delete(im);
return NULL; return NULL;
} }
im->image->w = w; im->image->w = w;
@ -241,7 +281,7 @@ evas_common_image_alpha_create(int w, int h)
evas_common_image_surface_alloc(im->image); evas_common_image_surface_alloc(im->image);
if (!im->image->data) if (!im->image->data)
{ {
evas_common_image_free(im); evas_common_image_delete(im);
return NULL; return NULL;
} }
im->flags = RGBA_IMAGE_IS_DIRTY; im->flags = RGBA_IMAGE_IS_DIRTY;
@ -262,72 +302,6 @@ evas_common_image_new(void)
return im; 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 EAPI void
evas_common_image_colorspace_normalize(RGBA_Image *im) 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: case EVAS_COLORSPACE_YCBCR422P601_PL:
#ifdef BUILD_CONVERT_YUV #ifdef BUILD_CONVERT_YUV
if ((im->image->data) && (*((unsigned char **)im->cs.data))) 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); im->image->w, im->image->h);
#endif #endif
break; break;
@ -361,237 +335,27 @@ evas_common_image_colorspace_dirty(RGBA_Image *im)
im->cs.dirty = 1; 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 EAPI void
evas_common_image_set_cache(int size) evas_common_image_set_cache(int size)
{ {
cache_size = size; if (eci != NULL)
evas_common_image_flush_cache(); evas_cache_image_set(eci, size);
} }
EAPI int EAPI int
evas_common_image_get_cache(void) evas_common_image_get_cache(void)
{ {
return cache_size; return evas_cache_image_get(eci);
}
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;
} }
#define STAT_GAP 2 #define STAT_GAP 2
EAPI RGBA_Image * 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; int error;
RGBA_Image *im;
char buf[4096 + 1024];
Evas_Object_List *l;
struct stat st;
static time_t laststat = 0;
time_t t, mt = 0;
if ((!file) && (!key)) return NULL; if (file == NULL) return NULL;
if (!file) return NULL; return evas_cache_image_request(eci, file, key, lo, &error);
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;
} }
EAPI int EAPI int
@ -609,19 +373,18 @@ evas_common_image_ram_usage(RGBA_Image *im)
return ram; return ram;
} }
EAPI void
evas_common_image_dirty(RGBA_Image *im)
{
evas_common_image_unstore(im);
im->flags |= RGBA_IMAGE_IS_DIRTY;
}
EAPI void EAPI void
evas_common_image_cache_free(void) evas_common_image_cache_free(void)
{ {
evas_common_image_set_cache(0); evas_common_image_set_cache(0);
} }
EAPI Evas_Cache_Image*
evas_common_image_cache_get(void)
{
return eci;
}
EAPI RGBA_Image * EAPI RGBA_Image *
evas_common_image_line_buffer_obtain(int len) evas_common_image_line_buffer_obtain(int len)
{ {
@ -653,7 +416,7 @@ evas_common_image_line_buffer_obtain(int len)
EAPI void EAPI void
evas_common_image_line_buffer_release(RGBA_Image *im) 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) return;
if (EVAS_RGBA_LINE_BUFFER_MAX_LEN < evas_rgba_line_buffer->image->w) 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 EAPI void
evas_common_image_line_buffer_free(RGBA_Image *im) 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; if (!evas_rgba_line_buffer) return;
evas_common_image_free(evas_rgba_line_buffer); evas_common_image_free(evas_rgba_line_buffer);
@ -711,7 +474,7 @@ evas_common_image_alpha_line_buffer_obtain(int len)
EAPI void EAPI void
evas_common_image_alpha_line_buffer_release(RGBA_Image *im) 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) return;
if (EVAS_ALPHA_LINE_BUFFER_MAX_LEN < evas_alpha_line_buffer->image->w) 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 EAPI void
evas_common_image_premul(RGBA_Image *im) evas_common_image_premul(RGBA_Image *im)
{ {

View File

@ -483,7 +483,9 @@ evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
static void static void
evas_common_pipe_op_image_free(RGBA_Pipe_Op *op) 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); 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) if (info)
{ {
RGBA_Draw_Context context; RGBA_Draw_Context context;
memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
#ifdef EVAS_SLI #ifdef EVAS_SLI
evas_common_draw_context_set_sli(&(context), info->y, info->h); 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); evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
#endif #endif
if (op->op.image.smooth) 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), dst, &(context),
op->op.image.sx, op->op.image.sx,
op->op.image.sy, 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.dw,
op->op.image.dh); op->op.image.dh);
else 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), dst, &(context),
op->op.image.sx, op->op.image.sx,
op->op.image.sy, 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 else
{ {
if (op->op.image.smooth) 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), dst, &(op->context),
op->op.image.sx, op->op.image.sx,
op->op.image.sy, 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.dw,
op->op.image.dh); op->op.image.dh);
else 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), dst, &(op->context),
op->op.image.sx, op->op.image.sx,
op->op.image.sy, op->op.image.sy,

View File

@ -20,7 +20,7 @@ evas_imaging_image_load(const char *file, const char *key)
im = calloc(1, sizeof(Evas_Imaging_Image)); im = calloc(1, sizeof(Evas_Imaging_Image));
if (!im) if (!im)
{ {
evas_common_image_free(image); evas_cache_image_drop(image);
return NULL; return NULL;
} }
im->image = image; im->image = image;
@ -31,7 +31,7 @@ EAPI void
evas_imaging_image_free(Evas_Imaging_Image *im) evas_imaging_image_free(Evas_Imaging_Image *im)
{ {
if (!im) return; if (!im) return;
evas_common_image_unref(im->image); evas_cache_image_drop(im->image);
free(im); free(im);
} }

View File

@ -109,27 +109,28 @@
/*****************************************************************************/ /*****************************************************************************/
#ifndef _WIN32_WCE #ifndef _WIN32_WCE
typedef unsigned long long DATA64; typedef unsigned long long DATA64;
#else #else
typedef unsigned __int64 DATA64; typedef unsigned __int64 DATA64;
#define strdup _strdup #define strdup _strdup
#define snprintf _snprintf #define snprintf _snprintf
#define rewind(f) fseek(f, 0, SEEK_SET) #define rewind(f) fseek(f, 0, SEEK_SET)
#endif #endif
typedef unsigned int DATA32; typedef unsigned int DATA32;
typedef unsigned short DATA16; typedef unsigned short DATA16;
typedef unsigned char DATA8; 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_Image_Loadopts RGBA_Image_Loadopts;
typedef struct _RGBA_Pipe_Op RGBA_Pipe_Op; typedef struct _RGBA_Pipe_Op RGBA_Pipe_Op;
typedef struct _RGBA_Pipe RGBA_Pipe; typedef struct _RGBA_Pipe RGBA_Pipe;
typedef struct _RGBA_Pipe_Thread_Info RGBA_Pipe_Thread_Info; typedef struct _RGBA_Pipe_Thread_Info RGBA_Pipe_Thread_Info;
typedef struct _RGBA_Image RGBA_Image; typedef struct _RGBA_Image RGBA_Image;
typedef struct _RGBA_Engine_Image RGBA_Engine_Image;
typedef struct _RGBA_Surface RGBA_Surface; typedef struct _RGBA_Surface RGBA_Surface;
typedef struct _RGBA_Image_Span RGBA_Image_Span; typedef struct _RGBA_Image_Span RGBA_Image_Span;
typedef struct _RGBA_Draw_Context RGBA_Draw_Context; 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_Rect Cutout_Rect;
typedef struct _Cutout_Rects Cutout_Rects; 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 Tilebuf;
typedef struct _Tilebuf_Tile Tilebuf_Tile; typedef struct _Tilebuf_Tile Tilebuf_Tile;
typedef struct _Tilebuf_Rect Tilebuf_Rect; 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 _Regionbuf Regionbuf;
typedef struct _Regionspan Regionspan; 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_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 (*RGBA_Gfx_Pt_Func) (DATA32 src, DATA8 mask, DATA32 col, DATA32 *dst);
typedef void (*Gfx_Func_Copy) (DATA32 *src, DATA32 *dst, int len); 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_INDEXED = (1 << 2),
RGBA_IMAGE_ALPHA_ONLY = (1 << 3), RGBA_IMAGE_ALPHA_ONLY = (1 << 3),
RGBA_IMAGE_ALPHA_TILES = (1 << 4), 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; } RGBA_Image_Flags;
typedef enum _Convert_Pal_Mode typedef enum _Convert_Pal_Mode
@ -364,11 +372,16 @@ struct _RGBA_Image
char *comment; char *comment;
// int format; // int format;
} info; } info;
void *extended_info; void *extended_info;
RGBA_Pipe *pipe; RGBA_Pipe *pipe;
int references; int references;
RGBA_Image_Loadopts load_opts; RGBA_Image_Loadopts load_opts;
unsigned char scale;
int ref; int ref;
/* Colorspace stuff. */
time_t timestamp; time_t timestamp;
time_t laststat; time_t laststat;
struct { struct {
@ -377,7 +390,32 @@ struct _RGBA_Image
unsigned char no_free : 1; unsigned char no_free : 1;
unsigned char dirty : 1; unsigned char dirty : 1;
} cs; } 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 struct _RGBA_Gradient_Color_Stop
@ -659,6 +697,82 @@ struct _Convert_Pal
void *data; 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" #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_alloc (RGBA_Surface *is);/*2*/
EAPI void evas_common_image_surface_dealloc (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_normalize(RGBA_Image *im);
EAPI void evas_common_image_colorspace_dirty (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_cache_free (void); /*2*/ EAPI void evas_common_image_cache_free (void); /*2*/
EAPI void evas_common_image_premul (RGBA_Image *im); /*2*/ EAPI void evas_common_image_premul (RGBA_Image *im); /*2*/
EAPI void evas_common_image_set_alpha_sparse (RGBA_Image *im); /*2*/ EAPI void evas_common_image_set_alpha_sparse (RGBA_Image *im); /*2*/
/*done*/
EAPI RGBA_Image *evas_common_image_alpha_create (int w, int h); 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_create (int w, int h);
EAPI RGBA_Image *evas_common_image_new (void); 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 int evas_common_image_size_set (RGBA_Image* dst, const RGBA_Image* im, int w, int h);
EAPI void evas_common_image_ref (RGBA_Image *im); EAPI int evas_common_image_from_copied_data (RGBA_Image* dst, int w, int h, DATA32 *image_data, int alpha, int cspace);
EAPI void evas_common_image_unref (RGBA_Image *im); EAPI int evas_common_image_from_data (RGBA_Image* dst, int w, int h, DATA32 *image_data, int alpha, int cspace);
EAPI void evas_common_image_flush_cache (void);
/*done*/
EAPI void evas_common_image_set_cache (int size); EAPI void evas_common_image_set_cache (int size);
EAPI int evas_common_image_get_cache (void); EAPI int evas_common_image_get_cache (void);
EAPI int evas_common_image_ram_usage (RGBA_Image *im); 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 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_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 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_release (RGBA_Image *im);
EAPI void evas_common_image_alpha_line_buffer_free (RGBA_Image *im); EAPI void evas_common_image_alpha_line_buffer_free (RGBA_Image *im);
/*done*/ /*done*/
EAPI RGBA_Image *evas_common_load_image_from_file (const char *file, const char *key, RGBA_Image_Loadopts *lo); 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 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); 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_init(void);
void evas_stringshare_shutdown(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 #ifdef __cplusplus

View File

@ -16,6 +16,7 @@ software_x11 \
software_xcb \ software_xcb \
xrender_x11 \ xrender_x11 \
xrender_xcb \ xrender_xcb \
software_sdl \
glitz_x11 \ glitz_x11 \
software_16 \ software_16 \
software_16_x11 software_16_x11

View File

@ -12,7 +12,7 @@ evas_buffer_outbuf_buf_free(Outbuf *buf)
{ {
if (buf->priv.back_buf) if (buf->priv.back_buf)
{ {
evas_common_image_free(buf->priv.back_buf); evas_common_image_delete(buf->priv.back_buf);
} }
free(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 void
evas_buffer_outbuf_buf_free_region_for_update(Outbuf *buf, RGBA_Image *update) 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 void
@ -263,7 +263,7 @@ evas_buffer_outbuf_buf_push_updated_region(Outbuf *buf, RGBA_Image *update, int
{ {
DATA32 *dest, *src, *dst; DATA32 *dest, *src, *dst;
int yy, row_bytes; int yy, row_bytes;
row_bytes = buf->dest_row_bytes; row_bytes = buf->dest_row_bytes;
dest = (DATA8 *)(buf->dest) + (y * row_bytes) + (x * 4); dest = (DATA8 *)(buf->dest) + (y * row_bytes) + (x * 4);
if (buf->func.new_update_region) if (buf->func.new_update_region)

View File

@ -14,7 +14,7 @@ evas_fb_outbuf_fb_free(Outbuf *buf)
/* FIXME: impliment */ /* FIXME: impliment */
printf("destroying fb info.. not implemented!!!! WARNING. LEAK!\n"); printf("destroying fb info.. not implemented!!!! WARNING. LEAK!\n");
if (buf->priv.back_buf) if (buf->priv.back_buf)
evas_common_image_free(buf->priv.back_buf); evas_common_image_delete(buf->priv.back_buf);
free(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 void
evas_fb_outbuf_fb_free_region_for_update(Outbuf *buf, RGBA_Image *update) 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 void
@ -333,7 +333,7 @@ evas_fb_outbuf_fb_reconfigure(Outbuf *buf, int w, int h, int rot, Outbuf_Depth d
return; return;
if (buf->priv.back_buf) 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; buf->priv.back_buf = NULL;
} }
if (buf->priv.fb.fb) 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 (buf->priv.back_buf)
{ {
if (have_backbuf) return; 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; buf->priv.back_buf = NULL;
} }
else else

View File

@ -15,7 +15,7 @@ evas_gl_common_image_load(Evas_GL_Context *gc, const char *file, const char *key
im = l->data; im = l->data;
if (im->im == im_im) 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_remove_list(gc->images, l);
gc->images = evas_list_prepend(gc->images, im); gc->images = evas_list_prepend(gc->images, im);
im->references++; 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)); im = calloc(1, sizeof(Evas_GL_Image));
if (!im) return NULL; if (!im) return NULL;
im->references = 1; im->references = 1;
im->im = evas_common_image_new(); im->im = evas_cache_image_empty(evas_common_image_cache_get());
if (!im->im) if (!im->im)
{ {
free(im); free(im);
return NULL; 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->gc = gc;
im->im->image->w = w; im->im->image->w = w;
im->im->image->h = h; 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)); im = calloc(1, sizeof(Evas_GL_Image));
if (!im) return NULL; if (!im) return NULL;
im->references = 1; 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) if (!im->im)
{ {
free(im); free(im);
return NULL; return NULL;
} }
im->im->image->w = w;
im->im->image->h = h;
im->gc = gc; im->gc = gc;
im->cs.space = cspace; im->cs.space = cspace;
if (alpha) 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) switch (cspace)
{ {
case EVAS_COLORSPACE_ARGB8888: case EVAS_COLORSPACE_ARGB8888:
evas_common_image_surface_alloc(im->im->image);
if (data) if (data)
memcpy(im->im->image->data, data, w * h * sizeof(DATA32)); memcpy(im->im->image->data, data, w * h * sizeof(DATA32));
break; break;
case EVAS_COLORSPACE_YCBCR422P601_PL: case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_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); if (im->tex) evas_gl_common_texture_free(im->tex);
im->tex = NULL; im->tex = NULL;
im->cs.no_free = 0; 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)); im = calloc(1, sizeof(Evas_GL_Image));
if (!im) return NULL; if (!im) return NULL;
im->references = 1; 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) if (!im->im)
{ {
free(im); free(im);
return NULL; return NULL;
} }
im->im->image->w = w;
im->im->image->h = h;
im->gc = gc; im->gc = gc;
im->cs.space = cspace; im->cs.space = cspace;
if (alpha) 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) switch (cspace)
{ {
case EVAS_COLORSPACE_ARGB8888: case EVAS_COLORSPACE_ARGB8888:
evas_common_image_surface_alloc(im->im->image);
// if (data) // if (data)
// memcpy(im->im->image->data, data, w * h * sizeof(DATA32)); // memcpy(im->im->image->data, data, w * h * sizeof(DATA32));
break; 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->cs.no_free) free(im->cs.data);
} }
if (im->cached) im->gc->images = evas_list_remove(im->gc->images, im); 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); if (im->tex) evas_gl_common_texture_free(im->tex);
free(im); free(im);
} }
@ -216,7 +213,7 @@ evas_gl_common_image_free(Evas_GL_Image *im)
void void
evas_gl_common_image_dirty(Evas_GL_Image *im) 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; 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; r = g = b = a = 255;
} }
evas_common_load_image_data_from_file(im->im);
/* leak in this switch */ /* leak in this switch */
switch (im->cs.space) switch (im->cs.space)
{ {
case EVAS_COLORSPACE_ARGB8888: case EVAS_COLORSPACE_ARGB8888:
evas_cache_image_load_data(im->im);
if ((im->tex) && (im->dirty)) if ((im->tex) && (im->dirty))
{ {
evas_gl_common_texture_update(im->tex, im->im, im->tex->smooth); evas_gl_common_texture_update(im->tex, im->im, im->tex->smooth);

View File

@ -163,7 +163,7 @@ soft16_image_load_new(const char *file, const char *key,
_calc_stride(sim->image->w), have_alpha, 0); _calc_stride(sim->image->w), have_alpha, 0);
if (!im) if (!im)
{ {
evas_common_image_unref(sim); evas_cache_image_drop(sim);
return NULL; 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_alloc_pixels(im);
if (im->pixels) _soft16_image_rgba32_import(im, im->source_im->image->data); 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; im->source_im = NULL;
} }

View File

@ -349,7 +349,7 @@ eng_image_alpha_get(void *data, void *image)
static int static int
eng_image_colorspace_get(void *data, void *image) eng_image_colorspace_get(void *data, void *image)
{ {
RGBA_Image *im; RGBA_Image *im;
if (!image) return EVAS_COLORSPACE_ARGB8888; if (!image) return EVAS_COLORSPACE_ARGB8888;
im = image; im = image;
@ -368,24 +368,9 @@ eng_image_alpha_set(void *data, void *image, int has_alpha)
im->flags &= ~RGBA_IMAGE_HAS_ALPHA; im->flags &= ~RGBA_IMAGE_HAS_ALPHA;
return im; return im;
} }
if (im->references > 1) im = evas_cache_image_alone(im);
{ evas_common_image_colorspace_dirty(im);
RGBA_Image *im_new;
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) if (has_alpha)
im->flags |= RGBA_IMAGE_HAS_ALPHA; im->flags |= RGBA_IMAGE_HAS_ALPHA;
else else
@ -488,84 +473,19 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I
static void * static void *
eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
{ {
RGBA_Image *im; return evas_cache_image_data(evas_common_image_cache_get(), w, h, image_data, alpha, cspace);
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;
} }
static void * static void *
eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
{ {
RGBA_Image *im; return evas_cache_image_copied_data(evas_common_image_cache_get(), w, h, image_data, alpha, cspace);
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;
} }
static void static void
eng_image_free(void *data, void *image) eng_image_free(void *data, void *image)
{ {
evas_common_image_unref(image); evas_cache_image_drop(image);
} }
static void static void
@ -581,46 +501,20 @@ eng_image_size_get(void *data, void *image, int *w, int *h)
static void * static void *
eng_image_size_set(void *data, void *image, int w, int h) eng_image_size_set(void *data, void *image, int w, int h)
{ {
RGBA_Image *im, *im_old; RGBA_Image *im;
im_old = image; im = image;
if ((im_old->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) || return evas_cache_image_size_set(image, w, h);
(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;
} }
static void * static void *
eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h) eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h)
{ {
RGBA_Image* im = image;
if (!image) return NULL; if (!image) return NULL;
evas_common_image_dirty(image); im = evas_cache_image_dirty(im, x, y, w, h);
evas_common_image_colorspace_dirty(image); return im;
return image;
} }
static void * static void *
@ -639,22 +533,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data)
{ {
case EVAS_COLORSPACE_ARGB8888: case EVAS_COLORSPACE_ARGB8888:
if (to_write) if (to_write)
{ im = evas_cache_image_alone(im);
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);
}
*image_data = im->image->data; *image_data = im->image->data;
break; break;
case EVAS_COLORSPACE_YCBCR422P601_PL: 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) if (image_data != im->image->data)
{ {
int w, h; int w, h;
w = im->image->w; w = im->image->w;
h = im->image->h; h = im->image->h;
im2 = eng_image_new_from_data(data, w, h, image_data, im2 = eng_image_new_from_data(data, w, h, image_data,
eng_image_alpha_get(data, image), eng_image_alpha_get(data, image),
eng_image_colorspace_get(data, image)); eng_image_colorspace_get(data, image));
evas_common_image_unref(im); evas_cache_image_drop(im);
im = im2; im = im2;
} }
break; 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) 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; RGBA_Image *im;
if (!image) return; if (!image) return;
im = image; im = image;
if (im->cs.space == EVAS_COLORSPACE_ARGB8888) if (im->cs.space == EVAS_COLORSPACE_ARGB8888)

View File

@ -0,0 +1,6 @@
.deps
.libs
Makefile
Makefile.in
*.lo
*.la

View File

@ -0,0 +1,24 @@
#ifndef _EVAS_ENGINE_SDL_H
#define _EVAS_ENGINE_SDL_H
#include <SDL/SDL.h>
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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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.g == 0x00ff00) &&
(buf->priv.mask.b == 0x0000ff)) (buf->priv.mask.b == 0x0000ff))
{ {
im = evas_common_image_new(); im = evas_cache_image_empty(evas_common_image_cache_get());
im->image = evas_common_image_surface_new(im);
im->image->w = w; im->image->w = w;
im->image->h = h; im->image->h = h;
im->image->data = NULL; 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 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; im->extended_info = obr;
if ((buf->rot == 0) || (buf->rot == 180)) if ((buf->rot == 0) || (buf->rot == 180))
obr->xob = evas_software_x11_x_output_buffer_new(buf->priv.x.disp, 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; im = buf->priv.pending_writes->data;
buf->priv.pending_writes = evas_list_remove_list(buf->priv.pending_writes, buf->priv.pending_writes); buf->priv.pending_writes = evas_list_remove_list(buf->priv.pending_writes, buf->priv.pending_writes);
obr = im->extended_info; 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->xob) evas_software_x11_x_output_buffer_free(obr->xob, 0);
if (obr->mxob) evas_software_x11_x_output_buffer_free(obr->mxob, 0); if (obr->mxob) evas_software_x11_x_output_buffer_free(obr->mxob, 0);
free(obr); free(obr);

View File

@ -281,8 +281,7 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf,
(buf->priv.mask.g == 0x00ff00) && (buf->priv.mask.g == 0x00ff00) &&
(buf->priv.mask.b == 0x0000ff)) (buf->priv.mask.b == 0x0000ff))
{ {
im = evas_common_image_new(); im = evas_cache_image_empty(evas_common_image_cache_get());
im->image = evas_common_image_surface_new(im);
im->image->w = w; im->image->w = w;
im->image->h = h; im->image->h = h;
im->image->data = NULL; im->image->data = NULL;
@ -305,7 +304,10 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf,
} }
else 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; im->extended_info = obr;
if ((buf->rot == 0) || (buf->rot == 180)) if ((buf->rot == 0) || (buf->rot == 180))
obr->xcbob = evas_software_xcb_x_output_buffer_new(buf->priv.x.conn, 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 = evas_list_remove_list(buf->priv.pending_writes,
buf->priv.pending_writes); buf->priv.pending_writes);
obr = im->extended_info; 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->xcbob) evas_software_xcb_x_output_buffer_free(obr->xcbob, 0);
if (obr->mxcbob) evas_software_xcb_x_output_buffer_free(obr->mxcbob, 0); if (obr->mxcbob) evas_software_xcb_x_output_buffer_free(obr->mxcbob, 0);
free(obr); free(obr);

View File

@ -560,14 +560,14 @@ eng_image_colorspace_set(void *data, void *image, int cspace)
im->cs.data = NULL; im->cs.data = NULL;
im->cs.no_free = 0; 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; im->im = NULL;
break; break;
case EVAS_COLORSPACE_YCBCR422P601_PL: case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL: case EVAS_COLORSPACE_YCBCR422P709_PL:
if ((im->free_data) && (im->data)) free(im->data); if ((im->free_data) && (im->data)) free(im->data);
im->data = NULL; im->data = NULL;
if (im->im) evas_common_image_unref(im->im); if (im->im) evas_cache_image_drop(im->im);
im->im = NULL; im->im = NULL;
if (im->cs.data) if (im->cs.data)
{ {

View File

@ -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); im->image = evas_common_image_surface_new(im);
if (!im->image) if (!im->image)
{ {
evas_common_image_free(im); evas_common_image_delete(im);
_xr_render_surface_free(gr->surface); _xr_render_surface_free(gr->surface);
gr->surface = NULL; gr->surface = NULL;
return; 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); xim = _xr_image_new(gr->xinf, w, h, gr->surface->depth);
if (!xim) if (!xim)
{ {
evas_common_image_free(im); evas_common_image_delete(im);
_xr_render_surface_free(gr->surface); _xr_render_surface_free(gr->surface);
gr->surface = NULL; gr->surface = NULL;
return; 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); _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->render_op = op;
dc->clip.use = cuse; dc->clip.use = cuse;
} }

View File

@ -235,7 +235,7 @@ __xre_image_real_free(XR_Image *im)
if (im->file) evas_stringshare_del(im->file); if (im->file) evas_stringshare_del(im->file);
if (im->key) evas_stringshare_del(im->key); if (im->key) evas_stringshare_del(im->key);
if (im->fkey) free(im->fkey); 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->data) && (im->dirty)) __xre_image_dirty_hash_del(im);
if ((im->free_data) && (im->data)) free(im->data); if ((im->free_data) && (im->data)) free(im->data);
if (im->surface) _xr_render_surface_free(im->surface); 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) else if (im->im)
{ {
evas_common_image_unref(im->im); evas_cache_image_drop(im->im);
im->im = NULL; im->im = NULL;
if (im->free_data) if (im->free_data)
{ {
@ -360,7 +360,7 @@ _xre_image_resize(XR_Image *im, int w, int h)
} }
if (im->im) if (im->im)
{ {
evas_common_image_unref(im->im); evas_cache_image_drop(im->im);
im->im = NULL; im->im = NULL;
} }
if (!im->cs.no_free) if (!im->cs.no_free)
@ -421,7 +421,7 @@ _xre_image_data_put(XR_Image *im, void *data)
if (im->im) if (im->im)
{ {
if (data == im->im->image->data) return; if (data == im->im->image->data) return;
evas_common_image_unref(im->im); evas_cache_image_drop(im->im);
im->im = NULL; im->im = NULL;
} }
if (im->cs.data == data) return; if (im->cs.data == data) return;
@ -636,7 +636,7 @@ _xre_image_surface_gen(XR_Image *im)
im->w + 2, 1); im->w + 2, 1);
if ((im->im) && (!im->dirty)) if ((im->im) && (!im->dirty))
{ {
evas_common_image_unref(im->im); evas_cache_image_drop(im->im);
im->im = NULL; im->im = NULL;
} }
if (tdata) free(tdata); if (tdata) free(tdata);

View File

@ -199,7 +199,7 @@ __xre_image_real_free(XR_Image *im)
if (im->file) evas_stringshare_del(im->file); if (im->file) evas_stringshare_del(im->file);
if (im->key) evas_stringshare_del(im->key); if (im->key) evas_stringshare_del(im->key);
if (im->fkey) free(im->fkey); 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->data) && (im->dirty)) __xre_image_dirty_hash_del(im);
if ((im->free_data) && (im->data)) free(im->data); if ((im->free_data) && (im->data)) free(im->data);
if (im->surface) _xr_render_surface_free(im->surface); 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 (im2) im2->alpha = im->alpha;
if ((im->im) && (!im->dirty)) if ((im->im) && (!im->dirty))
{ {
evas_common_image_unref(im->im); evas_cache_image_drop(im->im);
im->im = NULL; im->im = NULL;
} }
return im2; return im2;
@ -335,9 +335,9 @@ _xre_image_resize(XR_Image *im, int w, int h)
else if (im->im) else if (im->im)
{ {
RGBA_Image *im_old; RGBA_Image *im_old;
im_old = im->im; 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) if (!im->im)
{ {
im->im = im_old; im->im = im_old;
@ -348,22 +348,26 @@ _xre_image_resize(XR_Image *im, int w, int h)
} }
return; 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); evas_common_load_image_data_from_file(im_old);
if (im_old->image->data) if (im_old->image->data)
{ {
int x = 0, y = 0, ww, hh; int x = 0, y = 0, ww, hh;
ww = w; hh = h; ww = w; hh = h;
RECTS_CLIP_TO_RECT(x, y, ww, hh, 0, 0, im->w, im->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_blit_rectangle(im_old, im->im, 0, 0, ww, hh, 0, 0);
evas_common_cpu_end_opt(); evas_common_cpu_end_opt();
} }
im->free_data = 1; im->free_data = 1;
/* FIXME: Hum ? */
im->data = im->im->image->data; im->data = im->im->image->data;
im->im->image->data = NULL; im->im->image->data = NULL;
evas_common_image_unref(im->im); evas_cache_image_drop(im->im);
im->im = NULL; im->im = NULL;
evas_common_image_unref(im_old); evas_cache_image_drop(im_old);
__xre_image_dirty_hash_add(im); __xre_image_dirty_hash_add(im);
} }
else else
@ -426,7 +430,7 @@ _xre_image_data_put(XR_Image *im, void *data)
if (data == imdata) return; if (data == imdata) return;
if (im->im) if (im->im)
{ {
evas_common_image_unref(im->im); evas_cache_image_drop(im->im);
im->im = NULL; im->im = NULL;
} }
} }
@ -580,7 +584,7 @@ _xre_image_surface_gen(XR_Image *im)
1, 1); 1, 1);
if ((im->im) && (!im->dirty)) if ((im->im) && (!im->dirty))
{ {
evas_common_image_unref(im->im); evas_cache_image_drop(im->im);
im->im = NULL; im->im = NULL;
} }
} }