2003-09-07 04:24:48 -07:00
|
|
|
#include "evas_gl_private.h"
|
|
|
|
|
2009-11-06 03:32:23 -08:00
|
|
|
static const GLenum rgba_fmt = GL_RGBA;
|
|
|
|
static const GLenum rgba_ifmt = GL_RGBA;
|
2010-02-17 23:10:28 -08:00
|
|
|
//#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
|
|
|
|
//static const GLenum rgb_fmt = GL_RGBA;
|
|
|
|
//static const GLenum rgb_ifmt = GL_RGBA;
|
|
|
|
//#else
|
2010-01-22 02:52:53 -08:00
|
|
|
static const GLenum rgb_fmt = GL_RGBA;
|
2010-01-27 07:29:24 -08:00
|
|
|
static const GLenum rgb_ifmt = GL_RGB;
|
2010-02-17 23:10:28 -08:00
|
|
|
//#endif
|
|
|
|
#ifdef GL_BGRA
|
2010-08-09 19:35:07 -07:00
|
|
|
# if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
|
2010-08-01 23:46:38 -07:00
|
|
|
static const GLenum bgra_fmt = GL_BGRA;
|
|
|
|
static const GLenum bgra_ifmt = GL_BGRA;
|
|
|
|
static const GLenum bgr_fmt = GL_BGRA;
|
|
|
|
static const GLenum bgr_ifmt = GL_BGRA;
|
2010-08-09 19:35:07 -07:00
|
|
|
# else
|
2010-02-17 23:10:28 -08:00
|
|
|
static const GLenum bgra_fmt = GL_BGRA;
|
|
|
|
static const GLenum bgra_ifmt = GL_RGBA;
|
|
|
|
static const GLenum bgr_fmt = GL_BGRA;
|
|
|
|
static const GLenum bgr_ifmt = GL_RGB;
|
2010-08-01 23:46:38 -07:00
|
|
|
# endif
|
2010-01-27 07:29:24 -08:00
|
|
|
#endif
|
2011-08-23 08:13:40 -07:00
|
|
|
static const GLenum alpha_fmt = GL_ALPHA;
|
|
|
|
static const GLenum alpha_ifmt = GL_ALPHA;
|
|
|
|
static const GLenum lum_fmt = GL_LUMINANCE;
|
|
|
|
static const GLenum lum_ifmt = GL_LUMINANCE;
|
|
|
|
static const GLenum lum_alpha_fmt = GL_LUMINANCE_ALPHA;
|
|
|
|
static const GLenum lum_alpha_ifmt = GL_LUMINANCE_ALPHA;
|
|
|
|
static const GLenum rgba8_ifmt = GL_RGBA8;
|
|
|
|
static const GLenum rgba8_fmt = GL_BGRA;
|
2009-11-06 03:32:23 -08:00
|
|
|
|
2010-08-26 19:02:38 -07:00
|
|
|
static struct {
|
|
|
|
struct {
|
|
|
|
int num, pix;
|
|
|
|
} c, a, v, r, n, d;
|
2010-09-18 19:10:09 -07:00
|
|
|
} texinfo = {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}};
|
2010-08-26 19:02:38 -07:00
|
|
|
|
2010-09-18 16:16:25 -07:00
|
|
|
static void
|
2010-08-26 19:02:38 -07:00
|
|
|
_print_tex_count(void)
|
|
|
|
{
|
|
|
|
if (getenv("EVAS_GL_MEMINFO"))
|
|
|
|
{
|
|
|
|
fprintf(stderr,
|
|
|
|
"T: c:%i/%ik | a:%i/%ik | v:%i/%ik | r:%i/%ik | n:%i/%ik | d:%i/%ik\n",
|
|
|
|
texinfo.c.num, (texinfo.c.pix * 4) / 1024,
|
|
|
|
texinfo.a.num, (texinfo.a.pix ) / 1024,
|
|
|
|
texinfo.v.num, (texinfo.v.pix ) / 1024,
|
|
|
|
texinfo.r.num, (texinfo.r.pix * 4) / 1024,
|
|
|
|
texinfo.n.num, (texinfo.n.pix * 4) / 1024,
|
|
|
|
texinfo.d.num, (texinfo.d.pix * 4) / 1024
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
static int
|
|
|
|
_nearest_pow2(int num)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
2009-10-09 05:10:27 -07:00
|
|
|
unsigned int n = num - 1;
|
|
|
|
n |= n >> 1;
|
|
|
|
n |= n >> 2;
|
|
|
|
n |= n >> 4;
|
|
|
|
n |= n >> 8;
|
|
|
|
n |= n >> 16;
|
|
|
|
return n + 1;
|
|
|
|
}
|
2003-09-07 04:24:48 -07:00
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
static void
|
2011-03-16 10:32:49 -07:00
|
|
|
_tex_adjust(Evas_Engine_GL_Context *gc, int *w, int *h)
|
2009-10-09 05:10:27 -07:00
|
|
|
{
|
2009-10-22 01:53:25 -07:00
|
|
|
if (gc->shared->info.tex_npo2) return;
|
2009-10-13 02:40:39 -07:00
|
|
|
/*if (gc->shared->info.tex_rect) return;*/
|
2009-10-09 05:10:27 -07:00
|
|
|
*w = _nearest_pow2(*w);
|
|
|
|
*h = _nearest_pow2(*h);
|
|
|
|
}
|
2003-09-07 04:24:48 -07:00
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
static int
|
2011-03-16 10:32:49 -07:00
|
|
|
_tex_round_slot(Evas_Engine_GL_Context *gc, int h)
|
2009-10-09 05:10:27 -07:00
|
|
|
{
|
2009-10-22 01:53:25 -07:00
|
|
|
if (!gc->shared->info.tex_npo2)
|
2009-10-09 05:10:27 -07:00
|
|
|
h = _nearest_pow2(h);
|
2010-08-25 18:41:48 -07:00
|
|
|
return (h + gc->shared->info.tune.atlas.slot_size - 1) /
|
|
|
|
gc->shared->info.tune.atlas.slot_size;
|
2009-10-09 05:10:27 -07:00
|
|
|
}
|
2003-09-07 04:24:48 -07:00
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
static int
|
|
|
|
_tex_format_index(GLuint format)
|
|
|
|
{
|
|
|
|
switch (format)
|
2005-10-07 23:22:43 -07:00
|
|
|
{
|
2009-10-09 05:10:27 -07:00
|
|
|
case GL_RGBA:
|
2010-02-17 23:10:28 -08:00
|
|
|
#ifdef GL_BGRA
|
|
|
|
case GL_BGRA:
|
2011-06-17 00:47:28 -07:00
|
|
|
#endif
|
2009-10-09 05:10:27 -07:00
|
|
|
return 0;
|
|
|
|
case GL_RGB:
|
|
|
|
return 1;
|
|
|
|
case GL_ALPHA:
|
|
|
|
return 2;
|
2011-01-13 02:41:08 -08:00
|
|
|
case GL_LUMINANCE: // never used in atlas
|
2009-10-10 06:24:15 -07:00
|
|
|
return 3;
|
2009-10-09 05:10:27 -07:00
|
|
|
default:
|
2010-02-17 23:10:28 -08:00
|
|
|
return 0;
|
2005-10-07 23:22:43 -07:00
|
|
|
}
|
2009-10-09 05:10:27 -07:00
|
|
|
return 0;
|
|
|
|
}
|
2008-04-11 17:32:30 -07:00
|
|
|
|
2009-11-06 03:32:23 -08:00
|
|
|
static void
|
2009-11-06 07:13:29 -08:00
|
|
|
_tex_2d(int intfmt, int w, int h, int fmt, int type)
|
2009-11-06 03:32:23 -08:00
|
|
|
{
|
2009-11-06 07:13:29 -08:00
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, intfmt, w, h, 0, fmt, type, NULL);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-11-06 03:32:23 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-11-06 07:13:29 -08:00
|
|
|
_tex_sub_2d(int x, int y, int w, int h, int fmt, int type, const void *pix)
|
2009-11-06 03:32:23 -08:00
|
|
|
{
|
2009-11-06 07:13:29 -08:00
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, fmt, type, pix);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-11-06 03:32:23 -08:00
|
|
|
}
|
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
static Evas_GL_Texture_Pool *
|
2011-03-16 10:32:49 -07:00
|
|
|
_pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, GLenum format)
|
2009-10-09 05:10:27 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Texture_Pool *pt;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
|
|
|
|
if (!pt) return NULL;
|
2010-08-25 18:41:48 -07:00
|
|
|
h = _tex_round_slot(gc, h) * gc->shared->info.tune.atlas.slot_size;
|
2009-10-09 05:10:27 -07:00
|
|
|
_tex_adjust(gc, &w, &h);
|
|
|
|
pt->gc = gc;
|
|
|
|
pt->w = w;
|
|
|
|
pt->h = h;
|
2009-11-06 03:32:23 -08:00
|
|
|
pt->intformat = intformat;
|
2009-10-09 05:10:27 -07:00
|
|
|
pt->format = format;
|
2009-11-06 03:32:23 -08:00
|
|
|
pt->dataformat = GL_UNSIGNED_BYTE;
|
2009-10-09 05:10:27 -07:00
|
|
|
pt->references = 0;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-26 19:02:38 -07:00
|
|
|
if (format == alpha_fmt)
|
|
|
|
{
|
|
|
|
texinfo.a.num++;
|
|
|
|
texinfo.a.pix += pt->w * pt->h;
|
|
|
|
}
|
|
|
|
else if (format == lum_fmt)
|
|
|
|
{
|
|
|
|
texinfo.v.num++;
|
|
|
|
texinfo.v.pix += pt->w * pt->h;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
texinfo.c.num++;
|
|
|
|
texinfo.c.pix += pt->w * pt->h;
|
|
|
|
}
|
|
|
|
|
|
|
|
_print_tex_count();
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
glGenTextures(1, &(pt->texture));
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-10-09 05:10:27 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, pt->texture);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-10-12 17:37:16 -07:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-10-12 17:37:16 -07:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-10-12 17:37:16 -07:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-10-12 17:37:16 -07:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-11-06 03:32:23 -08:00
|
|
|
_tex_2d(pt->intformat, w, h, pt->format, pt->dataformat);
|
2010-08-08 20:27:59 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-10-09 05:10:27 -07:00
|
|
|
return pt;
|
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
static int
|
2010-09-18 19:10:09 -07:00
|
|
|
_pool_tex_alloc(Evas_GL_Texture_Pool *pt, int w, int h __UNUSED__, int *u, int *v, Eina_List **l_after)
|
2009-10-09 05:10:27 -07:00
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
Evas_GL_Texture *tex, *tex2;
|
|
|
|
int nx, d, b;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
if (pt->allocations)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
2009-10-09 05:10:27 -07:00
|
|
|
tex = pt->allocations->data;
|
|
|
|
// if firest tex is not at left edge...
|
|
|
|
if (tex->x > (0 + 1))
|
|
|
|
{
|
|
|
|
if ((tex->x - 1) >= w)
|
|
|
|
{
|
|
|
|
*u = 0;
|
|
|
|
*v = 0;
|
|
|
|
*l_after = NULL;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2003-09-07 04:24:48 -07:00
|
|
|
}
|
2009-10-09 05:10:27 -07:00
|
|
|
EINA_LIST_FOREACH(pt->allocations, l, tex)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
2009-10-09 05:10:27 -07:00
|
|
|
b = tex->x + tex->w + 2;
|
|
|
|
if (l->next)
|
|
|
|
{
|
|
|
|
tex2 = l->next->data;
|
|
|
|
nx = tex2->x - 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nx = pt->w - 1;
|
|
|
|
d = nx - b;
|
|
|
|
if (d >= w)
|
|
|
|
{
|
|
|
|
*u = b;
|
|
|
|
*v = 0;
|
|
|
|
*l_after = l;
|
|
|
|
return 1;
|
|
|
|
}
|
2003-09-07 04:24:48 -07:00
|
|
|
}
|
2009-10-09 05:10:27 -07:00
|
|
|
*l_after = NULL;
|
|
|
|
return 0;
|
2003-09-07 04:24:48 -07:00
|
|
|
}
|
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
static Evas_GL_Texture_Pool *
|
2011-06-17 00:47:28 -07:00
|
|
|
_pool_tex_find(Evas_Engine_GL_Context *gc, int w, int h,
|
|
|
|
int intformat, int format, int *u, int *v,
|
2009-11-06 03:32:23 -08:00
|
|
|
Eina_List **l_after, int atlas_w)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
2009-10-09 05:10:27 -07:00
|
|
|
Evas_GL_Texture_Pool *pt = NULL;
|
|
|
|
Eina_List *l;
|
|
|
|
int th, th2;
|
2010-08-25 21:37:43 -07:00
|
|
|
|
2010-08-25 18:41:48 -07:00
|
|
|
if (atlas_w > gc->shared->info.max_texture_size)
|
|
|
|
atlas_w = gc->shared->info.max_texture_size;
|
2011-06-17 00:47:28 -07:00
|
|
|
if ((w > gc->shared->info.tune.atlas.max_w) ||
|
2010-08-25 18:41:48 -07:00
|
|
|
(h > gc->shared->info.tune.atlas.max_h))
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
2009-11-06 03:32:23 -08:00
|
|
|
pt = _pool_tex_new(gc, w, h, intformat, format);
|
2009-10-13 02:40:39 -07:00
|
|
|
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, pt);
|
2009-10-09 05:10:27 -07:00
|
|
|
pt->slot = -1;
|
|
|
|
pt->fslot = -1;
|
|
|
|
pt->whole = 1;
|
|
|
|
*u = 0;
|
|
|
|
*v = 0;
|
|
|
|
*l_after = NULL;
|
|
|
|
return pt;
|
2003-09-07 04:24:48 -07:00
|
|
|
}
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
th = _tex_round_slot(gc, h);
|
2010-02-17 23:10:28 -08:00
|
|
|
th2 = _tex_format_index(intformat);
|
2009-10-13 02:40:39 -07:00
|
|
|
EINA_LIST_FOREACH(gc->shared->tex.atlas[th][th2], l, pt)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
2009-11-06 03:32:23 -08:00
|
|
|
if (_pool_tex_alloc(pt, w, h, u, v, l_after))
|
2009-10-09 05:10:27 -07:00
|
|
|
{
|
2011-06-17 00:47:28 -07:00
|
|
|
gc->shared->tex.atlas[th][th2] =
|
2009-10-13 02:40:39 -07:00
|
|
|
eina_list_remove_list(gc->shared->tex.atlas[th][th2], l);
|
2011-06-17 00:47:28 -07:00
|
|
|
gc->shared->tex.atlas[th][th2] =
|
2009-10-13 02:40:39 -07:00
|
|
|
eina_list_prepend(gc->shared->tex.atlas[th][th2], pt);
|
2009-10-09 05:10:27 -07:00
|
|
|
return pt;
|
|
|
|
}
|
2003-09-07 04:24:48 -07:00
|
|
|
}
|
2009-11-06 03:32:23 -08:00
|
|
|
pt = _pool_tex_new(gc, atlas_w, h, intformat, format);
|
2011-06-17 00:47:28 -07:00
|
|
|
gc->shared->tex.atlas[th][th2] =
|
2009-10-22 01:53:25 -07:00
|
|
|
eina_list_prepend(gc->shared->tex.atlas[th][th2], pt);
|
2009-10-09 05:10:27 -07:00
|
|
|
pt->slot = th;
|
|
|
|
pt->fslot = th2;
|
|
|
|
*u = 0;
|
|
|
|
*v = 0;
|
|
|
|
*l_after = NULL;
|
|
|
|
return pt;
|
|
|
|
}
|
2003-09-07 04:24:48 -07:00
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
Evas_GL_Texture *
|
2011-03-16 10:32:49 -07:00
|
|
|
evas_gl_common_texture_new(Evas_Engine_GL_Context *gc, RGBA_Image *im)
|
2009-10-09 05:10:27 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Texture *tex;
|
|
|
|
Eina_List *l_after = NULL;
|
|
|
|
int u = 0, v = 0;
|
2003-09-07 04:24:48 -07:00
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
tex = calloc(1, sizeof(Evas_GL_Texture));
|
|
|
|
if (!tex) return NULL;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
tex->gc = gc;
|
|
|
|
tex->references = 1;
|
2010-01-19 06:29:20 -08:00
|
|
|
|
|
|
|
if (im->cache_entry.flags.alpha)
|
|
|
|
{
|
2010-02-17 23:10:28 -08:00
|
|
|
if (gc->shared->info.bgra)
|
2010-08-25 18:41:48 -07:00
|
|
|
tex->pt = _pool_tex_find(gc, im->cache_entry.w + 2,
|
2011-06-17 00:47:28 -07:00
|
|
|
im->cache_entry.h + 1, bgra_ifmt, bgra_fmt,
|
2010-08-25 21:37:43 -07:00
|
|
|
&u, &v, &l_after,
|
|
|
|
gc->shared->info.tune.atlas.max_alloc_size);
|
2010-02-17 23:10:28 -08:00
|
|
|
else
|
2010-08-25 18:41:48 -07:00
|
|
|
tex->pt = _pool_tex_find(gc, im->cache_entry.w + 2,
|
2011-06-17 00:47:28 -07:00
|
|
|
im->cache_entry.h + 1, rgba_ifmt, rgba_fmt,
|
2010-08-25 18:41:48 -07:00
|
|
|
&u, &v, &l_after,
|
2010-08-25 21:37:43 -07:00
|
|
|
gc->shared->info.tune.atlas.max_alloc_size);
|
2010-01-19 06:29:20 -08:00
|
|
|
tex->alpha = 1;
|
|
|
|
}
|
|
|
|
else
|
2010-02-17 23:10:28 -08:00
|
|
|
{
|
|
|
|
if (gc->shared->info.bgra)
|
2011-06-17 00:47:28 -07:00
|
|
|
tex->pt = _pool_tex_find(gc, im->cache_entry.w + 3,
|
2010-08-25 18:41:48 -07:00
|
|
|
im->cache_entry.h + 1, bgr_ifmt, bgr_fmt,
|
|
|
|
&u, &v, &l_after,
|
|
|
|
gc->shared->info.tune.atlas.max_alloc_size);
|
2010-02-17 23:10:28 -08:00
|
|
|
else
|
2010-02-27 02:31:17 -08:00
|
|
|
#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
|
2011-06-17 00:47:28 -07:00
|
|
|
tex->pt = _pool_tex_find(gc, im->cache_entry.w + 3,
|
2010-08-25 18:41:48 -07:00
|
|
|
im->cache_entry.h + 1, rgba_ifmt, rgba_fmt,
|
|
|
|
&u, &v, &l_after,
|
|
|
|
gc->shared->info.tune.atlas.max_alloc_size);
|
2010-02-27 02:31:17 -08:00
|
|
|
#else
|
2011-06-17 00:47:28 -07:00
|
|
|
tex->pt = _pool_tex_find(gc, im->cache_entry.w + 3,
|
2010-08-25 18:41:48 -07:00
|
|
|
im->cache_entry.h + 1, rgb_ifmt, rgb_fmt,
|
|
|
|
&u, &v, &l_after,
|
|
|
|
gc->shared->info.tune.atlas.max_alloc_size);
|
2010-02-27 02:31:17 -08:00
|
|
|
#endif
|
2010-02-17 23:10:28 -08:00
|
|
|
}
|
2009-10-09 05:10:27 -07:00
|
|
|
if (!tex->pt)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
2009-10-09 05:10:27 -07:00
|
|
|
free(tex);
|
|
|
|
return NULL;
|
2003-09-07 04:24:48 -07:00
|
|
|
}
|
2009-10-09 05:10:27 -07:00
|
|
|
tex->x = u + 1;
|
|
|
|
tex->y = v;
|
|
|
|
tex->w = im->cache_entry.w;
|
|
|
|
tex->h = im->cache_entry.h;
|
|
|
|
if (l_after)
|
2011-06-17 00:47:28 -07:00
|
|
|
tex->pt->allocations =
|
2009-10-09 05:10:27 -07:00
|
|
|
eina_list_append_relative_list(tex->pt->allocations, tex, l_after);
|
|
|
|
else
|
2011-06-17 00:47:28 -07:00
|
|
|
tex->pt->allocations =
|
2009-10-09 05:10:27 -07:00
|
|
|
eina_list_prepend(tex->pt->allocations, tex);
|
|
|
|
tex->pt->references++;
|
|
|
|
evas_gl_common_texture_update(tex, im);
|
|
|
|
return tex;
|
2003-09-07 04:24:48 -07:00
|
|
|
}
|
|
|
|
|
2009-11-12 23:22:31 -08:00
|
|
|
static Evas_GL_Texture_Pool *
|
2011-03-16 10:32:49 -07:00
|
|
|
_pool_tex_render_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, int format)
|
2009-11-12 23:22:31 -08:00
|
|
|
{
|
|
|
|
Evas_GL_Texture_Pool *pt;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2009-11-12 23:22:31 -08:00
|
|
|
pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
|
|
|
|
if (!pt) return NULL;
|
2010-08-25 18:41:48 -07:00
|
|
|
h = _tex_round_slot(gc, h) * gc->shared->info.tune.atlas.slot_size;
|
2009-11-12 23:22:31 -08:00
|
|
|
_tex_adjust(gc, &w, &h);
|
|
|
|
pt->gc = gc;
|
|
|
|
pt->w = w;
|
|
|
|
pt->h = h;
|
|
|
|
pt->intformat = intformat;
|
|
|
|
pt->format = format;
|
2011-08-23 08:13:40 -07:00
|
|
|
if (intformat == rgba8_ifmt && format == rgba8_fmt)
|
|
|
|
pt->dataformat = GL_UNSIGNED_INT_8_8_8_8_REV;
|
|
|
|
else
|
|
|
|
pt->dataformat = GL_UNSIGNED_BYTE;
|
2010-01-23 05:49:54 -08:00
|
|
|
pt->render = 1;
|
2009-11-12 23:22:31 -08:00
|
|
|
pt->references = 0;
|
|
|
|
#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
|
2009-11-13 03:30:28 -08:00
|
|
|
# ifndef GL_FRAMEBUFFER
|
|
|
|
# define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
|
|
|
|
# endif
|
|
|
|
# ifndef GL_COLOR_ATTACHMENT0
|
|
|
|
# define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES
|
|
|
|
# endif
|
2009-11-12 23:22:31 -08:00
|
|
|
#else
|
2009-11-13 03:30:28 -08:00
|
|
|
# ifndef GL_FRAMEBUFFER
|
|
|
|
# define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
|
|
|
|
# endif
|
|
|
|
# ifndef GL_COLOR_ATTACHMENT0
|
|
|
|
# define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT
|
|
|
|
# endif
|
2011-06-17 00:47:28 -07:00
|
|
|
#endif
|
2010-08-26 19:02:38 -07:00
|
|
|
texinfo.r.num++;
|
|
|
|
texinfo.r.pix += pt->w * pt->h;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-26 19:02:38 -07:00
|
|
|
_print_tex_count();
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2009-11-12 23:22:31 -08:00
|
|
|
glGenTextures(1, &(pt->texture));
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-11-12 23:22:31 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, pt->texture);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-11-12 23:22:31 -08:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-11-12 23:22:31 -08:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-11-12 23:22:31 -08:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-11-12 23:22:31 -08:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-11-12 23:22:31 -08:00
|
|
|
_tex_2d(pt->intformat, w, h, pt->format, pt->dataformat);
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2009-11-21 02:51:51 -08:00
|
|
|
glsym_glGenFramebuffers(1, &(pt->fb));
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-11-21 02:51:51 -08:00
|
|
|
glsym_glBindFramebuffer(GL_FRAMEBUFFER, pt->fb);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-11-21 02:51:51 -08:00
|
|
|
glsym_glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pt->texture, 0);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-11-21 02:51:51 -08:00
|
|
|
glsym_glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-08 20:27:59 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-11-12 23:22:31 -08:00
|
|
|
return pt;
|
|
|
|
}
|
|
|
|
|
2010-01-21 00:44:11 -08:00
|
|
|
static Evas_GL_Texture_Pool *
|
2011-03-16 10:32:49 -07:00
|
|
|
_pool_tex_native_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, int format, Evas_GL_Image *im)
|
2010-01-21 00:44:11 -08:00
|
|
|
{
|
|
|
|
Evas_GL_Texture_Pool *pt;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-01-21 00:44:11 -08:00
|
|
|
pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
|
|
|
|
if (!pt) return NULL;
|
|
|
|
pt->gc = gc;
|
2011-06-17 00:47:28 -07:00
|
|
|
#ifdef GL_TEXTURE_RECTANGLE_ARB
|
2010-01-30 18:50:01 -08:00
|
|
|
if (im->native.target == GL_TEXTURE_RECTANGLE_ARB)
|
|
|
|
{
|
|
|
|
printf("REEEEEEEEECT\n");
|
2010-08-26 19:02:38 -07:00
|
|
|
pt->w = w;
|
|
|
|
pt->h = h;
|
2010-01-30 18:50:01 -08:00
|
|
|
}
|
|
|
|
else
|
2011-06-17 00:47:28 -07:00
|
|
|
#endif
|
2010-01-30 18:50:01 -08:00
|
|
|
{
|
2010-02-01 23:00:10 -08:00
|
|
|
// FIXME: handle po2 only textures
|
2010-01-30 18:50:01 -08:00
|
|
|
pt->w = w;
|
|
|
|
pt->h = h;
|
|
|
|
}
|
2010-01-21 00:44:11 -08:00
|
|
|
pt->intformat = intformat;
|
|
|
|
pt->format = format;
|
|
|
|
pt->dataformat = GL_UNSIGNED_BYTE;
|
|
|
|
pt->references = 0;
|
2010-01-23 05:49:54 -08:00
|
|
|
pt->native = 1;
|
2010-08-26 19:02:38 -07:00
|
|
|
texinfo.n.num++;
|
|
|
|
texinfo.n.pix += pt->w * pt->h;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-26 19:02:38 -07:00
|
|
|
_print_tex_count();
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-01-21 00:44:11 -08:00
|
|
|
glGenTextures(1, &(pt->texture));
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2010-01-30 18:50:01 -08:00
|
|
|
glBindTexture(im->native.target, pt->texture);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-01-21 01:42:26 -08:00
|
|
|
#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
|
2010-01-23 21:11:54 -08:00
|
|
|
#else
|
|
|
|
if (im->native.loose)
|
|
|
|
{
|
|
|
|
if (im->native.func.bind)
|
|
|
|
im->native.func.bind(im->native.func.data, im);
|
|
|
|
}
|
2010-01-21 01:42:26 -08:00
|
|
|
#endif
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-01-30 18:50:01 -08:00
|
|
|
glTexParameteri(im->native.target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2010-01-30 18:50:01 -08:00
|
|
|
glTexParameteri(im->native.target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2010-01-30 18:50:01 -08:00
|
|
|
glTexParameteri(im->native.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2010-01-30 18:50:01 -08:00
|
|
|
glTexParameteri(im->native.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2010-01-30 18:50:01 -08:00
|
|
|
glBindTexture(im->native.target, 0);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2010-08-08 20:27:59 -07:00
|
|
|
glBindTexture(im->native.target, gc->pipe[0].shader.cur_tex);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2010-01-21 00:44:11 -08:00
|
|
|
return pt;
|
|
|
|
}
|
|
|
|
|
2010-08-13 03:34:51 -07:00
|
|
|
static Evas_GL_Texture_Pool *
|
2011-03-16 10:32:49 -07:00
|
|
|
_pool_tex_dynamic_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, int format)
|
2010-08-13 03:34:51 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Texture_Pool *pt = NULL;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-13 03:34:51 -07:00
|
|
|
#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
|
|
|
|
int fmt; // EGL_MAP_GL_TEXTURE_RGBA_SEC or EGL_MAP_GL_TEXTURE_RGB_SEC or bust
|
|
|
|
int pixtype; // EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC or bust
|
|
|
|
int attr[] =
|
|
|
|
{
|
|
|
|
EGL_MAP_GL_TEXTURE_WIDTH_SEC, 32,
|
|
|
|
EGL_MAP_GL_TEXTURE_HEIGHT_SEC, 32,
|
|
|
|
EGL_MAP_GL_TEXTURE_FORMAT_SEC, EGL_MAP_GL_TEXTURE_RGBA_SEC,
|
|
|
|
EGL_MAP_GL_TEXTURE_PIXEL_TYPE_SEC, EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC,
|
|
|
|
EGL_NONE
|
|
|
|
};
|
2010-08-13 04:08:57 -07:00
|
|
|
void *egldisplay;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-13 03:34:51 -07:00
|
|
|
pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
|
|
|
|
if (!pt) return NULL;
|
2010-08-25 21:37:43 -07:00
|
|
|
h = _tex_round_slot(gc, h) * gc->shared->info.tune.atlas.slot_size;
|
2010-08-13 03:34:51 -07:00
|
|
|
_tex_adjust(gc, &w, &h);
|
|
|
|
pt->gc = gc;
|
|
|
|
pt->w = w;
|
|
|
|
pt->h = h;
|
|
|
|
pt->intformat = intformat;
|
|
|
|
pt->format = format;
|
|
|
|
pt->dataformat = GL_UNSIGNED_BYTE;
|
|
|
|
pt->render = 1;
|
|
|
|
pt->references = 0;
|
2010-08-26 19:02:38 -07:00
|
|
|
texinfo.d.num++;
|
|
|
|
texinfo.d.pix += pt->w * pt->h;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-26 19:02:38 -07:00
|
|
|
_print_tex_count();
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-13 03:34:51 -07:00
|
|
|
glGenTextures(1, &(pt->texture));
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
glBindTexture(GL_TEXTURE_2D, pt->texture);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
|
2010-08-13 04:08:57 -07:00
|
|
|
egldisplay = pt->gc->egldisp;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-13 03:34:51 -07:00
|
|
|
attr[1] = pt->w;
|
2010-08-13 04:08:57 -07:00
|
|
|
attr[3] = pt->h;
|
2010-08-13 03:34:51 -07:00
|
|
|
|
2010-08-18 02:53:14 -07:00
|
|
|
// FIXME: seems a bit slower than i'd like - maybe too many flushes?
|
|
|
|
// FIXME: YCbCr no support as yet
|
2010-08-13 03:34:51 -07:00
|
|
|
pt->dyn.img = secsym_eglCreateImage(egldisplay,
|
2011-06-17 00:47:28 -07:00
|
|
|
EGL_NO_CONTEXT,
|
2010-08-13 03:34:51 -07:00
|
|
|
EGL_MAP_GL_TEXTURE_2D_SEC,
|
|
|
|
0, attr);
|
|
|
|
if (!pt->dyn.img)
|
|
|
|
{
|
From: Jiyoun Park <jy0703.park@samsung.com>
Subject: [E-devel] [Patch] evas gl engine's texture creation
Hello.
1. _pool_tex_dynamic_new function, it didnt set pt to NULL when secsym_eglCreateImage function failed.
In this case, it returns wrong pt pointer and it has possibility to make crash.
So I add free pt code and return NULL code into _pool_tex_dynamic_new function.
2. I modified eng_image_data_get of gl engine.
If Evas_GL_Image's texture creation failed and evas_gl_image's cache image was droped,
Im->im can be NULL. So I add check code.
Example: evas_gl_common_image_content_hint_set
1) EVAS_IMAGE_CONTENT_HINT_DYNAMIC , it drop cache image
2) if evas_gl_common_texture_dynamic_new failed
3) then, im->im =NULL, im->tex=NULL
In this situation, if application call's evas_object_image_data_get function,
It make crash in evas_cache_image_load_data function.
3. I think function's related with evas_object's engine data have to be return NULL if it failed.
If function's returns null, evas object code can handle error more easily.
But evas object's code was implemented differently each case. Does my suggestion right?
I add engine data null check code to evas_object_image based on upper consumtion.
If it is wrong , the patch code related with evas object image have to be removed.
If it is right , I will survey other evas object type also.
SVN revision: 62775
2011-08-24 21:48:45 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
2010-08-13 03:34:51 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
From: Jiyoun Park <jy0703.park@samsung.com>
Subject: [E-devel] [Patch] evas gl engine's texture creation
Hello.
1. _pool_tex_dynamic_new function, it didnt set pt to NULL when secsym_eglCreateImage function failed.
In this case, it returns wrong pt pointer and it has possibility to make crash.
So I add free pt code and return NULL code into _pool_tex_dynamic_new function.
2. I modified eng_image_data_get of gl engine.
If Evas_GL_Image's texture creation failed and evas_gl_image's cache image was droped,
Im->im can be NULL. So I add check code.
Example: evas_gl_common_image_content_hint_set
1) EVAS_IMAGE_CONTENT_HINT_DYNAMIC , it drop cache image
2) if evas_gl_common_texture_dynamic_new failed
3) then, im->im =NULL, im->tex=NULL
In this situation, if application call's evas_object_image_data_get function,
It make crash in evas_cache_image_load_data function.
3. I think function's related with evas_object's engine data have to be return NULL if it failed.
If function's returns null, evas object code can handle error more easily.
But evas object's code was implemented differently each case. Does my suggestion right?
I add engine data null check code to evas_object_image based on upper consumtion.
If it is wrong , the patch code related with evas object image have to be removed.
If it is right , I will survey other evas object type also.
SVN revision: 62775
2011-08-24 21:48:45 -07:00
|
|
|
glDeleteTextures(1, &(pt->texture));
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
free(pt);
|
|
|
|
return NULL;
|
2010-08-13 03:34:51 -07:00
|
|
|
}
|
|
|
|
if (secsym_eglGetImageAttribSEC(egldisplay,
|
|
|
|
pt->dyn.img,
|
|
|
|
EGL_MAP_GL_TEXTURE_WIDTH_SEC,
|
From: Jiyoun Park <jy0703.park@samsung.com>
Subject: [E-devel] [Patch] evas gl engine's texture creation
Hello.
1. _pool_tex_dynamic_new function, it didnt set pt to NULL when secsym_eglCreateImage function failed.
In this case, it returns wrong pt pointer and it has possibility to make crash.
So I add free pt code and return NULL code into _pool_tex_dynamic_new function.
2. I modified eng_image_data_get of gl engine.
If Evas_GL_Image's texture creation failed and evas_gl_image's cache image was droped,
Im->im can be NULL. So I add check code.
Example: evas_gl_common_image_content_hint_set
1) EVAS_IMAGE_CONTENT_HINT_DYNAMIC , it drop cache image
2) if evas_gl_common_texture_dynamic_new failed
3) then, im->im =NULL, im->tex=NULL
In this situation, if application call's evas_object_image_data_get function,
It make crash in evas_cache_image_load_data function.
3. I think function's related with evas_object's engine data have to be return NULL if it failed.
If function's returns null, evas object code can handle error more easily.
But evas object's code was implemented differently each case. Does my suggestion right?
I add engine data null check code to evas_object_image based on upper consumtion.
If it is wrong , the patch code related with evas object image have to be removed.
If it is right , I will survey other evas object type also.
SVN revision: 62775
2011-08-24 21:48:45 -07:00
|
|
|
&(pt->dyn.w)) != EGL_TRUE) goto error;
|
2010-08-13 03:34:51 -07:00
|
|
|
if (secsym_eglGetImageAttribSEC(egldisplay,
|
|
|
|
pt->dyn.img,
|
|
|
|
EGL_MAP_GL_TEXTURE_HEIGHT_SEC,
|
From: Jiyoun Park <jy0703.park@samsung.com>
Subject: [E-devel] [Patch] evas gl engine's texture creation
Hello.
1. _pool_tex_dynamic_new function, it didnt set pt to NULL when secsym_eglCreateImage function failed.
In this case, it returns wrong pt pointer and it has possibility to make crash.
So I add free pt code and return NULL code into _pool_tex_dynamic_new function.
2. I modified eng_image_data_get of gl engine.
If Evas_GL_Image's texture creation failed and evas_gl_image's cache image was droped,
Im->im can be NULL. So I add check code.
Example: evas_gl_common_image_content_hint_set
1) EVAS_IMAGE_CONTENT_HINT_DYNAMIC , it drop cache image
2) if evas_gl_common_texture_dynamic_new failed
3) then, im->im =NULL, im->tex=NULL
In this situation, if application call's evas_object_image_data_get function,
It make crash in evas_cache_image_load_data function.
3. I think function's related with evas_object's engine data have to be return NULL if it failed.
If function's returns null, evas object code can handle error more easily.
But evas object's code was implemented differently each case. Does my suggestion right?
I add engine data null check code to evas_object_image based on upper consumtion.
If it is wrong , the patch code related with evas object image have to be removed.
If it is right , I will survey other evas object type also.
SVN revision: 62775
2011-08-24 21:48:45 -07:00
|
|
|
&(pt->dyn.h)) != EGL_TRUE) goto error;
|
2010-08-13 03:34:51 -07:00
|
|
|
if (secsym_eglGetImageAttribSEC(egldisplay,
|
|
|
|
pt->dyn.img,
|
|
|
|
EGL_MAP_GL_TEXTURE_STRIDE_IN_BYTES_SEC,
|
From: Jiyoun Park <jy0703.park@samsung.com>
Subject: [E-devel] [Patch] evas gl engine's texture creation
Hello.
1. _pool_tex_dynamic_new function, it didnt set pt to NULL when secsym_eglCreateImage function failed.
In this case, it returns wrong pt pointer and it has possibility to make crash.
So I add free pt code and return NULL code into _pool_tex_dynamic_new function.
2. I modified eng_image_data_get of gl engine.
If Evas_GL_Image's texture creation failed and evas_gl_image's cache image was droped,
Im->im can be NULL. So I add check code.
Example: evas_gl_common_image_content_hint_set
1) EVAS_IMAGE_CONTENT_HINT_DYNAMIC , it drop cache image
2) if evas_gl_common_texture_dynamic_new failed
3) then, im->im =NULL, im->tex=NULL
In this situation, if application call's evas_object_image_data_get function,
It make crash in evas_cache_image_load_data function.
3. I think function's related with evas_object's engine data have to be return NULL if it failed.
If function's returns null, evas object code can handle error more easily.
But evas object's code was implemented differently each case. Does my suggestion right?
I add engine data null check code to evas_object_image based on upper consumtion.
If it is wrong , the patch code related with evas object image have to be removed.
If it is right , I will survey other evas object type also.
SVN revision: 62775
2011-08-24 21:48:45 -07:00
|
|
|
&(pt->dyn.stride)) != EGL_TRUE) goto error;
|
2010-08-13 03:34:51 -07:00
|
|
|
if (secsym_eglGetImageAttribSEC(egldisplay,
|
|
|
|
pt->dyn.img,
|
|
|
|
EGL_MAP_GL_TEXTURE_FORMAT_SEC,
|
From: Jiyoun Park <jy0703.park@samsung.com>
Subject: [E-devel] [Patch] evas gl engine's texture creation
Hello.
1. _pool_tex_dynamic_new function, it didnt set pt to NULL when secsym_eglCreateImage function failed.
In this case, it returns wrong pt pointer and it has possibility to make crash.
So I add free pt code and return NULL code into _pool_tex_dynamic_new function.
2. I modified eng_image_data_get of gl engine.
If Evas_GL_Image's texture creation failed and evas_gl_image's cache image was droped,
Im->im can be NULL. So I add check code.
Example: evas_gl_common_image_content_hint_set
1) EVAS_IMAGE_CONTENT_HINT_DYNAMIC , it drop cache image
2) if evas_gl_common_texture_dynamic_new failed
3) then, im->im =NULL, im->tex=NULL
In this situation, if application call's evas_object_image_data_get function,
It make crash in evas_cache_image_load_data function.
3. I think function's related with evas_object's engine data have to be return NULL if it failed.
If function's returns null, evas object code can handle error more easily.
But evas object's code was implemented differently each case. Does my suggestion right?
I add engine data null check code to evas_object_image based on upper consumtion.
If it is wrong , the patch code related with evas object image have to be removed.
If it is right , I will survey other evas object type also.
SVN revision: 62775
2011-08-24 21:48:45 -07:00
|
|
|
&(fmt)) != EGL_TRUE) goto error;
|
|
|
|
if (fmt != EGL_MAP_GL_TEXTURE_RGBA_SEC) goto error;
|
|
|
|
|
2010-08-13 03:34:51 -07:00
|
|
|
if (secsym_eglGetImageAttribSEC(egldisplay,
|
|
|
|
pt->dyn.img,
|
|
|
|
EGL_MAP_GL_TEXTURE_PIXEL_TYPE_SEC,
|
From: Jiyoun Park <jy0703.park@samsung.com>
Subject: [E-devel] [Patch] evas gl engine's texture creation
Hello.
1. _pool_tex_dynamic_new function, it didnt set pt to NULL when secsym_eglCreateImage function failed.
In this case, it returns wrong pt pointer and it has possibility to make crash.
So I add free pt code and return NULL code into _pool_tex_dynamic_new function.
2. I modified eng_image_data_get of gl engine.
If Evas_GL_Image's texture creation failed and evas_gl_image's cache image was droped,
Im->im can be NULL. So I add check code.
Example: evas_gl_common_image_content_hint_set
1) EVAS_IMAGE_CONTENT_HINT_DYNAMIC , it drop cache image
2) if evas_gl_common_texture_dynamic_new failed
3) then, im->im =NULL, im->tex=NULL
In this situation, if application call's evas_object_image_data_get function,
It make crash in evas_cache_image_load_data function.
3. I think function's related with evas_object's engine data have to be return NULL if it failed.
If function's returns null, evas object code can handle error more easily.
But evas object's code was implemented differently each case. Does my suggestion right?
I add engine data null check code to evas_object_image based on upper consumtion.
If it is wrong , the patch code related with evas object image have to be removed.
If it is right , I will survey other evas object type also.
SVN revision: 62775
2011-08-24 21:48:45 -07:00
|
|
|
&(pixtype)) != EGL_TRUE) goto error;
|
|
|
|
|
|
|
|
if (pixtype != EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC) goto error;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-13 03:34:51 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2010-09-18 19:10:09 -07:00
|
|
|
#else
|
|
|
|
gc = NULL;
|
|
|
|
w = 0;
|
|
|
|
h = 0;
|
|
|
|
intformat = 0;
|
|
|
|
format = 0;
|
2011-06-17 00:47:28 -07:00
|
|
|
#endif
|
2010-08-13 03:34:51 -07:00
|
|
|
return pt;
|
From: Jiyoun Park <jy0703.park@samsung.com>
Subject: [E-devel] [Patch] evas gl engine's texture creation
Hello.
1. _pool_tex_dynamic_new function, it didnt set pt to NULL when secsym_eglCreateImage function failed.
In this case, it returns wrong pt pointer and it has possibility to make crash.
So I add free pt code and return NULL code into _pool_tex_dynamic_new function.
2. I modified eng_image_data_get of gl engine.
If Evas_GL_Image's texture creation failed and evas_gl_image's cache image was droped,
Im->im can be NULL. So I add check code.
Example: evas_gl_common_image_content_hint_set
1) EVAS_IMAGE_CONTENT_HINT_DYNAMIC , it drop cache image
2) if evas_gl_common_texture_dynamic_new failed
3) then, im->im =NULL, im->tex=NULL
In this situation, if application call's evas_object_image_data_get function,
It make crash in evas_cache_image_load_data function.
3. I think function's related with evas_object's engine data have to be return NULL if it failed.
If function's returns null, evas object code can handle error more easily.
But evas object's code was implemented differently each case. Does my suggestion right?
I add engine data null check code to evas_object_image based on upper consumtion.
If it is wrong , the patch code related with evas object image have to be removed.
If it is right , I will survey other evas object type also.
SVN revision: 62775
2011-08-24 21:48:45 -07:00
|
|
|
|
|
|
|
/* ERROR HANDLING */
|
|
|
|
error:
|
|
|
|
secsym_eglDestroyImage(egldisplay, pt->dyn.img);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
pt->dyn.img = NULL;
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
glDeleteTextures(1, &(pt->texture));
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
free(pt);
|
|
|
|
return NULL;
|
2010-08-13 03:34:51 -07:00
|
|
|
}
|
|
|
|
|
2011-01-13 02:41:08 -08:00
|
|
|
void
|
|
|
|
evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt)
|
2010-01-19 06:29:20 -08:00
|
|
|
{
|
2011-01-13 02:41:08 -08:00
|
|
|
if (!pt->gc) return;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-26 19:02:38 -07:00
|
|
|
if (pt->format == alpha_fmt)
|
|
|
|
{
|
|
|
|
texinfo.a.num--;
|
|
|
|
texinfo.a.pix -= pt->w * pt->h;
|
|
|
|
}
|
|
|
|
else if (pt->format == lum_fmt)
|
|
|
|
{
|
|
|
|
texinfo.v.num--;
|
|
|
|
texinfo.v.pix -= pt->w * pt->h;
|
|
|
|
}
|
|
|
|
else if (pt->dyn.img)
|
|
|
|
{
|
|
|
|
texinfo.d.num--;
|
|
|
|
texinfo.d.pix -= pt->w * pt->h;
|
|
|
|
}
|
|
|
|
else if (pt->render)
|
|
|
|
{
|
|
|
|
texinfo.r.num--;
|
|
|
|
texinfo.r.pix -= pt->w * pt->h;
|
|
|
|
}
|
|
|
|
else if (pt->native)
|
|
|
|
{
|
|
|
|
texinfo.n.num--;
|
|
|
|
texinfo.n.pix -= pt->w * pt->h;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
texinfo.c.num--;
|
|
|
|
texinfo.c.pix -= pt->w * pt->h;
|
|
|
|
}
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-26 19:02:38 -07:00
|
|
|
_print_tex_count();
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-13 03:34:51 -07:00
|
|
|
#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
|
|
|
|
if (pt->dyn.img)
|
|
|
|
{
|
|
|
|
secsym_eglDestroyImage(pt->gc->egldisp, pt->dyn.img);
|
|
|
|
pt->dyn.img = NULL;
|
|
|
|
pt->dyn.data = NULL;
|
|
|
|
pt->dyn.w = 0;
|
|
|
|
pt->dyn.h = 0;
|
|
|
|
pt->dyn.stride = 0;
|
|
|
|
}
|
2011-06-17 00:47:28 -07:00
|
|
|
#endif
|
|
|
|
|
2010-01-19 06:29:20 -08:00
|
|
|
glDeleteTextures(1, &(pt->texture));
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
if (pt->fb)
|
|
|
|
{
|
|
|
|
glsym_glDeleteFramebuffers(1, &(pt->fb));
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-01-13 02:41:08 -08:00
|
|
|
pt->fb = 0;
|
|
|
|
}
|
|
|
|
while (pt->allocations)
|
2011-06-17 00:47:28 -07:00
|
|
|
pt->allocations =
|
2011-01-13 02:41:08 -08:00
|
|
|
eina_list_remove_list(pt->allocations, pt->allocations);
|
|
|
|
pt->texture = 0;
|
|
|
|
pt->gc = NULL;
|
|
|
|
pt->w = 0;
|
|
|
|
pt->h = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
pt_unref(Evas_GL_Texture_Pool *pt)
|
|
|
|
{
|
|
|
|
if (!pt->gc) return;
|
|
|
|
pt->references--;
|
|
|
|
if (pt->references != 0) return;
|
|
|
|
|
|
|
|
if (!((pt->render) || (pt->native)))
|
|
|
|
{
|
|
|
|
if (pt->whole)
|
2011-06-17 00:47:28 -07:00
|
|
|
pt->gc->shared->tex.whole =
|
2011-01-13 02:41:08 -08:00
|
|
|
eina_list_remove(pt->gc->shared->tex.whole, pt);
|
|
|
|
else
|
|
|
|
pt->gc->shared->tex.atlas [pt->slot][pt->fslot] =
|
|
|
|
eina_list_remove(pt->gc->shared->tex.atlas[pt->slot][pt->fslot], pt);
|
2010-02-16 20:21:59 -08:00
|
|
|
}
|
2011-01-13 02:41:08 -08:00
|
|
|
evas_gl_texture_pool_empty(pt);
|
2010-01-19 06:29:20 -08:00
|
|
|
free(pt);
|
|
|
|
}
|
|
|
|
|
2010-01-21 00:44:11 -08:00
|
|
|
Evas_GL_Texture *
|
2011-03-16 10:32:49 -07:00
|
|
|
evas_gl_common_texture_native_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, Evas_GL_Image *im)
|
2010-01-21 00:44:11 -08:00
|
|
|
{
|
|
|
|
Evas_GL_Texture *tex;
|
|
|
|
|
|
|
|
tex = calloc(1, sizeof(Evas_GL_Texture));
|
|
|
|
if (!tex) return NULL;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-01-21 00:44:11 -08:00
|
|
|
tex->gc = gc;
|
|
|
|
tex->references = 1;
|
|
|
|
tex->alpha = alpha;
|
|
|
|
if (alpha)
|
2010-02-17 23:10:28 -08:00
|
|
|
{
|
|
|
|
if (gc->shared->info.bgra)
|
|
|
|
tex->pt = _pool_tex_native_new(gc, w, h, rgba_ifmt, rgba_fmt, im);
|
|
|
|
else
|
|
|
|
tex->pt = _pool_tex_native_new(gc, w, h, rgba_ifmt, rgba_fmt, im);
|
|
|
|
}
|
2010-01-21 00:44:11 -08:00
|
|
|
else
|
2010-02-17 23:10:28 -08:00
|
|
|
{
|
|
|
|
if (gc->shared->info.bgra)
|
|
|
|
tex->pt = _pool_tex_native_new(gc, w, h, rgb_ifmt, rgb_fmt, im);
|
|
|
|
else
|
|
|
|
tex->pt = _pool_tex_native_new(gc, w, h, rgb_ifmt, rgb_fmt, im);
|
|
|
|
}
|
2010-01-21 00:44:11 -08:00
|
|
|
if (!tex->pt)
|
|
|
|
{
|
|
|
|
free(tex);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
tex->x = 0;
|
|
|
|
tex->y = 0;
|
|
|
|
tex->w = w;
|
|
|
|
tex->h = h;
|
|
|
|
tex->pt->references++;
|
|
|
|
return tex;
|
|
|
|
}
|
|
|
|
|
2009-11-12 23:22:31 -08:00
|
|
|
Evas_GL_Texture *
|
2011-03-16 10:32:49 -07:00
|
|
|
evas_gl_common_texture_render_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha)
|
2009-11-12 23:22:31 -08:00
|
|
|
{
|
|
|
|
Evas_GL_Texture *tex;
|
|
|
|
|
|
|
|
tex = calloc(1, sizeof(Evas_GL_Texture));
|
|
|
|
if (!tex) return NULL;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2009-11-12 23:22:31 -08:00
|
|
|
tex->gc = gc;
|
|
|
|
tex->references = 1;
|
2010-01-19 06:29:20 -08:00
|
|
|
tex->alpha = alpha;
|
|
|
|
if (alpha)
|
2010-02-17 23:10:28 -08:00
|
|
|
{
|
|
|
|
if (gc->shared->info.bgra)
|
|
|
|
tex->pt = _pool_tex_render_new(gc, w, h, rgba_ifmt, rgba_fmt);
|
|
|
|
else
|
|
|
|
tex->pt = _pool_tex_render_new(gc, w, h, rgba_ifmt, rgba_fmt);
|
|
|
|
}
|
2010-01-19 06:29:20 -08:00
|
|
|
else
|
2010-02-17 23:10:28 -08:00
|
|
|
{
|
|
|
|
if (gc->shared->info.bgra)
|
|
|
|
tex->pt = _pool_tex_render_new(gc, w, h, rgb_ifmt, rgb_fmt);
|
|
|
|
else
|
|
|
|
tex->pt = _pool_tex_render_new(gc, w, h, rgb_ifmt, rgb_fmt);
|
|
|
|
}
|
2009-11-12 23:22:31 -08:00
|
|
|
if (!tex->pt)
|
|
|
|
{
|
|
|
|
free(tex);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
tex->x = 0;
|
|
|
|
tex->y = 0;
|
|
|
|
tex->w = w;
|
|
|
|
tex->h = h;
|
2011-06-17 00:47:28 -07:00
|
|
|
tex->pt->references++;
|
2010-10-26 00:00:26 -07:00
|
|
|
return tex;
|
2009-11-12 23:22:31 -08:00
|
|
|
}
|
|
|
|
|
2010-08-13 03:34:51 -07:00
|
|
|
Evas_GL_Texture *
|
2011-03-16 10:32:49 -07:00
|
|
|
evas_gl_common_texture_dynamic_new(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
|
2010-08-13 03:34:51 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Texture *tex;
|
|
|
|
|
|
|
|
tex = calloc(1, sizeof(Evas_GL_Texture));
|
|
|
|
if (!tex) return NULL;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-13 03:34:51 -07:00
|
|
|
tex->gc = gc;
|
|
|
|
tex->references = 1;
|
|
|
|
tex->alpha = im->alpha;
|
|
|
|
tex->x = 0;
|
|
|
|
tex->y = 0;
|
|
|
|
tex->w = im->w;
|
|
|
|
tex->h = im->h;
|
|
|
|
if (tex->alpha)
|
|
|
|
{
|
|
|
|
if (gc->shared->info.bgra)
|
2010-08-18 02:53:14 -07:00
|
|
|
tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h, bgra_ifmt, bgra_fmt);
|
2010-08-13 03:34:51 -07:00
|
|
|
else
|
2010-08-18 02:53:14 -07:00
|
|
|
tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h, bgra_ifmt, bgra_fmt);
|
2010-08-13 03:34:51 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (gc->shared->info.bgra)
|
2010-08-18 02:53:14 -07:00
|
|
|
tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h, bgra_ifmt, bgra_fmt);
|
2010-08-13 03:34:51 -07:00
|
|
|
else
|
2010-08-18 02:53:14 -07:00
|
|
|
tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h, bgra_ifmt, bgra_fmt);
|
2010-08-13 03:34:51 -07:00
|
|
|
}
|
|
|
|
if (!tex->pt)
|
|
|
|
{
|
|
|
|
free(tex);
|
|
|
|
return NULL;
|
|
|
|
}
|
2010-10-04 04:17:11 -07:00
|
|
|
tex->pt->references++;
|
2010-08-13 03:34:51 -07:00
|
|
|
return tex;
|
|
|
|
}
|
|
|
|
|
2003-09-07 04:24:48 -07:00
|
|
|
void
|
2009-10-09 05:10:27 -07:00
|
|
|
evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
2010-02-17 23:10:28 -08:00
|
|
|
GLuint fmt;
|
2010-08-25 02:29:56 -07:00
|
|
|
|
2010-01-19 06:29:20 -08:00
|
|
|
if (tex->alpha != im->cache_entry.flags.alpha)
|
|
|
|
{
|
|
|
|
tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex);
|
|
|
|
pt_unref(tex->pt);
|
|
|
|
tex->alpha = im->cache_entry.flags.alpha;
|
|
|
|
if (tex->alpha)
|
2010-02-17 23:10:28 -08:00
|
|
|
{
|
|
|
|
if (tex->gc->shared->info.bgra)
|
|
|
|
tex->pt = _pool_tex_render_new(tex->gc, tex->w, tex->h, bgra_ifmt, bgra_fmt);
|
|
|
|
else
|
|
|
|
tex->pt = _pool_tex_render_new(tex->gc, tex->w, tex->h, rgba_ifmt, rgba_fmt);
|
|
|
|
}
|
2010-01-19 06:29:20 -08:00
|
|
|
else
|
2010-02-17 23:10:28 -08:00
|
|
|
{
|
|
|
|
if (tex->gc->shared->info.bgra)
|
|
|
|
tex->pt = _pool_tex_render_new(tex->gc, tex->w, tex->h, bgr_ifmt, bgr_fmt);
|
|
|
|
else
|
|
|
|
tex->pt = _pool_tex_render_new(tex->gc, tex->w, tex->h, rgb_ifmt, rgb_fmt);
|
|
|
|
}
|
2010-01-19 06:29:20 -08:00
|
|
|
}
|
2010-01-29 02:53:53 -08:00
|
|
|
if (!tex->pt) return;
|
2010-08-25 02:29:56 -07:00
|
|
|
if (!im->image.data) return;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-02-17 23:10:28 -08:00
|
|
|
fmt = tex->pt->format;
|
2009-10-09 05:10:27 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-06-17 00:47:28 -07:00
|
|
|
#ifdef GL_UNPACK_ROW_LENGTH
|
2009-10-10 06:24:15 -07:00
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-06-17 00:47:28 -07:00
|
|
|
#endif
|
2009-10-09 05:10:27 -07:00
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-12-19 22:23:13 -08:00
|
|
|
|
2011-02-08 03:41:38 -08:00
|
|
|
// printf("tex upload %ix%i\n", im->cache_entry.w, im->cache_entry.h);
|
2009-10-09 05:10:27 -07:00
|
|
|
// +-+
|
|
|
|
// +-+
|
2011-06-17 00:47:28 -07:00
|
|
|
//
|
|
|
|
_tex_sub_2d(tex->x, tex->y,
|
2009-11-06 03:32:23 -08:00
|
|
|
im->cache_entry.w, im->cache_entry.h,
|
2010-02-17 23:10:28 -08:00
|
|
|
fmt, tex->pt->dataformat,
|
2009-11-06 03:32:23 -08:00
|
|
|
im->image.data);
|
2009-10-09 05:10:27 -07:00
|
|
|
// |xxx
|
|
|
|
// |xxx
|
2011-06-17 00:47:28 -07:00
|
|
|
//
|
|
|
|
_tex_sub_2d(tex->x - 1, tex->y,
|
2009-11-06 03:32:23 -08:00
|
|
|
1, im->cache_entry.h,
|
2010-02-17 23:10:28 -08:00
|
|
|
fmt, tex->pt->dataformat,
|
2009-11-06 03:32:23 -08:00
|
|
|
im->image.data);
|
2009-10-09 05:10:27 -07:00
|
|
|
// xxx|
|
|
|
|
// xxx|
|
2011-06-17 00:47:28 -07:00
|
|
|
//
|
|
|
|
_tex_sub_2d(tex->x + im->cache_entry.w, tex->y,
|
2009-11-06 03:32:23 -08:00
|
|
|
1, im->cache_entry.h,
|
2010-02-17 23:10:28 -08:00
|
|
|
fmt, tex->pt->dataformat,
|
2009-11-06 03:32:23 -08:00
|
|
|
im->image.data + (im->cache_entry.w - 1));
|
2009-10-09 05:10:27 -07:00
|
|
|
// xxx
|
|
|
|
// xxx
|
|
|
|
// ---
|
2009-11-06 03:32:23 -08:00
|
|
|
_tex_sub_2d(tex->x, tex->y + im->cache_entry.h,
|
|
|
|
im->cache_entry.w, 1,
|
2010-02-17 23:10:28 -08:00
|
|
|
fmt, tex->pt->dataformat,
|
2009-11-06 03:32:23 -08:00
|
|
|
im->image.data + ((im->cache_entry.h - 1) * im->cache_entry.w));
|
2009-10-09 05:10:27 -07:00
|
|
|
// xxx
|
|
|
|
// xxx
|
|
|
|
// o
|
2009-11-06 03:32:23 -08:00
|
|
|
_tex_sub_2d(tex->x - 1, tex->y + im->cache_entry.h,
|
|
|
|
1, 1,
|
2010-02-17 23:10:28 -08:00
|
|
|
fmt, tex->pt->dataformat,
|
2009-11-06 03:32:23 -08:00
|
|
|
im->image.data + ((im->cache_entry.h - 1) * im->cache_entry.w));
|
2009-10-09 05:10:27 -07:00
|
|
|
// xxx
|
|
|
|
// xxx
|
|
|
|
// o
|
2009-11-06 03:32:23 -08:00
|
|
|
_tex_sub_2d(tex->x + im->cache_entry.w, tex->y + im->cache_entry.h,
|
|
|
|
1, 1,
|
2010-02-17 23:10:28 -08:00
|
|
|
fmt, tex->pt->dataformat,
|
2009-11-06 03:32:23 -08:00
|
|
|
im->image.data + ((im->cache_entry.h - 1) * im->cache_entry.w) + (im->cache_entry.w - 1));
|
2010-08-08 20:27:59 -07:00
|
|
|
if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
|
2010-02-16 20:21:59 -08:00
|
|
|
{
|
2010-08-08 20:27:59 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
2003-09-07 04:24:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2009-10-09 05:10:27 -07:00
|
|
|
evas_gl_common_texture_free(Evas_GL_Texture *tex)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
2009-10-09 05:10:27 -07:00
|
|
|
if (!tex) return;
|
|
|
|
tex->references--;
|
2010-01-29 02:53:53 -08:00
|
|
|
if (tex->references != 0) return;
|
|
|
|
if (tex->pt)
|
|
|
|
{
|
|
|
|
// printf("tex->pt = %p\n", tex->pt);
|
|
|
|
// printf("tex->pt->references = %i\n", tex->pt->references);
|
|
|
|
tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex);
|
|
|
|
pt_unref(tex->pt);
|
|
|
|
}
|
2009-10-10 07:55:10 -07:00
|
|
|
if (tex->ptu) pt_unref(tex->ptu);
|
|
|
|
if (tex->ptv) pt_unref(tex->ptv);
|
2009-10-09 05:10:27 -07:00
|
|
|
free(tex);
|
2003-09-07 04:24:48 -07:00
|
|
|
}
|
2006-12-17 07:48:52 -08:00
|
|
|
|
|
|
|
Evas_GL_Texture *
|
2011-03-16 10:32:49 -07:00
|
|
|
evas_gl_common_texture_alpha_new(Evas_Engine_GL_Context *gc, DATA8 *pixels,
|
2010-09-18 16:16:25 -07:00
|
|
|
unsigned int w, unsigned int h, int fh)
|
2006-12-17 07:48:52 -08:00
|
|
|
{
|
|
|
|
Evas_GL_Texture *tex;
|
2009-10-09 05:10:27 -07:00
|
|
|
Eina_List *l_after = NULL;
|
|
|
|
int u = 0, v = 0;
|
|
|
|
|
2006-12-17 07:48:52 -08:00
|
|
|
tex = calloc(1, sizeof(Evas_GL_Texture));
|
|
|
|
if (!tex) return NULL;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2006-12-17 07:48:52 -08:00
|
|
|
tex->gc = gc;
|
2009-10-09 05:10:27 -07:00
|
|
|
tex->references = 1;
|
2010-08-25 21:37:43 -07:00
|
|
|
tex->pt = _pool_tex_find(gc, w + 3, fh, alpha_ifmt, alpha_fmt, &u, &v,
|
2011-06-17 00:47:28 -07:00
|
|
|
&l_after,
|
2010-08-25 18:41:48 -07:00
|
|
|
gc->shared->info.tune.atlas.max_alloc_alpha_size);
|
2009-10-09 05:10:27 -07:00
|
|
|
if (!tex->pt)
|
2006-12-19 06:12:40 -08:00
|
|
|
{
|
2009-10-09 05:10:27 -07:00
|
|
|
free(tex);
|
|
|
|
return NULL;
|
2006-12-19 06:12:40 -08:00
|
|
|
}
|
2009-10-09 05:10:27 -07:00
|
|
|
tex->x = u + 1;
|
|
|
|
tex->y = v;
|
|
|
|
tex->w = w;
|
|
|
|
tex->h = h;
|
|
|
|
if (l_after)
|
2011-06-17 00:47:28 -07:00
|
|
|
tex->pt->allocations =
|
2009-11-13 21:08:00 -08:00
|
|
|
eina_list_append_relative_list(tex->pt->allocations, tex, l_after);
|
2006-12-19 06:12:40 -08:00
|
|
|
else
|
2009-10-09 05:10:27 -07:00
|
|
|
tex->pt->allocations = eina_list_prepend(tex->pt->allocations, tex);
|
|
|
|
tex->pt->references++;
|
|
|
|
evas_gl_common_texture_alpha_update(tex, pixels, w, h, fh);
|
2006-12-17 07:48:52 -08:00
|
|
|
return tex;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-09-18 16:16:25 -07:00
|
|
|
evas_gl_common_texture_alpha_update(Evas_GL_Texture *tex, DATA8 *pixels,
|
2010-09-18 19:10:09 -07:00
|
|
|
unsigned int w, unsigned int h, int fh __UNUSED__)
|
2006-12-17 07:48:52 -08:00
|
|
|
{
|
2010-01-29 02:53:53 -08:00
|
|
|
if (!tex->pt) return;
|
2009-10-09 05:10:27 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-06-17 00:47:28 -07:00
|
|
|
#ifdef GL_UNPACK_ROW_LENGTH
|
2009-10-10 06:24:15 -07:00
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-06-17 00:47:28 -07:00
|
|
|
#endif
|
2009-10-13 03:42:03 -07:00
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-06-17 00:47:28 -07:00
|
|
|
_tex_sub_2d(tex->x, tex->y, w, h, tex->pt->format, tex->pt->dataformat,
|
2009-11-13 21:08:00 -08:00
|
|
|
pixels);
|
2010-08-08 20:27:59 -07:00
|
|
|
if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
|
2010-02-16 20:21:59 -08:00
|
|
|
{
|
2010-08-08 20:27:59 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
2006-12-17 07:48:52 -08:00
|
|
|
}
|
2009-10-10 06:24:15 -07:00
|
|
|
|
|
|
|
Evas_GL_Texture *
|
2011-03-16 10:32:49 -07:00
|
|
|
evas_gl_common_texture_yuv_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h)
|
2009-10-10 06:24:15 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Texture *tex;
|
|
|
|
|
|
|
|
tex = calloc(1, sizeof(Evas_GL_Texture));
|
|
|
|
if (!tex) return NULL;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2009-10-10 06:24:15 -07:00
|
|
|
tex->gc = gc;
|
|
|
|
tex->references = 1;
|
2009-11-06 03:32:23 -08:00
|
|
|
tex->pt = _pool_tex_new(gc, w + 1, h + 1, lum_ifmt, lum_fmt);
|
2010-01-29 02:53:53 -08:00
|
|
|
if (!tex->pt)
|
|
|
|
{
|
|
|
|
free(tex);
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-10-13 02:40:39 -07:00
|
|
|
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, tex->pt);
|
2009-10-10 06:24:15 -07:00
|
|
|
tex->pt->slot = -1;
|
|
|
|
tex->pt->fslot = -1;
|
|
|
|
tex->pt->whole = 1;
|
2009-11-06 03:32:23 -08:00
|
|
|
tex->ptu = _pool_tex_new(gc, (w / 2) + 1, (h / 2) + 1, lum_ifmt, lum_fmt);
|
2010-01-29 02:53:53 -08:00
|
|
|
if (!tex->ptu)
|
|
|
|
{
|
|
|
|
free(tex);
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-10-13 02:40:39 -07:00
|
|
|
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, tex->ptu);
|
2009-10-10 06:24:15 -07:00
|
|
|
tex->ptu->slot = -1;
|
|
|
|
tex->ptu->fslot = -1;
|
|
|
|
tex->ptu->whole = 1;
|
2009-11-06 03:32:23 -08:00
|
|
|
tex->ptv = _pool_tex_new(gc, (w / 2) + 1, (h / 2) + 1, lum_ifmt, lum_fmt);
|
2010-01-29 02:53:53 -08:00
|
|
|
if (!tex->ptv)
|
|
|
|
{
|
2010-01-30 18:50:01 -08:00
|
|
|
pt_unref(tex->pt);
|
|
|
|
pt_unref(tex->ptu);
|
2010-01-29 02:53:53 -08:00
|
|
|
free(tex);
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-10-13 02:40:39 -07:00
|
|
|
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, tex->ptv);
|
2009-10-10 06:24:15 -07:00
|
|
|
tex->ptv->slot = -1;
|
|
|
|
tex->ptv->fslot = -1;
|
|
|
|
tex->ptv->whole = 1;
|
|
|
|
tex->x = 0;
|
|
|
|
tex->y = 0;
|
|
|
|
tex->w = w;
|
|
|
|
tex->h = h;
|
|
|
|
tex->pt->allocations = eina_list_prepend(tex->pt->allocations, tex);
|
|
|
|
tex->ptu->allocations = eina_list_prepend(tex->ptu->allocations, tex);
|
|
|
|
tex->ptv->allocations = eina_list_prepend(tex->ptv->allocations, tex);
|
|
|
|
tex->pt->references++;
|
|
|
|
tex->ptu->references++;
|
|
|
|
tex->ptv->references++;
|
|
|
|
evas_gl_common_texture_yuv_update(tex, rows, w, h);
|
|
|
|
return tex;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-09-18 16:16:25 -07:00
|
|
|
evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
|
2009-10-10 06:24:15 -07:00
|
|
|
{
|
2010-01-29 02:53:53 -08:00
|
|
|
if (!tex->pt) return;
|
2009-10-11 20:31:24 -07:00
|
|
|
// FIXME: works on lowest size 4 pixel high buffers. must also be multiple of 2
|
|
|
|
#ifdef GL_UNPACK_ROW_LENGTH
|
2009-10-10 06:24:15 -07:00
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-10-10 06:24:15 -07:00
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-10-10 06:24:15 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-11-06 03:32:23 -08:00
|
|
|
_tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
|
2009-10-10 06:24:15 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->ptu->texture);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-10-10 06:24:15 -07:00
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + 1] - rows[h]);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-11-06 03:32:23 -08:00
|
|
|
_tex_sub_2d(0, 0, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat, rows[h]);
|
2009-10-10 06:24:15 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->ptv->texture);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-10-10 06:24:15 -07:00
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + (h / 2) + 1] - rows[h + (h / 2)]);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-11-06 03:32:23 -08:00
|
|
|
_tex_sub_2d(0, 0, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2)]);
|
2009-10-11 20:31:24 -07:00
|
|
|
#else
|
2011-04-08 21:13:21 -07:00
|
|
|
unsigned int y;
|
2010-08-18 09:08:30 -07:00
|
|
|
|
2009-10-11 20:31:24 -07:00
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2009-10-11 20:31:24 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-04-08 21:13:21 -07:00
|
|
|
if ((rows[1] - rows[0]) == (int)w)
|
2009-11-06 03:32:23 -08:00
|
|
|
_tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
|
2009-10-11 20:31:24 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
for (y = 0; y < h; y++)
|
2009-11-06 03:32:23 -08:00
|
|
|
_tex_sub_2d(0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
|
2009-10-11 20:31:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->ptu->texture);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-04-08 21:13:21 -07:00
|
|
|
if ((rows[h + 1] - rows[h]) == (int)(w / 2))
|
2009-11-06 03:32:23 -08:00
|
|
|
_tex_sub_2d(0, 0, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat, rows[h]);
|
2009-10-11 20:31:24 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
for (y = 0; y < (h / 2); y++)
|
2009-11-06 03:32:23 -08:00
|
|
|
_tex_sub_2d(0, y, w / 2, 1, tex->ptu->format, tex->ptu->dataformat, rows[h + y]);
|
2009-10-11 20:31:24 -07:00
|
|
|
}
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2009-10-11 20:31:24 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->ptv->texture);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-04-08 21:13:21 -07:00
|
|
|
if ((rows[h + (h / 2) + 1] - rows[h + (h / 2)]) == (int)(w / 2))
|
2009-11-06 03:32:23 -08:00
|
|
|
_tex_sub_2d(0, 0, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2)]);
|
2009-10-11 20:31:24 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
for (y = 0; y < (h / 2); y++)
|
2009-11-06 03:32:23 -08:00
|
|
|
_tex_sub_2d(0, y, w / 2, 1, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2) + y]);
|
2009-10-11 20:31:24 -07:00
|
|
|
}
|
2011-06-17 00:47:28 -07:00
|
|
|
#endif
|
2010-08-08 20:27:59 -07:00
|
|
|
if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
|
2010-02-16 20:21:59 -08:00
|
|
|
{
|
2010-08-08 20:27:59 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
2009-10-10 06:24:15 -07:00
|
|
|
}
|
2011-08-23 08:13:40 -07:00
|
|
|
|
|
|
|
Evas_GL_Texture *
|
|
|
|
evas_gl_common_texture_yuy2_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h)
|
|
|
|
{
|
|
|
|
Evas_GL_Texture *tex;
|
|
|
|
|
|
|
|
tex = calloc(1, sizeof(Evas_GL_Texture));
|
|
|
|
if (!tex) return NULL;
|
|
|
|
|
|
|
|
tex->gc = gc;
|
|
|
|
tex->references = 1;
|
|
|
|
tex->pt = _pool_tex_new(gc, w + 1, h + 1, lum_alpha_ifmt, lum_alpha_fmt);
|
|
|
|
if (!tex->pt)
|
|
|
|
{
|
|
|
|
free(tex);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, tex->pt);
|
|
|
|
tex->pt->slot = -1;
|
|
|
|
tex->pt->fslot = -1;
|
|
|
|
tex->pt->whole = 1;
|
|
|
|
tex->ptuv = _pool_tex_new(gc, (w / 2) + 1, h + 1, rgba8_ifmt, rgba8_fmt);
|
|
|
|
if (!tex->ptuv)
|
|
|
|
{
|
|
|
|
pt_unref(tex->pt);
|
|
|
|
free(tex);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, tex->ptuv);
|
|
|
|
tex->ptuv->slot = -1;
|
|
|
|
tex->ptuv->fslot = -1;
|
|
|
|
tex->ptuv->whole = 1;
|
|
|
|
tex->x = 0;
|
|
|
|
tex->y = 0;
|
|
|
|
tex->w = w;
|
|
|
|
tex->h = h;
|
|
|
|
tex->pt->allocations = eina_list_prepend(tex->pt->allocations, tex);
|
|
|
|
tex->ptuv->allocations = eina_list_prepend(tex->ptuv->allocations, tex);
|
|
|
|
tex->pt->references++;
|
|
|
|
tex->ptuv->references++;
|
|
|
|
evas_gl_common_texture_yuy2_update(tex, rows, w, h);
|
|
|
|
return tex;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
|
|
|
|
{
|
|
|
|
if (!tex->pt) return;
|
|
|
|
// FIXME: works on lowest size 4 pixel high buffers. must also be multiple of 2
|
|
|
|
#undef GL_UNPACK_ROW_LENGTH
|
|
|
|
#ifdef GL_UNPACK_ROW_LENGTH
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
fprintf(stderr, "rows: %p\n", rows[0]);
|
|
|
|
fprintf(stderr, "rows end: %p\n", rows[h - 1] + (rows[1] - rows[0]));
|
|
|
|
_tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
_tex_sub_2d(0, 0, w / 2, h, tex->ptuv->format, tex->ptuv->dataformat, rows[0]);
|
|
|
|
#else
|
|
|
|
unsigned int y;
|
|
|
|
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
if ((rows[1] - rows[0]) == (int)w * 4)
|
|
|
|
_tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (y = 0; y < h; y++)
|
|
|
|
_tex_sub_2d(0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
|
|
|
|
}
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
if ((rows[1] - rows[0]) == (int)(w * 2))
|
|
|
|
_tex_sub_2d(0, 0, w / 2, h, tex->ptuv->format, tex->ptuv->dataformat, rows[0]);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (y = 0; y < h; y++)
|
|
|
|
_tex_sub_2d(0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[y]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
|
|
|
|
{
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
|
|
|
}
|