cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=2fd69743f968aa7a184edf183384e5a359e79c8f
commit 2fd69743f968aa7a184edf183384e5a359e79c8f Author: Cedric BAIL <cedric.b...@samsung.com> Date: Mon Mar 24 19:55:45 2014 +0900 evas: change TGV internal encoding to account for GPU needs of duplicated border. With OpenGL, the border of a texture are not "well" defined. So interpolation at the border can result in weird/bad looking texture border. To avoid that we do duplicate the border in all direction at the time of the texture upload. But with ETC1 it is not possible as the border are grouped with 15 others pixels. It needs to be done at saving time. So internally we do have an image that would be of size width + 2 pixels and height + 2 pixels. --- src/modules/evas/savers/tgv/evas_image_save_tgv.c | 156 ++++++++++++++-------- 1 file changed, 99 insertions(+), 57 deletions(-) diff --git a/src/modules/evas/savers/tgv/evas_image_save_tgv.c b/src/modules/evas/savers/tgv/evas_image_save_tgv.c index 5ccbed4..c344df0 100644 --- a/src/modules/evas/savers/tgv/evas_image_save_tgv.c +++ b/src/modules/evas/savers/tgv/evas_image_save_tgv.c @@ -28,6 +28,7 @@ evas_image_save_file_tgv(RGBA_Image *im, unsigned int x, y; unsigned int compress_length; unsigned int block_count; + unsigned int real_x, real_y; if (!im || !im->image.data || !file) return 0; @@ -86,63 +87,104 @@ evas_image_save_file_tgv(RGBA_Image *im, } // Write block - for (y = 0; y < im->cache_entry.h; y += block) - for (x = 0; x < im->cache_entry.w; x += block) - { - unsigned int i, j; - int wlen; - char *offset = buffer; - - for (i = 0; i < block; i += 4) - for (j = 0; j < block; j += 4) - { - unsigned char todo[64] = { 0 }; - int k, kmax, lmax; - - kmax = y + i + 4 < im->cache_entry.h ? - 4 : im->cache_entry.h - y - i - 1; - lmax = x + j + 4 < im->cache_entry.w ? - 4 : im->cache_entry.w - x - j - 1; - - if (lmax > 0) - { - for (k = 0; k < kmax; k++) - memcpy(&todo[k * 16], - &data[(y + i + k) * im->cache_entry.w + x + j], - 4 * lmax); - } - - rg_etc1_pack_block(offset, (unsigned int*) todo, ¶m); - offset += 8; - } - - if (compress) - { - wlen = LZ4_compress(buffer, comp, block_count * 8); - } - else - { - comp = buffer; - wlen = block_count * 8; - } - - if (wlen > 0) - { - unsigned int blen = wlen; - - while (blen) - { - unsigned char plen; - - plen = blen & 0x7F; - blen = blen >> 7; - - if (blen) plen = 0x80 | plen; - fwrite(&plen, 1, 1, f); - } - fwrite(comp, wlen, 1, f); - } - } + for (y = 0; y < im->cache_entry.h + 2; y += block) + { + real_y = y > 0 ? y - 1 : 0; + + for (x = 0; x < im->cache_entry.w + 2; x += block) + { + unsigned int i, j; + unsigned char duplicate_w[2], duplicate_h[2]; + int wlen; + char *offset = buffer; + + real_x = x > 0 ? x - 1 : 0; + + for (i = 0; i < block; i += 4) + { + unsigned char block_h; + int kmax; + + duplicate_h[0] = !!((real_y + i) == 0); + duplicate_h[1] = !!((real_y + i + (4 - duplicate_h[0])) >= im->cache_entry.h); + block_h = 4 - duplicate_h[0] - duplicate_h[1]; + + kmax = real_y + i + block_h < im->cache_entry.h ? + block_h : im->cache_entry.h - real_y - i - 1; + + for (j = 0; j < block; j += 4) + { + unsigned char todo[64] = { 0 }; + unsigned char block_w; + int block_length; + int k, lmax; + + duplicate_w[0] = !!((real_x + j) == 0); + duplicate_w[1] = !!(((real_x + j + (4 - duplicate_w[0]))) >= im->cache_entry.w); + block_w = 4 - duplicate_w[0] - duplicate_w[1]; + + lmax = real_x + j + block_w < im->cache_entry.w ? + block_w : im->cache_entry.w - real_x - j - 1; + block_length = real_x + j + 4 < im->cache_entry.w ? + 4 : im->cache_entry.w - real_x - j - 1; + + if (lmax > 0) + { + for (k = duplicate_h[0]; k < kmax; k++) + memcpy(&todo[k * 16 + duplicate_w[0] * 4], + &data[(real_y + i + k) * im->cache_entry.w + real_x + j], + 4 * lmax); + } + + if (duplicate_h[0] && block_length > 0) // Duplicate first line + memcpy(&todo[0], &data[(real_y + i) * im->cache_entry.w + real_x + j], block_length); + if (duplicate_h[1] && block_length > 0 && kmax > 0) // Duplicate last line + memcpy(&todo[kmax * 16], &data[(real_y + i + kmax) * im->cache_entry.w + real_x + j], block_length); + if (duplicate_w[0]) // Duplicate first row + { + for (k = 0; k < kmax; k++) + memcpy(&todo[k * 16], &data[(real_y + i + k) * im->cache_entry.w + real_x + j], 4); // Copy a pixel at a time + } + if (duplicate_w[1] && lmax >= 0) // Duplicate last row + { + for (k = 0; k < kmax; k++) + memcpy(&todo[k * 16 + (duplicate_w[0] + lmax) * 4], + &data[(real_y + i + k) * im->cache_entry.w + real_x + j + lmax], 4); // Copy a pixel at a time + } + + rg_etc1_pack_block(offset, (unsigned int*) todo, ¶m); + offset += 8; + } + } + + if (compress) + { + wlen = LZ4_compress(buffer, comp, block_count * 8); + } + else + { + comp = buffer; + wlen = block_count * 8; + } + + if (wlen > 0) + { + unsigned int blen = wlen; + + while (blen) + { + unsigned char plen; + + plen = blen & 0x7F; + blen = blen >> 7; + + if (blen) plen = 0x80 | plen; + fwrite(&plen, 1, 1, f); + } + fwrite(comp, wlen, 1, f); + } + } + } fclose(f); return 1; --