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.
{
Eina_List *images;
+ int images_size;
+
struct {
GLint max_texture_units;
GLint max_texture_size;
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);
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++;
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;
}
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;
}
}
}
+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)
{
{
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);
}
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)
{
Evas_GL_Image *im = image;
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);