Evas gl: Add support for ETC1+Alpha textures

Compile-in the required shaders, add support for the
new EVAS_COLORSPACE_ETC1_ALPHA, and upload textures as RGB+A
pairs.

@feature
This commit is contained in:
Jean-Philippe Andre 2014-07-07 20:14:02 +09:00
parent 0bba7422cb
commit 48bcf182b4
7 changed files with 452 additions and 48 deletions

View File

@ -134,6 +134,7 @@ _evas_common_rgba_image_surface_size(unsigned int w, unsigned int h,
case EVAS_COLORSPACE_RGBA_S3TC_DXT3:
case EVAS_COLORSPACE_RGBA_S3TC_DXT4:
case EVAS_COLORSPACE_RGBA_S3TC_DXT5:
case EVAS_COLORSPACE_ETC1_ALPHA:
block_size = 16;
// fallthrough
case EVAS_COLORSPACE_ETC1:

View File

@ -332,6 +332,9 @@ typedef enum {
SHADER_YUY2_NOMUL,
SHADER_NV12,
SHADER_NV12_NOMUL,
SHADER_RGB_A_PAIR,
SHADER_RGB_A_PAIR_NOMUL,
/*
SHADER_FILTER_INVERT,
SHADER_FILTER_INVERT_NOMUL,
@ -413,6 +416,8 @@ struct _Evas_GL_Shared
#define MAX_ATLAS_H 512
#define DEF_ATLAS_H 512
#define ATLAS_FORMATS_COUNT 11
Eina_List *cspaces; // depend on the values of etc1, etc2 and st3c
struct {
@ -433,7 +438,7 @@ struct _Evas_GL_Shared
struct {
Eina_List *whole;
Eina_List *atlas[10];
Eina_List *atlas[ATLAS_FORMATS_COUNT];
} tex;
Eina_Hash *native_pm_hash;
@ -595,7 +600,11 @@ struct _Evas_GL_Texture
{
Evas_Engine_GL_Context *gc;
Evas_GL_Image *im;
Evas_GL_Texture_Pool *pt, *ptu, *ptv, *ptuv, *ptt;
Evas_GL_Texture_Pool *pt, *ptu, *ptv, *ptt;
union {
Evas_GL_Texture_Pool *ptuv;
Evas_GL_Texture_Pool *pta;
};
RGBA_Font_Glyph *fglyph;
int x, y, w, h;
int tx, ty;
@ -777,6 +786,12 @@ void evas_gl_common_context_nv12_push(Evas_Engine_GL_Context *gc,
int x, int y, int w, int h,
int r, int g, int b, int a,
Eina_Bool smooth);
void evas_gl_common_context_rgb_a_pair_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
int r, int g, int b, int a,
Eina_Bool smooth);
void evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
int npoints,
@ -821,6 +836,8 @@ Evas_GL_Texture *evas_gl_common_texture_nv12_new(Evas_Engine_GL_Context *gc, DA
void evas_gl_common_texture_nv12_update(Evas_GL_Texture *tex, DATA8 **row, unsigned int w, unsigned int h);
Evas_GL_Texture *evas_gl_common_texture_nv12tiled_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h);
void evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **row, unsigned int w, unsigned int h);
Evas_GL_Texture *evas_gl_common_texture_rgb_a_pair_new(Evas_Engine_GL_Context *gc, RGBA_Image *im);
void evas_gl_common_texture_rgb_a_pair_update(Evas_GL_Texture *tex, RGBA_Image *im);
void evas_gl_common_image_alloc_ensure(Evas_GL_Image *im);
void evas_gl_common_image_all_unload(Evas_Engine_GL_Context *gc);
@ -900,6 +917,7 @@ void pt_unref(Evas_GL_Texture_Pool *pt);
#else
# define GLERR(fn, fl, ln, op)
#endif
#define GLERRLOG() GLERR(__FUNCTION__, __FILE__, __LINE__, "")
Eina_Bool evas_gl_common_module_open(void);
void evas_gl_common_module_close(void);
@ -913,6 +931,15 @@ _tex_sub_2d(Evas_Engine_GL_Context *gc, int x, int y, int w, int h, int fmt, int
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
}
static inline void
_comp_tex_sub_2d(Evas_Engine_GL_Context *gc, int x, int y, int w, int h, int fmt, int imgsize, const void *pix)
{
if ((w > gc->shared->info.max_texture_size) ||
(h > gc->shared->info.max_texture_size)) return;
glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, fmt, imgsize, pix);
GLERR(__FUNCTION__, __FILE__, __LINE__, "glCompressedTexSubImage2D");
}
#include "evas_gl_3d_common.h"
#endif

View File

@ -861,6 +861,11 @@ evas_gl_common_context_new(void)
SHADER_TEXTURE_ADD(shared, NV12_NOMUL, tex);
SHADER_TEXTURE_ADD(shared, NV12_NOMUL, texuv);
SHADER_TEXTURE_ADD(shared, RGB_A_PAIR, tex);
SHADER_TEXTURE_ADD(shared, RGB_A_PAIR, texm);
SHADER_TEXTURE_ADD(shared, RGB_A_PAIR_NOMUL, tex);
SHADER_TEXTURE_ADD(shared, RGB_A_PAIR_NOMUL, texm);
if (gc->state.current.cur_prog == PRG_INVALID)
glUseProgram(shared->shader[0].prog);
else glUseProgram(gc->state.current.cur_prog);
@ -2293,6 +2298,108 @@ evas_gl_common_context_nv12_push(Evas_Engine_GL_Context *gc,
}
}
void
evas_gl_common_context_rgb_a_pair_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy,
double sw, double sh,
int x, int y, int w, int h,
int r, int g, int b, int a,
Eina_Bool smooth)
{
/* This RGB+Alpha mode is used for ETC1+Alpha textures, where the shader
* will multiply RGB by alpha. Two textures are created: tex->{pt,pta}.
* Since the exact encoding doesn't matter here (decoding is transparent
* from the shader point of view), this method could be used for other
* colorspaces as well (eg. RGB565+Alpha4, ...).
*/
int pnum, nv, nc, nu, nm, i;
GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
GLuint prog;
int pn;
prog = gc->shared->shader[evas_gl_common_shader_choice
(0, NULL, r, g, b, a, SHADER_RGB_A_PAIR_NOMUL, SHADER_RGB_A_PAIR)].prog;
pn = _evas_gl_common_context_push(RTYPE_IMAGE,
gc, tex, NULL,
prog,
x, y, w, h,
EINA_TRUE,
smooth,
EINA_FALSE, 0, 0, 0, 0);
gc->pipe[pn].region.type = RTYPE_IMAGE;
gc->pipe[pn].shader.cur_tex = tex->pt->texture;
gc->pipe[pn].shader.cur_texm = tex->pta->texture;
gc->pipe[pn].shader.cur_prog = prog;
gc->pipe[pn].shader.smooth = smooth;
gc->pipe[pn].shader.blend = EINA_TRUE;
gc->pipe[pn].shader.render_op = gc->dc->render_op;
gc->pipe[pn].shader.clip = 0;
gc->pipe[pn].shader.cx = 0;
gc->pipe[pn].shader.cy = 0;
gc->pipe[pn].shader.cw = 0;
gc->pipe[pn].shader.ch = 0;
gc->pipe[pn].array.line = 0;
gc->pipe[pn].array.use_vertex = EINA_TRUE;
// if nomul... dont need this
gc->pipe[pn].array.use_color = EINA_TRUE;
gc->pipe[pn].array.use_texuv = EINA_TRUE;
gc->pipe[pn].array.use_texuv2 = 0;
gc->pipe[pn].array.use_texuv3 = 0;
gc->pipe[pn].array.use_texm = EINA_TRUE;
gc->pipe[pn].array.use_texsam = 0;
pipe_region_expand(gc, pn, x, y, w, h);
pnum = gc->pipe[pn].array.num;
nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nm = pnum * 2;
gc->pipe[pn].array.num += 6;
array_alloc(gc, pn);
tx1 = (sx) / (double)tex->pt->w;
ty1 = (sy) / (double)tex->pt->h;
tx2 = (sx + sw) / (double)tex->pt->w;
ty2 = (sy + sh) / (double)tex->pt->h;
t2x1 = sx / (double)tex->pta->w;
t2y1 = sy / (double)tex->pta->h;
t2x2 = (sx + sw) / (double)tex->pta->w;
t2y2 = (sy + sh) / (double)tex->pta->h;
PUSH_VERTEX(pn, x , y , 0);
PUSH_VERTEX(pn, x + w, y , 0);
PUSH_VERTEX(pn, x , y + h, 0);
PUSH_TEXUV(pn, tx1, ty1);
PUSH_TEXUV(pn, tx2, ty1);
PUSH_TEXUV(pn, tx1, ty2);
PUSH_TEXM(pn, t2x1, t2y1);
PUSH_TEXM(pn, t2x2, t2y1);
PUSH_TEXM(pn, t2x1, t2y2);
PUSH_VERTEX(pn, x + w, y , 0);
PUSH_VERTEX(pn, x + w, y + h, 0);
PUSH_VERTEX(pn, x , y + h, 0);
PUSH_TEXUV(pn, tx2, ty1);
PUSH_TEXUV(pn, tx2, ty2);
PUSH_TEXUV(pn, tx1, ty2);
PUSH_TEXM(pn, t2x2, t2y1);
PUSH_TEXM(pn, t2x2, t2y2);
PUSH_TEXM(pn, t2x1, t2y2);
for (i = 0; i < 6; i++)
{
PUSH_COLOR(pn, r, g, b, a);
}
}
void
evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,

View File

@ -132,9 +132,13 @@ _evas_gl_cspace_list_fill(Evas_Engine_GL_Context *gc)
CS_APPEND(EVAS_COLORSPACE_RGBA8_ETC2_EAC);
CS_APPEND(EVAS_COLORSPACE_RGB8_ETC2);
CS_APPEND(EVAS_COLORSPACE_ETC1);
CS_APPEND(EVAS_COLORSPACE_ETC1_ALPHA);
}
else if (gc->shared->info.etc1)
CS_APPEND(EVAS_COLORSPACE_ETC1);
{
CS_APPEND(EVAS_COLORSPACE_ETC1);
CS_APPEND(EVAS_COLORSPACE_ETC1_ALPHA);
}
if (gc->shared->info.s3tc)
{
CS_APPEND(EVAS_COLORSPACE_RGB_S3TC_DXT1);
@ -347,6 +351,7 @@ evas_gl_common_image_new_from_data(Evas_Engine_GL_Context *gc, unsigned int w, u
case EVAS_COLORSPACE_AGRY88:
break;
case EVAS_COLORSPACE_ETC1:
case EVAS_COLORSPACE_ETC1_ALPHA:
if (gc->shared->info.etc1 && !gc->shared->info.etc2) break;
ERR("We don't know what to do with ETC1 on this hardware. You need to add a software converter here.");
break;
@ -400,6 +405,7 @@ evas_gl_common_image_new_from_copied_data(Evas_Engine_GL_Context *gc, unsigned i
case EVAS_COLORSPACE_AGRY88:
break;
case EVAS_COLORSPACE_ETC1:
case EVAS_COLORSPACE_ETC1_ALPHA:
if (gc->shared->info.etc1 && !gc->shared->info.etc2) break;
ERR("We don't know what to do with ETC1 on this hardware. You need to add a software converter here.");
break;
@ -460,6 +466,7 @@ evas_gl_common_image_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned in
case EVAS_COLORSPACE_AGRY88:
break;
case EVAS_COLORSPACE_ETC1:
case EVAS_COLORSPACE_ETC1_ALPHA:
if (gc->shared->info.etc1 && !gc->shared->info.etc2) break;
ERR("We don't know what to do with ETC1 on this hardware. You need to add a software converter here.");
break;
@ -601,12 +608,19 @@ evas_gl_common_image_content_hint_set(Evas_GL_Image *im, int hint)
if (!im->gc->shared->info.sec_image_map) return;
if (!im->gc->shared->info.bgra) return;
// does not handle yuv yet.
if (im->cs.space != EVAS_COLORSPACE_ARGB8888 &&
im->cs.space != EVAS_COLORSPACE_GRY8 &&
im->cs.space != EVAS_COLORSPACE_AGRY88 &&
im->cs.space != EVAS_COLORSPACE_ETC1 &&
im->cs.space != EVAS_COLORSPACE_RGB8_ETC2 &&
im->cs.space != EVAS_COLORSPACE_RGBA8_ETC2_EAC) return;
// TODO: Check this list of cspaces
switch (im->cs.space)
{
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
case EVAS_COLORSPACE_RGB565_A5P:
case EVAS_COLORSPACE_YCBCR422601_PL:
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
case EVAS_COLORSPACE_ETC1_ALPHA:
return;
default: break;
}
if (im->content_hint == EVAS_IMAGE_CONTENT_HINT_DYNAMIC)
{
if (im->cs.data)
@ -831,6 +845,22 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
im->dirty = 0;
if (!im->tex) return;
break;
case EVAS_COLORSPACE_ETC1_ALPHA:
if ((im->tex) && (im->dirty))
{
evas_cache_image_load_data(&im->im->cache_entry);
evas_gl_common_texture_rgb_a_pair_update(im->tex, im->im);
evas_cache_image_unload_data(&im->im->cache_entry);
}
else if ((!im->tex))
{
evas_cache_image_load_data(&im->im->cache_entry);
im->tex = evas_gl_common_texture_rgb_a_pair_new(gc, im->im);
evas_cache_image_unload_data(&im->im->cache_entry);
}
im->dirty = 0;
if (!im->tex) return;
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
if ((im->tex) && (im->dirty))
@ -942,13 +972,14 @@ evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->cs.space);
}
void
evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
int dx, int dy, int dw, int dh,
int sx, int sy, int sw, int sh,
int cx, int cy, int cw, int ch,
int r, int g, int b, int a, int smooth,
int yuv, int yuy2, int nv12)
static void
_evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
int dx, int dy, int dw, int dh,
int sx, int sy, int sw, int sh,
int cx, int cy, int cw, int ch,
int r, int g, int b, int a, Eina_Bool smooth,
Eina_Bool yuv, Eina_Bool yuy2, Eina_Bool nv12,
Eina_Bool rgb_a_pair)
{
double ssx, ssy, ssw, ssh;
int nx, ny, nw, nh;
@ -981,6 +1012,13 @@ evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
dx, dy, dw, dh,
r, g, b, a,
smooth);
else if (rgb_a_pair)
evas_gl_common_context_rgb_a_pair_push(gc,
im->tex,
sx, sy, sw, sh,
dx, dy, dw, dh,
r, g, b, a,
smooth);
else
evas_gl_common_context_image_push(gc,
im->tex,
@ -1017,6 +1055,13 @@ evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
nx, ny, nw, nh,
r, g, b, a,
smooth);
else if (rgb_a_pair)
evas_gl_common_context_rgb_a_pair_push(gc,
im->tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
r, g, b, a,
smooth);
else
evas_gl_common_context_image_push(gc,
im->tex,
@ -1035,9 +1080,10 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
Cutout_Rect *rct;
int c, cx, cy, cw, ch;
int i;
int yuv = 0;
int yuy2 = 0;
int nv12 = 0;
Eina_Bool yuv = EINA_FALSE;
Eina_Bool yuy2 = EINA_FALSE;
Eina_Bool nv12 = EINA_FALSE;
Eina_Bool rgb_a_pair = EINA_FALSE;
if (sw < 1) sw = 1;
if (sh < 1) sh = 1;
@ -1061,14 +1107,24 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
return;
}
if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
(im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
yuv = 1;
if (im->cs.space == EVAS_COLORSPACE_YCBCR422601_PL)
yuy2 = 1;
if ((im->cs.space == EVAS_COLORSPACE_YCBCR420NV12601_PL) ||
(im->cs.space == EVAS_COLORSPACE_YCBCR420TM12601_PL))
nv12 = 1;
switch (im->cs.space)
{
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
yuv = EINA_TRUE;
break;
case EVAS_COLORSPACE_YCBCR422601_PL:
yuy2 = EINA_TRUE;
break;
case EVAS_COLORSPACE_YCBCR420NV12601_PL:
case EVAS_COLORSPACE_YCBCR420TM12601_PL:
nv12 = EINA_TRUE;
break;
case EVAS_COLORSPACE_ETC1_ALPHA:
rgb_a_pair = EINA_TRUE;
break;
default: break;
}
if ((sw == dw) && (sh == dh)) smooth = 0;
@ -1079,22 +1135,22 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
{
if (gc->dc->clip.use)
{
evas_gl_common_image_push(gc, im,
dx, dy, dw, dh,
sx, sy, sw, sh,
gc->dc->clip.x, gc->dc->clip.y,
gc->dc->clip.w, gc->dc->clip.h,
r, g, b, a, smooth,
yuv, yuy2, nv12);
_evas_gl_common_image_push(gc, im,
dx, dy, dw, dh,
sx, sy, sw, sh,
gc->dc->clip.x, gc->dc->clip.y,
gc->dc->clip.w, gc->dc->clip.h,
r, g, b, a, smooth,
yuv, yuy2, nv12, rgb_a_pair);
}
else
{
evas_gl_common_image_push(gc, im,
dx, dy, dw, dh,
sx, sy, sw, sh,
dx, dy, dw, dh,
r, g, b, a, smooth,
yuv, yuy2, nv12);
_evas_gl_common_image_push(gc, im,
dx, dy, dw, dh,
sx, sy, sw, sh,
dx, dy, dw, dh,
r, g, b, a, smooth,
yuv, yuy2, nv12, rgb_a_pair);
}
return;
}
@ -1114,12 +1170,12 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
{
rct = rects->rects + i;
evas_gl_common_image_push(gc, im,
dx, dy, dw, dh,
sx, sy, sw, sh,
rct->x, rct->y, rct->w, rct->h,
r, g, b, a, smooth,
yuv, yuy2, nv12);
_evas_gl_common_image_push(gc, im,
dx, dy, dw, dh,
sx, sy, sw, sh,
rct->x, rct->y, rct->w, rct->h,
r, g, b, a, smooth,
yuv, yuy2, nv12, rgb_a_pair);
}
/* restore clip info */
gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch;

View File

@ -771,6 +771,43 @@ Evas_GL_Program_Source shader_yuv_nomul_vert_src =
NULL, 0
};
/////////////////////////////////////////////
const char rgb_a_pair_frag_glsl[] =
#include "shader/rgb_a_pair_frag.h"
;
Evas_GL_Program_Source shader_rgb_a_pair_frag_src =
{
rgb_a_pair_frag_glsl,
NULL, 0
};
const char rgb_a_pair_vert_glsl[] =
#include "shader/rgb_a_pair_vert.h"
;
Evas_GL_Program_Source shader_rgb_a_pair_vert_src =
{
rgb_a_pair_vert_glsl,
NULL, 0
};
const char rgb_a_pair_nomul_frag_glsl[] =
#include "shader/rgb_a_pair_nomul_frag.h"
;
Evas_GL_Program_Source shader_rgb_a_pair_nomul_frag_src =
{
rgb_a_pair_nomul_frag_glsl,
NULL, 0
};
const char rgb_a_pair_nomul_vert_glsl[] =
#include "shader/rgb_a_pair_nomul_vert.h"
;
Evas_GL_Program_Source shader_rgb_a_pair_nomul_vert_src =
{
rgb_a_pair_nomul_vert_glsl,
NULL, 0
};
/////////////////////////////////////////////
static void
@ -1048,6 +1085,9 @@ static const struct {
SHADER_SOURCE_LINE(YUY2_NOMUL, yuy2_nomul),
SHADER_SOURCE_LINE(NV12, nv12),
SHADER_SOURCE_LINE(NV12_NOMUL, nv12_nomul),
SHADER_SOURCE_LINE(RGB_A_PAIR, rgb_a_pair),
SHADER_SOURCE_LINE(RGB_A_PAIR_NOMUL, rgb_a_pair_nomul),
};
static int

View File

@ -71,6 +71,7 @@ static const struct {
{ EINA_FALSE, EINA_TRUE, EVAS_COLORSPACE_GRY8, &lum_fmt, &lum_ifmt },
{ EINA_TRUE, EINA_FALSE, EVAS_COLORSPACE_AGRY88, &lum_alpha_fmt, &lum_alpha_ifmt },
{ EINA_TRUE, EINA_TRUE, EVAS_COLORSPACE_AGRY88, &lum_alpha_fmt, &lum_alpha_ifmt },
// ETC1/2 support
{ EINA_FALSE, EINA_FALSE, EVAS_COLORSPACE_ETC1, &etc1_fmt, &etc1_fmt },
{ 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 },
@ -80,6 +81,8 @@ static const struct {
// images marked as no alpha but format supports it (RGBA8_ETC2_EAC):
{ 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 },
{ EINA_TRUE, EINA_FALSE, EVAS_COLORSPACE_ETC1_ALPHA, &etc1_fmt, &etc1_fmt },
{ EINA_TRUE, EINA_TRUE, EVAS_COLORSPACE_ETC1_ALPHA, &etc1_fmt, &etc1_fmt },
// S3TC support
{ EINA_FALSE, EINA_FALSE, EVAS_COLORSPACE_RGB_S3TC_DXT1, &s3tc_rgb_dxt1_fmt, &s3tc_rgb_dxt1_fmt },
{ EINA_FALSE, EINA_TRUE, EVAS_COLORSPACE_RGB_S3TC_DXT1, &s3tc_rgb_dxt1_fmt, &s3tc_rgb_dxt1_fmt },
@ -516,6 +519,7 @@ evas_gl_common_texture_new(Evas_Engine_GL_Context *gc, RGBA_Image *im)
case EVAS_COLORSPACE_ETC1:
case EVAS_COLORSPACE_RGB8_ETC2:
case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
case EVAS_COLORSPACE_ETC1_ALPHA:
case EVAS_COLORSPACE_RGB_S3TC_DXT1:
case EVAS_COLORSPACE_RGBA_S3TC_DXT1:
case EVAS_COLORSPACE_RGBA_S3TC_DXT2:
@ -1183,6 +1187,7 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
case EVAS_COLORSPACE_RGB_S3TC_DXT1:
case EVAS_COLORSPACE_RGBA_S3TC_DXT1:
case EVAS_COLORSPACE_ETC1:
case EVAS_COLORSPACE_ETC1_ALPHA:
case EVAS_COLORSPACE_RGB8_ETC2:
{
/*
@ -1205,7 +1210,8 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
if ((tex->gc->shared->info.etc1_subimage ||
(im->cache_entry.space != EVAS_COLORSPACE_ETC1))
((im->cache_entry.space != EVAS_COLORSPACE_ETC1) &&
(im->cache_entry.space != EVAS_COLORSPACE_ETC1_ALPHA)))
&& (tex->pt->w != width || tex->pt->h != height))
{
int err;
@ -1225,7 +1231,8 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
// 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)
if ((im->cache_entry.space == EVAS_COLORSPACE_ETC1) ||
(im->cache_entry.space == EVAS_COLORSPACE_ETC1_ALPHA))
tex->gc->shared->info.etc1_subimage = EINA_FALSE;
}
}
@ -1461,6 +1468,171 @@ evas_gl_common_texture_alpha_update(Evas_GL_Texture *tex, DATA8 *pixels,
}
}
Evas_GL_Texture *
evas_gl_common_texture_rgb_a_pair_new(Evas_Engine_GL_Context *gc,
RGBA_Image *im)
{
Evas_GL_Texture *tex;
int lformat, w, h;
// FIXME/TODO: We don't support texture atlasses here (a bit tricky)
// Some debugging. We could return.
if (im->cache_entry.space != EVAS_COLORSPACE_ETC1_ALPHA)
WRN("Using RGB+A texture pair with format %d", im->cache_entry.space);
w = im->cache_entry.w;
h = im->cache_entry.h;
lformat = _evas_gl_texture_search_format(EINA_FALSE, gc->shared->info.bgra,
im->cache_entry.space);
if (lformat < 0) return NULL;
tex = evas_gl_common_texture_alloc(gc, w, h, EINA_TRUE);
if (!tex) return NULL;
// Allocate RGB texture normally - as a 'whole'
tex->pt = _pool_tex_new(gc, w, h,
*matching_format[lformat].intformat,
*matching_format[lformat].format);
if (!tex->pt)
{
evas_gl_common_texture_light_free(tex);
return NULL;
}
pt_link(gc, tex->pt);
tex->pt->slot = -1;
// And now Alpha texture -- FIXME could intformat be different? (eg. ALPHA4)
tex->pta = _pool_tex_new(gc, w, h,
*matching_format[lformat].intformat,
*matching_format[lformat].format);
if (!tex->pta)
{
pt_unref(tex->pt);
evas_gl_common_texture_light_free(tex);
return NULL;
}
pt_link(gc, tex->pta);
tex->pta->slot = -1;
evas_gl_common_texture_rgb_a_pair_update(tex, im);
return tex;
}
void
evas_gl_common_texture_rgb_a_pair_update(Evas_GL_Texture *tex,
RGBA_Image *im)
{
DATA8 *data1, *data2;
Eina_Bool comp, upload;
int w, h, sz, rowlen, ystep = 1;
if (!tex->pt) return;
// Handle compressed formats with 4x4 blocks format
if (((int) im->cache_entry.space >= (int) EVAS_COLORSPACE_ETC1) &&
((int) im->cache_entry.space <= (int) EVAS_COLORSPACE_RGBA_S3TC_DXT5))
ystep = 4;
w = im->cache_entry.w + im->cache_entry.borders.l + im->cache_entry.borders.r;
h = im->cache_entry.h + im->cache_entry.borders.t + im->cache_entry.borders.b;
rowlen = _evas_gl_texture_size_get(w, ystep, tex->pt->intformat, NULL);
sz = _evas_gl_texture_size_get(w, h, tex->pt->intformat, &comp);
data1 = im->image.data8;
data2 = data1 + sz;
upload = !!data1;
if (tex->gc->shared->info.unpack_row_length)
{
glPixelStorei(GL_UNPACK_ROW_LENGTH, w); GLERRLOG();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); GLERRLOG();
glBindTexture(GL_TEXTURE_2D, tex->pt->texture); GLERRLOG();
if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat))
goto on_error;
if (upload)
{
if (comp)
_comp_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, sz, data1);
else
_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, data1);
}
glBindTexture(GL_TEXTURE_2D, tex->pta->texture); GLERRLOG();
if (!_tex_2d(tex->gc, tex->pta->intformat, w, h, tex->pta->format, tex->pta->dataformat))
goto on_error;
if (upload)
{
if (comp)
_comp_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, sz, data2);
else
_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, data2);
}
}
else
{
int y;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); GLERRLOG();
glBindTexture(GL_TEXTURE_2D, tex->pt->texture); GLERRLOG();
if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format,
tex->pt->dataformat))
goto on_error;
if (upload)
{
if (w == tex->w)
{
if (comp)
_comp_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, sz, data1);
else
_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, data1);
}
else
{
for (y = 0; y < h; y += ystep)
{
if (comp)
_comp_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, sz, data1);
else
_tex_sub_2d(tex->gc, 0, y, w, ystep, tex->pt->format,
tex->pt->dataformat, data1 + rowlen * y / ystep);
}
}
}
glBindTexture(GL_TEXTURE_2D, tex->pta->texture); GLERRLOG();
if (!_tex_2d(tex->gc, tex->pta->intformat, w, h, tex->pta->format,
tex->pta->dataformat))
goto on_error;
if (upload)
{
if (w == tex->w)
{
if (comp)
_comp_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, sz, data2);
else
_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, data2);
}
else
{
for (y = 0; y < h; y += ystep)
{
if (comp)
_comp_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, sz, data2);
else
_tex_sub_2d(tex->gc, 0, y, w, ystep, tex->pt->format,
tex->pt->dataformat, data2 + rowlen * y / ystep);
}
}
}
}
on_error:
if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
{
glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
GLERRLOG();
}
}
Evas_GL_Texture *
evas_gl_common_texture_yuv_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h)
{

View File

@ -2304,6 +2304,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
case EVAS_COLORSPACE_ETC1:
case EVAS_COLORSPACE_RGB8_ETC2:
case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
case EVAS_COLORSPACE_ETC1_ALPHA:
ERR("This image is encoded in ETC1 or ETC2, not returning any data");
error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
*image_data = NULL;