From: Jean-Philippe Andre Date: Tue, 27 May 2014 07:34:04 +0000 (+0900) Subject: Evas TGV: Add ETC2 support to the TGV saver X-Git-Tag: upstream/1.10.0+1149+ga3a15b1~653^2~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cdf6e5297410c82a24f4d525aa802f4a2e672b94;p=platform%2Fupstream%2Fefl.git Evas TGV: Add ETC2 support to the TGV saver This will call the new ETC2 encoding functions. Note that the quality and performance will be horrible, but at least alpha should be supported. Also, there is no way to choose between ETC1 and ETC2 from the client API side, which, well, sucks. So ETC2 is selected if and only if the image has alpha (according to its flag). @feature: Encode images in ETC2 with support for Alpha (if needed). --- 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 8b2b50d..5aaa037 100644 --- a/src/modules/evas/savers/tgv/evas_image_save_tgv.c +++ b/src/modules/evas/savers/tgv/evas_image_save_tgv.c @@ -147,13 +147,20 @@ evas_image_save_file_tgv(RGBA_Image *im, { rg_etc1_pack_params param; FILE *f; - char *comp; - char *buffer; + uint8_t *comp = NULL; + uint8_t *buffer; uint32_t *data; uint32_t width, height; uint8_t header[8] = "TGV1"; int block_width, block_height, macro_block_width, macro_block_height; - int block_count, image_stride, image_height; + int block_count, image_stride, image_height, etc_block_size; + Evas_Colorspace cspace; + Eina_Bool alpha; + + /* FIXME: How to tell the encoder to encode as ETC1 or ETC2? + * The save API is weak. For now, assume ETC2 iif there's alpha. + * As long as we don't have a full ETC2 encoder, this is fine. + */ if (!im || !im->image.data || !file) return 0; @@ -161,8 +168,7 @@ evas_image_save_file_tgv(RGBA_Image *im, switch (im->cache_entry.space) { case EVAS_COLORSPACE_ARGB8888: - if (im->cache_entry.flags.alpha) - return 0; + alpha = im->cache_entry.flags.alpha; break; case EVAS_COLORSPACE_ETC1: case EVAS_COLORSPACE_RGB8_ETC2: @@ -177,6 +183,7 @@ evas_image_save_file_tgv(RGBA_Image *im, data = im->image.data; width = htonl(image_stride); height = htonl(image_height); + compress = !!compress; // Disable dithering, as it will deteriorate the quality of flat surfaces param.m_dithering = 0; @@ -193,11 +200,22 @@ evas_image_save_file_tgv(RGBA_Image *im, block_height = _block_size_get(image_height + 2); header[4] = (block_height << 4) | block_width; - // header[5]: 0 for ETC1 - header[5] = 0; + // header[5]: 0 for ETC1, 1 for RGB8_ETC2, 2 for RGBA8_ETC2_EAC + if (alpha) + { + cspace = EVAS_COLORSPACE_RGBA8_ETC2_EAC; + etc_block_size = 16; + header[5] = 2; + } + else + { + cspace = EVAS_COLORSPACE_ETC1; + etc_block_size = 8; + header[5] = 0; + } // header[6]: 0 for raw, 1, for LZ4 compressed - header[6] = (!!compress & 0x1); + header[6] = compress; // header[7]: options (unused) header[7] = 0; @@ -216,16 +234,10 @@ evas_image_save_file_tgv(RGBA_Image *im, // Number of ETC1 blocks in a compressed block block_count = (macro_block_width * macro_block_height) / (4 * 4); - buffer = alloca(block_count * 8); + buffer = alloca(block_count * etc_block_size); if (compress) - { - comp = alloca(LZ4_compressBound(block_count * 8)); - } - else - { - comp = NULL; - } + comp = alloca(LZ4_compressBound(block_count * etc_block_size)); // Write macro block for (int y = 0; y < image_height + 2; y += macro_block_height) @@ -240,7 +252,7 @@ evas_image_save_file_tgv(RGBA_Image *im, for (int x = 0; x < image_stride + 2; x += macro_block_width) { - char *offset = buffer; + uint8_t *offset = buffer; int real_x = x; if (x == 0) real_x = 0; @@ -315,19 +327,33 @@ evas_image_save_file_tgv(RGBA_Image *im, } } - rg_etc1_pack_block(offset, (unsigned int*) todo, ¶m); - offset += 8; + switch (cspace) + { + case EVAS_COLORSPACE_ETC1: + rg_etc1_pack_block(offset, (uint32_t *) todo, ¶m); + break; + case EVAS_COLORSPACE_RGB8_ETC2: + etc2_rgb8_block_pack(offset, (uint32_t *) todo, ¶m); + break; + case EVAS_COLORSPACE_RGBA8_ETC2_EAC: + etc2_rgba8_block_pack(offset, (uint32_t *) todo, ¶m); + break; + default: return 0; + } + + offset += etc_block_size; } } if (compress) { - wlen = LZ4_compressHC(buffer, comp, block_count * 8); + wlen = LZ4_compressHC((char *) buffer, (char *) comp, + block_count * etc_block_size); } else { comp = buffer; - wlen = block_count * 8; + wlen = block_count * etc_block_size; } if (wlen > 0)