forked from enlightenment/efl
evas engines - add more support for noscale pixel buffers esp in gl
for gl noscale buffers are texture atlases that are fbo's. the point is never to scale or transofmr them but to render them pixel for pixel and just store pre-rendered data where its cheaper to do this than rebuild every time. this is the enigne infra for sw and gl with the gl code... it SHOULD work... in theory...
This commit is contained in:
parent
f7b2ec8bff
commit
3eb0df1022
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue