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:
Carsten Haitzler 2016-11-17 12:26:46 +09:00
parent f7b2ec8bff
commit 3eb0df1022
6 changed files with 163 additions and 3 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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);

View File

@ -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,