diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 68b1b52a24..bcb1d84ab4 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1391,6 +1391,7 @@ struct _Evas_Func void (*image_prepare) (void *data, void *image); void *(*image_surface_noscale_new) (void *data, int w, int h, int alpha); + void (*image_surface_noscale_region_get)(void *data, void *image, int *x, int *y, int *w, int *h); int (*image_native_init) (void *data, Evas_Native_Surface_Type type); void (*image_native_shutdown) (void *data, Evas_Native_Surface_Type type); diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h index 8b56abe7b7..44999916f7 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h @@ -651,6 +651,7 @@ void evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt); Evas_GL_Texture *evas_gl_common_texture_new(Evas_Engine_GL_Context *gc, RGBA_Image *im, Eina_Bool disable_atlas); Evas_GL_Texture *evas_gl_common_texture_native_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, Evas_GL_Image *im); Evas_GL_Texture *evas_gl_common_texture_render_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, int stencil); +Evas_GL_Texture *evas_gl_common_texture_render_noscale_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha); Evas_GL_Texture *evas_gl_common_texture_dynamic_new(Evas_Engine_GL_Context *gc, Evas_GL_Image *im); void evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im); void evas_gl_common_texture_upload(Evas_GL_Texture *tex, RGBA_Image *im, unsigned int bytes_count); @@ -680,6 +681,7 @@ void evas_gl_common_image_scale_hint_set(Evas_GL_Image *im, int hin void evas_gl_common_image_content_hint_set(Evas_GL_Image *im, int hint); void evas_gl_common_image_cache_flush(Evas_Engine_GL_Context *gc); Evas_GL_Image *evas_gl_common_image_surface_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, int stencil); +Evas_GL_Image *evas_gl_common_image_surface_noscale_new(Evas_Engine_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); void evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im); void evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int npoints, RGBA_Map_Point *p, int smooth, int level); diff --git a/src/modules/evas/engines/gl_common/evas_gl_image.c b/src/modules/evas/engines/gl_common/evas_gl_image.c index 99f75be2d2..0d9a5ddb21 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_image.c +++ b/src/modules/evas/engines/gl_common/evas_gl_image.c @@ -743,6 +743,28 @@ evas_gl_common_image_surface_new(Evas_Engine_GL_Context *gc, unsigned int w, uns return im; } +Evas_GL_Image * +evas_gl_common_image_surface_noscale_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha) +{ + Evas_GL_Image *im; + + if (((int)w > gc->shared->info.max_texture_size) || + ((int)h > gc->shared->info.max_texture_size)) + return NULL; + + im = calloc(1, sizeof(Evas_GL_Image)); + if (!im) return NULL; + im->references = 1; + im->gc = gc; + im->cs.space = EVAS_COLORSPACE_ARGB8888; + im->alpha = alpha; + im->w = w; + im->h = h; + im->tex = evas_gl_common_texture_render_noscale_new(gc, w, h, alpha); + im->tex_only = 1; + return im; +} + void evas_gl_common_image_dirty(Evas_GL_Image *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h) { diff --git a/src/modules/evas/engines/gl_common/evas_gl_texture.c b/src/modules/evas/engines/gl_common/evas_gl_texture.c index ff2737f3d5..1d4b7b192e 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_texture.c +++ b/src/modules/evas/engines/gl_common/evas_gl_texture.c @@ -493,6 +493,7 @@ _pool_tex_find(Evas_Engine_GL_Context *gc, int w, int h, if (th2 < 0) return NULL; EINA_LIST_FOREACH(gc->shared->tex.atlas[th2], l, pt) { + if (pt->render) continue; if ((*apt = _pool_tex_alloc(pt, w, h, u, v)) != NULL) { gc->shared->tex.atlas[th2] = @@ -673,6 +674,65 @@ _pool_tex_render_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, in return pt; } +static Evas_GL_Texture_Pool * +_pool_tex_render_find(Evas_Engine_GL_Context *gc, int w, int h, + GLenum intformat, GLenum format, int *u, int *v, + Eina_Rectangle **apt, int atlas_w, Eina_Bool disable_atlas) +{ + Evas_GL_Texture_Pool *pt = NULL; + Eina_List *l; + int th2; + int pool_h; + /*Return texture unit without atlas*/ + if (disable_atlas) + { + pt = _pool_tex_render_new(gc, w, h, intformat, format, EINA_FALSE); + return pt ? pt : NULL; + } + if (atlas_w > gc->shared->info.max_texture_size) + atlas_w = gc->shared->info.max_texture_size; + if ((w > gc->shared->info.tune.atlas.max_w) || + (h > gc->shared->info.tune.atlas.max_h) || + (!gc->shared->info.etc1_subimage && (intformat == etc1_fmt))) + { + pt = _pool_tex_render_new(gc, w, h, intformat, format, EINA_FALSE); + if (!pt) return NULL; + gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, pt); + pt->fslot = -1; + pt->whole = 1; + *apt = _pool_tex_alloc(pt, w, h, u, v); + return pt; + } + + th2 = _tex_format_index(intformat); + if (th2 < 0) return NULL; + EINA_LIST_FOREACH(gc->shared->tex.atlas[th2], l, pt) + { + if (!pt->render) continue; + if ((*apt = _pool_tex_alloc(pt, w, h, u, v)) != NULL) + { + gc->shared->tex.atlas[th2] = + eina_list_promote_list(gc->shared->tex.atlas[th2], l); + return pt; + } + } + pool_h = atlas_w; + if ( h > pool_h || w > atlas_w ) + { + atlas_w = gc->shared->info.tune.atlas.max_w; + pool_h = gc->shared->info.tune.atlas.max_h; + } + pt = _pool_tex_render_new(gc, atlas_w, pool_h, intformat, format, EINA_FALSE); + if (!pt) return NULL; + gc->shared->tex.atlas[th2] = + eina_list_prepend(gc->shared->tex.atlas[th2], pt); + pt->fslot = th2; + + *apt = _pool_tex_alloc(pt, w, h, u, v); + + return pt; +} + static Evas_GL_Texture_Pool * _pool_tex_native_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, int format, Evas_GL_Image *im) { @@ -983,7 +1043,7 @@ pt_unref(Evas_GL_Texture_Pool *pt) pt->references--; if (pt->references != 0) return; - if ((pt->gc) && !((pt->render) || (pt->native))) + if ((pt->gc) && !(pt->native)) { if (pt->whole) pt->gc->shared->tex.whole = @@ -1054,6 +1114,37 @@ evas_gl_common_texture_render_new(Evas_Engine_GL_Context *gc, unsigned int w, un return tex; } +Evas_GL_Texture * +evas_gl_common_texture_render_noscale_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha) +{ + Evas_GL_Texture *tex; + int u = 0, v = 0; + int lformat; + + lformat = _evas_gl_texture_search_format(alpha, gc->shared->info.bgra, EVAS_COLORSPACE_ARGB8888); + if (lformat < 0) return NULL; + + tex = evas_gl_common_texture_alloc(gc, w, h, alpha); + if (!tex) return NULL; + tex->pt = _pool_tex_render_find(gc, w, h, + *matching_format[lformat].intformat, + *matching_format[lformat].format, + &u, &v, &tex->apt, + // XXX: should this be another atlas size? + gc->shared->info.tune.atlas.max_alloc_size, + EINA_FALSE); + if (!tex->pt) + { + evas_gl_common_texture_light_free(tex); + return NULL; + } + tex->x = u; + tex->y = v; + + tex->pt->references++; + return tex; +} + Evas_GL_Texture * evas_gl_common_texture_dynamic_new(Evas_Engine_GL_Context *gc, Evas_GL_Image *im) { diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index dcd66f79ad..4c5a168253 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -3106,10 +3106,30 @@ eng_image_surface_noscale_new(void *engdata, int w, int h, int alpha) re->window_use(re->software.ob); gl_context = re->window_gl_context_get(re->software.ob); - // XXX: FIXME: need a special surface new func that can use an atlas - return evas_gl_common_image_surface_new(gl_context, w, h, alpha); + return evas_gl_common_image_surface_noscale_new(gl_context, w, h, alpha); } +static void +eng_image_surface_noscale_region_get(void *engdata, void *image, int *x, int *y, int *w, int *h) +{ + Evas_GL_Image *im = image; + + if (im) + { + *x = im->tex->x; + *y = im->tex->y; + *w = im->w; + *h = im->h; + return; + } + else + { + *x = 0; + *y = 0; + *w = 0; + *h = 0; + } +} static int module_open(Evas_Module *em) @@ -3198,6 +3218,7 @@ module_open(Evas_Module *em) ORD(image_prepare); ORD(image_surface_noscale_new); + ORD(image_surface_noscale_region_get); ORD(font_cache_flush); ORD(font_cache_set); diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 674c93eac9..69536aecf0 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -1955,6 +1955,28 @@ eng_image_surface_noscale_new(void *engdata, int w, int h, int alpha) return eng_image_map_surface_new(engdata, w, h, alpha); } +static void +eng_image_surface_noscale_region_get(void *engdata, void *image, int *x, int *y, int *w, int *h) +{ + RGBA_Image *im = image; + + if (im) + { + *x = 0; + *y = 0; + *w = im->cache_entry.w; + *h = im->cache_entry.h; + return; + } + else + { + *x = 0; + *y = 0; + *w = 0; + *h = 0; + } +} + static void _image_flip_horizontal(DATA32 *pixels_out, const DATA32 *pixels_in, int iw, int ih) @@ -4669,6 +4691,7 @@ static Evas_Func func = eng_image_data_slice_add, eng_image_prepare, eng_image_surface_noscale_new, + eng_image_surface_noscale_region_get, eng_image_native_init, eng_image_native_shutdown, eng_image_native_set,