jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=b0df3079276b542d2264af4413ff9cedfb098f89

commit b0df3079276b542d2264af4413ff9cedfb098f89
Author: Jean-Philippe Andre <jp.an...@samsung.com>
Date:   Mon Jun 30 15:10:07 2014 +0900

    Evas gl: Add support for S3TC textures
    
    Add support for DXT1, DXT3 and DXT5 textures (4 formats in total).
    
    @feature Add support for S3TC textures if the GPU supports them
---
 src/lib/evas/common/evas_image_main.c              |  6 ++
 .../evas/engines/gl_common/evas_gl_common.h        | 18 ++++-
 .../evas/engines/gl_common/evas_gl_context.c       |  6 ++
 src/modules/evas/engines/gl_common/evas_gl_image.c | 94 ++++++++++++----------
 .../evas/engines/gl_common/evas_gl_texture.c       | 45 ++++++++++-
 src/modules/evas/loaders/dds/evas_image_load_dds.c |  6 +-
 6 files changed, 124 insertions(+), 51 deletions(-)

diff --git a/src/lib/evas/common/evas_image_main.c 
b/src/lib/evas/common/evas_image_main.c
index faabda4..c911d3f 100644
--- a/src/lib/evas/common/evas_image_main.c
+++ b/src/lib/evas/common/evas_image_main.c
@@ -130,10 +130,16 @@ _evas_common_rgba_image_surface_size(unsigned int w, 
unsigned int h,
       case EVAS_COLORSPACE_GRY8: siz = w * h * sizeof(DATA8); break;
       case EVAS_COLORSPACE_AGRY88: siz = w * h * sizeof(DATA16); break;
       case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT2:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT3:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT4:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT5:
         block_size = 16;
         // fallthrough
       case EVAS_COLORSPACE_ETC1:
       case EVAS_COLORSPACE_RGB8_ETC2:
+      case EVAS_COLORSPACE_RGB_S3TC_DXT1:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT1:
         reset_borders = EINA_FALSE;
         if (l && r && t && b)
           {
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 4e9fe63..fb1281e 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_common.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_common.h
@@ -120,7 +120,18 @@
 #ifndef GL_COMPRESSED_RGBA8_ETC2_EAC
 # define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
 #endif
-
+#ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT
+# define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#endif
+#ifndef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
+# define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#endif
+#ifndef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
+# define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
+#endif
+#ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
+# define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
+#endif
 
 #ifndef GL_UNPACK_ROW_LENGTH
 # define GL_UNPACK_ROW_LENGTH 0x0cf2
@@ -379,6 +390,7 @@ struct _Evas_GL_Shared
       Eina_Bool etc1 : 1;
       Eina_Bool etc2 : 1;
       Eina_Bool etc1_subimage : 1;
+      Eina_Bool s3tc : 1;
       // tuning params - per gpu/cpu combo?
 #define MAX_CUTOUT             512
 #define DEF_CUTOUT                  512
@@ -403,6 +415,8 @@ struct _Evas_GL_Shared
 #define MAX_ATLAS_H            512
 #define DEF_ATLAS_H                 512
 
+      Eina_List *cspaces; // depend on the values of etc1, etc2 and st3c
+
       struct {
          struct {
             int max;
@@ -421,7 +435,7 @@ struct _Evas_GL_Shared
 
    struct {
       Eina_List       *whole;
-      Eina_List       *atlas[6];
+      Eina_List       *atlas[10];
    } tex;
 
    Eina_Hash          *native_pm_hash;
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 6c2e9b0..e24d2ba 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_context.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_context.c
@@ -625,6 +625,9 @@ evas_gl_common_context_new(void)
 #endif
              if (strstr((char *)ext, "OES_compressed_ETC1_RGB8_texture"))
                shared->info.etc1 = 1;
+             if (strstr((char *)ext, "GL_EXT_texture_compression_s3tc") ||
+                 strstr((char *)ext, "GL_S3_s3tc"))
+               shared->info.s3tc = 1;
 #ifdef GL_GLES
              // FIXME: there should be an extension name/string to check for
              // not just symbols in the lib
@@ -761,6 +764,7 @@ evas_gl_common_context_new(void)
                    "bgra : %i\n"
                    "etc1 : %i\n"
                    "etc2 : %i%s\n"
+                   "s3tc : %i\n"
                    "max ansiotropic filtering: %3.3f\n"
                    "egl sec map image: %i\n"
                    "max vertex count: %i\n"
@@ -781,6 +785,7 @@ evas_gl_common_context_new(void)
                    (int)shared->info.bgra,
                    (int)shared->info.etc1,
                    (int)shared->info.etc2, shared->info.etc2 ? " 
(GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGBA8_ETC2_EAC)" : "",
+                   (int)shared->info.s3tc,
                    (double)shared->info.anisotropic,
                    (int)shared->info.sec_image_map,
                    (int)shared->info.max_vertex_elements,
@@ -943,6 +948,7 @@ evas_gl_common_context_free(Evas_Engine_GL_Context *gc)
           }
         EINA_LIST_FOREACH(gc->shared->tex.whole, l, pt)
            evas_gl_texture_pool_empty(pt);
+        eina_list_free(gc->shared->info.cspaces);
         eina_list_free(gc->shared->tex.whole);
         eina_hash_free(gc->shared->native_pm_hash);
         eina_hash_free(gc->shared->native_tex_hash);
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 13b7598..0a6d8c9 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_image.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_image.c
@@ -122,30 +122,36 @@ evas_gl_common_image_unref(Evas_GL_Image *im)
      }
 }
 
-static const Evas_Colorspace known_cspace[] = {
-   EVAS_COLORSPACE_GRY8,
-   EVAS_COLORSPACE_AGRY88,
-   EVAS_COLORSPACE_ARGB8888
-};
-
-static const Evas_Colorspace known_etc1_cspace[] = {
-   EVAS_COLORSPACE_ETC1,
-   EVAS_COLORSPACE_GRY8,
-   EVAS_COLORSPACE_AGRY88,
-   EVAS_COLORSPACE_ARGB8888
-};
-
-static const Evas_Colorspace known_etc2_cspace[] = {
-   EVAS_COLORSPACE_RGBA8_ETC2_EAC,
-   EVAS_COLORSPACE_RGB8_ETC2,
-   EVAS_COLORSPACE_ETC1,
-   EVAS_COLORSPACE_GRY8,
-   EVAS_COLORSPACE_AGRY88,
-   EVAS_COLORSPACE_ARGB8888
-};
+static void
+_evas_gl_cspace_list_fill(Evas_Engine_GL_Context *gc)
+{
+#define CS_APPEND(cs) gc->shared->info.cspaces = eina_list_append \
+   (gc->shared->info.cspaces, (void *) (intptr_t) cs)
+   if (gc->shared->info.etc2)
+     {
+        CS_APPEND(EVAS_COLORSPACE_RGBA8_ETC2_EAC);
+        CS_APPEND(EVAS_COLORSPACE_RGB8_ETC2);
+        CS_APPEND(EVAS_COLORSPACE_ETC1);
+     }
+   else if (gc->shared->info.etc1)
+     CS_APPEND(EVAS_COLORSPACE_ETC1);
+   if (gc->shared->info.s3tc)
+     {
+        CS_APPEND(EVAS_COLORSPACE_RGB_S3TC_DXT1);
+        CS_APPEND(EVAS_COLORSPACE_RGBA_S3TC_DXT1);
+        CS_APPEND(EVAS_COLORSPACE_RGBA_S3TC_DXT2);
+        CS_APPEND(EVAS_COLORSPACE_RGBA_S3TC_DXT3);
+        CS_APPEND(EVAS_COLORSPACE_RGBA_S3TC_DXT4);
+        CS_APPEND(EVAS_COLORSPACE_RGBA_S3TC_DXT5);
+     }
+   CS_APPEND(EVAS_COLORSPACE_GRY8);
+   CS_APPEND(EVAS_COLORSPACE_AGRY88);
+   CS_APPEND(EVAS_COLORSPACE_ARGB8888);
+}
 
 static Evas_GL_Image *
-_evas_gl_common_image(Evas_Engine_GL_Context *gc, RGBA_Image *im_im, 
Evas_Image_Load_Opts *lo, int *error)
+_evas_gl_common_image(Evas_Engine_GL_Context *gc, RGBA_Image *im_im,
+                      Evas_Image_Load_Opts *lo, int *error)
 {
    Evas_GL_Image *im;
    Eina_List     *l;
@@ -193,31 +199,27 @@ _evas_gl_common_image(Evas_Engine_GL_Context *gc, 
RGBA_Image *im_im, Evas_Image_
      }
    if (im_im->cache_entry.cspaces)
      {
-        const Evas_Colorspace *cspaces;
+        Evas_Colorspace cs;
         unsigned int i;
+        Eina_List *l2;
+        void *ldata;
 
-        if (gc->shared->info.etc2)
-          cspaces = known_etc2_cspace;
-        else if (gc->shared->info.etc1)
-          cspaces = known_etc1_cspace;
-        else
-          cspaces = known_cspace;
+        if (!gc->shared->info.cspaces)
+          _evas_gl_cspace_list_fill(gc);
 
+        cspace = EVAS_COLORSPACE_ARGB8888;
         for (i = 0; im_im->cache_entry.cspaces[i] != EVAS_COLORSPACE_ARGB8888; 
i++)
-          {
-             unsigned int j;
-
-             for (j = 0;
-                  cspaces[j] != EVAS_COLORSPACE_ARGB8888;
-                  j++)
-               if (cspaces[j] == im_im->cache_entry.cspaces[i])
-                 break;
-
-             if (cspaces[j] == im_im->cache_entry.cspaces[i])
-               break;
-          }
-
-        cspace = im_im->cache_entry.cspaces[i];
+          EINA_LIST_FOREACH(gc->shared->info.cspaces, l2, ldata)
+            {
+               cs = (Evas_Colorspace) (intptr_t) ldata;
+               if (cs == im_im->cache_entry.cspaces[i])
+                 {
+                    cspace = cs;
+                    goto found_cspace;
+                 }
+            }
+
+found_cspace:
         // ETC2 is backwards compatible with ETC1 but we prefer ETC2
         if (cspace == EVAS_COLORSPACE_ETC1 && gc->shared->info.etc2)
           cspace = EVAS_COLORSPACE_RGB8_ETC2;
@@ -786,6 +788,12 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, 
Evas_GL_Image *im)
       case EVAS_COLORSPACE_ETC1:
       case EVAS_COLORSPACE_RGB8_ETC2:
       case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+      case EVAS_COLORSPACE_RGB_S3TC_DXT1:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT1:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT2:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT3:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT4:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT5:
          if ((im->tex) &&
              ((im->dirty) || (ie->animated.animated) || 
(ie->flags.updated_data)))
           {
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 c76fcfe..eaac74b 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_texture.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_texture.c
@@ -39,6 +39,11 @@ static const GLenum etc1_fmt       = GL_ETC1_RGB8_OES;
 static const GLenum etc2_rgb_fmt   = GL_COMPRESSED_RGB8_ETC2;
 static const GLenum etc2_rgba_fmt  = GL_COMPRESSED_RGBA8_ETC2_EAC;
 
+static const GLenum s3tc_rgb_dxt1_fmt   = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
+static const GLenum s3tc_rgba_dxt1_fmt  = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+static const GLenum s3tc_rgba_dxt23_fmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+static const GLenum s3tc_rgba_dxt45_fmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+
 static struct {
    struct {
       int num, pix;
@@ -74,7 +79,20 @@ static const struct {
   { 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):
   { 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_FALSE, EINA_TRUE, EVAS_COLORSPACE_RGBA8_ETC2_EAC, &etc2_rgba_fmt, 
&etc2_rgba_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 },
+  { EINA_TRUE, EINA_FALSE, EVAS_COLORSPACE_RGBA_S3TC_DXT1, 
&s3tc_rgba_dxt1_fmt, &s3tc_rgba_dxt1_fmt },
+  { EINA_TRUE, EINA_TRUE, EVAS_COLORSPACE_RGBA_S3TC_DXT1, &s3tc_rgba_dxt1_fmt, 
&s3tc_rgba_dxt1_fmt },
+  { EINA_TRUE, EINA_FALSE, EVAS_COLORSPACE_RGBA_S3TC_DXT2, 
&s3tc_rgba_dxt23_fmt, &s3tc_rgba_dxt23_fmt },
+  { EINA_TRUE, EINA_TRUE, EVAS_COLORSPACE_RGBA_S3TC_DXT2, 
&s3tc_rgba_dxt23_fmt, &s3tc_rgba_dxt23_fmt },
+  { EINA_TRUE, EINA_FALSE, EVAS_COLORSPACE_RGBA_S3TC_DXT3, 
&s3tc_rgba_dxt23_fmt, &s3tc_rgba_dxt23_fmt },
+  { EINA_TRUE, EINA_TRUE, EVAS_COLORSPACE_RGBA_S3TC_DXT3, 
&s3tc_rgba_dxt23_fmt, &s3tc_rgba_dxt23_fmt },
+  { EINA_TRUE, EINA_FALSE, EVAS_COLORSPACE_RGBA_S3TC_DXT4, 
&s3tc_rgba_dxt45_fmt, &s3tc_rgba_dxt45_fmt },
+  { EINA_TRUE, EINA_TRUE, EVAS_COLORSPACE_RGBA_S3TC_DXT4, 
&s3tc_rgba_dxt45_fmt, &s3tc_rgba_dxt45_fmt },
+  { EINA_TRUE, EINA_FALSE, EVAS_COLORSPACE_RGBA_S3TC_DXT5, 
&s3tc_rgba_dxt45_fmt, &s3tc_rgba_dxt45_fmt },
+  { EINA_TRUE, EINA_TRUE, EVAS_COLORSPACE_RGBA_S3TC_DXT5, 
&s3tc_rgba_dxt45_fmt, &s3tc_rgba_dxt45_fmt }
 };
 
 static const GLenum matching_rgb[] = { GL_RGB4, GL_RGB8, GL_RGB12, GL_RGB16, 
0x0 };
@@ -206,17 +224,25 @@ _tex_format_index(GLuint format)
         return 4;
       case GL_COMPRESSED_RGBA8_ETC2_EAC:
         return 5;
+      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+        return 6;
+      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+        return 7;
+      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: // dxt2 as well
+        return 8;
+      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: // dxt4 as well
+        return 9;
       case GL_LUMINANCE: // never used in atlas
       case GL_LUMINANCE4:
       case GL_LUMINANCE8:
       case GL_LUMINANCE12:
       case GL_LUMINANCE16:
-        return 6;
+        return 10;
       case GL_LUMINANCE4_ALPHA4:
       case GL_LUMINANCE8_ALPHA8:
       case GL_LUMINANCE12_ALPHA12:
       case GL_LUMINANCE16_ALPHA16:
-        return 7;
+        return 11;
       default:
         // abort?
         return 0;
@@ -490,6 +516,12 @@ 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_RGB_S3TC_DXT1:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT1:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT2:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT3:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT4:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT5:
         // Add border to avoid artifacts
         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;
@@ -1140,9 +1172,16 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, 
RGBA_Image *im)
       case EVAS_COLORSPACE_ARGB8888: bytes_count = 4; break;
       case EVAS_COLORSPACE_GRY8: bytes_count = 1; break;
       case EVAS_COLORSPACE_AGRY88: bytes_count = 2; break;
+      // Compressed texture formats: S3TC and ETC1/2
       case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT2:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT3:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT4:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT5:
         bsize = 16;
         // fallthrough
+      case EVAS_COLORSPACE_RGB_S3TC_DXT1:
+      case EVAS_COLORSPACE_RGBA_S3TC_DXT1:
       case EVAS_COLORSPACE_ETC1:
       case EVAS_COLORSPACE_RGB8_ETC2:
         {
diff --git a/src/modules/evas/loaders/dds/evas_image_load_dds.c 
b/src/modules/evas/loaders/dds/evas_image_load_dds.c
index cd3f87f..fb151ab 100644
--- a/src/modules/evas/loaders/dds/evas_image_load_dds.c
+++ b/src/modules/evas/loaders/dds/evas_image_load_dds.c
@@ -78,7 +78,7 @@ enum DDSCaps {
 #endif
 
 static const Evas_Colorspace cspaces_s3tc_dxt1_rgb[] = {
-   //EVAS_COLORSPACE_RGB_S3TC_DXT1,
+   EVAS_COLORSPACE_RGB_S3TC_DXT1,
    EVAS_COLORSPACE_ARGB8888
 };
 
@@ -88,7 +88,7 @@ static const Evas_Colorspace cspaces_s3tc_dxt1_rgba[] = {
 };
 
 static const Evas_Colorspace cspaces_s3tc_dxt2[] = {
-   //EVAS_COLORSPACE_RGBA_S3TC_DXT2,
+   EVAS_COLORSPACE_RGBA_S3TC_DXT2,
    EVAS_COLORSPACE_ARGB8888
 };
 
@@ -98,7 +98,7 @@ static const Evas_Colorspace cspaces_s3tc_dxt3[] = {
 };
 
 static const Evas_Colorspace cspaces_s3tc_dxt4[] = {
-   //EVAS_COLORSPACE_RGBA_S3TC_DXT4,
+   EVAS_COLORSPACE_RGBA_S3TC_DXT4,
    EVAS_COLORSPACE_ARGB8888
 };
 

-- 


Reply via email to