summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRajeev Ranjan <rajeev.r@samsung.com>2014-06-19 14:35:37 +0200
committerCedric BAIL <c.bail@partner.samsung.com>2014-06-19 16:48:45 +0200
commitbd65b5db5ddcada0255c5ccbaaa1280279ea5679 (patch)
treee5e733fd84babdcc9a3cbfc17af666401271302b
parent2cebf6785eed26e3f4eda7b6d3d77954a19d3bfc (diff)
evas: improvement of Eina Rectangle Pool and integration with Evas GL backend.
Summary: This patch introduce various new logic for packing/unpacking of Eina Rectangle in a pool. It is then used by Evas GL backend texture allocation to improve how efficiently we pack image in texture atlas. This lead to improved memory usage and reduced power consumption with usually a more stable higher FPS (as it use less texture to do the same task, their is less texture switch, so saving memory and speed at the same time). This patch was developped on Cedric's suggestions to optimize the packing logic using Skyline algorithm. This patch is based on master and is a new submission for earlier phab link https://phab.enlightenment.org/D774. Signed-off-by: Sanjay Nirankari <sanjay.n1@samsung.com> Signed-off-by: Rajeev Ranjan <rajeev.r@samsung.com> Signed-off-by: Sreedeep Moulik <sreedeep.m@samsung.com> Reviewers: cedric, raster CC: wonsik, jpeg, sreedeep.m, sanjay, govi Differential Revision: https://phab.enlightenment.org/D1063 Signed-off-by: Cedric BAIL <c.bail@partner.samsung.com>
-rw-r--r--AUTHORS1
-rw-r--r--src/lib/eina/eina_rectangle.c342
-rw-r--r--src/lib/eina/eina_rectangle.h24
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_common.h14
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_context.c17
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_texture.c154
6 files changed, 441 insertions, 111 deletions
diff --git a/AUTHORS b/AUTHORS
index d40a8fdb88..000723eb40 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -130,6 +130,7 @@ Paulo Cavalcanti <paulo.cavalcanti@linux.intel.com>
130Jean-Philippe Andre <jp.andre@samsung.com> 130Jean-Philippe Andre <jp.andre@samsung.com>
131Yury Usischev <y.usishchev@samsung.com> 131Yury Usischev <y.usishchev@samsung.com>
132Youngbok Shin <youngb.shin@samsung.com> 132Youngbok Shin <youngb.shin@samsung.com>
133Rajeev Ranjan (Rajeev) <rajeev.r@samsung.com> <rajeev.jnnce@gmail.com>
133 134
134Ecore 135Ecore
135----- 136-----
diff --git a/src/lib/eina/eina_rectangle.c b/src/lib/eina/eina_rectangle.c
index 5ae680b7df..972755fad3 100644
--- a/src/lib/eina/eina_rectangle.c
+++ b/src/lib/eina/eina_rectangle.c
@@ -61,9 +61,13 @@ struct _Eina_Rectangle_Pool
61 Eina_List *empty; 61 Eina_List *empty;
62 void *data; 62 void *data;
63 63
64 Eina_Compare_Cb eina_rectangle_compare_func;
65
64 Eina_Trash *bucket; 66 Eina_Trash *bucket;
65 unsigned int bucket_count; 67 unsigned int bucket_count;
66 68
69 Eina_Rectangle_Packing type;
70
67 unsigned int references; 71 unsigned int references;
68 int w; 72 int w;
69 int h; 73 int h;
@@ -109,18 +113,40 @@ static int _eina_rectangle_log_dom = -1;
109#define DBG(...) EINA_LOG_DOM_DBG(_eina_rectangle_log_dom, __VA_ARGS__) 113#define DBG(...) EINA_LOG_DOM_DBG(_eina_rectangle_log_dom, __VA_ARGS__)
110 114
111static int 115static int
112_eina_rectangle_cmp(const Eina_Rectangle *r1, const Eina_Rectangle *r2) 116_eina_rectangle_cmp(const void *data1, const void *data2)
113{ 117{
118 Eina_Rectangle *r1 = (Eina_Rectangle *) data1;
119 Eina_Rectangle *r2 = (Eina_Rectangle *) data2;
114 return (r2->w * r2->h) - (r1->w * r1->h); 120 return (r2->w * r2->h) - (r1->w * r1->h);
115} 121}
116 122
123static int
124_eina_rectangle_cmp_asc(const void *data1, const void *data2)
125{
126 Eina_Rectangle *r1 = (Eina_Rectangle *) data1;
127 Eina_Rectangle *r2 = (Eina_Rectangle *) data2;
128 return (r1->w * r1->h) - (r2->w * r2->h);
129}
130
131static int
132_eina_rectangle_cmp_bl(const void *data1, const void *data2)
133{
134 Eina_Rectangle *r1 = (Eina_Rectangle *) data1;
135 Eina_Rectangle *r2 = (Eina_Rectangle *) data2;
136 if (r1->y != r2->y)
137 return (r1->y) - (r2->y);
138 else
139 return (r1->x) - (r2->x);
140}
141
117static Eina_List * 142static Eina_List *
118_eina_rectangle_merge_list(Eina_List *empty, Eina_Rectangle *r) 143_eina_rectangle_merge_list(Eina_List *empty, Eina_Rectangle_Packing type, Eina_Rectangle *r)
119{ 144{
120 Eina_Rectangle *match; 145 Eina_Rectangle *match, *r1;
121 Eina_List *l; 146 Eina_List *l;
122 int xw; 147 int xw;
123 int yh; 148 int yh;
149 int x2 ,y2 ,w2 ,h2;
124 150
125 if (r->w == 0 || r->h == 0) 151 if (r->w == 0 || r->h == 0)
126 { 152 {
@@ -166,13 +192,41 @@ start_again:
166 192
167 goto start_again; 193 goto start_again;
168 } 194 }
195 else if (match->y > r->y && type == Eina_Packing_Bottom_Left_Skyline
196 && (match->y + match->h == r->y + r->h) &&
197 (match->x + match->w == r->x || r->x + r->w == match->x))
198 {
199
200 if (r->x < match->x)
201 match->x = r->x;
202
203 match->w += r->w;
204
205 x2 = r->x;
206 y2 = r->y;
207 w2 = r->w;
208 h2 = match->y - r->y;
209
210 eina_rectangle_free(r);
211
212 r1 = eina_rectangle_new(x2, y2, w2, h2);
213
214 empty = eina_list_remove_list(empty, l);
215
216 if (r1)
217 empty = eina_list_append(empty, r1);
218
219 r = match;
220
221 goto start_again;
222 }
169 } 223 }
170 224
171 return eina_list_append(empty, r); 225 return eina_list_append(empty, r);
172} 226}
173 227
174static Eina_List * 228static Eina_List *
175_eina_rectangle_empty_space_find(Eina_List *empty, int w, int h, int *x, int *y) 229_eina_rectangle_empty_space_find(Eina_List *empty, Eina_Rectangle_Packing type, int w, int h, int *x, int *y)
176{ 230{
177 Eina_Rectangle *r; 231 Eina_Rectangle *r;
178 Eina_List *l; 232 Eina_List *l;
@@ -211,7 +265,7 @@ _eina_rectangle_empty_space_find(Eina_List *empty, int w, int h, int *x, int *y)
211 /* w2 could be w or r->w */ 265 /* w2 could be w or r->w */
212 h2 = r->h - h; 266 h2 = r->h - h;
213 267
214 if (rw1 * r->h > h2 * r->w) 268 if ((rw1 * r->h > h2 * r->w) || type == Eina_Packing_Bottom_Left || type == Eina_Packing_Bottom_Left_Skyline)
215 { 269 {
216 rh1 = r->h; 270 rh1 = r->h;
217 w2 = w; 271 w2 = w;
@@ -221,16 +275,21 @@ _eina_rectangle_empty_space_find(Eina_List *empty, int w, int h, int *x, int *y)
221 rh1 = h; 275 rh1 = h;
222 w2 = r->w; 276 w2 = r->w;
223 } 277 }
278 if (type == Eina_Packing_Bottom_Left_Skyline_Improved)
279 {
280 rh1 = r->h;
281 w2 = r->w;
282 }
224 283
225 EINA_RECTANGLE_SET(r, rx1, ry1, rw1, rh1); 284 EINA_RECTANGLE_SET(r, rx1, ry1, rw1, rh1);
226 empty = _eina_rectangle_merge_list(empty, r); 285 empty = _eina_rectangle_merge_list(empty, type, r);
227 286
228 r = eina_rectangle_new(x2, y2, w2, h2); 287 r = eina_rectangle_new(x2, y2, w2, h2);
229 } 288 }
230 289
231 if (r) 290 if (r)
232 { 291 {
233 empty = _eina_rectangle_merge_list(empty, r); /* Return empty */ 292 empty = _eina_rectangle_merge_list(empty, type, r); /* Return empty */
234 293
235 } 294 }
236 295
@@ -243,6 +302,216 @@ _eina_rectangle_empty_space_find(Eina_List *empty, int w, int h, int *x, int *y)
243 return empty; 302 return empty;
244} 303}
245 304
305static Eina_List *
306_eina_rectangle_skyline_merge_list(Eina_List *empty, Eina_Rectangle *r)
307{
308 Eina_Rectangle *match;
309 Eina_List *l;
310
311 EINA_LIST_FOREACH(empty, l, match)
312 {
313 if (match->x == r->x + r->w)
314 {
315 match->x = r->x;
316 match->w = r->w + match->w;
317 }
318 else if (match->y == r->y + r->h)
319 {
320 match->y = r->y;
321 match->h = r->h + match->h;
322 }
323 else if (match->x + match->w == r->x)
324 {
325 match->w = r->w + match->w;
326 }
327 else if (match->y + match->h == r->y )
328 {
329 match->h = r->h + match->h;
330 }
331 }
332 return empty;
333}
334
335static Eina_List *
336_eina_rectangle_skyline_list_update(Eina_List *empty, Eina_Rectangle *rect)
337{
338 Eina_Rectangle *r, *r1;
339 Eina_List *l;
340 int x2, y2, w2, h2;
341
342start_again :
343 EINA_LIST_FOREACH(empty, l, r)
344 {
345 if (eina_rectangles_intersect(rect, r))
346 {
347 /* Remove l from empty */
348 empty = eina_list_remove_list(empty, l);
349
350 if (r->y > rect->y)
351 {
352 if (r->y + r->h > rect->y + rect->h)
353 {
354 w2 = r->w;
355 h2 = (r->y +r->h) - (rect->y + rect->h);
356 x2 = r->x;
357 y2 = (r->y +r->h) - h2;
358 r1 = eina_rectangle_new(x2, y2, w2, h2);
359 empty = eina_list_prepend(empty, r1);
360 }
361 if ( r->x + r->w > rect->x + rect->w )
362 {
363 w2 = (r->x +r->w) - (rect->x + rect->w);
364 h2 = r->h;
365 x2 = rect->x + rect->w;
366 y2 = r->y;
367 r1 = eina_rectangle_new(x2, y2, w2, h2);
368 empty = eina_list_prepend(empty, r1);
369 }
370 if ( rect->x - r->x)
371 {
372 w2 = rect->x - r->x;
373 h2 = r->h;
374 x2 = r->x;
375 y2 = r->y;
376 r1 = eina_rectangle_new(x2, y2, w2, h2);
377 empty = eina_list_prepend(empty, r1);
378 }
379 }
380 else if (r->x > rect->x)
381 {
382 if (r->x + r->w > rect->x + rect->w)
383 {
384 w2 = (r->x + r->w) - (rect->x + rect->w);
385 h2 = r->h;
386 x2 = (r->x +r->w) - w2;
387 y2 = r->y;
388 r1 = eina_rectangle_new(x2, y2, w2, h2);
389 empty = eina_list_prepend(empty, r1);
390 }
391 if ( r->y + r->h > rect->y + rect->y )
392 {
393 w2 = r->w;
394 h2 = (r->y +r->h) - (rect->y + rect->h);
395 x2 = r->x;
396 y2 = rect->y + rect->h;
397 r1 = eina_rectangle_new(x2, y2, w2, h2);
398 empty = eina_list_prepend(empty, r1);
399 }
400 if ( rect->y > r->y)
401 {
402 w2 = r->w;;
403 h2 = rect->y - r->y;
404 x2 = r->x;
405 y2 = r->y;
406 r1 = eina_rectangle_new(x2, y2, w2, h2);
407 empty = eina_list_prepend(empty, r1);
408 }
409 }
410 else if (r->x == rect->x && r->y < rect->y)
411 {
412 if (rect->y + rect->h < r->y + r->h)
413 {
414 w2 = r->w;
415 h2 = (r->y +r->h) - (rect->y + rect->h);
416 x2 = r->x;
417 y2 = rect->y + rect->h;
418 r1 = eina_rectangle_new(x2, y2, w2, h2);
419 empty = eina_list_prepend(empty, r1);
420 }
421 w2 = r->w;
422 h2 = rect->y - r->y;
423 x2 = r->x;
424 y2 = r->y;
425 r1 = eina_rectangle_new(x2, y2, w2, h2);
426 empty = eina_list_prepend(empty, r1);
427 }
428 else if (r->y == rect->y && r->x < rect->x)
429 {
430 if (rect->w + rect->x < r->w + r->x)
431 {
432 w2 = (r->x + r->w) - (rect->x + rect->w);
433 h2 = r->h;
434 x2 = rect->x + rect->w;
435 y2 = r->y;
436 r1 = eina_rectangle_new(x2, y2, w2, h2);
437 empty = eina_list_prepend(empty, r1);
438 }
439 w2 = rect->x - r->x;
440 h2 = r->h;;
441 x2 = r->x;
442 y2 = r->y;
443 r1 = eina_rectangle_new(x2, y2, w2, h2);
444 empty = eina_list_prepend(empty, r1);
445 }
446 else if (r->x < rect->x && r->y < rect->y)
447 {
448 w2 = rect->x - r->x;
449 h2 = r->h;
450 x2 = r->x;
451 y2 = r->y;
452 r1 = eina_rectangle_new(x2, y2, w2, h2);
453 empty = eina_list_prepend(empty, r1);
454 w2 = r->w;
455 h2 = rect->y - r->y;
456 x2 = r->x;
457 y2 = r->y;
458 r1 = eina_rectangle_new(x2, y2, w2, h2);
459 empty = eina_list_prepend(empty, r1);
460 }
461 else if (r->x == rect->x && r->y == rect->y)
462 {
463 if (r->w > rect->w )
464 {
465 w2 = r->w - rect->w;
466 h2 = r->h;
467 x2 = rect->x + rect->w;
468 y2 = r->y;
469 r1 = eina_rectangle_new(x2, y2, w2, h2);
470 empty = eina_list_prepend(empty, r1);
471 }
472 if (r->h > rect->h )
473 {
474 w2 = r->w;
475 h2 = r->h - rect->h;
476 x2 = r->x;
477 y2 = rect->y + rect->h;
478 r1 = eina_rectangle_new(x2, y2, w2, h2);
479 empty = eina_list_prepend(empty, r1);
480 }
481 }
482 goto start_again;
483 }
484 }
485 return empty;
486}
487
488static Eina_List *
489_eina_rectangle_skyline_list_update_duplicate(Eina_List *empty)
490{
491 Eina_Rectangle *r, *r1;
492 Eina_List *l, *l1, *l2;
493
494start_again:
495 EINA_LIST_FOREACH(empty, l, r)
496 {
497 l1 = eina_list_next(l);
498 EINA_LIST_FOREACH(l1, l2, r1)
499 {
500 if ((r->x <= r1->x) && (r->y <= r1->y) && (r->x + r->w >= r1->x + r1->w) && (r->y + r->h >= r1->y + r1->h))
501 {
502 empty = eina_list_remove_list(empty, l2);
503 goto start_again;
504 }
505 else if ((r->x >= r1->x) && (r->y >= r1->y) && (r->x + r->w <= r1->x + r1->w) && (r->y + r->h <= r1->y + r1->h))
506 {
507 empty = eina_list_remove_list(empty, l);
508 goto start_again;
509 }
510 }
511 }
512 return empty;
513}
514
246/** 515/**
247 * @endcond 516 * @endcond
248 */ 517 */
@@ -376,6 +645,8 @@ eina_rectangle_pool_new(int w, int h)
376 new->h = h; 645 new->h = h;
377 new->bucket = NULL; 646 new->bucket = NULL;
378 new->bucket_count = 0; 647 new->bucket_count = 0;
648 new->eina_rectangle_compare_func = _eina_rectangle_cmp;
649 new->type = Eina_Packing_Ascending;
379 650
380 EINA_MAGIC_SET(new, EINA_RECTANGLE_POOL_MAGIC); 651 EINA_MAGIC_SET(new, EINA_RECTANGLE_POOL_MAGIC);
381 DBG("pool=%p, size=(%d, %d)", new, w, h); 652 DBG("pool=%p, size=(%d, %d)", new, w, h);
@@ -387,10 +658,17 @@ EAPI void
387eina_rectangle_pool_free(Eina_Rectangle_Pool *pool) 658eina_rectangle_pool_free(Eina_Rectangle_Pool *pool)
388{ 659{
389 Eina_Rectangle_Alloc *del; 660 Eina_Rectangle_Alloc *del;
661 Eina_List *l;
662 Eina_Rectangle *r;
390 663
391 EINA_SAFETY_ON_NULL_RETURN(pool); 664 EINA_SAFETY_ON_NULL_RETURN(pool);
392 DBG("pool=%p, size=(%d, %d), references=%u", 665 DBG("pool=%p, size=(%d, %d), references=%u",
393 pool, pool->w, pool->h, pool->references); 666 pool, pool->w, pool->h, pool->references);
667 EINA_LIST_FOREACH(pool->empty, l, r)
668 {
669 eina_rectangle_free(r);
670 pool->empty = eina_list_remove_list(pool->empty, l);
671 }
394 while (pool->head) 672 while (pool->head)
395 { 673 {
396 del = (Eina_Rectangle_Alloc *)pool->head; 674 del = (Eina_Rectangle_Alloc *)pool->head;
@@ -440,11 +718,13 @@ eina_rectangle_pool_request(Eina_Rectangle_Pool *pool, int w, int h)
440 if (!pool->sorted) 718 if (!pool->sorted)
441 { 719 {
442 pool->empty = 720 pool->empty =
443 eina_list_sort(pool->empty, 0, EINA_COMPARE_CB(_eina_rectangle_cmp)); 721 eina_list_sort(pool->empty, 0, pool->eina_rectangle_compare_func);
444 pool->sorted = EINA_TRUE; 722 pool->sorted = EINA_TRUE;
445 } 723 }
446 724
447 pool->empty = _eina_rectangle_empty_space_find(pool->empty, w, h, &x, &y); 725 if (pool->type == Eina_Packing_Bottom_Left_Skyline_Improved)
726 pool->empty = _eina_rectangle_skyline_list_update_duplicate(pool->empty);
727 pool->empty = _eina_rectangle_empty_space_find(pool->empty, pool->type, w, h, &x, &y);
448 if (x == -1) 728 if (x == -1)
449 return NULL; 729 return NULL;
450 730
@@ -466,6 +746,9 @@ eina_rectangle_pool_request(Eina_Rectangle_Pool *pool, int w, int h)
466 rect = (Eina_Rectangle *)(new + 1); 746 rect = (Eina_Rectangle *)(new + 1);
467 eina_rectangle_coords_from(rect, x, y, w, h); 747 eina_rectangle_coords_from(rect, x, y, w, h);
468 748
749 if (pool->type == Eina_Packing_Bottom_Left_Skyline_Improved)
750 pool->empty = _eina_rectangle_skyline_list_update(pool->empty, rect);
751
469 pool->head = eina_inlist_prepend(pool->head, EINA_INLIST_GET(new)); 752 pool->head = eina_inlist_prepend(pool->head, EINA_INLIST_GET(new));
470 pool->references++; 753 pool->references++;
471 754
@@ -482,7 +765,9 @@ EAPI void
482eina_rectangle_pool_release(Eina_Rectangle *rect) 765eina_rectangle_pool_release(Eina_Rectangle *rect)
483{ 766{
484 Eina_Rectangle_Alloc *era = ((Eina_Rectangle_Alloc *)rect) - 1; 767 Eina_Rectangle_Alloc *era = ((Eina_Rectangle_Alloc *)rect) - 1;
768 Eina_Rectangle_Alloc *new;
485 Eina_Rectangle *r; 769 Eina_Rectangle *r;
770 Eina_Rectangle *match;
486 771
487 EINA_SAFETY_ON_NULL_RETURN(rect); 772 EINA_SAFETY_ON_NULL_RETURN(rect);
488 773
@@ -498,8 +783,20 @@ eina_rectangle_pool_release(Eina_Rectangle *rect)
498 r = eina_rectangle_new(rect->x, rect->y, rect->w, rect->h); 783 r = eina_rectangle_new(rect->x, rect->y, rect->w, rect->h);
499 if (r) 784 if (r)
500 { 785 {
501 era->pool->empty = _eina_rectangle_merge_list(era->pool->empty, r); 786 if (era->pool->type == Eina_Packing_Bottom_Left_Skyline_Improved)
502 era->pool->sorted = EINA_FALSE; 787 {
788 era->pool->empty = _eina_rectangle_skyline_merge_list(era->pool->empty, r);
789 era->pool->empty = _eina_rectangle_skyline_list_update_duplicate(era->pool->empty);
790 EINA_INLIST_FOREACH(era->pool->head, new)
791 {
792 match =(Eina_Rectangle *) (new + 1);
793 if (match)
794 era->pool->empty = _eina_rectangle_skyline_list_update(era->pool->empty, match);
795 }
796 }
797 else
798 era->pool->empty = _eina_rectangle_merge_list(era->pool->empty, era->pool->type, r);
799 era->pool->sorted = EINA_FALSE;
503 } 800 }
504 801
505 if (era->pool->bucket_count < BUCKET_THRESHOLD) 802 if (era->pool->bucket_count < BUCKET_THRESHOLD)
@@ -532,6 +829,29 @@ eina_rectangle_pool_get(Eina_Rectangle *rect)
532} 829}
533 830
534EAPI void 831EAPI void
832eina_rectangle_pool_packing_set(Eina_Rectangle_Pool *pool, Eina_Rectangle_Packing type)
833{
834 EINA_MAGIC_CHECK_RECTANGLE_POOL(pool);
835 EINA_SAFETY_ON_NULL_RETURN(pool);
836
837 DBG("type=%d pool=%p, size=(%d, %d), references=%u",
838 type, pool, pool->w, pool->h, pool->references);
839 pool->type =type;
840
841 switch (type)
842 {
843 case Eina_Packing_Ascending:
844 pool->eina_rectangle_compare_func = _eina_rectangle_cmp_asc;
845 break;
846 case Eina_Packing_Descending:
847 pool->eina_rectangle_compare_func = _eina_rectangle_cmp;
848 break;
849 default:
850 pool->eina_rectangle_compare_func = _eina_rectangle_cmp_bl;
851 }
852}
853
854EAPI void
535eina_rectangle_pool_data_set(Eina_Rectangle_Pool *pool, const void *data) 855eina_rectangle_pool_data_set(Eina_Rectangle_Pool *pool, const void *data)
536{ 856{
537 EINA_MAGIC_CHECK_RECTANGLE_POOL(pool); 857 EINA_MAGIC_CHECK_RECTANGLE_POOL(pool);
diff --git a/src/lib/eina/eina_rectangle.h b/src/lib/eina/eina_rectangle.h
index d3e2443a95..8f5eead1de 100644
--- a/src/lib/eina/eina_rectangle.h
+++ b/src/lib/eina/eina_rectangle.h
@@ -61,6 +61,19 @@ typedef struct _Eina_Rectangle
61 */ 61 */
62typedef struct _Eina_Rectangle_Pool Eina_Rectangle_Pool; 62typedef struct _Eina_Rectangle_Pool Eina_Rectangle_Pool;
63 63
64/**
65 * @typedef Eina_Rectangle_Pool_Type
66 * Type for an Eina Pool based on packing algorithm.
67 * @since 1.11
68 */
69typedef enum {
70 Eina_Packing_Descending, /**< Current */
71 Eina_Packing_Ascending, /**< sorting in assending order */
72 Eina_Packing_Bottom_Left, /**< sorting in bottemleft fasion */
73 Eina_Packing_Bottom_Left_Skyline, /**< bottemleft skyline */
74 Eina_Packing_Bottom_Left_Skyline_Improved /**< optimized bottemleft skyline */
75} Eina_Rectangle_Packing;
76
64static inline int eina_spans_intersect(int c1, int l1, int c2, int l2) EINA_WARN_UNUSED_RESULT; 77static inline int eina_spans_intersect(int c1, int l1, int c2, int l2) EINA_WARN_UNUSED_RESULT;
65static inline Eina_Bool eina_rectangle_is_empty(const Eina_Rectangle *r) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; 78static inline Eina_Bool eina_rectangle_is_empty(const Eina_Rectangle *r) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
66static inline void eina_rectangle_coords_from(Eina_Rectangle *r, int x, int y, int w, int h) EINA_ARG_NONNULL(1); 79static inline void eina_rectangle_coords_from(Eina_Rectangle *r, int x, int y, int w, int h) EINA_ARG_NONNULL(1);
@@ -238,6 +251,17 @@ EAPI Eina_Rectangle *eina_rectangle_new(int x, int y, int w, int h) EINA_MALLOC
238 */ 251 */
239EAPI void eina_rectangle_free(Eina_Rectangle *rect) EINA_ARG_NONNULL(1); 252EAPI void eina_rectangle_free(Eina_Rectangle *rect) EINA_ARG_NONNULL(1);
240 253
254/**
255 * @brief Sets the type of given rectangle pool.
256 *
257 * @param pool The rectangle pool for which type is to be set.
258 *
259 * This function sets @p type of @p pool.
260 * @see Eina_Rectangle_Packing
261 * @since 1.11
262 */
263EAPI void eina_rectangle_pool_packing_set(Eina_Rectangle_Pool *pool,Eina_Rectangle_Packing type) EINA_ARG_NONNULL(1);
264
241#include "eina_inline_rectangle.x" 265#include "eina_inline_rectangle.x"
242 266
243/** 267/**
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 4e45df0089..da30a8eddc 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_common.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_common.h
@@ -391,11 +391,11 @@ struct _Evas_GL_Shared
391 391
392#define MIN_ATLAS_ALLOC 16 392#define MIN_ATLAS_ALLOC 16
393#define MAX_ATLAS_ALLOC 1024 393#define MAX_ATLAS_ALLOC 1024
394#define DEF_ATLAS_ALLOC 1024 394#define DEF_ATLAS_ALLOC 256
395 395
396#define MIN_ATLAS_ALLOC_ALPHA 16 396#define MIN_ATLAS_ALLOC_ALPHA 16
397#define MAX_ATLAS_ALLOC_ALPHA 4096 397#define MAX_ATLAS_ALLOC_ALPHA 4096
398#define DEF_ATLAS_ALLOC_ALPHA 4096 398#define DEF_ATLAS_ALLOC_ALPHA 512
399 399
400#define MAX_ATLAS_W 512 400#define MAX_ATLAS_W 512
401#define DEF_ATLAS_W 512 401#define DEF_ATLAS_W 512
@@ -403,10 +403,6 @@ struct _Evas_GL_Shared
403#define MAX_ATLAS_H 512 403#define MAX_ATLAS_H 512
404#define DEF_ATLAS_H 512 404#define DEF_ATLAS_H 512
405 405
406#define MIN_ATLAS_SLOT 16
407#define MAX_ATLAS_SLOT 512
408#define DEF_ATLAS_SLOT 16
409
410 struct { 406 struct {
411 struct { 407 struct {
412 int max; 408 int max;
@@ -419,14 +415,13 @@ struct _Evas_GL_Shared
419 int max_alloc_alpha_size; 415 int max_alloc_alpha_size;
420 int max_w; 416 int max_w;
421 int max_h; 417 int max_h;
422 int slot_size;
423 } atlas; 418 } atlas;
424 } tune; 419 } tune;
425 } info; 420 } info;
426 421
427 struct { 422 struct {
428 Eina_List *whole; 423 Eina_List *whole;
429 Eina_List *atlas[33][6]; 424 Eina_List *atlas[6];
430 } tex; 425 } tex;
431 426
432 Eina_Hash *native_pm_hash; 427 Eina_Hash *native_pm_hash;
@@ -572,6 +567,7 @@ struct _Evas_GL_Texture_Pool
572 int checked_out; 567 int checked_out;
573 } dyn; 568 } dyn;
574 Eina_List *allocations; 569 Eina_List *allocations;
570 Eina_Rectangle_Pool *eina_pool;
575 Eina_Bool whole : 1; 571 Eina_Bool whole : 1;
576 Eina_Bool render : 1; 572 Eina_Bool render : 1;
577 Eina_Bool native : 1; 573 Eina_Bool native : 1;
@@ -590,7 +586,6 @@ struct _Evas_GL_Texture
590 Evas_Engine_GL_Context *gc; 586 Evas_Engine_GL_Context *gc;
591 Evas_GL_Image *im; 587 Evas_GL_Image *im;
592 Evas_GL_Texture_Pool *pt, *ptu, *ptv, *ptuv, *ptt; 588 Evas_GL_Texture_Pool *pt, *ptu, *ptv, *ptuv, *ptt;
593 Evas_GL_Texture_Alloca *apt, *aptt;
594 RGBA_Font_Glyph *fglyph; 589 RGBA_Font_Glyph *fglyph;
595 int x, y, w, h; 590 int x, y, w, h;
596 int tx, ty; 591 int tx, ty;
@@ -604,6 +599,7 @@ struct _Evas_GL_Texture
604 } double_buffer; 599 } double_buffer;
605 600
606 Eina_List *targets; 601 Eina_List *targets;
602 Eina_Rectangle *apt, *aptt;
607 603
608 Eina_Bool alpha : 1; 604 Eina_Bool alpha : 1;
609 Eina_Bool dyn : 1; 605 Eina_Bool dyn : 1;
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 21d14120f4..1f4db9474d 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_context.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_context.c
@@ -674,7 +674,6 @@ evas_gl_common_context_new(void)
674 shared->info.tune.atlas.max_alloc_alpha_size = DEF_ATLAS_ALLOC_ALPHA; 674 shared->info.tune.atlas.max_alloc_alpha_size = DEF_ATLAS_ALLOC_ALPHA;
675 shared->info.tune.atlas.max_w = DEF_ATLAS_W; 675 shared->info.tune.atlas.max_w = DEF_ATLAS_W;
676 shared->info.tune.atlas.max_h = DEF_ATLAS_H; 676 shared->info.tune.atlas.max_h = DEF_ATLAS_H;
677 shared->info.tune.atlas.slot_size = DEF_ATLAS_SLOT;
678 677
679 // per gpu hacks. based on impirical measurement of some known gpu's 678 // per gpu hacks. based on impirical measurement of some known gpu's
680 s = (const char *)glGetString(GL_RENDERER); 679 s = (const char *)glGetString(GL_RENDERER);
@@ -711,7 +710,6 @@ evas_gl_common_context_new(void)
711 GETENVOPT("EVAS_GL_ATLAS_ALLOC_ALPHA_SIZE", atlas.max_alloc_alpha_size, MIN_ATLAS_ALLOC_ALPHA, MAX_ATLAS_ALLOC_ALPHA); 710 GETENVOPT("EVAS_GL_ATLAS_ALLOC_ALPHA_SIZE", atlas.max_alloc_alpha_size, MIN_ATLAS_ALLOC_ALPHA, MAX_ATLAS_ALLOC_ALPHA);
712 GETENVOPT("EVAS_GL_ATLAS_MAX_W", atlas.max_w, 0, MAX_ATLAS_W); 711 GETENVOPT("EVAS_GL_ATLAS_MAX_W", atlas.max_w, 0, MAX_ATLAS_W);
713 GETENVOPT("EVAS_GL_ATLAS_MAX_H", atlas.max_h, 0, MAX_ATLAS_H); 712 GETENVOPT("EVAS_GL_ATLAS_MAX_H", atlas.max_h, 0, MAX_ATLAS_H);
714 GETENVOPT("EVAS_GL_ATLAS_SLOT_SIZE", atlas.slot_size, MIN_ATLAS_SLOT, MAX_ATLAS_SLOT);
715 s = (const char *)getenv("EVAS_GL_GET_PROGRAM_BINARY"); 713 s = (const char *)getenv("EVAS_GL_GET_PROGRAM_BINARY");
716 if (s) 714 if (s)
717 { 715 {
@@ -775,7 +773,6 @@ evas_gl_common_context_new(void)
775 "EVAS_GL_ATLAS_ALLOC_SIZE: %i\n" 773 "EVAS_GL_ATLAS_ALLOC_SIZE: %i\n"
776 "EVAS_GL_ATLAS_ALLOC_ALPHA_SIZE: %i\n" 774 "EVAS_GL_ATLAS_ALLOC_ALPHA_SIZE: %i\n"
777 "EVAS_GL_ATLAS_MAX_W x EVAS_GL_ATLAS_MAX_H: %i x %i\n" 775 "EVAS_GL_ATLAS_MAX_W x EVAS_GL_ATLAS_MAX_H: %i x %i\n"
778 "EVAS_GL_ATLAS_SLOT_SIZE: %i\n"
779 , 776 ,
780 (int)shared->info.max_texture_size, (int)shared->info.max_texture_size, 777 (int)shared->info.max_texture_size, (int)shared->info.max_texture_size,
781 (int)shared->info.max_texture_units, 778 (int)shared->info.max_texture_units,
@@ -793,8 +790,7 @@ evas_gl_common_context_new(void)
793 (int)shared->info.tune.pipes.max, 790 (int)shared->info.tune.pipes.max,
794 (int)shared->info.tune.atlas.max_alloc_size, 791 (int)shared->info.tune.atlas.max_alloc_size,
795 (int)shared->info.tune.atlas.max_alloc_alpha_size, 792 (int)shared->info.tune.atlas.max_alloc_alpha_size,
796 (int)shared->info.tune.atlas.max_w, (int)shared->info.tune.atlas.max_h, 793 (int)shared->info.tune.atlas.max_w, (int)shared->info.tune.atlas.max_h
797 (int)shared->info.tune.atlas.slot_size
798 ); 794 );
799 795
800 glDisable(GL_DEPTH_TEST); 796 glDisable(GL_DEPTH_TEST);
@@ -939,14 +935,11 @@ evas_gl_common_context_free(Evas_Engine_GL_Context *gc)
939 evas_gl_common_image_free(gc->shared->images->data); 935 evas_gl_common_image_free(gc->shared->images->data);
940 } 936 }
941 937
942 for (i = 0; i < 33; i++) 938 for (j = 0; j < 6; j++)
943 { 939 {
944 for (j = 0; j < 3; j++) 940 EINA_LIST_FOREACH(gc->shared->tex.atlas[j], l, pt)
945 { 941 evas_gl_texture_pool_empty(pt);
946 EINA_LIST_FOREACH(gc->shared->tex.atlas[i][j], l, pt) 942 eina_list_free(gc->shared->tex.atlas[j]);
947 evas_gl_texture_pool_empty(pt);
948 eina_list_free(gc->shared->tex.atlas[i][j]);
949 }
950 } 943 }
951 EINA_LIST_FOREACH(gc->shared->tex.whole, l, pt) 944 EINA_LIST_FOREACH(gc->shared->tex.whole, l, pt)
952 evas_gl_texture_pool_empty(pt); 945 evas_gl_texture_pool_empty(pt);
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 29a559493f..87c1346ae3 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_texture.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_texture.c
@@ -172,14 +172,6 @@ _tex_adjust(Evas_Engine_GL_Context *gc, int *w, int *h)
172 *h = _nearest_pow2(*h); 172 *h = _nearest_pow2(*h);
173} 173}
174 174
175static int
176_tex_round_slot(Evas_Engine_GL_Context *gc, int h)
177{
178 if (!gc->shared->info.tex_npo2)
179 h = _nearest_pow2(h);
180 return (h + gc->shared->info.tune.atlas.slot_size - 1) /
181 gc->shared->info.tune.atlas.slot_size;
182}
183 175
184static int 176static int
185_tex_format_index(GLuint format) 177_tex_format_index(GLuint format)
@@ -314,7 +306,6 @@ _pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, GLenum intformat, GLenum
314 306
315 if (!no_rounding) 307 if (!no_rounding)
316 { 308 {
317 h = _tex_round_slot(gc, h) * gc->shared->info.tune.atlas.slot_size;
318 _tex_adjust(gc, &w, &h); 309 _tex_adjust(gc, &w, &h);
319 } 310 }
320 pt->gc = gc; 311 pt->gc = gc;
@@ -324,6 +315,7 @@ _pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, GLenum intformat, GLenum
324 pt->format = format; 315 pt->format = format;
325 pt->dataformat = GL_UNSIGNED_BYTE; 316 pt->dataformat = GL_UNSIGNED_BYTE;
326 pt->references = 0; 317 pt->references = 0;
318 pt->eina_pool = eina_rectangle_pool_new(w, h);
327 319
328 glGenTextures(1, &(pt->texture)); 320 glGenTextures(1, &(pt->texture));
329 GLERR(__FUNCTION__, __FILE__, __LINE__, ""); 321 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
@@ -343,6 +335,8 @@ _pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, GLenum intformat, GLenum
343 if (!ok) 335 if (!ok)
344 { 336 {
345 glDeleteTextures(1, &(pt->texture)); 337 glDeleteTextures(1, &(pt->texture));
338 if (pt->eina_pool)
339 eina_rectangle_pool_free(pt->eina_pool);
346 free(pt); 340 free(pt);
347 return NULL; 341 return NULL;
348 } 342 }
@@ -366,59 +360,30 @@ _pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, GLenum intformat, GLenum
366 return pt; 360 return pt;
367} 361}
368 362
369static Evas_GL_Texture_Alloca * 363static Eina_Rectangle *
370_pool_tex_define(Evas_GL_Texture_Pool *pt, int lastx, int w, int *u, Eina_List *l) 364_pool_tex_alloc(Evas_GL_Texture_Pool *pt, int w, int h, int *u, int *v)
371{ 365{
372 Evas_GL_Texture_Alloca *napt; 366 Eina_Rectangle *r;
373 367 r = eina_rectangle_pool_request( pt->eina_pool, w, h);
374 *u = lastx; 368 if (r)
375
376 napt = malloc(sizeof (Evas_GL_Texture_Alloca));
377 if (!napt) return NULL;
378
379 napt->tex = NULL;
380 napt->x = lastx;
381 napt->w = w;
382
383 if (l == NULL)
384 pt->allocations = eina_list_append(pt->allocations, napt);
385 else
386 pt->allocations = eina_list_prepend_relative_list(pt->allocations, napt, l);
387
388 return napt;
389}
390
391static Evas_GL_Texture_Alloca *
392_pool_tex_alloc(Evas_GL_Texture_Pool *pt, int w, int h EINA_UNUSED, int *u, int *v)
393{
394 Evas_GL_Texture_Alloca *apt;
395 Eina_List *l;
396 int lastx = 0;
397
398 *v = 0;
399
400 EINA_LIST_FOREACH(pt->allocations, l, apt)
401 { 369 {
402 if (apt->x - lastx >= w) 370 *v = r->y;
403 return _pool_tex_define(pt, lastx, w, u, l); 371 *u = r->x;
404 372 pt->allocations = eina_list_prepend(pt->allocations, r);
405 lastx = apt->x + apt->w;
406 } 373 }
407 374
408 if (pt->w - lastx >= w) 375 return r;
409 return _pool_tex_define(pt, lastx, w, u, NULL);
410
411 return NULL;
412} 376}
413 377
414static Evas_GL_Texture_Pool * 378static Evas_GL_Texture_Pool *
415_pool_tex_find(Evas_Engine_GL_Context *gc, int w, int h, 379_pool_tex_find(Evas_Engine_GL_Context *gc, int w, int h,
416 GLenum intformat, GLenum format, int *u, int *v, 380 GLenum intformat, GLenum format, int *u, int *v,
417 Evas_GL_Texture_Alloca **apt, int atlas_w) 381 Eina_Rectangle **apt, int atlas_w)
418{ 382{
419 Evas_GL_Texture_Pool *pt = NULL; 383 Evas_GL_Texture_Pool *pt = NULL;
420 Eina_List *l; 384 Eina_List *l;
421 int th, th2; 385 int th2;
386 int pool_h;
422 387
423 if (atlas_w > gc->shared->info.max_texture_size) 388 if (atlas_w > gc->shared->info.max_texture_size)
424 atlas_w = gc->shared->info.max_texture_size; 389 atlas_w = gc->shared->info.max_texture_size;
@@ -429,32 +394,35 @@ _pool_tex_find(Evas_Engine_GL_Context *gc, int w, int h,
429 pt = _pool_tex_new(gc, w, h, intformat, format); 394 pt = _pool_tex_new(gc, w, h, intformat, format);
430 if (!pt) return NULL; 395 if (!pt) return NULL;
431 gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, pt); 396 gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, pt);
432 pt->slot = -1;
433 pt->fslot = -1; 397 pt->fslot = -1;
434 pt->whole = 1; 398 pt->whole = 1;
435 *apt = _pool_tex_alloc(pt, w, h, u, v); 399 *apt = _pool_tex_alloc(pt, w, h, u, v);
436 return pt; 400 return pt;
437 } 401 }
438 402
439 th = _tex_round_slot(gc, h);
440 th2 = _tex_format_index(intformat); 403 th2 = _tex_format_index(intformat);
441 EINA_LIST_FOREACH(gc->shared->tex.atlas[th][th2], l, pt) 404 EINA_LIST_FOREACH(gc->shared->tex.atlas[th2], l, pt)
442 { 405 {
443 if ((*apt = _pool_tex_alloc(pt, w, h, u, v)) != NULL) 406 if ((*apt = _pool_tex_alloc(pt, w, h, u, v)) != NULL)
444 { 407 {
445 gc->shared->tex.atlas[th][th2] = 408 gc->shared->tex.atlas[th2] =
446 eina_list_remove_list(gc->shared->tex.atlas[th][th2], l); 409 eina_list_remove_list(gc->shared->tex.atlas[th2], l);
447 gc->shared->tex.atlas[th][th2] = 410 gc->shared->tex.atlas[th2] =
448 eina_list_prepend(gc->shared->tex.atlas[th][th2], pt); 411 eina_list_prepend(gc->shared->tex.atlas[th2], pt);
449 return pt; 412 return pt;
450 } 413 }
451 } 414 }
415 pool_h = atlas_w;
416 if ( h > pool_h || w > atlas_w )
417 {
418 atlas_w = gc->shared->info.tune.atlas.max_w;
419 pool_h = gc->shared->info.tune.atlas.max_h;
420 }
421 pt = _pool_tex_new(gc, atlas_w, pool_h, intformat, format);
452 422
453 pt = _pool_tex_new(gc, atlas_w, h, intformat, format);
454 if (!pt) return NULL; 423 if (!pt) return NULL;
455 gc->shared->tex.atlas[th][th2] = 424 gc->shared->tex.atlas[th2] =
456 eina_list_prepend(gc->shared->tex.atlas[th][th2], pt); 425 eina_list_prepend(gc->shared->tex.atlas[th2], pt);
457 pt->slot = th;
458 pt->fslot = th2; 426 pt->fslot = th2;
459 427
460 *apt = _pool_tex_alloc(pt, w, h, u, v); 428 *apt = _pool_tex_alloc(pt, w, h, u, v);
@@ -495,7 +463,7 @@ evas_gl_common_texture_new(Evas_Engine_GL_Context *gc, RGBA_Image *im)
495 default: 463 default:
496 /* This need to be adjusted if we do something else than strip allocation */ 464 /* This need to be adjusted if we do something else than strip allocation */
497 w = im->cache_entry.w + TEX_HREP + 2; /* one pixel stop gap and two pixels for the border */ 465 w = im->cache_entry.w + TEX_HREP + 2; /* one pixel stop gap and two pixels for the border */
498 h = im->cache_entry.h + TEX_VREP; /* only one added border for security down */ 466 h = im->cache_entry.h + TEX_VREP + 2; /* only one added border for security down */
499 } 467 }
500 468
501 tex->pt = _pool_tex_find(gc, w, h, 469 tex->pt = _pool_tex_find(gc, w, h,
@@ -508,7 +476,6 @@ evas_gl_common_texture_new(Evas_Engine_GL_Context *gc, RGBA_Image *im)
508 evas_gl_common_texture_light_free(tex); 476 evas_gl_common_texture_light_free(tex);
509 return NULL; 477 return NULL;
510 } 478 }
511 tex->apt->tex = tex;
512 tex->x = u + 1; 479 tex->x = u + 1;
513 tex->y = v + yoffset; 480 tex->y = v + yoffset;
514 481
@@ -542,6 +509,7 @@ _pool_tex_render_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, in
542 pt->dataformat = GL_UNSIGNED_BYTE; 509 pt->dataformat = GL_UNSIGNED_BYTE;
543 pt->render = 1; 510 pt->render = 1;
544 pt->references = 0; 511 pt->references = 0;
512 pt->eina_pool = eina_rectangle_pool_new(w, h);
545#ifdef GL_GLES 513#ifdef GL_GLES
546# ifndef GL_FRAMEBUFFER 514# ifndef GL_FRAMEBUFFER
547# define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES 515# define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
@@ -587,6 +555,8 @@ _pool_tex_render_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, in
587 if (!ok) 555 if (!ok)
588 { 556 {
589 glDeleteTextures(1, &(pt->texture)); 557 glDeleteTextures(1, &(pt->texture));
558 if (pt->eina_pool)
559 eina_rectangle_pool_free(pt->eina_pool);
590 free(pt); 560 free(pt);
591 return NULL; 561 return NULL;
592 } 562 }
@@ -630,6 +600,7 @@ _pool_tex_native_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, in
630 pt->dataformat = GL_UNSIGNED_BYTE; 600 pt->dataformat = GL_UNSIGNED_BYTE;
631 pt->references = 0; 601 pt->references = 0;
632 pt->native = 1; 602 pt->native = 1;
603 pt->eina_pool = eina_rectangle_pool_new(w, h);
633 glGenTextures(1, &(pt->texture)); 604 glGenTextures(1, &(pt->texture));
634 GLERR(__FUNCTION__, __FILE__, __LINE__, ""); 605 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
635 glBindTexture(im->native.target, pt->texture); 606 glBindTexture(im->native.target, pt->texture);
@@ -698,7 +669,6 @@ _pool_tex_dynamic_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, i
698 669
699 pt = calloc(1, sizeof(Evas_GL_Texture_Pool)); 670 pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
700 if (!pt) return NULL; 671 if (!pt) return NULL;
701 h = _tex_round_slot(gc, h) * gc->shared->info.tune.atlas.slot_size;
702 _tex_adjust(gc, &w, &h); 672 _tex_adjust(gc, &w, &h);
703 pt->gc = gc; 673 pt->gc = gc;
704 pt->w = w; 674 pt->w = w;
@@ -708,6 +678,7 @@ _pool_tex_dynamic_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, i
708 pt->dataformat = GL_UNSIGNED_BYTE; 678 pt->dataformat = GL_UNSIGNED_BYTE;
709 pt->render = 1; 679 pt->render = 1;
710 pt->references = 0; 680 pt->references = 0;
681 pt->eina_pool = eina_rectangle_pool_new(w, h);
711 texinfo.d.num++; 682 texinfo.d.num++;
712 texinfo.d.pix += pt->w * pt->h; 683 texinfo.d.pix += pt->w * pt->h;
713 684
@@ -744,6 +715,8 @@ _pool_tex_dynamic_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, i
744 GLERR(__FUNCTION__, __FILE__, __LINE__, ""); 715 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
745 glDeleteTextures(1, &(pt->texture)); 716 glDeleteTextures(1, &(pt->texture));
746 GLERR(__FUNCTION__, __FILE__, __LINE__, ""); 717 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
718 if (pt->eina_pool)
719 eina_rectangle_pool_free(pt->eina_pool);
747 free(pt); 720 free(pt);
748 return NULL; 721 return NULL;
749 } 722 }
@@ -788,6 +761,8 @@ error:
788 GLERR(__FUNCTION__, __FILE__, __LINE__, ""); 761 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
789 glDeleteTextures(1, &(pt->texture)); 762 glDeleteTextures(1, &(pt->texture));
790 GLERR(__FUNCTION__, __FILE__, __LINE__, ""); 763 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
764 if (pt->eina_pool)
765 eina_rectangle_pool_free(pt->eina_pool);
791 free(pt); 766 free(pt);
792 return NULL; 767 return NULL;
793#endif 768#endif
@@ -796,7 +771,7 @@ error:
796void 771void
797evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt) 772evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt)
798{ 773{
799 Evas_GL_Texture_Alloca *apt; 774 Eina_Rectangle *apt;
800 775
801 if (!pt->gc) return; 776 if (!pt->gc) return;
802 777
@@ -858,9 +833,8 @@ evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt)
858 GLERR(__FUNCTION__, __FILE__, __LINE__, ""); 833 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
859 pt->fb = 0; 834 pt->fb = 0;
860 } 835 }
861 836 EINA_LIST_FREE(pt->allocations, apt)
862 EINA_LIST_FREE(pt->allocations, apt) 837 eina_rectangle_pool_release(apt);
863 free(apt);
864 pt->texture = 0; 838 pt->texture = 0;
865 pt->gc = NULL; 839 pt->gc = NULL;
866 pt->w = 0; 840 pt->w = 0;
@@ -881,10 +855,12 @@ pt_unref(Evas_GL_Texture_Pool *pt)
881 pt->gc->shared->tex.whole = 855 pt->gc->shared->tex.whole =
882 eina_list_remove(pt->gc->shared->tex.whole, pt); 856 eina_list_remove(pt->gc->shared->tex.whole, pt);
883 else 857 else
884 pt->gc->shared->tex.atlas [pt->slot][pt->fslot] = 858 pt->gc->shared->tex.atlas [pt->fslot] =
885 eina_list_remove(pt->gc->shared->tex.atlas[pt->slot][pt->fslot], pt); 859 eina_list_remove(pt->gc->shared->tex.atlas[pt->fslot], pt);
886 } 860 }
887 evas_gl_texture_pool_empty(pt); 861 evas_gl_texture_pool_empty(pt);
862 if (pt->eina_pool)
863 eina_rectangle_pool_free(pt->eina_pool);
888 free(pt); 864 free(pt);
889} 865}
890 866
@@ -892,7 +868,6 @@ static void
892pt_link(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt) 868pt_link(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt)
893{ 869{
894 gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, pt); 870 gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, pt);
895 pt->slot = -1;
896 pt->fslot = -1; 871 pt->fslot = -1;
897 pt->whole = 1; 872 pt->whole = 1;
898 pt->references++; 873 pt->references++;
@@ -1010,6 +985,28 @@ evas_gl_common_texture_upload(Evas_GL_Texture *tex, RGBA_Image *im, unsigned int
1010 1, 1, 985 1, 1,
1011 fmt, tex->pt->dataformat, 986 fmt, tex->pt->dataformat,
1012 (unsigned char *) im->image.data + (((im->cache_entry.h - 1) * im->cache_entry.w) + (im->cache_entry.w - 1)) * bytes_count); 987 (unsigned char *) im->image.data + (((im->cache_entry.h - 1) * im->cache_entry.w) + (im->cache_entry.w - 1)) * bytes_count);
988 //2D packing
989 // ---
990 // xxx
991 // xxx
992 _tex_sub_2d(tex->gc, tex->x, tex->y - 1,
993 im->cache_entry.w, 1,
994 fmt, tex->pt->dataformat,
995 im->image.data);
996 // o
997 // xxx
998 // xxx
999 _tex_sub_2d(tex->gc, tex->x - 1, tex->y - 1,
1000 1, 1,
1001 fmt, tex->pt->dataformat,
1002 im->image.data);
1003 // o
1004 // xxx
1005 // xxx
1006 _tex_sub_2d(tex->gc, tex->x + im->cache_entry.w, tex->y - 1,
1007 1, 1,
1008 fmt, tex->pt->dataformat,
1009 im->image.data + (im->cache_entry.w - 1) * bytes_count);
1013 if (tex->gc->shared->info.unpack_row_length) 1010 if (tex->gc->shared->info.unpack_row_length)
1014 { 1011 {
1015 glPixelStorei(GL_UNPACK_ROW_LENGTH, im->cache_entry.w); 1012 glPixelStorei(GL_UNPACK_ROW_LENGTH, im->cache_entry.w);
@@ -1083,8 +1080,8 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
1083 int lformat; 1080 int lformat;
1084 1081
1085 tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex->apt); 1082 tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex->apt);
1086 pt_unref(tex->pt); 1083 if (tex->apt)
1087 tex->alpha = im->cache_entry.flags.alpha; 1084 eina_rectangle_pool_release(tex->apt);
1088 1085
1089 lformat = _evas_gl_texture_search_format(tex->alpha, tex->gc->shared->info.bgra, im->cache_entry.space); 1086 lformat = _evas_gl_texture_search_format(tex->alpha, tex->gc->shared->info.bgra, im->cache_entry.space);
1090 // FIXME: why a 'render' new here ??? Should already have been allocated, quite a weird path. 1087 // FIXME: why a 'render' new here ??? Should already have been allocated, quite a weird path.
@@ -1238,7 +1235,6 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
1238 tex->gc->shared->info.tune.atlas.max_alloc_size); 1235 tex->gc->shared->info.tune.atlas.max_alloc_size);
1239 if (!tex->ptt) 1236 if (!tex->ptt)
1240 goto upload; 1237 goto upload;
1241 tex->aptt->tex = tex;
1242 1238
1243 tex->tx = u + 1; 1239 tex->tx = u + 1;
1244 tex->ty = v; 1240 tex->ty = v;
@@ -1327,14 +1323,16 @@ evas_gl_common_texture_free(Evas_GL_Texture *tex, Eina_Bool force EINA_UNUSED)
1327 if (tex->pt) 1323 if (tex->pt)
1328 { 1324 {
1329 tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex->apt); 1325 tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex->apt);
1330 free(tex->apt); 1326 if (tex->apt)
1327 eina_rectangle_pool_release(tex->apt);
1331 tex->apt = NULL; 1328 tex->apt = NULL;
1332 pt_unref(tex->pt); 1329 pt_unref(tex->pt);
1333 } 1330 }
1334 if (tex->ptt) 1331 if (tex->ptt)
1335 { 1332 {
1336 tex->ptt->allocations = eina_list_remove(tex->ptt->allocations, tex->aptt); 1333 tex->ptt->allocations = eina_list_remove(tex->pt->allocations, tex->aptt);
1337 free(tex->aptt); 1334 if (tex->aptt)
1335 eina_rectangle_pool_release(tex->aptt);
1338 tex->aptt = NULL; 1336 tex->aptt = NULL;
1339 pt_unref(tex->ptt); 1337 pt_unref(tex->ptt);
1340 } 1338 }
@@ -1366,7 +1364,6 @@ evas_gl_common_texture_alpha_new(Evas_Engine_GL_Context *gc, DATA8 *pixels,
1366 evas_gl_common_texture_light_free(tex); 1364 evas_gl_common_texture_light_free(tex);
1367 return NULL; 1365 return NULL;
1368 } 1366 }
1369 tex->apt->tex = tex;
1370 tex->x = u + 1; 1367 tex->x = u + 1;
1371 tex->y = v; 1368 tex->y = v;
1372 tex->pt->references++; 1369 tex->pt->references++;
@@ -1435,7 +1432,6 @@ evas_gl_common_texture_yuv_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigne
1435 return NULL; 1432 return NULL;
1436 } 1433 }
1437 gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, tex->pt); 1434 gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, tex->pt);
1438 tex->pt->slot = -1;
1439 tex->pt->fslot = -1; 1435 tex->pt->fslot = -1;
1440 tex->pt->whole = 1; 1436 tex->pt->whole = 1;
1441 tex->pt->references++; 1437 tex->pt->references++;