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-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;
|
2014-01-12 12:09:29 -08:00
|
|
|
|
|
|
|
#ifdef GL_GLES
|
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;
|
2014-01-12 12:09:29 -08: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-01-27 07:29:24 -08:00
|
|
|
#endif
|
2014-01-12 12:09:29 -08:00
|
|
|
|
|
|
|
#ifdef GL_GLES
|
2011-08-23 08:13:40 -07:00
|
|
|
static const GLenum alpha_fmt = GL_ALPHA;
|
|
|
|
static const GLenum alpha_ifmt = GL_ALPHA;
|
2014-01-12 12:09:29 -08:00
|
|
|
#else
|
|
|
|
static const GLenum alpha_fmt = GL_ALPHA;
|
|
|
|
static const GLenum alpha_ifmt = GL_ALPHA4;
|
|
|
|
#endif
|
|
|
|
|
2011-08-23 08:13:40 -07:00
|
|
|
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;
|
2011-08-29 14:52:00 -07:00
|
|
|
static const GLenum rgba8_ifmt = GL_RGBA;
|
2011-08-23 08:13:40 -07:00
|
|
|
static const GLenum rgba8_fmt = GL_BGRA;
|
2009-11-06 03:32:23 -08:00
|
|
|
|
2014-04-24 22:51:42 -07:00
|
|
|
/* FIXME: RGB8_ETC2 is a superset of ETC1,
|
|
|
|
* but is GL_ETC1_RGB8_OES supported whenever GL_COMPRESSED_RGB8_ETC2 is?
|
|
|
|
*/
|
2014-03-26 21:12:12 -07:00
|
|
|
static const GLenum etc1_fmt = GL_ETC1_RGB8_OES;
|
2014-04-24 22:51:42 -07:00
|
|
|
static const GLenum etc2_rgb_fmt = GL_COMPRESSED_RGB8_ETC2;
|
|
|
|
static const GLenum etc2_rgba_fmt = GL_COMPRESSED_RGBA8_ETC2_EAC;
|
2014-03-26 21:12:12 -07: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
|
|
|
|
2013-06-12 03:37:44 -07:00
|
|
|
static const struct {
|
|
|
|
Eina_Bool alpha;
|
|
|
|
Eina_Bool bgra;
|
|
|
|
|
2014-03-20 03:29:57 -07:00
|
|
|
Evas_Colorspace cspace;
|
|
|
|
|
2013-06-12 03:37:44 -07:00
|
|
|
const GLenum *intformat;
|
|
|
|
const GLenum *format;
|
|
|
|
} matching_format[] = {
|
2014-03-20 03:29:57 -07:00
|
|
|
{ EINA_TRUE, EINA_TRUE, EVAS_COLORSPACE_ARGB8888, &bgra_ifmt, &bgra_fmt },
|
|
|
|
{ EINA_TRUE, EINA_FALSE, EVAS_COLORSPACE_ARGB8888, &rgba_ifmt, &rgba_fmt },
|
|
|
|
{ EINA_FALSE, EINA_TRUE, EVAS_COLORSPACE_ARGB8888, &bgr_ifmt, &bgr_fmt },
|
2013-06-12 03:37:44 -07:00
|
|
|
#ifdef GL_GLES
|
2014-03-20 03:29:57 -07:00
|
|
|
{ EINA_FALSE, EINA_FALSE, EVAS_COLORSPACE_ARGB8888, &rgba_ifmt, &rgba_fmt },
|
2013-06-12 03:37:44 -07:00
|
|
|
#else
|
2014-03-20 03:29:57 -07:00
|
|
|
{ EINA_FALSE, EINA_FALSE, EVAS_COLORSPACE_ARGB8888, &rgb_ifmt, &rgb_fmt },
|
2013-06-12 03:37:44 -07:00
|
|
|
#endif
|
2014-03-20 03:29:57 -07:00
|
|
|
{ EINA_FALSE, EINA_FALSE, EVAS_COLORSPACE_GRY8, &lum_fmt, &lum_ifmt },
|
2014-03-20 19:54:27 -07:00
|
|
|
{ EINA_FALSE, EINA_TRUE, EVAS_COLORSPACE_GRY8, &lum_fmt, &lum_ifmt },
|
|
|
|
{ EINA_TRUE, EINA_FALSE, EVAS_COLORSPACE_AGRY88, &lum_alpha_fmt, &lum_alpha_ifmt },
|
2014-03-26 21:12:12 -07:00
|
|
|
{ EINA_TRUE, EINA_TRUE, EVAS_COLORSPACE_AGRY88, &lum_alpha_fmt, &lum_alpha_ifmt },
|
|
|
|
{ EINA_FALSE, EINA_FALSE, EVAS_COLORSPACE_ETC1, &etc1_fmt, &etc1_fmt },
|
2014-04-24 22:51:42 -07:00
|
|
|
{ EINA_FALSE, EINA_TRUE, EVAS_COLORSPACE_ETC1, &etc1_fmt, &etc1_fmt },
|
|
|
|
{ EINA_FALSE, EINA_FALSE, EVAS_COLORSPACE_RGB8_ETC2, &etc2_rgb_fmt, &etc2_rgb_fmt },
|
|
|
|
{ EINA_FALSE, EINA_TRUE, EVAS_COLORSPACE_RGB8_ETC2, &etc2_rgb_fmt, &etc2_rgb_fmt },
|
2014-05-11 21:24:06 -07:00
|
|
|
{ EINA_TRUE, EINA_FALSE, EVAS_COLORSPACE_RGBA8_ETC2_EAC, &etc2_rgba_fmt, &etc2_rgba_fmt },
|
|
|
|
{ EINA_TRUE, EINA_TRUE, EVAS_COLORSPACE_RGBA8_ETC2_EAC, &etc2_rgba_fmt, &etc2_rgba_fmt },
|
|
|
|
// images marked as no alpha but format supports it (RGBA8_ETC2_EAC):
|
2014-04-24 22:51:42 -07:00
|
|
|
{ EINA_FALSE, EINA_FALSE, EVAS_COLORSPACE_RGBA8_ETC2_EAC, &etc2_rgba_fmt, &etc2_rgba_fmt },
|
|
|
|
{ EINA_FALSE, EINA_TRUE, EVAS_COLORSPACE_RGBA8_ETC2_EAC, &etc2_rgba_fmt, &etc2_rgba_fmt }
|
2013-06-12 03:37:44 -07:00
|
|
|
};
|
|
|
|
|
2013-11-26 18:06:56 -08:00
|
|
|
static const GLenum matching_rgba[] = { GL_RGBA4, GL_RGBA8, GL_RGBA12, GL_RGBA16, 0x0 };
|
|
|
|
static const GLenum matching_alpha[] = { GL_ALPHA4, GL_ALPHA8, GL_ALPHA12, GL_ALPHA16, 0x0 };
|
|
|
|
static const GLenum matching_luminance[] = { GL_LUMINANCE4, GL_LUMINANCE8, GL_LUMINANCE12, GL_LUMINANCE16, 0x0 };
|
|
|
|
static const GLenum matching_luminance_alpha[] = { GL_LUMINANCE4_ALPHA4, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE12_ALPHA12, GL_LUMINANCE16_ALPHA16, 0x0 };
|
|
|
|
|
|
|
|
static const struct {
|
|
|
|
GLenum master;
|
|
|
|
const GLenum *matching;
|
|
|
|
} matching_fmt[] = {
|
|
|
|
{ GL_RGBA, matching_rgba },
|
|
|
|
{ GL_ALPHA, matching_alpha },
|
|
|
|
{ GL_LUMINANCE, matching_luminance },
|
|
|
|
{ GL_LUMINANCE_ALPHA, matching_luminance_alpha }
|
|
|
|
};
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_evas_gl_texture_match(GLenum intfmt, GLenum intfmtret)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
if (intfmt == intfmtret) return EINA_TRUE;
|
|
|
|
|
|
|
|
for (i = 0; i < sizeof (matching_fmt) / sizeof (matching_fmt[0]); i++)
|
|
|
|
if (matching_fmt[i].master == intfmt)
|
|
|
|
{
|
|
|
|
unsigned int j;
|
|
|
|
|
|
|
|
for (j = 0; matching_fmt[i].matching[j] != 0x0; j++)
|
|
|
|
if (matching_fmt[i].matching[j] == intfmtret)
|
|
|
|
return EINA_TRUE;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2013-06-12 03:37:44 -07:00
|
|
|
static int
|
2014-03-20 03:29:57 -07:00
|
|
|
_evas_gl_texture_search_format(Eina_Bool alpha, Eina_Bool bgra, Evas_Colorspace cspace)
|
2013-06-12 03:37:44 -07:00
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
alpha = !!alpha;
|
|
|
|
bgra = !!bgra;
|
|
|
|
|
|
|
|
for (i = 0; i < sizeof (matching_format) / sizeof (matching_format[0]); ++i)
|
|
|
|
if (matching_format[i].alpha == alpha &&
|
2014-03-20 03:29:57 -07:00
|
|
|
matching_format[i].bgra == bgra &&
|
|
|
|
matching_format[i].cspace == cspace)
|
2013-06-12 03:37:44 -07:00
|
|
|
return i;
|
|
|
|
|
|
|
|
abort();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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) /
|
2013-07-10 20:39:44 -07:00
|
|
|
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
|
|
|
{
|
2014-01-12 12:09:29 -08:00
|
|
|
case GL_RGBA:
|
|
|
|
case GL_RGBA4:
|
|
|
|
case GL_RGBA8:
|
|
|
|
case GL_RGBA12:
|
|
|
|
case GL_RGBA16:
|
|
|
|
case GL_BGRA:
|
2009-10-09 05:10:27 -07:00
|
|
|
return 0;
|
2014-01-12 12:09:29 -08:00
|
|
|
case GL_RGB:
|
2014-01-12 14:02:24 -08:00
|
|
|
case GL_R3_G3_B2:
|
2014-01-12 12:09:29 -08:00
|
|
|
case GL_RGB4:
|
2014-01-12 14:02:24 -08:00
|
|
|
case GL_RGB5:
|
2014-01-12 12:09:29 -08:00
|
|
|
case GL_RGB8:
|
2014-01-12 14:02:24 -08:00
|
|
|
case GL_RGB10:
|
2014-01-12 12:09:29 -08:00
|
|
|
case GL_RGB12:
|
|
|
|
case GL_RGB16:
|
2009-10-09 05:10:27 -07:00
|
|
|
return 1;
|
2014-01-12 12:09:29 -08:00
|
|
|
case GL_ALPHA:
|
|
|
|
case GL_ALPHA4:
|
|
|
|
case GL_ALPHA8:
|
|
|
|
case GL_ALPHA12:
|
|
|
|
case GL_ALPHA16:
|
2009-10-09 05:10:27 -07:00
|
|
|
return 2;
|
2014-06-16 03:37:15 -07:00
|
|
|
case GL_ETC1_RGB8_OES:
|
|
|
|
return 3;
|
|
|
|
case GL_COMPRESSED_RGB8_ETC2:
|
|
|
|
return 4;
|
|
|
|
case GL_COMPRESSED_RGBA8_ETC2_EAC:
|
|
|
|
return 5;
|
2014-01-12 12:09:29 -08:00
|
|
|
case GL_LUMINANCE: // never used in atlas
|
|
|
|
case GL_LUMINANCE4:
|
|
|
|
case GL_LUMINANCE8:
|
|
|
|
case GL_LUMINANCE12:
|
|
|
|
case GL_LUMINANCE16:
|
2014-06-16 03:37:15 -07:00
|
|
|
return 6;
|
2014-03-20 03:29:57 -07:00
|
|
|
case GL_LUMINANCE4_ALPHA4:
|
|
|
|
case GL_LUMINANCE8_ALPHA8:
|
|
|
|
case GL_LUMINANCE12_ALPHA12:
|
|
|
|
case GL_LUMINANCE16_ALPHA16:
|
2014-06-16 03:37:15 -07:00
|
|
|
return 7;
|
2014-01-12 12:09:29 -08:00
|
|
|
default:
|
2014-06-16 03:37:15 -07:00
|
|
|
// abort?
|
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
|
|
|
|
2013-07-10 20:39:44 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_tex_2d(Evas_Engine_GL_Context *gc, int intfmt, int w, int h, int fmt, int type)
|
2009-11-06 03:32:23 -08:00
|
|
|
{
|
2013-07-10 20:39:44 -07:00
|
|
|
if ((w > gc->shared->info.max_texture_size) ||
|
|
|
|
(h > gc->shared->info.max_texture_size))
|
|
|
|
{
|
|
|
|
ERR("Fail tex too big %ix%i", w, h);
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
2011-12-17 21:03:24 -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__, "");
|
2011-10-21 05:03:41 -07:00
|
|
|
#ifdef GL_TEXTURE_INTERNAL_FORMAT
|
2012-11-14 21:03:45 -08:00
|
|
|
# ifdef GL_GLES
|
2014-06-18 00:23:23 -07:00
|
|
|
# else
|
2011-10-21 05:03:41 -07:00
|
|
|
// this is not in opengles!!! hrrrm
|
2012-11-14 21:03:45 -08:00
|
|
|
// if (glGetTexLevelParameteriv) // in case of weak symbols?
|
2011-10-21 03:03:17 -07:00
|
|
|
{
|
2012-11-14 21:03:45 -08:00
|
|
|
int intfmtret = -1;
|
2014-06-18 00:23:23 -07:00
|
|
|
|
2012-07-03 00:33:44 -07:00
|
|
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
|
|
|
|
GL_TEXTURE_INTERNAL_FORMAT, &intfmtret);
|
2013-11-26 18:06:56 -08:00
|
|
|
if (!_evas_gl_texture_match(intfmt, intfmtret))
|
2012-07-03 00:33:44 -07:00
|
|
|
{
|
|
|
|
ERR("Fail tex alloc %ix%i", w, h);
|
|
|
|
// XXX send async err to evas
|
2013-07-10 20:39:44 -07:00
|
|
|
return EINA_FALSE;
|
2012-07-03 00:33:44 -07:00
|
|
|
}
|
|
|
|
}
|
2012-11-14 21:03:45 -08:00
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// ERR("GL_TEXTURE_INTERNAL_FORMAT defined but no symbol loaded.");
|
|
|
|
// }
|
2014-06-18 00:23:23 -07:00
|
|
|
# endif
|
2013-07-10 20:39:44 -07:00
|
|
|
#endif
|
|
|
|
return EINA_TRUE;
|
2009-11-06 03:32:23 -08:00
|
|
|
}
|
|
|
|
|
2013-06-03 22:13:20 -07:00
|
|
|
static Evas_GL_Texture *
|
|
|
|
evas_gl_common_texture_alloc(Evas_Engine_GL_Context *gc,
|
2014-06-18 00:23:23 -07:00
|
|
|
Evas_Coord w, Evas_Coord h,
|
2013-06-03 22:13:20 -07:00
|
|
|
Eina_Bool alpha)
|
|
|
|
{
|
|
|
|
Evas_GL_Texture *tex;
|
|
|
|
|
|
|
|
tex = calloc(1, sizeof(Evas_GL_Texture));
|
|
|
|
if (!tex) return NULL;
|
|
|
|
|
|
|
|
tex->gc = gc;
|
|
|
|
tex->references = 1;
|
|
|
|
tex->alpha = alpha;
|
|
|
|
tex->w = w;
|
|
|
|
tex->h = h;
|
|
|
|
|
|
|
|
return tex;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_gl_common_texture_light_free(Evas_GL_Texture *tex)
|
|
|
|
{
|
|
|
|
free(tex);
|
|
|
|
}
|
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
static Evas_GL_Texture_Pool *
|
2014-04-28 23:33:51 -07:00
|
|
|
_pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, GLenum intformat, GLenum format)
|
2009-10-09 05:10:27 -07:00
|
|
|
{
|
|
|
|
Evas_GL_Texture_Pool *pt;
|
2014-04-28 23:33:51 -07:00
|
|
|
Eina_Bool ok, no_rounding = EINA_FALSE;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2013-07-10 20:39:44 -07:00
|
|
|
if ((w > gc->shared->info.max_texture_size) ||
|
|
|
|
(h > gc->shared->info.max_texture_size))
|
|
|
|
{
|
|
|
|
ERR("Fail tex too big %ix%i", w, h);
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-10-09 05:10:27 -07:00
|
|
|
pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
|
|
|
|
if (!pt) return NULL;
|
2014-04-28 23:33:51 -07:00
|
|
|
|
2014-06-11 22:44:28 -07:00
|
|
|
if (!gc->shared->info.etc1_subimage && (intformat == etc1_fmt))
|
2014-04-28 23:33:51 -07:00
|
|
|
no_rounding = EINA_TRUE;
|
|
|
|
|
|
|
|
if (!no_rounding)
|
|
|
|
{
|
|
|
|
h = _tex_round_slot(gc, h) * gc->shared->info.tune.atlas.slot_size;
|
|
|
|
_tex_adjust(gc, &w, &h);
|
|
|
|
}
|
2009-10-09 05:10:27 -07:00
|
|
|
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
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
glGenTextures(1, &(pt->texture));
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, pt->texture);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -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__, "");
|
2011-12-17 21:03:24 -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__, "");
|
2013-07-10 20:39:44 -07:00
|
|
|
ok = _tex_2d(gc, pt->intformat, w, h, pt->format, pt->dataformat);
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2013-07-10 20:39:44 -07:00
|
|
|
if (!ok)
|
|
|
|
{
|
|
|
|
glDeleteTextures(1, &(pt->texture));
|
|
|
|
free(pt);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
2009-10-09 05:10:27 -07:00
|
|
|
return pt;
|
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2013-06-12 03:37:44 -07:00
|
|
|
static Evas_GL_Texture_Alloca *
|
|
|
|
_pool_tex_define(Evas_GL_Texture_Pool *pt, int lastx, int w, int *u, Eina_List *l)
|
|
|
|
{
|
|
|
|
Evas_GL_Texture_Alloca *napt;
|
|
|
|
|
|
|
|
*u = lastx;
|
|
|
|
|
|
|
|
napt = malloc(sizeof (Evas_GL_Texture_Alloca));
|
2013-06-20 01:30:21 -07:00
|
|
|
if (!napt) return NULL;
|
2013-06-12 03:37:44 -07:00
|
|
|
|
|
|
|
napt->tex = NULL;
|
|
|
|
napt->x = lastx;
|
|
|
|
napt->w = w;
|
|
|
|
|
2013-06-20 01:30:21 -07:00
|
|
|
if (l == NULL)
|
|
|
|
pt->allocations = eina_list_append(pt->allocations, napt);
|
|
|
|
else
|
|
|
|
pt->allocations = eina_list_prepend_relative_list(pt->allocations, napt, l);
|
2013-06-12 03:37:44 -07:00
|
|
|
|
|
|
|
return napt;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_GL_Texture_Alloca *
|
|
|
|
_pool_tex_alloc(Evas_GL_Texture_Pool *pt, int w, int h EINA_UNUSED, int *u, int *v)
|
2009-10-09 05:10:27 -07:00
|
|
|
{
|
2013-06-12 03:37:44 -07:00
|
|
|
Evas_GL_Texture_Alloca *apt;
|
2009-10-09 05:10:27 -07:00
|
|
|
Eina_List *l;
|
2013-06-12 03:37:44 -07:00
|
|
|
int lastx = 0;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2013-06-12 03:37:44 -07:00
|
|
|
*v = 0;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(pt->allocations, l, apt)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
2013-06-12 03:37:44 -07:00
|
|
|
if (apt->x - lastx >= w)
|
|
|
|
return _pool_tex_define(pt, lastx, w, u, l);
|
|
|
|
|
|
|
|
lastx = apt->x + apt->w;
|
2003-09-07 04:24:48 -07:00
|
|
|
}
|
2013-06-12 03:37:44 -07:00
|
|
|
|
|
|
|
if (pt->w - lastx >= w)
|
|
|
|
return _pool_tex_define(pt, lastx, w, u, NULL);
|
|
|
|
|
|
|
|
return NULL;
|
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,
|
2014-03-26 21:12:12 -07:00
|
|
|
GLenum intformat, GLenum format, int *u, int *v,
|
2013-06-12 03:37:44 -07:00
|
|
|
Evas_GL_Texture_Alloca **apt, 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) ||
|
2014-03-26 21:12:12 -07:00
|
|
|
(h > gc->shared->info.tune.atlas.max_h) ||
|
2014-06-11 22:44:28 -07:00
|
|
|
(!gc->shared->info.etc1_subimage && (intformat == etc1_fmt)))
|
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);
|
2013-07-14 18:59:29 -07:00
|
|
|
if (!pt) return NULL;
|
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;
|
2013-06-20 04:08:36 -07:00
|
|
|
*apt = _pool_tex_alloc(pt, w, h, u, v);
|
2009-10-09 05:10:27 -07:00
|
|
|
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
|
|
|
{
|
2013-06-12 03:37:44 -07:00
|
|
|
if ((*apt = _pool_tex_alloc(pt, w, h, u, v)) != NULL)
|
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
|
|
|
}
|
2013-06-12 03:37:44 -07:00
|
|
|
|
2009-11-06 03:32:23 -08:00
|
|
|
pt = _pool_tex_new(gc, atlas_w, h, intformat, format);
|
2013-07-14 18:59:29 -07:00
|
|
|
if (!pt) return NULL;
|
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;
|
2013-06-12 03:37:44 -07:00
|
|
|
|
|
|
|
*apt = _pool_tex_alloc(pt, w, h, u, v);
|
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
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;
|
2014-03-26 21:12:12 -07:00
|
|
|
GLsizei w, h;
|
2014-04-24 22:51:42 -07:00
|
|
|
int u = 0, v = 0, yoffset = 0;
|
2013-06-12 03:37:44 -07:00
|
|
|
int lformat;
|
2003-09-07 04:24:48 -07:00
|
|
|
|
2013-06-03 22:13:20 -07:00
|
|
|
tex = evas_gl_common_texture_alloc(gc, im->cache_entry.w, im->cache_entry.h, im->cache_entry.flags.alpha);
|
2009-10-09 05:10:27 -07:00
|
|
|
if (!tex) return NULL;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2013-02-26 05:05:19 -08:00
|
|
|
#define TEX_HREP 1
|
|
|
|
#define TEX_VREP 1
|
2013-06-12 03:37:44 -07:00
|
|
|
|
2014-03-20 03:29:57 -07:00
|
|
|
lformat = _evas_gl_texture_search_format(im->cache_entry.flags.alpha, gc->shared->info.bgra, im->cache_entry.space);
|
2014-04-24 22:51:42 -07:00
|
|
|
switch (im->cache_entry.space)
|
2014-03-26 21:12:12 -07:00
|
|
|
{
|
2014-04-24 22:51:42 -07:00
|
|
|
case EVAS_COLORSPACE_ETC1:
|
|
|
|
case EVAS_COLORSPACE_RGB8_ETC2:
|
|
|
|
case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
|
|
|
|
// Add border to avoid artifacts
|
2014-03-26 21:12:12 -07:00
|
|
|
w = im->cache_entry.w + 2;
|
|
|
|
h = im->cache_entry.h + 2;
|
2014-04-24 22:51:42 -07:00
|
|
|
yoffset = 1;
|
2014-03-26 21:12:12 -07:00
|
|
|
|
2014-04-24 22:51:42 -07:00
|
|
|
// Adjust w and h for ETC1/2 formats (multiple of 4 pixels on both axes)
|
2014-03-26 21:12:12 -07:00
|
|
|
w = ((w >> 2) + (w & 0x3 ? 1 : 0)) << 2;
|
|
|
|
h = ((h >> 2) + (h & 0x3 ? 1 : 0)) << 2;
|
2014-04-24 22:51:42 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2014-03-26 21:12:12 -07:00
|
|
|
/* This need to be adjusted if we do something else than strip allocation */
|
|
|
|
w = im->cache_entry.w + TEX_HREP + 2; /* one pixel stop gap and two pixels for the border */
|
|
|
|
h = im->cache_entry.h + TEX_VREP; /* only one added border for security down */
|
|
|
|
}
|
|
|
|
|
|
|
|
tex->pt = _pool_tex_find(gc, w, h,
|
2013-06-12 03:37:44 -07:00
|
|
|
*matching_format[lformat].intformat,
|
|
|
|
*matching_format[lformat].format,
|
|
|
|
&u, &v, &tex->apt,
|
|
|
|
gc->shared->info.tune.atlas.max_alloc_size);
|
2009-10-09 05:10:27 -07:00
|
|
|
if (!tex->pt)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
2013-06-03 22:13:20 -07:00
|
|
|
evas_gl_common_texture_light_free(tex);
|
2009-10-09 05:10:27 -07:00
|
|
|
return NULL;
|
2003-09-07 04:24:48 -07:00
|
|
|
}
|
2013-06-20 01:30:21 -07:00
|
|
|
tex->apt->tex = tex;
|
2009-10-09 05:10:27 -07:00
|
|
|
tex->x = u + 1;
|
2014-04-24 22:51:42 -07:00
|
|
|
tex->y = v + yoffset;
|
2014-03-26 21:12:12 -07:00
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
tex->pt->references++;
|
|
|
|
evas_gl_common_texture_update(tex, im);
|
2013-06-20 01:30:21 -07:00
|
|
|
|
2009-10-09 05:10:27 -07:00
|
|
|
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;
|
2013-05-17 16:28:07 -07:00
|
|
|
int fnum;
|
2013-07-10 20:39:44 -07:00
|
|
|
Eina_Bool ok;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2013-07-10 20:39:44 -07:00
|
|
|
if ((w > gc->shared->info.max_texture_size) ||
|
|
|
|
(h > gc->shared->info.max_texture_size))
|
|
|
|
{
|
|
|
|
ERR("Fail tex too big %ix%i", w, h);
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-11-12 23:22:31 -08:00
|
|
|
pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
|
|
|
|
if (!pt) return NULL;
|
|
|
|
_tex_adjust(gc, &w, &h);
|
|
|
|
pt->gc = gc;
|
|
|
|
pt->w = w;
|
|
|
|
pt->h = h;
|
|
|
|
pt->intformat = intformat;
|
|
|
|
pt->format = format;
|
2011-08-29 14:52:00 -07:00
|
|
|
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;
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
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
|
2013-05-20 10:19:45 -07:00
|
|
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fnum);
|
2011-12-17 21:03:24 -08:00
|
|
|
glGenTextures(1, &(pt->texture));
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, pt->texture);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -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__, "");
|
2011-12-17 21:03:24 -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__, "");
|
2013-07-10 20:39:44 -07:00
|
|
|
ok = _tex_2d(gc, 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__, "");
|
2013-05-17 16:28:07 -07:00
|
|
|
glsym_glBindFramebuffer(GL_FRAMEBUFFER, fnum);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2014-06-18 00:23:23 -07:00
|
|
|
|
2013-07-10 20:39:44 -07:00
|
|
|
if (!ok)
|
|
|
|
{
|
|
|
|
glDeleteTextures(1, &(pt->texture));
|
|
|
|
free(pt);
|
|
|
|
return NULL;
|
|
|
|
}
|
2014-06-18 00:23:23 -07:00
|
|
|
|
2013-07-10 20:39:44 -07:00
|
|
|
texinfo.r.num++;
|
|
|
|
texinfo.r.pix += pt->w * pt->h;
|
|
|
|
_print_tex_count();
|
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
|
|
|
|
2013-07-10 20:39:44 -07:00
|
|
|
if ((w > gc->shared->info.max_texture_size) ||
|
|
|
|
(h > gc->shared->info.max_texture_size))
|
|
|
|
{
|
|
|
|
ERR("Fail tex too big %ix%i", w, h);
|
|
|
|
return NULL;
|
|
|
|
}
|
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;
|
2011-12-17 21:03:24 -08:00
|
|
|
glGenTextures(1, &(pt->texture));
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -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
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
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
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
glTexParameteri(im->native.target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glTexParameteri(im->native.target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -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__, "");
|
2011-12-17 21:03:24 -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__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(im->native.target, 0);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(im->native.target, gc->pipe[0].shader.cur_tex);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2014-06-18 00:23:23 -07:00
|
|
|
|
2013-07-10 20:39:44 -07:00
|
|
|
texinfo.n.num++;
|
|
|
|
texinfo.n.pix += pt->w * pt->h;
|
|
|
|
_print_tex_count();
|
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
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2010-08-13 03:34:51 -07:00
|
|
|
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
|
|
|
|
2011-09-30 08:51:32 -07:00
|
|
|
if (intformat != format) return NULL;
|
|
|
|
|
|
|
|
switch (intformat)
|
|
|
|
{
|
|
|
|
#ifdef EGL_MAP_GL_TEXTURE_LUMINANCE_SEC
|
|
|
|
case GL_LUMINANCE: attr[5] = EGL_MAP_GL_TEXTURE_LUMINANCE_SEC; break;
|
|
|
|
#endif
|
|
|
|
#ifdef EGL_MAP_GL_TEXTURE_LUMINANCE_ALPHA_SEC
|
|
|
|
case GL_LUMINANCE_ALPHA: attr[5] = EGL_MAP_GL_TEXTURE_LUMINANCE_ALPHA_SEC; break;
|
|
|
|
#endif
|
|
|
|
case GL_RGBA: attr[5] = EGL_MAP_GL_TEXTURE_RGBA_SEC; break;
|
2011-10-10 03:08:29 -07:00
|
|
|
case GL_BGRA: attr[5] = EGL_MAP_GL_TEXTURE_BGRA_SEC; break;
|
2011-09-30 08:51:32 -07:00
|
|
|
default: fprintf(stderr, "unknown format\n"); return NULL;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
glGenTextures(1, &(pt->texture));
|
2010-08-13 03:34:51 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, pt->texture);
|
2010-08-13 03:34:51 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
2010-08-13 03:34:51 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
2010-08-13 03:34:51 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
2010-08-13 03:34:51 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
2010-08-13 03:34:51 -07:00
|
|
|
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
|
2011-12-17 21:03:24 -08: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);
|
2011-09-30 08:51:32 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2010-08-13 03:34:51 -07:00
|
|
|
if (!pt->dyn.img)
|
|
|
|
{
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
2010-08-13 03:34:51 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glDeleteTextures(1, &(pt->texture));
|
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
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
free(pt);
|
|
|
|
return NULL;
|
2010-08-13 03:34:51 -07:00
|
|
|
}
|
2011-12-17 21:03:24 -08:00
|
|
|
if (secsym_eglGetImageAttribSEC(egldisplay,
|
2010-08-13 03:34:51 -07:00
|
|
|
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;
|
2011-12-17 21:03:24 -08:00
|
|
|
if (secsym_eglGetImageAttribSEC(egldisplay,
|
2010-08-13 03:34:51 -07:00
|
|
|
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;
|
2011-12-17 21:03:24 -08:00
|
|
|
if (secsym_eglGetImageAttribSEC(egldisplay,
|
2010-08-13 03:34:51 -07:00
|
|
|
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;
|
2011-12-17 21:03:24 -08:00
|
|
|
if (secsym_eglGetImageAttribSEC(egldisplay,
|
2010-08-13 03:34:51 -07:00
|
|
|
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;
|
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
if (secsym_eglGetImageAttribSEC(egldisplay,
|
2010-08-13 03:34:51 -07:00
|
|
|
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
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
|
2010-08-13 03:34:51 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2010-09-18 19:10:09 -07:00
|
|
|
#else
|
2012-11-14 21:03:45 -08:00
|
|
|
if (gc + w + h + intformat + format) return pt;
|
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 */
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
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:
|
2011-12-17 21:03:24 -08:00
|
|
|
secsym_eglDestroyImage(egldisplay, 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
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
pt->dyn.img = NULL;
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
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
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glDeleteTextures(1, &(pt->texture));
|
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
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
free(pt);
|
|
|
|
return NULL;
|
2014-06-18 00:23:23 -07:00
|
|
|
#endif
|
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
|
|
|
{
|
2013-06-12 03:37:44 -07:00
|
|
|
Evas_GL_Texture_Alloca *apt;
|
|
|
|
|
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
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2010-08-13 03:34:51 -07:00
|
|
|
if (pt->dyn.img)
|
|
|
|
{
|
2011-11-10 23:43:38 -08:00
|
|
|
if (pt->dyn.checked_out > 0)
|
2013-04-12 01:34:13 -07:00
|
|
|
secsym_eglUnmapImageSEC(pt->gc->egldisp, pt->dyn.img, EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC);
|
2011-12-17 21:03:24 -08:00
|
|
|
secsym_eglDestroyImage(pt->gc->egldisp, pt->dyn.img);
|
2010-08-13 03:34:51 -07:00
|
|
|
pt->dyn.img = NULL;
|
|
|
|
pt->dyn.data = NULL;
|
|
|
|
pt->dyn.w = 0;
|
|
|
|
pt->dyn.h = 0;
|
|
|
|
pt->dyn.stride = 0;
|
2011-11-10 23:36:15 -08:00
|
|
|
pt->dyn.checked_out = 0;
|
2010-08-13 03:34:51 -07:00
|
|
|
}
|
2011-06-17 00:47:28 -07:00
|
|
|
#endif
|
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
glDeleteTextures(1, &(pt->texture));
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2013-12-26 04:03:56 -08:00
|
|
|
if (pt->gc->pipe[0].shader.cur_tex == pt->texture)
|
|
|
|
pt->gc->pipe[0].shader.cur_tex = 0;
|
2010-02-16 20:21:59 -08:00
|
|
|
if (pt->fb)
|
|
|
|
{
|
|
|
|
glsym_glDeleteFramebuffers(1, &(pt->fb));
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-01-13 02:41:08 -08:00
|
|
|
pt->fb = 0;
|
|
|
|
}
|
2013-06-12 03:37:44 -07:00
|
|
|
|
|
|
|
EINA_LIST_FREE(pt->allocations, apt)
|
|
|
|
free(apt);
|
2011-01-13 02:41:08 -08:00
|
|
|
pt->texture = 0;
|
|
|
|
pt->gc = NULL;
|
|
|
|
pt->w = 0;
|
|
|
|
pt->h = 0;
|
|
|
|
}
|
|
|
|
|
2013-06-23 19:41:32 -07:00
|
|
|
void
|
2011-01-13 02:41:08 -08:00
|
|
|
pt_unref(Evas_GL_Texture_Pool *pt)
|
|
|
|
{
|
2011-09-06 00:56:47 -07:00
|
|
|
if (!pt) return;
|
2011-01-13 02:41:08 -08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2011-09-06 00:56:47 -07:00
|
|
|
static void
|
2013-06-12 03:37:44 -07:00
|
|
|
pt_link(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt)
|
2011-09-06 00:56:47 -07:00
|
|
|
{
|
|
|
|
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, pt);
|
|
|
|
pt->slot = -1;
|
|
|
|
pt->fslot = -1;
|
|
|
|
pt->whole = 1;
|
|
|
|
pt->references++;
|
|
|
|
}
|
|
|
|
|
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;
|
2013-06-12 03:37:44 -07:00
|
|
|
int lformat;
|
2010-01-21 00:44:11 -08:00
|
|
|
|
2013-06-03 22:13:20 -07:00
|
|
|
tex = evas_gl_common_texture_alloc(gc, w, h, alpha);
|
2010-01-21 00:44:11 -08:00
|
|
|
if (!tex) return NULL;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2014-03-20 03:29:57 -07:00
|
|
|
lformat = _evas_gl_texture_search_format(alpha, gc->shared->info.bgra, EVAS_COLORSPACE_ARGB8888);
|
2013-06-12 03:37:44 -07:00
|
|
|
tex->pt = _pool_tex_native_new(gc, w, h,
|
|
|
|
*matching_format[lformat].intformat,
|
|
|
|
*matching_format[lformat].format,
|
|
|
|
im);
|
2010-01-21 00:44:11 -08:00
|
|
|
if (!tex->pt)
|
|
|
|
{
|
2013-06-03 22:13:20 -07:00
|
|
|
evas_gl_common_texture_light_free(tex);
|
2010-01-21 00:44:11 -08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
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;
|
2013-06-12 03:37:44 -07:00
|
|
|
int lformat;
|
2009-11-12 23:22:31 -08:00
|
|
|
|
2013-06-03 22:13:20 -07:00
|
|
|
tex = evas_gl_common_texture_alloc(gc, w, h, alpha);
|
2009-11-12 23:22:31 -08:00
|
|
|
if (!tex) return NULL;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2014-03-20 03:29:57 -07:00
|
|
|
lformat = _evas_gl_texture_search_format(alpha, gc->shared->info.bgra, EVAS_COLORSPACE_ARGB8888);
|
2013-06-12 03:37:44 -07:00
|
|
|
tex->pt = _pool_tex_render_new(gc, w, h,
|
|
|
|
*matching_format[lformat].intformat,
|
|
|
|
*matching_format[lformat].format);
|
2009-11-12 23:22:31 -08:00
|
|
|
if (!tex->pt)
|
|
|
|
{
|
2013-06-03 22:13:20 -07:00
|
|
|
evas_gl_common_texture_light_free(tex);
|
2009-11-12 23:22:31 -08:00
|
|
|
return NULL;
|
|
|
|
}
|
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;
|
2013-06-12 03:37:44 -07:00
|
|
|
int lformat;
|
2010-08-13 03:34:51 -07:00
|
|
|
|
2013-06-03 22:13:20 -07:00
|
|
|
tex = evas_gl_common_texture_alloc(gc, im->w, im->h, im->alpha);
|
2010-08-13 03:34:51 -07:00
|
|
|
if (!tex) return NULL;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2014-03-20 03:29:57 -07:00
|
|
|
lformat = _evas_gl_texture_search_format(tex->alpha, gc->shared->info.bgra, EVAS_COLORSPACE_ARGB8888);
|
2013-06-12 03:37:44 -07:00
|
|
|
tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h,
|
|
|
|
*matching_format[lformat].intformat,
|
|
|
|
*matching_format[lformat].format);
|
2010-08-13 03:34:51 -07:00
|
|
|
if (!tex->pt)
|
|
|
|
{
|
2013-06-03 22:13:20 -07:00
|
|
|
evas_gl_common_texture_light_free(tex);
|
2010-08-13 03:34:51 -07:00
|
|
|
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
|
2014-03-20 19:54:27 -07:00
|
|
|
evas_gl_common_texture_upload(Evas_GL_Texture *tex, RGBA_Image *im, unsigned int bytes_count)
|
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
|
|
|
|
2014-03-20 19:54:27 -07:00
|
|
|
fmt = tex->pt->format;
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
if (tex->gc->shared->info.unpack_row_length)
|
|
|
|
{
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
|
|
|
|
// printf("tex upload %ix%i\n", im->cache_entry.w, im->cache_entry.h);
|
|
|
|
// +-+
|
|
|
|
// +-+
|
|
|
|
//
|
|
|
|
_tex_sub_2d(tex->gc, tex->x, tex->y,
|
|
|
|
im->cache_entry.w, im->cache_entry.h,
|
|
|
|
fmt, tex->pt->dataformat,
|
|
|
|
im->image.data);
|
|
|
|
// xxx
|
|
|
|
// xxx
|
|
|
|
// ---
|
|
|
|
_tex_sub_2d(tex->gc, tex->x, tex->y + im->cache_entry.h,
|
|
|
|
im->cache_entry.w, 1,
|
|
|
|
fmt, tex->pt->dataformat,
|
|
|
|
(unsigned char *) im->image.data + (((im->cache_entry.h - 1) * im->cache_entry.w)) * bytes_count);
|
|
|
|
// xxx
|
|
|
|
// xxx
|
|
|
|
// o
|
|
|
|
_tex_sub_2d(tex->gc, tex->x - 1, tex->y + im->cache_entry.h,
|
|
|
|
1, 1,
|
|
|
|
fmt, tex->pt->dataformat,
|
|
|
|
(unsigned char *) im->image.data + (((im->cache_entry.h - 1) * im->cache_entry.w)) * bytes_count);
|
|
|
|
// xxx
|
|
|
|
// xxx
|
|
|
|
// o
|
|
|
|
_tex_sub_2d(tex->gc, tex->x + im->cache_entry.w, tex->y + im->cache_entry.h,
|
|
|
|
1, 1,
|
|
|
|
fmt, tex->pt->dataformat,
|
|
|
|
(unsigned char *) im->image.data + (((im->cache_entry.h - 1) * im->cache_entry.w) + (im->cache_entry.w - 1)) * bytes_count);
|
|
|
|
if (tex->gc->shared->info.unpack_row_length)
|
|
|
|
{
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, im->cache_entry.w);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
// |xxx
|
|
|
|
// |xxx
|
|
|
|
//
|
|
|
|
_tex_sub_2d(tex->gc, tex->x - 1, tex->y,
|
|
|
|
1, im->cache_entry.h,
|
|
|
|
fmt, tex->pt->dataformat,
|
|
|
|
im->image.data);
|
|
|
|
// xxx|
|
|
|
|
// xxx|
|
|
|
|
//
|
|
|
|
_tex_sub_2d(tex->gc, tex->x + im->cache_entry.w, tex->y,
|
|
|
|
1, im->cache_entry.h,
|
|
|
|
fmt, tex->pt->dataformat,
|
|
|
|
(unsigned char *) im->image.data + (im->cache_entry.w - 1) * bytes_count);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DATA8 *tpix, *ps, *pd;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
tpix = alloca(im->cache_entry.h * bytes_count);
|
|
|
|
pd = tpix;
|
2014-04-02 20:26:46 -07:00
|
|
|
ps = im->image.data8;
|
2014-03-20 19:54:27 -07:00
|
|
|
for (i = 0; i < (int)im->cache_entry.h; i++)
|
|
|
|
{
|
|
|
|
memcpy(pd, ps, bytes_count);
|
2014-04-16 22:59:52 -07:00
|
|
|
pd += bytes_count;
|
2014-03-20 19:54:27 -07:00
|
|
|
ps += im->cache_entry.w * bytes_count;
|
|
|
|
}
|
|
|
|
// |xxx
|
|
|
|
// |xxx
|
|
|
|
//
|
|
|
|
_tex_sub_2d(tex->gc, tex->x - 1, tex->y,
|
|
|
|
1, im->cache_entry.h,
|
|
|
|
fmt, tex->pt->dataformat,
|
|
|
|
tpix);
|
|
|
|
pd = tpix;
|
2014-04-02 20:26:46 -07:00
|
|
|
ps = im->image.data8 + (im->cache_entry.w - 1) * bytes_count;
|
2014-03-20 19:54:27 -07:00
|
|
|
for (i = 0; i < (int)im->cache_entry.h; i++)
|
|
|
|
{
|
|
|
|
memcpy(pd, ps, bytes_count);
|
2014-04-16 22:59:52 -07:00
|
|
|
pd += bytes_count;
|
2014-03-20 19:54:27 -07:00
|
|
|
ps += im->cache_entry.w * bytes_count;
|
|
|
|
}
|
|
|
|
// xxx|
|
|
|
|
// xxx|
|
|
|
|
//
|
|
|
|
_tex_sub_2d(tex->gc, tex->x + im->cache_entry.w, tex->y,
|
|
|
|
1, im->cache_entry.h,
|
|
|
|
fmt, tex->pt->dataformat,
|
|
|
|
tpix);
|
|
|
|
}
|
|
|
|
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__, "");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
|
|
|
|
{
|
|
|
|
unsigned int bytes_count;
|
|
|
|
|
2010-01-19 06:29:20 -08:00
|
|
|
if (tex->alpha != im->cache_entry.flags.alpha)
|
|
|
|
{
|
2013-06-12 03:37:44 -07:00
|
|
|
int lformat;
|
|
|
|
|
|
|
|
tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex->apt);
|
2010-01-19 06:29:20 -08:00
|
|
|
pt_unref(tex->pt);
|
|
|
|
tex->alpha = im->cache_entry.flags.alpha;
|
2013-06-12 03:37:44 -07:00
|
|
|
|
2014-03-20 03:29:57 -07:00
|
|
|
lformat = _evas_gl_texture_search_format(tex->alpha, tex->gc->shared->info.bgra, im->cache_entry.space);
|
2014-03-26 21:12:12 -07:00
|
|
|
// FIXME: why a 'render' new here ??? Should already have been allocated, quite a weird path.
|
2013-06-12 03:37:44 -07:00
|
|
|
tex->pt = _pool_tex_render_new(tex->gc, tex->w, tex->h,
|
|
|
|
*matching_format[lformat].intformat,
|
|
|
|
*matching_format[lformat].format);
|
2010-01-19 06:29:20 -08:00
|
|
|
}
|
2013-06-23 19:41:32 -07:00
|
|
|
// If image was preloaded then we need a ptt
|
2010-01-29 02:53:53 -08:00
|
|
|
if (!tex->pt) return;
|
2013-06-25 19:49:16 -07:00
|
|
|
if (!im->image.data) return;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2014-03-20 19:54:27 -07:00
|
|
|
switch (im->cache_entry.space)
|
|
|
|
{
|
|
|
|
case EVAS_COLORSPACE_ARGB8888: bytes_count = 4; break;
|
|
|
|
case EVAS_COLORSPACE_GRY8: bytes_count = 1; break;
|
|
|
|
case EVAS_COLORSPACE_AGRY88: bytes_count = 2; break;
|
2014-03-26 21:12:12 -07:00
|
|
|
case EVAS_COLORSPACE_ETC1:
|
2014-04-24 22:51:42 -07:00
|
|
|
case EVAS_COLORSPACE_RGB8_ETC2:
|
|
|
|
case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
|
2014-03-26 21:12:12 -07:00
|
|
|
{
|
|
|
|
/*
|
2014-04-24 22:51:42 -07:00
|
|
|
ETC1/2 can't be scaled down on the fly and interpolated, like it is
|
2014-03-26 21:12:12 -07:00
|
|
|
required for preloading, so we don't take that path. Also as the content
|
|
|
|
already have duplicated border and we use a specific function to
|
|
|
|
upload the compressed data, there is no need to use the normal path at
|
|
|
|
all.
|
|
|
|
*/
|
|
|
|
GLsizei width, height;
|
2014-06-11 22:44:28 -07:00
|
|
|
GLint x, y;
|
2014-04-24 22:51:42 -07:00
|
|
|
int etc_block_size = 8;
|
|
|
|
|
|
|
|
if (im->cache_entry.space == EVAS_COLORSPACE_RGBA8_ETC2_EAC)
|
|
|
|
etc_block_size = 16;
|
2014-03-26 21:12:12 -07:00
|
|
|
|
2014-06-11 22:44:28 -07:00
|
|
|
x = tex->x - 1;
|
|
|
|
y = tex->y - 1;
|
2014-03-26 21:12:12 -07:00
|
|
|
width = im->cache_entry.w + 2;
|
|
|
|
height = im->cache_entry.h + 2;
|
|
|
|
width = ((width >> 2) + (width & 0x3 ? 1 : 0)) << 2;
|
|
|
|
height = ((height >> 2) + (height & 0x3 ? 1 : 0)) << 2;
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
|
2014-06-11 22:44:28 -07:00
|
|
|
if ((tex->gc->shared->info.etc1_subimage ||
|
|
|
|
(im->cache_entry.space != EVAS_COLORSPACE_ETC1))
|
|
|
|
&& (tex->pt->w != width || tex->pt->h != height))
|
|
|
|
{
|
|
|
|
int glerr;
|
|
|
|
glerr = glGetError();
|
|
|
|
|
|
|
|
if (!tex->pt->comptex_ready)
|
|
|
|
{
|
|
|
|
GLsizei tw, th;
|
|
|
|
tw = ((tex->pt->w >> 2) + (tex->pt->w & 0x3 ? 1 : 0)) << 2;
|
|
|
|
th = ((tex->pt->h >> 2) + (tex->pt->h & 0x3 ? 1 : 0)) << 2;
|
|
|
|
glCompressedTexImage2D(GL_TEXTURE_2D, 0, tex->pt->format,
|
|
|
|
tw, th, 0,
|
|
|
|
((tw * th) >> 4) * etc_block_size,
|
|
|
|
NULL);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
tex->pt->comptex_ready = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
|
|
|
|
x, y, width, height,
|
|
|
|
tex->pt->format,
|
|
|
|
((width * height) >> 4) * etc_block_size,
|
|
|
|
im->image.data);
|
|
|
|
|
|
|
|
glerr = glGetError();
|
|
|
|
if (glerr != GL_NO_ERROR)
|
|
|
|
{
|
|
|
|
ERR("glCompressedTexSubImage2D failed with ETC1/2: %d", glerr);
|
|
|
|
|
|
|
|
// FIXME: Changing settings on the fly.
|
|
|
|
// The first texture will be black.
|
|
|
|
// How to fallback? We need a whole texture now.
|
|
|
|
if (im->cache_entry.space == EVAS_COLORSPACE_ETC1)
|
|
|
|
tex->gc->shared->info.etc1_subimage = EINA_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
glCompressedTexImage2D(GL_TEXTURE_2D, 0, tex->pt->format,
|
|
|
|
width, height, 0,
|
|
|
|
((width * height) >> 4) * etc_block_size,
|
|
|
|
im->image.data);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
2014-03-26 21:12:12 -07:00
|
|
|
|
|
|
|
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__, "");
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
ERR("Don't know how to upload texture in colorspace %i.", im->cache_entry.space);
|
|
|
|
return;
|
2014-03-20 19:54:27 -07:00
|
|
|
}
|
|
|
|
|
2013-06-23 19:41:32 -07:00
|
|
|
// if preloaded, then async push it in after uploading a miniature of it
|
|
|
|
if (im->cache_entry.flags.preload_done && tex->w > 2 * EVAS_GL_TILE_SIZE && tex->h > 2 * EVAS_GL_TILE_SIZE)
|
|
|
|
{
|
|
|
|
Evas_GL_Texture_Async_Preload *async;
|
2014-03-20 19:54:27 -07:00
|
|
|
unsigned char *in;
|
|
|
|
unsigned char *out;
|
|
|
|
GLuint fmt;
|
2013-06-23 19:41:32 -07:00
|
|
|
float xstep, ystep;
|
|
|
|
float x, y;
|
|
|
|
int i, j;
|
|
|
|
int lformat;
|
|
|
|
int u, v;
|
|
|
|
|
|
|
|
if (tex->ptt) return ;
|
|
|
|
|
2014-03-20 19:54:27 -07:00
|
|
|
out = alloca(bytes_count * EVAS_GL_TILE_SIZE * EVAS_GL_TILE_SIZE);
|
2013-06-23 19:41:32 -07:00
|
|
|
xstep = (float)tex->w / (EVAS_GL_TILE_SIZE - 2);
|
|
|
|
ystep = (float)tex->h / (EVAS_GL_TILE_SIZE - 1);
|
2014-04-02 20:26:46 -07:00
|
|
|
in = im->image.data8;
|
2013-06-23 19:41:32 -07:00
|
|
|
|
|
|
|
for (y = 0, j = 0; j < EVAS_GL_TILE_SIZE - 1; y += ystep, j++)
|
|
|
|
{
|
2014-03-20 19:54:27 -07:00
|
|
|
memcpy(&out[j * EVAS_GL_TILE_SIZE * bytes_count],
|
|
|
|
&in[(int)y * im->cache_entry.w * bytes_count],
|
|
|
|
bytes_count);
|
2013-06-23 19:41:32 -07:00
|
|
|
for (x = 0, i = 1; i < EVAS_GL_TILE_SIZE - 1; x += xstep, i++)
|
2014-03-20 19:54:27 -07:00
|
|
|
memcpy(&out[(j * EVAS_GL_TILE_SIZE + i) * bytes_count],
|
|
|
|
&in[((int)y * im->cache_entry.w + (int)x) * bytes_count],
|
|
|
|
bytes_count);
|
|
|
|
memcpy(&out[(j * EVAS_GL_TILE_SIZE + i) * bytes_count],
|
|
|
|
&in[((int)y * im->cache_entry.w + (int)(x - xstep)) * bytes_count],
|
|
|
|
bytes_count);
|
2013-06-23 19:41:32 -07:00
|
|
|
}
|
|
|
|
|
2014-03-20 19:54:27 -07:00
|
|
|
memcpy(&out[(j * EVAS_GL_TILE_SIZE) * bytes_count],
|
|
|
|
&out[((j - 1) * EVAS_GL_TILE_SIZE) * bytes_count],
|
|
|
|
EVAS_GL_TILE_SIZE * bytes_count);
|
2013-06-23 19:41:32 -07:00
|
|
|
|
|
|
|
// out is a miniature of the texture, upload that now and schedule the data for later.
|
|
|
|
|
|
|
|
// Creating the mini picture texture
|
2014-03-20 03:29:57 -07:00
|
|
|
lformat = _evas_gl_texture_search_format(tex->alpha, tex->gc->shared->info.bgra, im->cache_entry.space);
|
2013-06-23 19:41:32 -07:00
|
|
|
tex->ptt = _pool_tex_find(tex->gc, EVAS_GL_TILE_SIZE, EVAS_GL_TILE_SIZE,
|
|
|
|
*matching_format[lformat].intformat,
|
|
|
|
*matching_format[lformat].format,
|
|
|
|
&u, &v, &tex->aptt,
|
|
|
|
tex->gc->shared->info.tune.atlas.max_alloc_size);
|
|
|
|
if (!tex->ptt)
|
|
|
|
goto upload;
|
|
|
|
tex->aptt->tex = tex;
|
|
|
|
|
|
|
|
tex->tx = u + 1;
|
|
|
|
tex->ty = v;
|
|
|
|
tex->ptt->references++;
|
|
|
|
|
|
|
|
// Bind and upload ! Vooom !
|
|
|
|
fmt = tex->ptt->format;
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->ptt->texture);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
if (tex->gc->shared->info.unpack_row_length)
|
|
|
|
{
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, u, tex->ty, EVAS_GL_TILE_SIZE, EVAS_GL_TILE_SIZE, fmt, tex->ptt->dataformat, out);
|
2013-06-23 19:41:32 -07:00
|
|
|
|
|
|
|
// Switch back to current texture
|
|
|
|
if (tex->ptt->texture != tex->gc->pipe[0].shader.cur_tex)
|
|
|
|
{
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now prepare uploading the main texture before returning;
|
|
|
|
async = malloc(sizeof (Evas_GL_Texture_Async_Preload));
|
|
|
|
if (!async)
|
|
|
|
{
|
|
|
|
goto upload;
|
|
|
|
}
|
|
|
|
|
|
|
|
async->tex = tex;
|
|
|
|
async->tex->references++;
|
|
|
|
async->im = im;
|
2013-10-29 03:06:33 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cache2_image_cached(&async->im->cache_entry))
|
|
|
|
evas_cache2_image_ref(&async->im->cache_entry);
|
|
|
|
else
|
|
|
|
#endif
|
2013-06-23 19:41:32 -07:00
|
|
|
evas_cache_image_ref(&async->im->cache_entry);
|
|
|
|
async->unpack_row_length = tex->gc->shared->info.unpack_row_length;
|
|
|
|
|
|
|
|
if (evas_gl_preload_push(async))
|
|
|
|
return ;
|
|
|
|
|
|
|
|
// Failed to start asynchronous upload, likely due to preload not being supported by the backend
|
|
|
|
async->tex->references--;
|
2013-10-29 03:06:33 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cache2_image_cached(&async->im->cache_entry))
|
|
|
|
evas_cache2_image_close(&async->im->cache_entry);
|
|
|
|
else
|
|
|
|
#endif
|
2013-06-23 19:41:32 -07:00
|
|
|
evas_cache_image_drop(&async->im->cache_entry);
|
|
|
|
free(async);
|
|
|
|
|
|
|
|
upload:
|
|
|
|
pt_unref(tex->ptt);
|
|
|
|
tex->ptt = NULL;
|
|
|
|
}
|
|
|
|
|
2014-03-20 19:54:27 -07:00
|
|
|
evas_gl_common_texture_upload(tex, im, bytes_count);
|
2003-09-07 04:24:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-06-13 23:51:18 -07:00
|
|
|
evas_gl_common_texture_free(Evas_GL_Texture *tex, Eina_Bool force EINA_UNUSED)
|
2003-09-07 04:24:48 -07:00
|
|
|
{
|
2009-10-09 05:10:27 -07:00
|
|
|
if (!tex) return;
|
2013-06-23 19:41:32 -07:00
|
|
|
if (force)
|
|
|
|
{
|
|
|
|
evas_gl_preload_pop(tex);
|
|
|
|
|
|
|
|
while (tex->targets)
|
|
|
|
evas_gl_preload_target_unregister(tex, eina_list_data_get(tex->targets));
|
|
|
|
}
|
2009-10-09 05:10:27 -07:00
|
|
|
tex->references--;
|
2010-01-29 02:53:53 -08:00
|
|
|
if (tex->references != 0) return;
|
2012-08-14 01:31:59 -07:00
|
|
|
if (tex->fglyph)
|
|
|
|
{
|
|
|
|
tex->gc->font_glyph_textures = eina_list_remove(tex->gc->font_glyph_textures, tex);
|
|
|
|
tex->fglyph->ext_dat = NULL;
|
|
|
|
tex->fglyph->ext_dat_free = NULL;
|
|
|
|
}
|
2013-06-12 03:37:44 -07:00
|
|
|
|
|
|
|
if (tex->pt)
|
2010-01-29 02:53:53 -08:00
|
|
|
{
|
2013-06-12 03:37:44 -07:00
|
|
|
tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex->apt);
|
|
|
|
free(tex->apt);
|
|
|
|
tex->apt = NULL;
|
|
|
|
pt_unref(tex->pt);
|
2011-09-06 00:56:47 -07:00
|
|
|
}
|
2013-06-12 03:37:44 -07:00
|
|
|
if (tex->ptt)
|
2011-09-06 00:56:47 -07:00
|
|
|
{
|
2013-06-20 01:30:21 -07:00
|
|
|
tex->ptt->allocations = eina_list_remove(tex->ptt->allocations, tex->aptt);
|
2013-06-12 03:37:44 -07:00
|
|
|
free(tex->aptt);
|
|
|
|
tex->aptt = NULL;
|
|
|
|
pt_unref(tex->ptt);
|
2010-01-29 02:53:53 -08:00
|
|
|
}
|
2013-06-12 03:37:44 -07:00
|
|
|
if (tex->ptu)
|
|
|
|
pt_unref(tex->ptu);
|
|
|
|
if (tex->ptv)
|
|
|
|
pt_unref(tex->ptv);
|
|
|
|
if (tex->ptuv)
|
|
|
|
pt_unref(tex->ptuv);
|
2013-06-03 22:13:20 -07:00
|
|
|
|
|
|
|
evas_gl_common_texture_light_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
|
|
|
int u = 0, v = 0;
|
|
|
|
|
2013-06-03 22:13:20 -07:00
|
|
|
tex = evas_gl_common_texture_alloc(gc, w, h, EINA_FALSE);
|
2006-12-17 07:48:52 -08:00
|
|
|
if (!tex) return NULL;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2010-08-25 21:37:43 -07:00
|
|
|
tex->pt = _pool_tex_find(gc, w + 3, fh, alpha_ifmt, alpha_fmt, &u, &v,
|
2013-06-12 03:37:44 -07:00
|
|
|
&tex->apt,
|
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
|
|
|
{
|
2013-06-03 22:13:20 -07:00
|
|
|
evas_gl_common_texture_light_free(tex);
|
2009-10-09 05:10:27 -07:00
|
|
|
return NULL;
|
2006-12-19 06:12:40 -08:00
|
|
|
}
|
2013-06-20 01:30:21 -07:00
|
|
|
tex->apt->tex = tex;
|
2009-10-09 05:10:27 -07:00
|
|
|
tex->x = u + 1;
|
|
|
|
tex->y = v;
|
|
|
|
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,
|
2012-11-04 03:51:42 -08:00
|
|
|
unsigned int w, unsigned int h, int fh EINA_UNUSED)
|
2006-12-17 07:48:52 -08:00
|
|
|
{
|
2010-01-29 02:53:53 -08:00
|
|
|
if (!tex->pt) return;
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2013-03-14 21:05:39 -07:00
|
|
|
if (tex->gc->shared->info.unpack_row_length)
|
|
|
|
{
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
2011-12-17 21:03:24 -08:00
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
2010-02-16 20:21:59 -08:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, tex->x, tex->y, w, h, tex->pt->format,
|
|
|
|
tex->pt->dataformat, 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
|
|
|
{
|
2011-12-17 21:03:24 -08: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;
|
|
|
|
|
2013-06-03 22:13:20 -07:00
|
|
|
tex = evas_gl_common_texture_alloc(gc, w, h, EINA_FALSE);
|
2009-10-10 06:24:15 -07:00
|
|
|
if (!tex) return NULL;
|
2011-06-17 00:47:28 -07:00
|
|
|
|
2011-11-13 14:21:58 -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)
|
|
|
|
{
|
2013-06-03 22:13:20 -07:00
|
|
|
evas_gl_common_texture_light_free(tex);
|
2010-01-29 02:53:53 -08:00
|
|
|
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;
|
2011-11-13 14:21:58 -08:00
|
|
|
tex->ptv = _pool_tex_new(gc, tex->ptu->w, tex->ptu->h, 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->ptu);
|
2013-06-03 22:13:20 -07:00
|
|
|
evas_gl_common_texture_light_free(tex);
|
2010-01-29 02:53:53 -08:00
|
|
|
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;
|
2011-11-13 14:21:58 -08:00
|
|
|
tex->pt = _pool_tex_new(gc, tex->ptu->w * 2, tex->ptu->h * 2, lum_ifmt, lum_fmt);
|
|
|
|
if (!tex->pt)
|
|
|
|
{
|
2013-07-14 18:59:29 -07:00
|
|
|
pt_unref(tex->ptu);
|
|
|
|
pt_unref(tex->ptv);
|
2013-06-03 22:13:20 -07:00
|
|
|
evas_gl_common_texture_light_free(tex);
|
2011-11-13 14:21:58 -08:00
|
|
|
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;
|
2009-10-10 06:24:15 -07:00
|
|
|
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
|
2013-03-14 21:05:39 -07:00
|
|
|
if (tex->gc->shared->info.unpack_row_length)
|
2009-10-11 20:31:24 -07:00
|
|
|
{
|
2013-03-14 21:05:39 -07:00
|
|
|
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__, "");
|
2013-07-10 20:39:44 -07:00
|
|
|
if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat))
|
|
|
|
return;
|
|
|
|
_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
|
2013-03-14 21:05:39 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->ptu->texture);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + 1] - rows[h]);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2013-07-10 20:39:44 -07:00
|
|
|
if (!_tex_2d(tex->gc, tex->ptu->intformat, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat))
|
|
|
|
return;
|
|
|
|
_tex_sub_2d(tex->gc, 0, 0, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat, rows[h]);
|
2013-03-14 21:05:39 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->ptv->texture);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + (h / 2) + 1] - rows[h + (h / 2)]);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2013-07-10 20:39:44 -07:00
|
|
|
if (!_tex_2d(tex->gc, tex->ptv->intformat, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat))
|
|
|
|
return;
|
|
|
|
_tex_sub_2d(tex->gc, 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
|
|
|
|
{
|
2013-03-14 21:05:39 -07:00
|
|
|
unsigned int y;
|
|
|
|
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2013-07-10 20:39:44 -07:00
|
|
|
if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat))
|
|
|
|
return;
|
2013-03-14 21:05:39 -07:00
|
|
|
if ((rows[1] - rows[0]) == (int)w)
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
|
2013-03-14 21:05:39 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
for (y = 0; y < h; y++)
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, 0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
|
2013-03-14 21:05:39 -07:00
|
|
|
}
|
2014-06-18 00:23:23 -07:00
|
|
|
|
2013-03-14 21:05:39 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->ptu->texture);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2013-07-10 20:39:44 -07:00
|
|
|
if (!_tex_2d(tex->gc, tex->ptu->intformat, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat))
|
|
|
|
return;
|
2013-03-14 21:05:39 -07:00
|
|
|
if ((rows[h + 1] - rows[h]) == (int)(w / 2))
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, 0, 0, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat, rows[h]);
|
2013-03-14 21:05:39 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
for (y = 0; y < (h / 2); y++)
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, 0, y, w / 2, 1, tex->ptu->format, tex->ptu->dataformat, rows[h + y]);
|
2013-03-14 21:05:39 -07:00
|
|
|
}
|
2014-06-18 00:23:23 -07:00
|
|
|
|
2013-03-14 21:05:39 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->ptv->texture);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2013-07-10 20:39:44 -07:00
|
|
|
if (!_tex_2d(tex->gc, tex->ptv->intformat, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat))
|
|
|
|
return;
|
2013-03-14 21:05:39 -07:00
|
|
|
if ((rows[h + (h / 2) + 1] - rows[h + (h / 2)]) == (int)(w / 2))
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, 0, 0, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2)]);
|
2013-03-14 21:05:39 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
for (y = 0; y < (h / 2); y++)
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, 0, y, w / 2, 1, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2) + y]);
|
2013-03-14 21:05:39 -07:00
|
|
|
}
|
2009-10-11 20:31:24 -07:00
|
|
|
}
|
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
|
|
|
{
|
2011-12-17 21:03:24 -08: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
|
|
|
|
2011-08-29 13:56:48 -07:00
|
|
|
static Evas_GL_Texture *
|
|
|
|
_evas_gl_common_texture_y2uv_new(Evas_Engine_GL_Context *gc,
|
2014-06-18 00:23:23 -07:00
|
|
|
unsigned int yw, unsigned int yh,
|
2011-11-13 14:21:58 -08:00
|
|
|
Eina_Bool uv2w, Eina_Bool uv2h,
|
2011-09-04 14:15:04 -07:00
|
|
|
GLenum y_ifmt, GLenum y_fmt,
|
2011-09-30 08:51:32 -07:00
|
|
|
GLenum uv_ifmt, GLenum uv_fmt,
|
2014-06-18 00:23:23 -07:00
|
|
|
Eina_Bool dynamic)
|
2011-08-23 08:13:40 -07:00
|
|
|
{
|
2011-09-06 00:56:47 -07:00
|
|
|
Evas_GL_Texture_Pool *pt[2] = { NULL, NULL };
|
|
|
|
Evas_GL_Texture_Pool *ptuv[2] = { NULL, NULL };
|
2011-08-23 08:13:40 -07:00
|
|
|
Evas_GL_Texture *tex;
|
2011-11-13 14:21:58 -08:00
|
|
|
unsigned int uvw, uvh;
|
|
|
|
|
|
|
|
uvw = uv2w ? yw / 2 + 1 : yw + 1;
|
|
|
|
uvh = uv2h ? yh / 2 + 1 : yh + 1;
|
2011-08-23 08:13:40 -07:00
|
|
|
|
2011-09-30 08:51:32 -07:00
|
|
|
if (!dynamic)
|
|
|
|
{
|
2011-11-13 14:21:58 -08:00
|
|
|
ptuv[0] = _pool_tex_new(gc, uvw, uvh, uv_ifmt, uv_fmt);
|
|
|
|
ptuv[1] = _pool_tex_new(gc, uvw, uvh, uv_ifmt, uv_fmt);
|
|
|
|
|
2014-06-18 00:23:23 -07:00
|
|
|
if (ptuv[0] && ptuv[1])
|
|
|
|
{
|
2011-11-13 14:21:58 -08:00
|
|
|
pt[0] = _pool_tex_new(gc,
|
|
|
|
ptuv[0]->w * (uv2w ? 2 : 1),
|
|
|
|
ptuv[0]->h * (uv2h ? 2 : 1),
|
|
|
|
y_ifmt, y_fmt);
|
|
|
|
pt[1] = _pool_tex_new(gc,
|
|
|
|
ptuv[1]->w * (uv2w ? 2 : 1),
|
|
|
|
ptuv[1]->h * (uv2h ? 2 : 1),
|
|
|
|
y_ifmt, y_fmt);
|
2014-06-18 00:23:23 -07:00
|
|
|
}
|
2011-09-30 08:51:32 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-11-13 14:21:58 -08:00
|
|
|
ptuv[0] = _pool_tex_dynamic_new(gc, uvw, uvh, uv_ifmt, uv_fmt);
|
|
|
|
ptuv[1] = _pool_tex_dynamic_new(gc, uvw, uvh, uv_ifmt, uv_fmt);
|
|
|
|
|
2014-06-18 00:23:23 -07:00
|
|
|
if (ptuv[0] && ptuv[1])
|
|
|
|
{
|
2011-11-13 14:21:58 -08:00
|
|
|
pt[0] = _pool_tex_dynamic_new(gc,
|
|
|
|
ptuv[0]->w * (uv2w ? 2 : 1),
|
|
|
|
ptuv[0]->h * (uv2h ? 2 : 1),
|
|
|
|
y_ifmt, y_fmt);
|
|
|
|
pt[1] = _pool_tex_dynamic_new(gc,
|
|
|
|
ptuv[1]->w * (uv2w ? 2 : 1),
|
|
|
|
ptuv[1]->h * (uv2h ? 2 : 1),
|
|
|
|
y_ifmt, y_fmt);
|
2014-06-18 00:23:23 -07:00
|
|
|
}
|
2011-09-30 08:51:32 -07:00
|
|
|
}
|
2011-09-06 00:56:47 -07:00
|
|
|
|
|
|
|
if (!pt[0] || !pt[1] || !ptuv[0] || !ptuv[1])
|
|
|
|
goto on_error;
|
|
|
|
|
2011-11-13 14:21:58 -08:00
|
|
|
INF("YUV [%i, %i] => Y[%i, %i], UV[%i, %i]",
|
|
|
|
yw, yh,
|
|
|
|
pt[0]->w, pt[0]->h,
|
|
|
|
ptuv[0]->w, ptuv[0]->h);
|
2013-06-03 22:13:20 -07:00
|
|
|
tex = evas_gl_common_texture_alloc(gc, yw, yh, EINA_FALSE);
|
2011-09-06 00:56:47 -07:00
|
|
|
if (!tex)
|
|
|
|
goto on_error;
|
2011-08-23 08:13:40 -07:00
|
|
|
|
2011-09-06 00:56:47 -07:00
|
|
|
tex->pt = pt[0];
|
|
|
|
tex->ptuv = ptuv[0];
|
2011-09-30 08:51:32 -07:00
|
|
|
tex->dyn = dynamic;
|
2011-09-06 00:56:47 -07:00
|
|
|
|
2013-06-12 03:37:44 -07:00
|
|
|
pt_link(gc, pt[0]);
|
|
|
|
pt_link(gc, pt[1]);
|
|
|
|
pt_link(gc, ptuv[0]);
|
|
|
|
pt_link(gc, ptuv[1]);
|
2011-09-06 00:56:47 -07:00
|
|
|
|
|
|
|
tex->double_buffer.source = 0;
|
|
|
|
memcpy(tex->double_buffer.pt, pt, sizeof (Evas_GL_Texture_Pool *) * 2);
|
|
|
|
memcpy(tex->double_buffer.ptuv, ptuv, sizeof (Evas_GL_Texture_Pool *) * 2);
|
|
|
|
|
2011-08-29 13:56:48 -07:00
|
|
|
return tex;
|
2011-09-06 00:56:47 -07:00
|
|
|
|
|
|
|
on_error:
|
|
|
|
pt_unref(pt[0]);
|
|
|
|
pt_unref(pt[1]);
|
|
|
|
pt_unref(ptuv[0]);
|
|
|
|
pt_unref(ptuv[1]);
|
|
|
|
return NULL;
|
2011-08-29 13:56:48 -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;
|
|
|
|
|
2011-11-13 14:21:58 -08:00
|
|
|
tex = _evas_gl_common_texture_y2uv_new(gc, w, h, EINA_TRUE, EINA_FALSE, lum_alpha_ifmt, lum_alpha_fmt, rgba8_ifmt, rgba8_fmt, 0);
|
2011-08-23 08:13:40 -07:00
|
|
|
evas_gl_common_texture_yuy2_update(tex, rows, w, h);
|
|
|
|
return tex;
|
|
|
|
}
|
|
|
|
|
2011-08-29 13:56:48 -07:00
|
|
|
Evas_GL_Texture *
|
|
|
|
evas_gl_common_texture_nv12_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h)
|
|
|
|
{
|
|
|
|
Evas_GL_Texture *tex;
|
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2011-11-13 14:21:58 -08:00
|
|
|
tex = _evas_gl_common_texture_y2uv_new(gc, w, h, EINA_TRUE, EINA_TRUE, lum_ifmt, lum_fmt, lum_alpha_ifmt, lum_alpha_fmt, 1);
|
2011-09-30 08:51:32 -07:00
|
|
|
if (!tex)
|
|
|
|
#endif
|
2011-11-13 14:21:58 -08:00
|
|
|
tex = _evas_gl_common_texture_y2uv_new(gc, w, h, EINA_TRUE, EINA_TRUE, lum_ifmt, lum_fmt, lum_alpha_ifmt, lum_alpha_fmt, 0);
|
2011-09-30 08:51:32 -07:00
|
|
|
|
2011-08-29 13:56:48 -07:00
|
|
|
evas_gl_common_texture_nv12_update(tex, rows, w, h);
|
|
|
|
return tex;
|
|
|
|
}
|
|
|
|
|
|
|
|
Evas_GL_Texture *
|
|
|
|
evas_gl_common_texture_nv12tiled_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h)
|
|
|
|
{
|
2011-09-30 08:51:32 -07:00
|
|
|
Evas_GL_Texture *tex = NULL;
|
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2011-11-13 14:21:58 -08:00
|
|
|
tex = _evas_gl_common_texture_y2uv_new(gc, w, h, EINA_TRUE, EINA_TRUE, lum_ifmt, lum_fmt, lum_alpha_ifmt, lum_alpha_fmt, 1);
|
2011-09-30 08:51:32 -07:00
|
|
|
if (!tex)
|
|
|
|
#endif
|
2011-11-13 14:21:58 -08:00
|
|
|
tex = _evas_gl_common_texture_y2uv_new(gc, w, h, EINA_TRUE, EINA_TRUE, lum_ifmt, lum_fmt, lum_alpha_ifmt, lum_alpha_fmt, 0);
|
2011-08-29 13:56:48 -07:00
|
|
|
|
|
|
|
evas_gl_common_texture_nv12tiled_update(tex, rows, w, h);
|
|
|
|
return tex;
|
|
|
|
}
|
|
|
|
|
2011-08-23 08:13:40 -07:00
|
|
|
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
|
2011-08-29 13:56:48 -07:00
|
|
|
unsigned int y;
|
|
|
|
|
2011-09-06 00:56:47 -07:00
|
|
|
tex->double_buffer.source = 1 - tex->double_buffer.source;
|
|
|
|
tex->pt = tex->double_buffer.pt[tex->double_buffer.source];
|
|
|
|
tex->ptuv = tex->double_buffer.ptuv[tex->double_buffer.source];
|
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
2011-08-29 13:56:48 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
2011-08-29 13:56:48 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2013-07-10 20:39:44 -07:00
|
|
|
if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat))
|
|
|
|
return;
|
2011-08-29 13:56:48 -07:00
|
|
|
if ((rows[1] - rows[0]) == (int)w * 4)
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
|
2011-08-29 13:56:48 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
for (y = 0; y < h; y++)
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, 0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
|
2011-08-29 13:56:48 -07:00
|
|
|
}
|
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
|
2011-08-29 13:56:48 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2013-07-10 20:39:44 -07:00
|
|
|
if (!_tex_2d(tex->gc, tex->ptuv->intformat, w / 2, h, tex->ptuv->format, tex->ptuv->dataformat))
|
|
|
|
return;
|
2011-11-13 14:21:58 -08:00
|
|
|
#if 0
|
|
|
|
/*
|
|
|
|
FIXME: this piece of code doesn't work anymore since texture width
|
|
|
|
is not anymore exactly w / 2. I don't understand why.
|
|
|
|
*/
|
2011-08-29 13:56:48 -07:00
|
|
|
if ((rows[1] - rows[0]) == (int)(w * 2))
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, 0, 0, w / 2, h, tex->ptuv->format, tex->ptuv->dataformat, rows[0]);
|
2011-08-29 13:56:48 -07:00
|
|
|
else
|
2011-11-13 14:21:58 -08:00
|
|
|
#endif
|
2011-08-29 13:56:48 -07:00
|
|
|
{
|
|
|
|
for (y = 0; y < h; y++)
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, 0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[y]);
|
2011-08-29 13:56:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
|
|
|
|
{
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
|
2011-08-29 13:56:48 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_gl_common_texture_nv12_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
|
|
|
|
{
|
|
|
|
if (!tex->pt) return;
|
2011-09-06 00:56:47 -07:00
|
|
|
|
|
|
|
tex->double_buffer.source = 1 - tex->double_buffer.source;
|
|
|
|
tex->pt = tex->double_buffer.pt[tex->double_buffer.source];
|
|
|
|
tex->ptuv = tex->double_buffer.ptuv[tex->double_buffer.source];
|
|
|
|
|
2011-08-29 13:56:48 -07:00
|
|
|
// FIXME: works on lowest size 4 pixel high buffers. must also be multiple of 2
|
2013-03-14 21:05:39 -07:00
|
|
|
if (tex->gc->shared->info.unpack_row_length)
|
2011-08-23 08:13:40 -07:00
|
|
|
{
|
2013-03-14 21:05:39 -07:00
|
|
|
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__, "");
|
2013-07-10 20:39:44 -07:00
|
|
|
if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat))
|
|
|
|
return;
|
|
|
|
_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
|
2013-03-14 21:05:39 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + 1] - rows[h]);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2013-07-10 20:39:44 -07:00
|
|
|
if (!_tex_2d(tex->gc, tex->ptuv->intformat, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat))
|
|
|
|
return;
|
|
|
|
_tex_sub_2d(tex->gc, 0, 0, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat, rows[h]);
|
2011-08-23 08:13:40 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-03-14 21:05:39 -07:00
|
|
|
unsigned int y;
|
2014-06-18 00:23:23 -07:00
|
|
|
|
2013-03-14 21:05:39 -07:00
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2013-07-10 20:39:44 -07:00
|
|
|
if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat))
|
|
|
|
return;
|
2013-03-14 21:05:39 -07:00
|
|
|
if ((rows[1] - rows[0]) == (int)w)
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
|
2013-03-14 21:05:39 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
for (y = 0; y < h; y++)
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, 0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
|
2013-03-14 21:05:39 -07:00
|
|
|
}
|
2014-06-18 00:23:23 -07:00
|
|
|
|
2013-03-14 21:05:39 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
|
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
2013-07-10 20:39:44 -07:00
|
|
|
if (!_tex_2d(tex->gc, tex->ptuv->intformat, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat))
|
|
|
|
return;
|
2013-03-14 21:05:39 -07:00
|
|
|
if ((rows[h + 1] - rows[h]) == (int)(w / 2))
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, 0, 0, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat, rows[h]);
|
2013-03-14 21:05:39 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
for (y = 0; y < (h / 2); y++)
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, 0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[h + y]);
|
2013-03-14 21:05:39 -07:00
|
|
|
}
|
2011-08-23 08:13:40 -07:00
|
|
|
}
|
|
|
|
if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
|
|
|
|
{
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
|
2011-08-23 08:13:40 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
}
|
|
|
|
}
|
2011-08-29 13:56:48 -07:00
|
|
|
|
|
|
|
void
|
|
|
|
evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
|
|
|
|
{
|
2011-09-04 14:15:04 -07:00
|
|
|
unsigned int mb_x, mb_y, mb_w, mb_h;
|
|
|
|
unsigned int base_h;
|
|
|
|
|
2011-08-29 13:56:48 -07:00
|
|
|
if (!tex->pt) return;
|
2011-09-04 14:15:04 -07:00
|
|
|
|
2011-09-06 00:56:47 -07:00
|
|
|
tex->double_buffer.source = 1 - tex->double_buffer.source;
|
|
|
|
tex->pt = tex->double_buffer.pt[tex->double_buffer.source];
|
|
|
|
tex->ptuv = tex->double_buffer.ptuv[tex->double_buffer.source];
|
|
|
|
|
2011-09-30 08:51:32 -07:00
|
|
|
mb_w = w / 64 + (w % 64 ? 1 : 0);
|
|
|
|
mb_h = h / 32 + (h % 32 ? 1 : 0);
|
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2011-09-30 08:51:32 -07:00
|
|
|
if (tex->dyn)
|
|
|
|
{
|
|
|
|
char *texture_addr;
|
2014-06-18 00:23:23 -07:00
|
|
|
char *tmp;
|
2011-09-30 08:51:32 -07:00
|
|
|
|
2013-04-12 01:34:13 -07:00
|
|
|
texture_addr = secsym_eglMapImageSEC(tex->gc->egldisp,
|
|
|
|
tex->pt->dyn.img,
|
|
|
|
EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC,
|
|
|
|
EGL_MAP_GL_TEXTURE_OPTION_WRITE_SEC);
|
2011-09-30 08:51:32 -07:00
|
|
|
|
2014-06-18 00:23:23 -07:00
|
|
|
/* Iterate each Y macroblock like we do in evas_convert_yuv.c */
|
|
|
|
for (mb_y = 0; mb_y < (mb_h >> 1); mb_y++)
|
|
|
|
{
|
|
|
|
int step = 2;
|
|
|
|
int offset = 0;
|
|
|
|
int x = 0;
|
|
|
|
int rmb_x = 0;
|
|
|
|
int ry[2];
|
|
|
|
|
|
|
|
ry[0] = mb_y * 2 * 32 * tex->pt->dyn.stride;
|
|
|
|
ry[1] = ry[0] + 32 * tex->pt->dyn.stride;
|
|
|
|
|
|
|
|
for (mb_x = 0; mb_x < mb_w * 2; mb_x++, rmb_x += 64 * 32)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
tmp = texture_addr + x + ry[offset];
|
|
|
|
|
|
|
|
for (i = 0; i < 32 * 64; i += 64, tmp += tex->pt->dyn.stride)
|
|
|
|
memcpy(tmp, rows[mb_y] + rmb_x + i, 64);
|
|
|
|
|
|
|
|
step++;
|
|
|
|
if ((step & 0x3) == 0)
|
|
|
|
{
|
|
|
|
offset = 1 - offset;
|
|
|
|
x -= 64;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
x += 64;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mb_h & 0x1)
|
|
|
|
{
|
|
|
|
int rmb_x = 0;
|
|
|
|
int x = 0;
|
|
|
|
int ry;
|
|
|
|
|
|
|
|
ry = mb_y * 2 * 32 * tex->pt->dyn.stride;
|
|
|
|
|
|
|
|
for (mb_x = 0; mb_x < mb_w; mb_x++, x += 64, rmb_x += 64 * 32)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
tmp = texture_addr + x + ry;
|
|
|
|
|
|
|
|
for (i = 0; i < 32 * 64; i += 64, tmp += tex->pt->dyn.stride)
|
|
|
|
memcpy(tmp, rows[mb_y] + rmb_x + i, 64);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
secsym_eglUnmapImageSEC(tex->gc->egldisp, tex->pt->dyn.img, EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC);
|
2011-09-30 08:51:32 -07:00
|
|
|
|
2013-04-12 01:34:13 -07:00
|
|
|
texture_addr = secsym_eglMapImageSEC(tex->gc->egldisp,
|
|
|
|
tex->ptuv->dyn.img,
|
|
|
|
EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC,
|
|
|
|
EGL_MAP_GL_TEXTURE_OPTION_WRITE_SEC);
|
2011-09-30 08:51:32 -07:00
|
|
|
|
2014-06-18 00:23:23 -07:00
|
|
|
/* Iterate each UV macroblock like we do in evas_convert_yuv.c */
|
|
|
|
base_h = (mb_h >> 1) + (mb_h & 0x1);
|
2011-09-30 08:51:32 -07:00
|
|
|
|
|
|
|
/* h is always a multiple of 32 */
|
|
|
|
mb_h = h / 2;
|
|
|
|
mb_h = (mb_h / 32 + (mb_h % 32 ? 1 : 0));
|
|
|
|
|
|
|
|
mb_w = w / 2;
|
2012-10-11 01:27:46 -07:00
|
|
|
mb_w = (mb_w / 64 + (mb_w % 64 ? 1 : 0));
|
2011-09-30 08:51:32 -07:00
|
|
|
|
2014-06-18 00:23:23 -07:00
|
|
|
for (mb_y = 0; mb_y < (mb_h >> 1); mb_y++)
|
|
|
|
{
|
|
|
|
int step = 2;
|
|
|
|
int offset = 0;
|
|
|
|
int x = 0;
|
|
|
|
int rmb_x = 0;
|
|
|
|
int ry[2];
|
2011-09-30 08:51:32 -07:00
|
|
|
|
2014-06-18 00:23:23 -07:00
|
|
|
ry[0] = mb_y * 2 * 32 * tex->ptuv->dyn.stride;
|
|
|
|
ry[1] = ry[0] + 32 * tex->ptuv->dyn.stride;
|
2011-09-30 08:51:32 -07:00
|
|
|
|
2014-06-18 00:23:23 -07:00
|
|
|
for (mb_x = 0; mb_x < mb_w * 4; mb_x++, rmb_x += 64 * 32)
|
|
|
|
{
|
|
|
|
unsigned int i = 0;
|
2011-09-30 08:51:32 -07:00
|
|
|
|
2014-06-18 00:23:23 -07:00
|
|
|
tmp = texture_addr + x + ry[offset];
|
2011-09-30 08:51:32 -07:00
|
|
|
|
|
|
|
for (i = 0; i < 32 * 64; i += 64, tmp += tex->ptuv->dyn.stride)
|
|
|
|
memcpy(tmp, rows[mb_y + base_h] + rmb_x + i, 64);
|
|
|
|
|
2014-06-18 00:23:23 -07:00
|
|
|
step++;
|
|
|
|
if ((step & 0x3) == 0)
|
|
|
|
{
|
|
|
|
offset = 1 - offset;
|
|
|
|
x -= 64;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
x += 64;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mb_h & 0x1)
|
|
|
|
{
|
|
|
|
int rmb_x = 0;
|
|
|
|
int x = 0;
|
|
|
|
int ry;
|
|
|
|
|
|
|
|
ry = mb_y * 2 * 32 * tex->ptuv->dyn.stride;
|
|
|
|
|
|
|
|
for (mb_x = 0; mb_x < mb_w * 2; mb_x++, x += 64, rmb_x += 64 * 32)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
tmp = texture_addr + x + ry;
|
|
|
|
|
|
|
|
/* It has horizontaly half the pixels, but they are double the size*/
|
|
|
|
for (i = 0; i < 32 * 64; i += 64, tmp += tex->ptuv->dyn.stride)
|
|
|
|
memcpy(tmp, rows[mb_y + base_h] + rmb_x + i, 64);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
secsym_eglUnmapImageSEC(tex->gc->egldisp, tex->ptuv->dyn.img, EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC);
|
|
|
|
return;
|
2011-09-30 08:51:32 -07:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
2011-09-04 14:15:04 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
2011-09-06 00:56:47 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
|
2011-09-05 07:58:18 -07:00
|
|
|
// We are telling the driver to not swizzle back the buffer as we are going to replace all pixel
|
2013-07-10 20:39:44 -07:00
|
|
|
if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat))
|
|
|
|
return;
|
2011-09-05 07:58:18 -07:00
|
|
|
|
2011-09-04 14:15:04 -07:00
|
|
|
/* Iterate each Y macroblock like we do in evas_convert_yuv.c */
|
|
|
|
for (mb_y = 0; mb_y < (mb_h >> 1); mb_y++)
|
|
|
|
{
|
|
|
|
int step = 2;
|
2014-06-18 00:23:23 -07:00
|
|
|
int offset = 0;
|
|
|
|
int x = 0;
|
|
|
|
int rmb_x = 0;
|
|
|
|
int ry[2];
|
|
|
|
|
|
|
|
ry[0] = mb_y * 2 * 32;
|
|
|
|
ry[1] = ry[0] + 32;
|
|
|
|
|
|
|
|
for (mb_x = 0; mb_x < mb_w * 2; mb_x++, rmb_x += 64 * 32)
|
|
|
|
{
|
|
|
|
_tex_sub_2d(tex->gc, x, ry[offset], 64, 32, tex->pt->format, tex->pt->dataformat, rows[mb_y] + rmb_x);
|
|
|
|
|
|
|
|
step++;
|
|
|
|
if ((step & 0x3) == 0)
|
|
|
|
{
|
|
|
|
offset = 1 - offset;
|
|
|
|
x -= 64;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
x += 64;
|
|
|
|
}
|
|
|
|
}
|
2011-09-04 14:15:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mb_h & 0x1)
|
|
|
|
{
|
|
|
|
int rmb_x = 0;
|
2014-06-18 00:23:23 -07:00
|
|
|
int x = 0;
|
|
|
|
int ry;
|
2011-09-04 14:15:04 -07:00
|
|
|
|
2014-06-18 00:23:23 -07:00
|
|
|
ry = mb_y * 2 * 32;
|
2011-09-04 14:15:04 -07:00
|
|
|
|
2014-06-18 00:23:23 -07:00
|
|
|
for (mb_x = 0; mb_x < mb_w; mb_x++, x += 64, rmb_x += 64 * 32)
|
|
|
|
_tex_sub_2d(tex->gc, x, ry, 64, 32, tex->pt->format, tex->pt->dataformat, rows[mb_y] + rmb_x);
|
2011-09-04 14:15:04 -07:00
|
|
|
}
|
|
|
|
|
2011-12-17 21:03:24 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
|
2011-09-04 14:15:04 -07:00
|
|
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
|
|
|
2013-07-10 20:39:44 -07:00
|
|
|
if (!_tex_2d(tex->gc, tex->ptuv->intformat, w, h, tex->ptuv->format, tex->ptuv->dataformat))
|
|
|
|
return;
|
2011-09-05 07:58:18 -07:00
|
|
|
|
2011-09-04 14:15:04 -07:00
|
|
|
/* Iterate each UV macroblock like we do in evas_convert_yuv.c */
|
|
|
|
base_h = (mb_h >> 1) + (mb_h & 0x1);
|
2011-09-30 08:51:32 -07:00
|
|
|
|
|
|
|
/* h is always a multiple of 32 */
|
|
|
|
mb_h = h / 2;
|
|
|
|
mb_h = (mb_h / 32 + (mb_h % 32 ? 1 : 0));
|
|
|
|
|
|
|
|
mb_w = w / 2;
|
|
|
|
mb_w = (mb_w / 32 + (mb_w % 32 ? 1 : 0));
|
|
|
|
|
|
|
|
for (mb_y = 0; mb_y < (mb_h >> 1); mb_y++)
|
2011-09-04 14:15:04 -07:00
|
|
|
{
|
|
|
|
int step = 2;
|
2014-06-18 00:23:23 -07:00
|
|
|
int offset = 0;
|
|
|
|
int x = 0;
|
|
|
|
int rmb_x = 0;
|
|
|
|
int ry[2];
|
2011-09-04 14:15:04 -07:00
|
|
|
|
2014-06-18 00:23:23 -07:00
|
|
|
ry[0] = mb_y * 2 * 32;
|
|
|
|
ry[1] = ry[0] + 32;
|
2011-09-04 14:15:04 -07:00
|
|
|
|
2014-06-18 00:23:23 -07:00
|
|
|
for (mb_x = 0; mb_x < mb_w * 2; mb_x++, rmb_x += 64 * 32)
|
|
|
|
{
|
2013-07-10 20:39:44 -07:00
|
|
|
_tex_sub_2d(tex->gc, x, ry[offset], 32, 32,
|
2011-09-04 14:15:04 -07:00
|
|
|
tex->ptuv->format, tex->ptuv->dataformat,
|
|
|
|
rows[mb_y + base_h] + rmb_x);
|
|
|
|
step++;
|
|
|
|
if ((step & 0x3) == 0)
|
|
|
|
{
|
|
|
|
offset = 1 - offset;
|
|
|
|
x -= 32;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
x += 32;
|
|
|
|
}
|
2014-06-18 00:23:23 -07:00
|
|
|
}
|
2011-09-04 14:15:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mb_h & 0x1)
|
|
|
|
{
|
|
|
|
int rmb_x = 0;
|
2014-06-18 00:23:23 -07:00
|
|
|
int x = 0;
|
|
|
|
int ry;
|
2011-09-04 14:15:04 -07:00
|
|
|
|
2014-06-18 00:23:23 -07:00
|
|
|
ry = mb_y * 2 * 32;
|
2011-09-04 14:15:04 -07:00
|
|
|
|
2014-06-18 00:23:23 -07:00
|
|
|
for (mb_x = 0; mb_x < mb_w; mb_x++, x += 32, rmb_x += 64 * 32)
|
|
|
|
_tex_sub_2d(tex->gc, x, ry, 64, 32, tex->ptuv->format, tex->ptuv->dataformat, rows[mb_y + base_h] + rmb_x);
|
2011-09-04 14:15:04 -07:00
|
|
|
}
|
2011-08-29 13:56:48 -07:00
|
|
|
}
|