diff --git a/src/lib/evas/common/evas_image_main.c b/src/lib/evas/common/evas_image_main.c index c911d3f63f..89d46a2664 100644 --- a/src/lib/evas/common/evas_image_main.c +++ b/src/lib/evas/common/evas_image_main.c @@ -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: diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h index 94e8ce47ef..8a1071ec48 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h @@ -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 diff --git a/src/modules/evas/engines/gl_common/evas_gl_context.c b/src/modules/evas/engines/gl_common/evas_gl_context.c index 22bb159ebf..a2513a29d2 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_context.c +++ b/src/modules/evas/engines/gl_common/evas_gl_context.c @@ -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, diff --git a/src/modules/evas/engines/gl_common/evas_gl_image.c b/src/modules/evas/engines/gl_common/evas_gl_image.c index 4f95a93773..8070da4f97 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_image.c +++ b/src/modules/evas/engines/gl_common/evas_gl_image.c @@ -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; diff --git a/src/modules/evas/engines/gl_common/evas_gl_shader.c b/src/modules/evas/engines/gl_common/evas_gl_shader.c index ef372787a9..3f16040f55 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_shader.c +++ b/src/modules/evas/engines/gl_common/evas_gl_shader.c @@ -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 diff --git a/src/modules/evas/engines/gl_common/evas_gl_texture.c b/src/modules/evas/engines/gl_common/evas_gl_texture.c index eaac74b118..6012f338d9 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_texture.c +++ b/src/modules/evas/engines/gl_common/evas_gl_texture.c @@ -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) { diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c index 587bc7a338..7c607b5bd4 100644 --- a/src/modules/evas/engines/gl_x11/evas_engine.c +++ b/src/modules/evas/engines/gl_x11/evas_engine.c @@ -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;