summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2014-06-30 17:13:51 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2014-07-03 11:37:48 +0900
commita2de0a0bc959fd4c6ab7054c66af77f913eb4d8f (patch)
treeeb36300d14a5b33b1c8543488902a7999a687e1b
parent2b191b3c51e75f9a97612b1ad324ecdf496aa031 (diff)
Evas: Support duplicated borders in surface alloc
Now, the evas loader is supposed to advertise the actual border size in case of compressed texture formats. The only case where the border was non zero was ETC formats, from the TGV loader, so I think we don't need to keep the previous behaviour (auto-calculate borders for ETC).
-rw-r--r--src/lib/evas/Evas_Loader.h2
-rw-r--r--src/lib/evas/cache/evas_cache_image.c2
-rw-r--r--src/lib/evas/cache2/evas_cache2.c2
-rw-r--r--src/lib/evas/common/evas_image_load.c8
-rw-r--r--src/lib/evas/common/evas_image_main.c62
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_texture.c21
6 files changed, 62 insertions, 35 deletions
diff --git a/src/lib/evas/Evas_Loader.h b/src/lib/evas/Evas_Loader.h
index 1b74253553..6cabb18bfa 100644
--- a/src/lib/evas/Evas_Loader.h
+++ b/src/lib/evas/Evas_Loader.h
@@ -183,7 +183,7 @@ struct _Evas_Image_Property
183 Evas_Colorspace cspace; /**< Specify the color space handle by the engine @since 1.10 */ 183 Evas_Colorspace cspace; /**< Specify the color space handle by the engine @since 1.10 */
184 184
185 struct { 185 struct {
186 unsigned char l, r, t, b; /**< Specify the dimensions of duplicated pixels borders (for OpenGL compressed textures). Set by the loader. @since 1.11 */ 186 unsigned char l, r, t, b; /**< Specify the dimensions of duplicated pixels borders for OpenGL compressed textures, set by the loader. @since 1.11 */
187 } borders; 187 } borders;
188}; 188};
189 189
diff --git a/src/lib/evas/cache/evas_cache_image.c b/src/lib/evas/cache/evas_cache_image.c
index 70d05472a4..dc1d0d83e7 100644
--- a/src/lib/evas/cache/evas_cache_image.c
+++ b/src/lib/evas/cache/evas_cache_image.c
@@ -305,8 +305,6 @@ _evas_cache_image_entry_surface_alloc__locked(Evas_Cache_Image *cache,
305 } 305 }
306 ie->w = wmin; 306 ie->w = wmin;
307 ie->h = hmin; 307 ie->h = hmin;
308 ie->allocated.w = wmin;
309 ie->allocated.h = hmin;
310} 308}
311 309
312static void 310static void
diff --git a/src/lib/evas/cache2/evas_cache2.c b/src/lib/evas/cache2/evas_cache2.c
index 353ab0d3ab..11b2f2eceb 100644
--- a/src/lib/evas/cache2/evas_cache2.c
+++ b/src/lib/evas/cache2/evas_cache2.c
@@ -294,8 +294,6 @@ evas_cache2_image_surface_alloc(Image_Entry *ie, int w, int h)
294 294
295 ie->w = wmin; 295 ie->w = wmin;
296 ie->h = hmin; 296 ie->h = hmin;
297 ie->allocated.w = wmin;
298 ie->allocated.h = hmin;
299 ie->flags.loaded = EINA_TRUE; 297 ie->flags.loaded = EINA_TRUE;
300} 298}
301 299
diff --git a/src/lib/evas/common/evas_image_load.c b/src/lib/evas/common/evas_image_load.c
index dc72986085..6158e0baa8 100644
--- a/src/lib/evas/common/evas_image_load.c
+++ b/src/lib/evas/common/evas_image_load.c
@@ -223,6 +223,10 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error)
223 223
224 ie->w = property.w; 224 ie->w = property.w;
225 ie->h = property.h; 225 ie->h = property.h;
226 ie->borders.l = property.borders.l;
227 ie->borders.r = property.borders.r;
228 ie->borders.t = property.borders.t;
229 ie->borders.b = property.borders.b;
226 ie->scale = property.scale; 230 ie->scale = property.scale;
227 ie->flags.alpha = property.alpha; 231 ie->flags.alpha = property.alpha;
228 if (property.cspaces) 232 if (property.cspaces)
@@ -417,6 +421,10 @@ evas_common_load_rgba_image_data_from_file(Image_Entry *ie)
417 property.cspace = ie->space; 421 property.cspace = ie->space;
418 422
419 evas_cache_image_surface_alloc(ie, ie->w, ie->h); 423 evas_cache_image_surface_alloc(ie, ie->w, ie->h);
424 property.borders.l = ie->borders.l;
425 property.borders.r = ie->borders.r;
426 property.borders.t = ie->borders.t;
427 property.borders.b = ie->borders.b;
420 428
421 pixels = evas_cache_image_pixels(ie); 429 pixels = evas_cache_image_pixels(ie);
422 if (!pixels) 430 if (!pixels)
diff --git a/src/lib/evas/common/evas_image_main.c b/src/lib/evas/common/evas_image_main.c
index e375675bfc..faabda4a3e 100644
--- a/src/lib/evas/common/evas_image_main.c
+++ b/src/lib/evas/common/evas_image_main.c
@@ -110,7 +110,9 @@ static const Evas_Cache2_Image_Func _evas_common_image_func2 =
110#endif 110#endif
111 111
112static inline int 112static inline int
113_evas_common_rgba_image_surface_size(unsigned int w, unsigned int h, Evas_Colorspace cspace) 113_evas_common_rgba_image_surface_size(unsigned int w, unsigned int h,
114 Evas_Colorspace cspace,
115 /* inout */ int *l, int *r, int *t, int *b)
114{ 116{
115#define PAGE_SIZE (4 * 1024) 117#define PAGE_SIZE (4 * 1024)
116#define HUGE_PAGE_SIZE (2 * 1024 * 1024) 118#define HUGE_PAGE_SIZE (2 * 1024 * 1024)
@@ -119,26 +121,40 @@ _evas_common_rgba_image_surface_size(unsigned int w, unsigned int h, Evas_Colors
119#else 121#else
120# define ALIGN_TO_PAGE(Siz) Siz 122# define ALIGN_TO_PAGE(Siz) Siz
121#endif 123#endif
122 int siz; 124
125 int siz, block_size = 8;
126 Eina_Bool reset_borders = EINA_TRUE;
123 127
124 switch (cspace) 128 switch (cspace)
125 { 129 {
126 case EVAS_COLORSPACE_GRY8: siz = w * h * sizeof(DATA8); break; 130 case EVAS_COLORSPACE_GRY8: siz = w * h * sizeof(DATA8); break;
127 case EVAS_COLORSPACE_AGRY88: siz = w * h * sizeof(DATA16); break; 131 case EVAS_COLORSPACE_AGRY88: siz = w * h * sizeof(DATA16); break;
132 case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
133 block_size = 16;
134 // fallthrough
128 case EVAS_COLORSPACE_ETC1: 135 case EVAS_COLORSPACE_ETC1:
129 case EVAS_COLORSPACE_RGB8_ETC2: 136 case EVAS_COLORSPACE_RGB8_ETC2:
130 // Need to round width and height independently 137 reset_borders = EINA_FALSE;
131 w += 2; h += 2; // We do duplicate border in ETC1 to have better rendering on GPU. 138 if (l && r && t && b)
132 siz = (w / 4 + (w % 4 ? 1 : 0)) * (h / 4 + (h % 4 ? 1 : 0)) * 8; 139 {
133 break; 140 w += *l + *r;
134 case EVAS_COLORSPACE_RGBA8_ETC2_EAC: 141 h += *t + *b;
135 w += 2; h += 2; 142 }
136 siz = (w / 4 + (w % 4 ? 1 : 0)) * (h / 4 + (h % 4 ? 1 : 0)) * 16; 143 EINA_SAFETY_ON_FALSE_RETURN_VAL(!(w & 0x3) && !(h & 0x3), 0);
137 break; 144 siz = (w >> 2) * (h >> 2) * block_size;
145 break;
138 default: 146 default:
139 case EVAS_COLORSPACE_ARGB8888: siz = w * h * sizeof(DATA32); break; 147 case EVAS_COLORSPACE_ARGB8888: siz = w * h * sizeof(DATA32); break;
140 } 148 }
141 149
150 if (reset_borders)
151 {
152 if (l) *l = 0;
153 if (r) *r = 0;
154 if (t) *t = 0;
155 if (b) *b = 0;
156 }
157
142 if (siz < PAGE_SIZE) return siz; 158 if (siz < PAGE_SIZE) return siz;
143 159
144 return ALIGN_TO_PAGE(siz); 160 return ALIGN_TO_PAGE(siz);
@@ -147,14 +163,15 @@ _evas_common_rgba_image_surface_size(unsigned int w, unsigned int h, Evas_Colors
147} 163}
148 164
149static void * 165static void *
150_evas_common_rgba_image_surface_mmap(unsigned int w, unsigned int h, Evas_Colorspace cspace) 166_evas_common_rgba_image_surface_mmap(Image_Entry *ie, unsigned int w, unsigned int h,
167 /* inout */ int *pl, int *pr, int *pt, int *pb)
151{ 168{
152 int siz; 169 int siz;
153#if defined (HAVE_SYS_MMAN_H) && (!defined (_WIN32)) 170#if defined (HAVE_SYS_MMAN_H) && (!defined (_WIN32))
154 void *r = MAP_FAILED; 171 void *r = MAP_FAILED;
155#endif 172#endif
156 173
157 siz = _evas_common_rgba_image_surface_size(w, h, cspace); 174 siz = _evas_common_rgba_image_surface_size(w, h, ie->space, pl, pr, pt, pb);
158 175
159#if defined (HAVE_SYS_MMAN_H) && (!defined (_WIN32)) 176#if defined (HAVE_SYS_MMAN_H) && (!defined (_WIN32))
160#ifndef MAP_HUGETLB 177#ifndef MAP_HUGETLB
@@ -186,7 +203,7 @@ _evas_common_rgba_image_surface_munmap(void *data, unsigned int w, unsigned int
186#if defined (HAVE_SYS_MMAN_H) && (!defined (_WIN32)) 203#if defined (HAVE_SYS_MMAN_H) && (!defined (_WIN32))
187 size_t siz; 204 size_t siz;
188 205
189 siz = _evas_common_rgba_image_surface_size(w, h, cspace); 206 siz = _evas_common_rgba_image_surface_size(w, h, cspace, NULL, NULL, NULL, NULL);
190 if (siz < PAGE_SIZE) 207 if (siz < PAGE_SIZE)
191 free(data); 208 free(data);
192 else 209 else
@@ -453,7 +470,8 @@ _evas_common_rgba_image_post_surface(Image_Entry *ie)
453static int 470static int
454_evas_common_rgba_image_surface_alloc(Image_Entry *ie, unsigned int w, unsigned int h) 471_evas_common_rgba_image_surface_alloc(Image_Entry *ie, unsigned int w, unsigned int h)
455{ 472{
456 RGBA_Image *im = (RGBA_Image *) ie; 473 RGBA_Image *im = (RGBA_Image *) ie;
474 int l = 0, r = 0, t = 0, b = 0;
457 475
458#ifdef EVAS_CSERVE2 476#ifdef EVAS_CSERVE2
459 if (ie->data1) return 0; 477 if (ie->data1) return 0;
@@ -471,16 +489,24 @@ _evas_common_rgba_image_surface_alloc(Image_Entry *ie, unsigned int w, unsigned
471#endif 489#endif
472 } 490 }
473 491
474 im->image.data = _evas_common_rgba_image_surface_mmap(w, h, ie->space); 492 l = ie->borders.l;
493 r = ie->borders.r;
494 t = ie->borders.t;
495 b = ie->borders.b;
496 im->image.data = _evas_common_rgba_image_surface_mmap(ie, w, h, &l, &r, &t, &b);
475 if (!im->image.data) return -1; 497 if (!im->image.data) return -1;
476 ie->allocated.w = w; 498 ie->borders.l = l;
477 ie->allocated.h = h; 499 ie->borders.r = r;
500 ie->borders.t = t;
501 ie->borders.b = b;
502 ie->allocated.w = w + l + r;
503 ie->allocated.h = h + t + b;
478#ifdef SURFDBG 504#ifdef SURFDBG
479 surfs = eina_list_append(surfs, ie); 505 surfs = eina_list_append(surfs, ie);
480#endif 506#endif
481#ifdef HAVE_VALGRIND 507#ifdef HAVE_VALGRIND
482 int siz = 0; 508 int siz = 0;
483 siz = _evas_common_rgba_image_surface_size(w, h, ie->space); 509 siz = _evas_common_rgba_image_surface_size(w, h, ie->space, &l, &r, &t, &b);
484# ifdef VALGRIND_MAKE_READABLE 510# ifdef VALGRIND_MAKE_READABLE
485 if (siz > 0) VALGRIND_MAKE_READABLE(im->image.data, siz); 511 if (siz > 0) VALGRIND_MAKE_READABLE(im->image.data, siz);
486# else 512# else
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 0c69398815..16cb9c4c59 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_texture.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_texture.c
@@ -453,19 +453,17 @@ evas_gl_common_texture_new(Evas_Engine_GL_Context *gc, RGBA_Image *im)
453 case EVAS_COLORSPACE_RGB8_ETC2: 453 case EVAS_COLORSPACE_RGB8_ETC2:
454 case EVAS_COLORSPACE_RGBA8_ETC2_EAC: 454 case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
455 // Add border to avoid artifacts 455 // Add border to avoid artifacts
456 w = im->cache_entry.w + 2; 456 w = im->cache_entry.w + im->cache_entry.borders.l + im->cache_entry.borders.r;
457 h = im->cache_entry.h + 2; 457 h = im->cache_entry.h + im->cache_entry.borders.t + im->cache_entry.borders.b;
458 EINA_SAFETY_ON_FALSE_RETURN_VAL(!(w & 0x3) && !(h & 0x3), NULL);
458 yoffset = 1; 459 yoffset = 1;
459
460 // Adjust w and h for ETC1/2 formats (multiple of 4 pixels on both axes)
461 w = ((w >> 2) + (w & 0x3 ? 1 : 0)) << 2;
462 h = ((h >> 2) + (h & 0x3 ? 1 : 0)) << 2;
463 break; 460 break;
464 461
465 default: 462 default:
466 /* This need to be adjusted if we do something else than strip allocation */ 463 /* This need to be adjusted if we do something else than strip allocation */
467 w = im->cache_entry.w + TEX_HREP + 2; /* one pixel stop gap and two pixels for the border */ 464 w = im->cache_entry.w + TEX_HREP + 2; /* one pixel stop gap and two pixels for the border */
468 h = im->cache_entry.h + TEX_VREP + 2; /* only one added border for security down */ 465 h = im->cache_entry.h + TEX_VREP + 2; /* only one added border for security down */
466 break;
469 } 467 }
470 468
471 tex->pt = _pool_tex_find(gc, w, h, 469 tex->pt = _pool_tex_find(gc, w, h,
@@ -1121,12 +1119,11 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
1121 if (im->cache_entry.space == EVAS_COLORSPACE_RGBA8_ETC2_EAC) 1119 if (im->cache_entry.space == EVAS_COLORSPACE_RGBA8_ETC2_EAC)
1122 etc_block_size = 16; 1120 etc_block_size = 16;
1123 1121
1124 x = tex->x - 1; 1122 x = tex->x - im->cache_entry.borders.l;
1125 y = tex->y - 1; 1123 y = tex->y - im->cache_entry.borders.t;
1126 width = im->cache_entry.w + 2; 1124 width = im->cache_entry.w + im->cache_entry.borders.l + im->cache_entry.borders.r;
1127 height = im->cache_entry.h + 2; 1125 height = im->cache_entry.h + im->cache_entry.borders.t + im->cache_entry.borders.b;
1128 width = ((width >> 2) + (width & 0x3 ? 1 : 0)) << 2; 1126 EINA_SAFETY_ON_FALSE_RETURN(!(width & 0x3) && !(height & 0x3));
1129 height = ((height >> 2) + (height & 0x3 ? 1 : 0)) << 2;
1130 1127
1131 glBindTexture(GL_TEXTURE_2D, tex->pt->texture); 1128 glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
1132 GLERR(__FUNCTION__, __FILE__, __LINE__, ""); 1129 GLERR(__FUNCTION__, __FILE__, __LINE__, "");