cache image scalings... :)

SVN revision: 4403
This commit is contained in:
Carsten Haitzler 2001-03-18 23:21:35 +00:00
parent 012b448a49
commit 183d80c31c
2 changed files with 256 additions and 24 deletions

View File

@ -1,10 +1,17 @@
#include "evas_imlib_routines.h" #include "evas_imlib_routines.h"
static void __evas_imlib_image_cache_flush(Display *disp); static void __evas_imlib_image_cache_flush(Display *disp);
static void __evas_imlib_image_cache_clean(void);
static Evas_Imlib_Image *__evas_imlib_image_cache_find(char *file);
static int __evas_anti_alias = 1; static int __evas_anti_alias = 1;
static int __evas_image_cache = 8 * 1024 * 1024;
static int __evas_image_cache_used = 0;
static Evas_List drawable_list = NULL; static Evas_List drawable_list = NULL;
static Evas_List images = NULL;
/* the current clip region and color */ /* the current clip region and color */
static int __evas_clip = 0; static int __evas_clip = 0;
static int __evas_clip_x = 0; static int __evas_clip_x = 0;
@ -23,11 +30,68 @@ static int __evas_clip_a = 0;
static void static void
__evas_imlib_image_cache_flush(Display *disp) __evas_imlib_image_cache_flush(Display *disp)
{ {
int size; __evas_imlib_image_cache_empty(disp);
}
static void
__evas_imlib_image_cache_clean(void)
{
while (__evas_image_cache_used > __evas_image_cache)
{
Evas_Imlib_Image *last;
Evas_List l;
for (l = images; l; l = l->next)
{
if (!l->next) last = l->data;
}
images = evas_list_remove(images, last);
imlib_context_set_image(last->image);
__evas_image_cache_used -=
imlib_image_get_width() *
imlib_image_get_height() * 4;
if (last->scaled.image)
{
imlib_context_set_image(last->scaled.image);
__evas_image_cache_used -=
imlib_image_get_width() *
imlib_image_get_height() * 4;
}
imlib_free_image();
free(last->file);
free(last);
}
}
static Evas_Imlib_Image *
__evas_imlib_image_cache_find(char *file)
{
Evas_Imlib_Image *im;
Evas_List l;
size = imlib_get_cache_size(); for (l = images; l; l = l->next)
imlib_set_cache_size(0); {
imlib_set_cache_size(size); im = l->data;
if (!strcmp(im->file, file))
{
im->references++;
images = evas_list_remove(images, im);
images = evas_list_prepend(images, im);
imlib_context_set_image(im->image);
__evas_image_cache_used -=
imlib_image_get_width() *
imlib_image_get_height() * 4;
if (im->scaled.image)
{
imlib_context_set_image(im->scaled.image);
__evas_image_cache_used -=
imlib_image_get_width() *
imlib_image_get_height() * 4;
}
return im;
}
}
return NULL;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -36,15 +100,44 @@ __evas_imlib_image_cache_flush(Display *disp)
Evas_Imlib_Image * Evas_Imlib_Image *
__evas_imlib_image_new_from_file(Display *disp, char *file) __evas_imlib_image_new_from_file(Display *disp, char *file)
{ {
return (Evas_Imlib_Image *)imlib_load_image(file); Evas_Imlib_Image *im;
Imlib_Image image;
im = __evas_imlib_image_cache_find(file);
if (im) return im;
image = imlib_load_image(file);
if (!image) return NULL;
im = malloc(sizeof(Evas_Imlib_Image));
im->file = strdup(file);
im->image = image;
im->scaled.aa = 0;
im->scaled.image = NULL;
im->references = 1;
images = evas_list_prepend(images, im);
return im;
} }
void void
__evas_imlib_image_free(Evas_Imlib_Image *im) __evas_imlib_image_free(Evas_Imlib_Image *im)
{ {
imlib_context_set_image((Imlib_Image)im); im->references--;
imlib_free_image(); if (im->references == 0)
{
imlib_context_set_image(im->image);
__evas_image_cache_used +=
imlib_image_get_width() *
imlib_image_get_height() * 4;
if (im->scaled.image)
{
imlib_context_set_image(im->scaled.image);
__evas_image_cache_used +=
imlib_image_get_width() *
imlib_image_get_height() * 4;
}
__evas_imlib_image_cache_clean();
}
} }
void void
@ -52,21 +145,23 @@ __evas_imlib_image_cache_empty(Display *disp)
{ {
int size; int size;
size = imlib_get_cache_size(); size = __evas_image_cache;
imlib_set_cache_size(0); __evas_image_cache = 0;
imlib_set_cache_size(size); __evas_imlib_image_cache_clean();
__evas_image_cache = size;
} }
void void
__evas_imlib_image_cache_set_size(Display *disp, int size) __evas_imlib_image_cache_set_size(Display *disp, int size)
{ {
imlib_set_cache_size(size); __evas_image_cache = size;
__evas_imlib_image_cache_clean();
} }
int int
__evas_imlib_image_cache_get_size(Display *disp) __evas_imlib_image_cache_get_size(Display *disp)
{ {
return imlib_get_cache_size(); return __evas_image_cache;
} }
void void
@ -134,16 +229,144 @@ __evas_imlib_image_draw(Evas_Imlib_Image *im,
if (__evas_clip) if (__evas_clip)
imlib_context_set_cliprect(__evas_clip_x - up->x, imlib_context_set_cliprect(__evas_clip_x - up->x,
__evas_clip_y - up->y, __evas_clip_y - up->y,
__evas_clip_w, __evas_clip_w,
__evas_clip_h); __evas_clip_h);
else imlib_context_set_cliprect(0, 0, 0, 0); else imlib_context_set_cliprect(0, 0, 0, 0);
if (!up->image) if (!up->image)
up->image = imlib_create_image(up->w, up->h); up->image = imlib_create_image(up->w, up->h);
imlib_context_set_image(up->image); /* if our src and dest are 1:1 scaling.. use original */
imlib_blend_image_onto_image(im, 0, if ((dst_w == src_w) && (dst_h == src_h))
src_x, src_y, src_w, src_h, {
dst_x - up->x, dst_y - up->y, dst_w, dst_h); imlib_context_set_image(up->image);
imlib_blend_image_onto_image(im->image, 0,
src_x, src_y, src_w, src_h,
dst_x - up->x, dst_y - up->y, dst_w, dst_h);
if (im->scaled.image)
{
imlib_context_set_image(im->scaled.image);
imlib_free_image();
im->scaled.image = NULL;
}
}
/* if we have a scaled image stored... */
else if ((im->scaled.image) && (im->scaled.aa == __evas_anti_alias))
{
Imlib_Border bd;
/* if the image has any border scaling... dont do it */
imlib_context_set_image(im->image);
imlib_image_get_border(&bd);
if ((bd.left != 0) ||
(bd.right != 0) ||
(bd.top != 0) ||
(bd.bottom != 0))
{
imlib_context_set_image(up->image);
imlib_blend_image_onto_image(im->image, 0,
src_x, src_y, src_w, src_h,
dst_x - up->x, dst_y - up->y, dst_w, dst_h);
}
else
{
int scw, sch, iw, ih;
imlib_context_set_image(im->image);
iw = imlib_image_get_width();
ih = imlib_image_get_height();
imlib_context_set_image(im->scaled.image);
scw = imlib_image_get_width();
sch = imlib_image_get_height();
/* if the scaled image is the same scaled output as needed here use it */
/* if we are using the WHOLE src image */
if ((src_x == 0) && (src_y == 0) &&
(src_w == iw) && (src_h == ih) &&
/* if our destination lies withint the output viewport and clip */
((dst_x >= 0) && (dst_y >= 0) &&
(dst_w + dst_x <= win_w) && (dst_h + dst_y <= win_h) &&
((!__evas_clip) ||
((dst_x >= __evas_clip_x) && (dst_y >= __evas_clip_y) &&
(dst_w + dst_x <= __evas_clip_w) && (dst_h + dst_y <= __evas_clip_h)))))
{
if ((scw == dst_w) && (sch == dst_h))
{
imlib_context_set_image(up->image);
imlib_blend_image_onto_image(im->scaled.image, 0,
0, 0, dst_w, dst_h,
dst_x - up->x, dst_y - up->y, dst_w, dst_h);
}
else
{
imlib_context_set_image(im->scaled.image);
imlib_free_image();
im->scaled.image = NULL;
imlib_context_set_image(im->image);
im->scaled.image = imlib_create_cropped_scaled_image(0, 0, iw, ih,
dst_w, dst_h);
im->scaled.aa = __evas_anti_alias;
imlib_context_set_image(up->image);
imlib_blend_image_onto_image(im->scaled.image, 0,
0, 0, dst_w, dst_h,
dst_x - up->x, dst_y - up->y, dst_w, dst_h);
}
}
/* just draw normally */
else
{
imlib_context_set_image(up->image);
imlib_blend_image_onto_image(im->image, 0,
src_x, src_y, src_w, src_h,
dst_x - up->x, dst_y - up->y, dst_w, dst_h);
}
}
}
/* if we dont and the image isnt clipped and its not original size */
else
{
int iw, ih;
if (im->scaled.image)
{
int scw, sch;
imlib_context_set_image(im->scaled.image);
scw = imlib_image_get_width();
sch = imlib_image_get_height();
imlib_context_set_image(im->scaled.image);
imlib_free_image();
im->scaled.image = NULL;
}
imlib_context_set_image(im->image);
iw = imlib_image_get_width();
ih = imlib_image_get_height();
/* if we are using the WHOLE src image */
if ((src_x == 0) && (src_y == 0) &&
(src_w == iw) && (src_h == ih) &&
/* if our destination lies withint the output viewport and clip */
((dst_x >= 0) && (dst_y >= 0) &&
(dst_w + dst_x <= win_w) && (dst_h + dst_y <= win_h) &&
((!__evas_clip) ||
((dst_x >= __evas_clip_x) && (dst_y >= __evas_clip_y) &&
(dst_w + dst_x <= __evas_clip_w) && (dst_h + dst_y <= __evas_clip_h)))))
{
imlib_context_set_image(im->image);
im->scaled.image = imlib_create_cropped_scaled_image(0, 0, iw, ih,
dst_w, dst_h);
im->scaled.aa = __evas_anti_alias;
imlib_context_set_image(up->image);
imlib_blend_image_onto_image(im->scaled.image, 0,
0, 0, dst_w, dst_h,
dst_x - up->x, dst_y - up->y, dst_w, dst_h);
}
else
{
imlib_context_set_image(up->image);
imlib_blend_image_onto_image(im->image, 0,
src_x, src_y, src_w, src_h,
dst_x - up->x, dst_y - up->y, dst_w, dst_h);
}
}
} }
} }
} }
@ -158,14 +381,14 @@ __evas_imlib_image_draw(Evas_Imlib_Image *im,
int int
__evas_imlib_image_get_width(Evas_Imlib_Image *im) __evas_imlib_image_get_width(Evas_Imlib_Image *im)
{ {
imlib_context_set_image((Imlib_Image)im); imlib_context_set_image(im->image);
return imlib_image_get_width(); return imlib_image_get_width();
} }
int int
__evas_imlib_image_get_height(Evas_Imlib_Image *im) __evas_imlib_image_get_height(Evas_Imlib_Image *im)
{ {
imlib_context_set_image((Imlib_Image)im); imlib_context_set_image(im->image);
return imlib_image_get_height(); return imlib_image_get_height();
} }
@ -175,7 +398,7 @@ __evas_imlib_image_set_borders(Evas_Imlib_Image *im, int left, int right,
{ {
Imlib_Border bd; Imlib_Border bd;
imlib_context_set_image((Imlib_Image)im); imlib_context_set_image(im->image);
bd.left = left; bd.left = left;
bd.right = right; bd.right = right;
bd.top = top; bd.top = top;
@ -949,8 +1172,6 @@ __evas_imlib_init(Display *disp, int screen, int colors)
if (!initted) if (!initted)
{ {
imlib_set_color_usage(colors); imlib_set_color_usage(colors);
imlib_set_font_cache_size(1024 * 1024);
imlib_set_cache_size(8 * 1024 * 1024);
initted = 1; initted = 1;
} }
imlib_set_color_usage(colors); imlib_set_color_usage(colors);

View File

@ -24,14 +24,25 @@
((SPANS_COMMON((x), (w), (xx), (ww))) && (SPANS_COMMON((y), (h), (yy), (hh)))) ((SPANS_COMMON((x), (w), (xx), (ww))) && (SPANS_COMMON((y), (h), (yy), (hh))))
#endif #endif
typedef void Evas_Imlib_Image;
typedef void Evas_Imlib_Font; typedef void Evas_Imlib_Font;
typedef struct _evas_imlib_image Evas_Imlib_Image;
typedef struct _evas_imlib_drawable Evas_Imlib_Drawable; typedef struct _evas_imlib_drawable Evas_Imlib_Drawable;
typedef struct _evas_imlib_update Evas_Imlib_Update; typedef struct _evas_imlib_update Evas_Imlib_Update;
typedef struct _evas_imlib_color Evas_Imlib_Color; typedef struct _evas_imlib_color Evas_Imlib_Color;
typedef struct _evas_imlib_gradient Evas_Imlib_Graident; typedef struct _evas_imlib_gradient Evas_Imlib_Graident;
struct _evas_imlib_image
{
char *file;
Imlib_Image image;
struct {
int aa;
Imlib_Image image;
} scaled;
int references;
};
struct _evas_imlib_drawable struct _evas_imlib_drawable
{ {
Display *disp; Display *disp;