improvement to gl engine wrt. caching.

SVN revision: 56801
This commit is contained in:
Carsten Haitzler 2011-02-08 11:41:38 +00:00
parent e2bd68dc91
commit 7881c0b849
5 changed files with 116 additions and 2 deletions

View File

@ -57,3 +57,10 @@
clip on the object. This is still buggy.
* Software support for arbitrary maps. So you can use any size map
(not just 4 points) for maps. Once again this is a little buggy.
2011-02-02 Carsten Haitzler (The Rasterman)
* GL engine gets a speculative texture cache to shadow the
normal image cache to avoid excess texture uploads when
cycling images often. Should improve performance in some
cases.

View File

@ -125,6 +125,8 @@ struct _Evas_GL_Shared
{
Eina_List *images;
int images_size;
struct {
GLint max_texture_units;
GLint max_texture_size;
@ -471,6 +473,7 @@ void evas_gl_common_image_native_enable(Evas_GL_Image *im);
void evas_gl_common_image_native_disable(Evas_GL_Image *im);
void evas_gl_common_image_scale_hint_set(Evas_GL_Image *im, int hint);
void evas_gl_common_image_content_hint_set(Evas_GL_Image *im, int hint);
void evas_gl_common_image_cache_flush(Evas_GL_Context *gc);
void evas_gl_common_image_free(Evas_GL_Image *im);
Evas_GL_Image *evas_gl_common_image_surface_new(Evas_GL_Context *gc, unsigned int w, unsigned int h, int alpha);
void evas_gl_common_image_dirty(Evas_GL_Image *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h);

View File

@ -30,11 +30,14 @@ evas_gl_common_image_load(Evas_GL_Context *gc, const char *file, const char *key
im_im = evas_common_load_image_from_file(file, key, lo, error);
if (!im_im) return NULL;
// FIXME: keep unreffed shared images around
EINA_LIST_FOREACH(gc->shared->images, l, im)
{
if (im->im == im_im)
{
evas_cache_image_drop(&im_im->cache_entry);
// why did i put this here? i think to free the rgba pixel data once a texture
// exists.
// evas_cache_image_drop(&im_im->cache_entry);
gc->shared->images = eina_list_remove_list(gc->shared->images, l);
gc->shared->images = eina_list_prepend(gc->shared->images, im);
im->references++;
@ -230,6 +233,8 @@ evas_gl_common_image_native_enable(Evas_GL_Image *im)
im->cs.no_free = 0;
if (im->cached)
{
if (im->references == 0)
im->gc->shared->images_size -= (im->w * im->h);
im->gc->shared->images = eina_list_remove(im->gc->shared->images, im);
im->cached = 0;
}
@ -302,6 +307,8 @@ evas_gl_common_image_content_hint_set(Evas_GL_Image *im, int hint)
im->cs.no_free = 0;
if (im->cached)
{
if (im->references == 0)
im->gc->shared->images_size -= (im->w * im->h);
im->gc->shared->images = eina_list_remove(im->gc->shared->images, im);
im->cached = 0;
}
@ -342,6 +349,59 @@ evas_gl_common_image_content_hint_set(Evas_GL_Image *im, int hint)
}
}
static void
_evas_gl_image_cache_trim(Evas_GL_Context *gc)
{
int size = evas_common_image_get_cache();
while (gc->shared->images_size > size)
{
Evas_GL_Image *im2;
Eina_List *l;
EINA_LIST_REVERSE_FOREACH(gc->shared->images, l, im2)
{
if (im2->references == 0)
{
im2->cached = 0;
im2->gc->shared->images =
eina_list_remove_list(im2->gc->shared->images, l);
im2->gc->shared->images_size -= (im2->w * im2->h);
evas_gl_common_image_free(im2);
break;
}
}
if (!l)
{
printf("EEEK images_size > 0 but no 0 ref images in cache\n");
break; // something went wrong
}
}
}
static Eina_Bool
_evas_gl_image_cache_add(Evas_GL_Image *im)
{
if (im->references == 0)
{
im->gc->shared->images_size += (im->w * im->h);
_evas_gl_image_cache_trim(im->gc);
return EINA_TRUE;
}
else
{
im->gc->shared->images = eina_list_remove(im->gc->shared->images, im);
im->cached = 0;
}
return EINA_FALSE;
}
void
evas_gl_common_image_cache_flush(Evas_GL_Context *gc)
{
_evas_gl_image_cache_trim(gc);
}
void
evas_gl_common_image_free(Evas_GL_Image *im)
{
@ -355,7 +415,10 @@ evas_gl_common_image_free(Evas_GL_Image *im)
{
if (!im->cs.no_free) free(im->cs.data);
}
if (im->cached) im->gc->shared->images = eina_list_remove(im->gc->shared->images, im);
if (im->cached)
{
if (_evas_gl_image_cache_add(im)) return;
}
if (im->im) evas_cache_image_drop(&im->im->cache_entry);
if (im->tex) evas_gl_common_texture_free(im->tex);
free(im);

View File

@ -847,6 +847,7 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
// printf("tex upload %ix%i\n", im->cache_entry.w, im->cache_entry.h);
// +-+
// +-+
//

View File

@ -1814,6 +1814,42 @@ eng_image_content_hint_get(void *data __UNUSED__, void *image)
return gim->content_hint;
}
static void
eng_image_cache_flush(void *data __UNUSED__)
{
Render_Engine *re;
int tmp_size;
re = (Render_Engine *)data;
tmp_size = evas_common_image_get_cache();
evas_common_image_set_cache(0);
evas_common_rgba_image_scalecache_flush();
evas_gl_common_image_cache_flush(re->win->gl_context);
evas_common_image_set_cache(tmp_size);
}
static void
eng_image_cache_set(void *data __UNUSED__, int bytes)
{
Render_Engine *re;
re = (Render_Engine *)data;
evas_common_image_set_cache(bytes);
evas_common_rgba_image_scalecache_size_set(bytes);
evas_gl_common_image_cache_flush(re->win->gl_context);
}
static int
eng_image_cache_get(void *data __UNUSED__)
{
Render_Engine *re;
re = (Render_Engine *)data;
return evas_common_image_get_cache();
}
static void
eng_image_stride_get(void *data __UNUSED__, void *image, int *stride)
{
@ -1948,6 +1984,10 @@ module_open(Evas_Module *em)
ORD(image_content_hint_set);
ORD(image_content_hint_get);
ORD(image_cache_flush);
ORD(image_cache_set);
ORD(image_cache_get);
/* now advertise out own api */
em->functions = (void *)(&func);