forked from enlightenment/efl
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>
This commit is contained in:
parent
2cebf6785e
commit
bd65b5db5d
1
AUTHORS
1
AUTHORS
|
@ -130,6 +130,7 @@ Paulo Cavalcanti <paulo.cavalcanti@linux.intel.com>
|
||||||
Jean-Philippe Andre <jp.andre@samsung.com>
|
Jean-Philippe Andre <jp.andre@samsung.com>
|
||||||
Yury Usischev <y.usishchev@samsung.com>
|
Yury Usischev <y.usishchev@samsung.com>
|
||||||
Youngbok Shin <youngb.shin@samsung.com>
|
Youngbok Shin <youngb.shin@samsung.com>
|
||||||
|
Rajeev Ranjan (Rajeev) <rajeev.r@samsung.com> <rajeev.jnnce@gmail.com>
|
||||||
|
|
||||||
Ecore
|
Ecore
|
||||||
-----
|
-----
|
||||||
|
|
|
@ -61,9 +61,13 @@ struct _Eina_Rectangle_Pool
|
||||||
Eina_List *empty;
|
Eina_List *empty;
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
|
Eina_Compare_Cb eina_rectangle_compare_func;
|
||||||
|
|
||||||
Eina_Trash *bucket;
|
Eina_Trash *bucket;
|
||||||
unsigned int bucket_count;
|
unsigned int bucket_count;
|
||||||
|
|
||||||
|
Eina_Rectangle_Packing type;
|
||||||
|
|
||||||
unsigned int references;
|
unsigned int references;
|
||||||
int w;
|
int w;
|
||||||
int h;
|
int h;
|
||||||
|
@ -109,18 +113,40 @@ static int _eina_rectangle_log_dom = -1;
|
||||||
#define DBG(...) EINA_LOG_DOM_DBG(_eina_rectangle_log_dom, __VA_ARGS__)
|
#define DBG(...) EINA_LOG_DOM_DBG(_eina_rectangle_log_dom, __VA_ARGS__)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_eina_rectangle_cmp(const Eina_Rectangle *r1, const Eina_Rectangle *r2)
|
_eina_rectangle_cmp(const void *data1, const void *data2)
|
||||||
{
|
{
|
||||||
|
Eina_Rectangle *r1 = (Eina_Rectangle *) data1;
|
||||||
|
Eina_Rectangle *r2 = (Eina_Rectangle *) data2;
|
||||||
return (r2->w * r2->h) - (r1->w * r1->h);
|
return (r2->w * r2->h) - (r1->w * r1->h);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eina_List *
|
static int
|
||||||
_eina_rectangle_merge_list(Eina_List *empty, Eina_Rectangle *r)
|
_eina_rectangle_cmp_asc(const void *data1, const void *data2)
|
||||||
{
|
{
|
||||||
Eina_Rectangle *match;
|
Eina_Rectangle *r1 = (Eina_Rectangle *) data1;
|
||||||
|
Eina_Rectangle *r2 = (Eina_Rectangle *) data2;
|
||||||
|
return (r1->w * r1->h) - (r2->w * r2->h);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_eina_rectangle_cmp_bl(const void *data1, const void *data2)
|
||||||
|
{
|
||||||
|
Eina_Rectangle *r1 = (Eina_Rectangle *) data1;
|
||||||
|
Eina_Rectangle *r2 = (Eina_Rectangle *) data2;
|
||||||
|
if (r1->y != r2->y)
|
||||||
|
return (r1->y) - (r2->y);
|
||||||
|
else
|
||||||
|
return (r1->x) - (r2->x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_List *
|
||||||
|
_eina_rectangle_merge_list(Eina_List *empty, Eina_Rectangle_Packing type, Eina_Rectangle *r)
|
||||||
|
{
|
||||||
|
Eina_Rectangle *match, *r1;
|
||||||
Eina_List *l;
|
Eina_List *l;
|
||||||
int xw;
|
int xw;
|
||||||
int yh;
|
int yh;
|
||||||
|
int x2 ,y2 ,w2 ,h2;
|
||||||
|
|
||||||
if (r->w == 0 || r->h == 0)
|
if (r->w == 0 || r->h == 0)
|
||||||
{
|
{
|
||||||
|
@ -164,6 +190,34 @@ start_again:
|
||||||
|
|
||||||
r = match;
|
r = match;
|
||||||
|
|
||||||
|
goto start_again;
|
||||||
|
}
|
||||||
|
else if (match->y > r->y && type == Eina_Packing_Bottom_Left_Skyline
|
||||||
|
&& (match->y + match->h == r->y + r->h) &&
|
||||||
|
(match->x + match->w == r->x || r->x + r->w == match->x))
|
||||||
|
{
|
||||||
|
|
||||||
|
if (r->x < match->x)
|
||||||
|
match->x = r->x;
|
||||||
|
|
||||||
|
match->w += r->w;
|
||||||
|
|
||||||
|
x2 = r->x;
|
||||||
|
y2 = r->y;
|
||||||
|
w2 = r->w;
|
||||||
|
h2 = match->y - r->y;
|
||||||
|
|
||||||
|
eina_rectangle_free(r);
|
||||||
|
|
||||||
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
||||||
|
|
||||||
|
empty = eina_list_remove_list(empty, l);
|
||||||
|
|
||||||
|
if (r1)
|
||||||
|
empty = eina_list_append(empty, r1);
|
||||||
|
|
||||||
|
r = match;
|
||||||
|
|
||||||
goto start_again;
|
goto start_again;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,7 +226,7 @@ start_again:
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eina_List *
|
static Eina_List *
|
||||||
_eina_rectangle_empty_space_find(Eina_List *empty, int w, int h, int *x, int *y)
|
_eina_rectangle_empty_space_find(Eina_List *empty, Eina_Rectangle_Packing type, int w, int h, int *x, int *y)
|
||||||
{
|
{
|
||||||
Eina_Rectangle *r;
|
Eina_Rectangle *r;
|
||||||
Eina_List *l;
|
Eina_List *l;
|
||||||
|
@ -211,7 +265,7 @@ _eina_rectangle_empty_space_find(Eina_List *empty, int w, int h, int *x, int *y)
|
||||||
/* w2 could be w or r->w */
|
/* w2 could be w or r->w */
|
||||||
h2 = r->h - h;
|
h2 = r->h - h;
|
||||||
|
|
||||||
if (rw1 * r->h > h2 * r->w)
|
if ((rw1 * r->h > h2 * r->w) || type == Eina_Packing_Bottom_Left || type == Eina_Packing_Bottom_Left_Skyline)
|
||||||
{
|
{
|
||||||
rh1 = r->h;
|
rh1 = r->h;
|
||||||
w2 = w;
|
w2 = w;
|
||||||
|
@ -221,16 +275,21 @@ _eina_rectangle_empty_space_find(Eina_List *empty, int w, int h, int *x, int *y)
|
||||||
rh1 = h;
|
rh1 = h;
|
||||||
w2 = r->w;
|
w2 = r->w;
|
||||||
}
|
}
|
||||||
|
if (type == Eina_Packing_Bottom_Left_Skyline_Improved)
|
||||||
|
{
|
||||||
|
rh1 = r->h;
|
||||||
|
w2 = r->w;
|
||||||
|
}
|
||||||
|
|
||||||
EINA_RECTANGLE_SET(r, rx1, ry1, rw1, rh1);
|
EINA_RECTANGLE_SET(r, rx1, ry1, rw1, rh1);
|
||||||
empty = _eina_rectangle_merge_list(empty, r);
|
empty = _eina_rectangle_merge_list(empty, type, r);
|
||||||
|
|
||||||
r = eina_rectangle_new(x2, y2, w2, h2);
|
r = eina_rectangle_new(x2, y2, w2, h2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r)
|
if (r)
|
||||||
{
|
{
|
||||||
empty = _eina_rectangle_merge_list(empty, r); /* Return empty */
|
empty = _eina_rectangle_merge_list(empty, type, r); /* Return empty */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,6 +302,216 @@ _eina_rectangle_empty_space_find(Eina_List *empty, int w, int h, int *x, int *y)
|
||||||
return empty;
|
return empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Eina_List *
|
||||||
|
_eina_rectangle_skyline_merge_list(Eina_List *empty, Eina_Rectangle *r)
|
||||||
|
{
|
||||||
|
Eina_Rectangle *match;
|
||||||
|
Eina_List *l;
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH(empty, l, match)
|
||||||
|
{
|
||||||
|
if (match->x == r->x + r->w)
|
||||||
|
{
|
||||||
|
match->x = r->x;
|
||||||
|
match->w = r->w + match->w;
|
||||||
|
}
|
||||||
|
else if (match->y == r->y + r->h)
|
||||||
|
{
|
||||||
|
match->y = r->y;
|
||||||
|
match->h = r->h + match->h;
|
||||||
|
}
|
||||||
|
else if (match->x + match->w == r->x)
|
||||||
|
{
|
||||||
|
match->w = r->w + match->w;
|
||||||
|
}
|
||||||
|
else if (match->y + match->h == r->y )
|
||||||
|
{
|
||||||
|
match->h = r->h + match->h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_List *
|
||||||
|
_eina_rectangle_skyline_list_update(Eina_List *empty, Eina_Rectangle *rect)
|
||||||
|
{
|
||||||
|
Eina_Rectangle *r, *r1;
|
||||||
|
Eina_List *l;
|
||||||
|
int x2, y2, w2, h2;
|
||||||
|
|
||||||
|
start_again :
|
||||||
|
EINA_LIST_FOREACH(empty, l, r)
|
||||||
|
{
|
||||||
|
if (eina_rectangles_intersect(rect, r))
|
||||||
|
{
|
||||||
|
/* Remove l from empty */
|
||||||
|
empty = eina_list_remove_list(empty, l);
|
||||||
|
|
||||||
|
if (r->y > rect->y)
|
||||||
|
{
|
||||||
|
if (r->y + r->h > rect->y + rect->h)
|
||||||
|
{
|
||||||
|
w2 = r->w;
|
||||||
|
h2 = (r->y +r->h) - (rect->y + rect->h);
|
||||||
|
x2 = r->x;
|
||||||
|
y2 = (r->y +r->h) - h2;
|
||||||
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
||||||
|
empty = eina_list_prepend(empty, r1);
|
||||||
|
}
|
||||||
|
if ( r->x + r->w > rect->x + rect->w )
|
||||||
|
{
|
||||||
|
w2 = (r->x +r->w) - (rect->x + rect->w);
|
||||||
|
h2 = r->h;
|
||||||
|
x2 = rect->x + rect->w;
|
||||||
|
y2 = r->y;
|
||||||
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
||||||
|
empty = eina_list_prepend(empty, r1);
|
||||||
|
}
|
||||||
|
if ( rect->x - r->x)
|
||||||
|
{
|
||||||
|
w2 = rect->x - r->x;
|
||||||
|
h2 = r->h;
|
||||||
|
x2 = r->x;
|
||||||
|
y2 = r->y;
|
||||||
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
||||||
|
empty = eina_list_prepend(empty, r1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (r->x > rect->x)
|
||||||
|
{
|
||||||
|
if (r->x + r->w > rect->x + rect->w)
|
||||||
|
{
|
||||||
|
w2 = (r->x + r->w) - (rect->x + rect->w);
|
||||||
|
h2 = r->h;
|
||||||
|
x2 = (r->x +r->w) - w2;
|
||||||
|
y2 = r->y;
|
||||||
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
||||||
|
empty = eina_list_prepend(empty, r1);
|
||||||
|
}
|
||||||
|
if ( r->y + r->h > rect->y + rect->y )
|
||||||
|
{
|
||||||
|
w2 = r->w;
|
||||||
|
h2 = (r->y +r->h) - (rect->y + rect->h);
|
||||||
|
x2 = r->x;
|
||||||
|
y2 = rect->y + rect->h;
|
||||||
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
||||||
|
empty = eina_list_prepend(empty, r1);
|
||||||
|
}
|
||||||
|
if ( rect->y > r->y)
|
||||||
|
{
|
||||||
|
w2 = r->w;;
|
||||||
|
h2 = rect->y - r->y;
|
||||||
|
x2 = r->x;
|
||||||
|
y2 = r->y;
|
||||||
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
||||||
|
empty = eina_list_prepend(empty, r1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (r->x == rect->x && r->y < rect->y)
|
||||||
|
{
|
||||||
|
if (rect->y + rect->h < r->y + r->h)
|
||||||
|
{
|
||||||
|
w2 = r->w;
|
||||||
|
h2 = (r->y +r->h) - (rect->y + rect->h);
|
||||||
|
x2 = r->x;
|
||||||
|
y2 = rect->y + rect->h;
|
||||||
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
||||||
|
empty = eina_list_prepend(empty, r1);
|
||||||
|
}
|
||||||
|
w2 = r->w;
|
||||||
|
h2 = rect->y - r->y;
|
||||||
|
x2 = r->x;
|
||||||
|
y2 = r->y;
|
||||||
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
||||||
|
empty = eina_list_prepend(empty, r1);
|
||||||
|
}
|
||||||
|
else if (r->y == rect->y && r->x < rect->x)
|
||||||
|
{
|
||||||
|
if (rect->w + rect->x < r->w + r->x)
|
||||||
|
{
|
||||||
|
w2 = (r->x + r->w) - (rect->x + rect->w);
|
||||||
|
h2 = r->h;
|
||||||
|
x2 = rect->x + rect->w;
|
||||||
|
y2 = r->y;
|
||||||
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
||||||
|
empty = eina_list_prepend(empty, r1);
|
||||||
|
}
|
||||||
|
w2 = rect->x - r->x;
|
||||||
|
h2 = r->h;;
|
||||||
|
x2 = r->x;
|
||||||
|
y2 = r->y;
|
||||||
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
||||||
|
empty = eina_list_prepend(empty, r1);
|
||||||
|
}
|
||||||
|
else if (r->x < rect->x && r->y < rect->y)
|
||||||
|
{
|
||||||
|
w2 = rect->x - r->x;
|
||||||
|
h2 = r->h;
|
||||||
|
x2 = r->x;
|
||||||
|
y2 = r->y;
|
||||||
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
||||||
|
empty = eina_list_prepend(empty, r1);
|
||||||
|
w2 = r->w;
|
||||||
|
h2 = rect->y - r->y;
|
||||||
|
x2 = r->x;
|
||||||
|
y2 = r->y;
|
||||||
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
||||||
|
empty = eina_list_prepend(empty, r1);
|
||||||
|
}
|
||||||
|
else if (r->x == rect->x && r->y == rect->y)
|
||||||
|
{
|
||||||
|
if (r->w > rect->w )
|
||||||
|
{
|
||||||
|
w2 = r->w - rect->w;
|
||||||
|
h2 = r->h;
|
||||||
|
x2 = rect->x + rect->w;
|
||||||
|
y2 = r->y;
|
||||||
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
||||||
|
empty = eina_list_prepend(empty, r1);
|
||||||
|
}
|
||||||
|
if (r->h > rect->h )
|
||||||
|
{
|
||||||
|
w2 = r->w;
|
||||||
|
h2 = r->h - rect->h;
|
||||||
|
x2 = r->x;
|
||||||
|
y2 = rect->y + rect->h;
|
||||||
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
||||||
|
empty = eina_list_prepend(empty, r1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto start_again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_List *
|
||||||
|
_eina_rectangle_skyline_list_update_duplicate(Eina_List *empty)
|
||||||
|
{
|
||||||
|
Eina_Rectangle *r, *r1;
|
||||||
|
Eina_List *l, *l1, *l2;
|
||||||
|
|
||||||
|
start_again:
|
||||||
|
EINA_LIST_FOREACH(empty, l, r)
|
||||||
|
{
|
||||||
|
l1 = eina_list_next(l);
|
||||||
|
EINA_LIST_FOREACH(l1, l2, r1)
|
||||||
|
{
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
empty = eina_list_remove_list(empty, l2);
|
||||||
|
goto start_again;
|
||||||
|
}
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
empty = eina_list_remove_list(empty, l);
|
||||||
|
goto start_again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @endcond
|
* @endcond
|
||||||
*/
|
*/
|
||||||
|
@ -376,6 +645,8 @@ eina_rectangle_pool_new(int w, int h)
|
||||||
new->h = h;
|
new->h = h;
|
||||||
new->bucket = NULL;
|
new->bucket = NULL;
|
||||||
new->bucket_count = 0;
|
new->bucket_count = 0;
|
||||||
|
new->eina_rectangle_compare_func = _eina_rectangle_cmp;
|
||||||
|
new->type = Eina_Packing_Ascending;
|
||||||
|
|
||||||
EINA_MAGIC_SET(new, EINA_RECTANGLE_POOL_MAGIC);
|
EINA_MAGIC_SET(new, EINA_RECTANGLE_POOL_MAGIC);
|
||||||
DBG("pool=%p, size=(%d, %d)", new, w, h);
|
DBG("pool=%p, size=(%d, %d)", new, w, h);
|
||||||
|
@ -387,10 +658,17 @@ EAPI void
|
||||||
eina_rectangle_pool_free(Eina_Rectangle_Pool *pool)
|
eina_rectangle_pool_free(Eina_Rectangle_Pool *pool)
|
||||||
{
|
{
|
||||||
Eina_Rectangle_Alloc *del;
|
Eina_Rectangle_Alloc *del;
|
||||||
|
Eina_List *l;
|
||||||
|
Eina_Rectangle *r;
|
||||||
|
|
||||||
EINA_SAFETY_ON_NULL_RETURN(pool);
|
EINA_SAFETY_ON_NULL_RETURN(pool);
|
||||||
DBG("pool=%p, size=(%d, %d), references=%u",
|
DBG("pool=%p, size=(%d, %d), references=%u",
|
||||||
pool, pool->w, pool->h, pool->references);
|
pool, pool->w, pool->h, pool->references);
|
||||||
|
EINA_LIST_FOREACH(pool->empty, l, r)
|
||||||
|
{
|
||||||
|
eina_rectangle_free(r);
|
||||||
|
pool->empty = eina_list_remove_list(pool->empty, l);
|
||||||
|
}
|
||||||
while (pool->head)
|
while (pool->head)
|
||||||
{
|
{
|
||||||
del = (Eina_Rectangle_Alloc *)pool->head;
|
del = (Eina_Rectangle_Alloc *)pool->head;
|
||||||
|
@ -440,11 +718,13 @@ eina_rectangle_pool_request(Eina_Rectangle_Pool *pool, int w, int h)
|
||||||
if (!pool->sorted)
|
if (!pool->sorted)
|
||||||
{
|
{
|
||||||
pool->empty =
|
pool->empty =
|
||||||
eina_list_sort(pool->empty, 0, EINA_COMPARE_CB(_eina_rectangle_cmp));
|
eina_list_sort(pool->empty, 0, pool->eina_rectangle_compare_func);
|
||||||
pool->sorted = EINA_TRUE;
|
pool->sorted = EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pool->empty = _eina_rectangle_empty_space_find(pool->empty, w, h, &x, &y);
|
if (pool->type == Eina_Packing_Bottom_Left_Skyline_Improved)
|
||||||
|
pool->empty = _eina_rectangle_skyline_list_update_duplicate(pool->empty);
|
||||||
|
pool->empty = _eina_rectangle_empty_space_find(pool->empty, pool->type, w, h, &x, &y);
|
||||||
if (x == -1)
|
if (x == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -466,6 +746,9 @@ eina_rectangle_pool_request(Eina_Rectangle_Pool *pool, int w, int h)
|
||||||
rect = (Eina_Rectangle *)(new + 1);
|
rect = (Eina_Rectangle *)(new + 1);
|
||||||
eina_rectangle_coords_from(rect, x, y, w, h);
|
eina_rectangle_coords_from(rect, x, y, w, h);
|
||||||
|
|
||||||
|
if (pool->type == Eina_Packing_Bottom_Left_Skyline_Improved)
|
||||||
|
pool->empty = _eina_rectangle_skyline_list_update(pool->empty, rect);
|
||||||
|
|
||||||
pool->head = eina_inlist_prepend(pool->head, EINA_INLIST_GET(new));
|
pool->head = eina_inlist_prepend(pool->head, EINA_INLIST_GET(new));
|
||||||
pool->references++;
|
pool->references++;
|
||||||
|
|
||||||
|
@ -482,7 +765,9 @@ EAPI void
|
||||||
eina_rectangle_pool_release(Eina_Rectangle *rect)
|
eina_rectangle_pool_release(Eina_Rectangle *rect)
|
||||||
{
|
{
|
||||||
Eina_Rectangle_Alloc *era = ((Eina_Rectangle_Alloc *)rect) - 1;
|
Eina_Rectangle_Alloc *era = ((Eina_Rectangle_Alloc *)rect) - 1;
|
||||||
|
Eina_Rectangle_Alloc *new;
|
||||||
Eina_Rectangle *r;
|
Eina_Rectangle *r;
|
||||||
|
Eina_Rectangle *match;
|
||||||
|
|
||||||
EINA_SAFETY_ON_NULL_RETURN(rect);
|
EINA_SAFETY_ON_NULL_RETURN(rect);
|
||||||
|
|
||||||
|
@ -498,7 +783,19 @@ eina_rectangle_pool_release(Eina_Rectangle *rect)
|
||||||
r = eina_rectangle_new(rect->x, rect->y, rect->w, rect->h);
|
r = eina_rectangle_new(rect->x, rect->y, rect->w, rect->h);
|
||||||
if (r)
|
if (r)
|
||||||
{
|
{
|
||||||
era->pool->empty = _eina_rectangle_merge_list(era->pool->empty, r);
|
if (era->pool->type == Eina_Packing_Bottom_Left_Skyline_Improved)
|
||||||
|
{
|
||||||
|
era->pool->empty = _eina_rectangle_skyline_merge_list(era->pool->empty, r);
|
||||||
|
era->pool->empty = _eina_rectangle_skyline_list_update_duplicate(era->pool->empty);
|
||||||
|
EINA_INLIST_FOREACH(era->pool->head, new)
|
||||||
|
{
|
||||||
|
match =(Eina_Rectangle *) (new + 1);
|
||||||
|
if (match)
|
||||||
|
era->pool->empty = _eina_rectangle_skyline_list_update(era->pool->empty, match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
era->pool->empty = _eina_rectangle_merge_list(era->pool->empty, era->pool->type, r);
|
||||||
era->pool->sorted = EINA_FALSE;
|
era->pool->sorted = EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -531,6 +828,29 @@ eina_rectangle_pool_get(Eina_Rectangle *rect)
|
||||||
return era->pool;
|
return era->pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
eina_rectangle_pool_packing_set(Eina_Rectangle_Pool *pool, Eina_Rectangle_Packing type)
|
||||||
|
{
|
||||||
|
EINA_MAGIC_CHECK_RECTANGLE_POOL(pool);
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(pool);
|
||||||
|
|
||||||
|
DBG("type=%d pool=%p, size=(%d, %d), references=%u",
|
||||||
|
type, pool, pool->w, pool->h, pool->references);
|
||||||
|
pool->type =type;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case Eina_Packing_Ascending:
|
||||||
|
pool->eina_rectangle_compare_func = _eina_rectangle_cmp_asc;
|
||||||
|
break;
|
||||||
|
case Eina_Packing_Descending:
|
||||||
|
pool->eina_rectangle_compare_func = _eina_rectangle_cmp;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pool->eina_rectangle_compare_func = _eina_rectangle_cmp_bl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
eina_rectangle_pool_data_set(Eina_Rectangle_Pool *pool, const void *data)
|
eina_rectangle_pool_data_set(Eina_Rectangle_Pool *pool, const void *data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,6 +61,19 @@ typedef struct _Eina_Rectangle
|
||||||
*/
|
*/
|
||||||
typedef struct _Eina_Rectangle_Pool Eina_Rectangle_Pool;
|
typedef struct _Eina_Rectangle_Pool Eina_Rectangle_Pool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef Eina_Rectangle_Pool_Type
|
||||||
|
* Type for an Eina Pool based on packing algorithm.
|
||||||
|
* @since 1.11
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
Eina_Packing_Descending, /**< Current */
|
||||||
|
Eina_Packing_Ascending, /**< sorting in assending order */
|
||||||
|
Eina_Packing_Bottom_Left, /**< sorting in bottemleft fasion */
|
||||||
|
Eina_Packing_Bottom_Left_Skyline, /**< bottemleft skyline */
|
||||||
|
Eina_Packing_Bottom_Left_Skyline_Improved /**< optimized bottemleft skyline */
|
||||||
|
} Eina_Rectangle_Packing;
|
||||||
|
|
||||||
static inline int eina_spans_intersect(int c1, int l1, int c2, int l2) EINA_WARN_UNUSED_RESULT;
|
static inline int eina_spans_intersect(int c1, int l1, int c2, int l2) EINA_WARN_UNUSED_RESULT;
|
||||||
static inline Eina_Bool eina_rectangle_is_empty(const Eina_Rectangle *r) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
static inline Eina_Bool eina_rectangle_is_empty(const Eina_Rectangle *r) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||||
static inline void eina_rectangle_coords_from(Eina_Rectangle *r, int x, int y, int w, int h) EINA_ARG_NONNULL(1);
|
static 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
|
||||||
*/
|
*/
|
||||||
EAPI void eina_rectangle_free(Eina_Rectangle *rect) EINA_ARG_NONNULL(1);
|
EAPI void eina_rectangle_free(Eina_Rectangle *rect) EINA_ARG_NONNULL(1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the type of given rectangle pool.
|
||||||
|
*
|
||||||
|
* @param pool The rectangle pool for which type is to be set.
|
||||||
|
*
|
||||||
|
* This function sets @p type of @p pool.
|
||||||
|
* @see Eina_Rectangle_Packing
|
||||||
|
* @since 1.11
|
||||||
|
*/
|
||||||
|
EAPI void eina_rectangle_pool_packing_set(Eina_Rectangle_Pool *pool,Eina_Rectangle_Packing type) EINA_ARG_NONNULL(1);
|
||||||
|
|
||||||
#include "eina_inline_rectangle.x"
|
#include "eina_inline_rectangle.x"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -391,11 +391,11 @@ struct _Evas_GL_Shared
|
||||||
|
|
||||||
#define MIN_ATLAS_ALLOC 16
|
#define MIN_ATLAS_ALLOC 16
|
||||||
#define MAX_ATLAS_ALLOC 1024
|
#define MAX_ATLAS_ALLOC 1024
|
||||||
#define DEF_ATLAS_ALLOC 1024
|
#define DEF_ATLAS_ALLOC 256
|
||||||
|
|
||||||
#define MIN_ATLAS_ALLOC_ALPHA 16
|
#define MIN_ATLAS_ALLOC_ALPHA 16
|
||||||
#define MAX_ATLAS_ALLOC_ALPHA 4096
|
#define MAX_ATLAS_ALLOC_ALPHA 4096
|
||||||
#define DEF_ATLAS_ALLOC_ALPHA 4096
|
#define DEF_ATLAS_ALLOC_ALPHA 512
|
||||||
|
|
||||||
#define MAX_ATLAS_W 512
|
#define MAX_ATLAS_W 512
|
||||||
#define DEF_ATLAS_W 512
|
#define DEF_ATLAS_W 512
|
||||||
|
@ -403,10 +403,6 @@ struct _Evas_GL_Shared
|
||||||
#define MAX_ATLAS_H 512
|
#define MAX_ATLAS_H 512
|
||||||
#define DEF_ATLAS_H 512
|
#define DEF_ATLAS_H 512
|
||||||
|
|
||||||
#define MIN_ATLAS_SLOT 16
|
|
||||||
#define MAX_ATLAS_SLOT 512
|
|
||||||
#define DEF_ATLAS_SLOT 16
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct {
|
struct {
|
||||||
int max;
|
int max;
|
||||||
|
@ -419,14 +415,13 @@ struct _Evas_GL_Shared
|
||||||
int max_alloc_alpha_size;
|
int max_alloc_alpha_size;
|
||||||
int max_w;
|
int max_w;
|
||||||
int max_h;
|
int max_h;
|
||||||
int slot_size;
|
|
||||||
} atlas;
|
} atlas;
|
||||||
} tune;
|
} tune;
|
||||||
} info;
|
} info;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Eina_List *whole;
|
Eina_List *whole;
|
||||||
Eina_List *atlas[33][6];
|
Eina_List *atlas[6];
|
||||||
} tex;
|
} tex;
|
||||||
|
|
||||||
Eina_Hash *native_pm_hash;
|
Eina_Hash *native_pm_hash;
|
||||||
|
@ -572,6 +567,7 @@ struct _Evas_GL_Texture_Pool
|
||||||
int checked_out;
|
int checked_out;
|
||||||
} dyn;
|
} dyn;
|
||||||
Eina_List *allocations;
|
Eina_List *allocations;
|
||||||
|
Eina_Rectangle_Pool *eina_pool;
|
||||||
Eina_Bool whole : 1;
|
Eina_Bool whole : 1;
|
||||||
Eina_Bool render : 1;
|
Eina_Bool render : 1;
|
||||||
Eina_Bool native : 1;
|
Eina_Bool native : 1;
|
||||||
|
@ -590,7 +586,6 @@ struct _Evas_GL_Texture
|
||||||
Evas_Engine_GL_Context *gc;
|
Evas_Engine_GL_Context *gc;
|
||||||
Evas_GL_Image *im;
|
Evas_GL_Image *im;
|
||||||
Evas_GL_Texture_Pool *pt, *ptu, *ptv, *ptuv, *ptt;
|
Evas_GL_Texture_Pool *pt, *ptu, *ptv, *ptuv, *ptt;
|
||||||
Evas_GL_Texture_Alloca *apt, *aptt;
|
|
||||||
RGBA_Font_Glyph *fglyph;
|
RGBA_Font_Glyph *fglyph;
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
int tx, ty;
|
int tx, ty;
|
||||||
|
@ -604,6 +599,7 @@ struct _Evas_GL_Texture
|
||||||
} double_buffer;
|
} double_buffer;
|
||||||
|
|
||||||
Eina_List *targets;
|
Eina_List *targets;
|
||||||
|
Eina_Rectangle *apt, *aptt;
|
||||||
|
|
||||||
Eina_Bool alpha : 1;
|
Eina_Bool alpha : 1;
|
||||||
Eina_Bool dyn : 1;
|
Eina_Bool dyn : 1;
|
||||||
|
|
|
@ -674,7 +674,6 @@ evas_gl_common_context_new(void)
|
||||||
shared->info.tune.atlas.max_alloc_alpha_size = DEF_ATLAS_ALLOC_ALPHA;
|
shared->info.tune.atlas.max_alloc_alpha_size = DEF_ATLAS_ALLOC_ALPHA;
|
||||||
shared->info.tune.atlas.max_w = DEF_ATLAS_W;
|
shared->info.tune.atlas.max_w = DEF_ATLAS_W;
|
||||||
shared->info.tune.atlas.max_h = DEF_ATLAS_H;
|
shared->info.tune.atlas.max_h = DEF_ATLAS_H;
|
||||||
shared->info.tune.atlas.slot_size = DEF_ATLAS_SLOT;
|
|
||||||
|
|
||||||
// per gpu hacks. based on impirical measurement of some known gpu's
|
// per gpu hacks. based on impirical measurement of some known gpu's
|
||||||
s = (const char *)glGetString(GL_RENDERER);
|
s = (const char *)glGetString(GL_RENDERER);
|
||||||
|
@ -711,7 +710,6 @@ evas_gl_common_context_new(void)
|
||||||
GETENVOPT("EVAS_GL_ATLAS_ALLOC_ALPHA_SIZE", atlas.max_alloc_alpha_size, MIN_ATLAS_ALLOC_ALPHA, MAX_ATLAS_ALLOC_ALPHA);
|
GETENVOPT("EVAS_GL_ATLAS_ALLOC_ALPHA_SIZE", atlas.max_alloc_alpha_size, MIN_ATLAS_ALLOC_ALPHA, MAX_ATLAS_ALLOC_ALPHA);
|
||||||
GETENVOPT("EVAS_GL_ATLAS_MAX_W", atlas.max_w, 0, MAX_ATLAS_W);
|
GETENVOPT("EVAS_GL_ATLAS_MAX_W", atlas.max_w, 0, MAX_ATLAS_W);
|
||||||
GETENVOPT("EVAS_GL_ATLAS_MAX_H", atlas.max_h, 0, MAX_ATLAS_H);
|
GETENVOPT("EVAS_GL_ATLAS_MAX_H", atlas.max_h, 0, MAX_ATLAS_H);
|
||||||
GETENVOPT("EVAS_GL_ATLAS_SLOT_SIZE", atlas.slot_size, MIN_ATLAS_SLOT, MAX_ATLAS_SLOT);
|
|
||||||
s = (const char *)getenv("EVAS_GL_GET_PROGRAM_BINARY");
|
s = (const char *)getenv("EVAS_GL_GET_PROGRAM_BINARY");
|
||||||
if (s)
|
if (s)
|
||||||
{
|
{
|
||||||
|
@ -775,7 +773,6 @@ evas_gl_common_context_new(void)
|
||||||
"EVAS_GL_ATLAS_ALLOC_SIZE: %i\n"
|
"EVAS_GL_ATLAS_ALLOC_SIZE: %i\n"
|
||||||
"EVAS_GL_ATLAS_ALLOC_ALPHA_SIZE: %i\n"
|
"EVAS_GL_ATLAS_ALLOC_ALPHA_SIZE: %i\n"
|
||||||
"EVAS_GL_ATLAS_MAX_W x EVAS_GL_ATLAS_MAX_H: %i x %i\n"
|
"EVAS_GL_ATLAS_MAX_W x EVAS_GL_ATLAS_MAX_H: %i x %i\n"
|
||||||
"EVAS_GL_ATLAS_SLOT_SIZE: %i\n"
|
|
||||||
,
|
,
|
||||||
(int)shared->info.max_texture_size, (int)shared->info.max_texture_size,
|
(int)shared->info.max_texture_size, (int)shared->info.max_texture_size,
|
||||||
(int)shared->info.max_texture_units,
|
(int)shared->info.max_texture_units,
|
||||||
|
@ -793,8 +790,7 @@ evas_gl_common_context_new(void)
|
||||||
(int)shared->info.tune.pipes.max,
|
(int)shared->info.tune.pipes.max,
|
||||||
(int)shared->info.tune.atlas.max_alloc_size,
|
(int)shared->info.tune.atlas.max_alloc_size,
|
||||||
(int)shared->info.tune.atlas.max_alloc_alpha_size,
|
(int)shared->info.tune.atlas.max_alloc_alpha_size,
|
||||||
(int)shared->info.tune.atlas.max_w, (int)shared->info.tune.atlas.max_h,
|
(int)shared->info.tune.atlas.max_w, (int)shared->info.tune.atlas.max_h
|
||||||
(int)shared->info.tune.atlas.slot_size
|
|
||||||
);
|
);
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
@ -939,14 +935,11 @@ evas_gl_common_context_free(Evas_Engine_GL_Context *gc)
|
||||||
evas_gl_common_image_free(gc->shared->images->data);
|
evas_gl_common_image_free(gc->shared->images->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 33; i++)
|
for (j = 0; j < 6; j++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < 3; j++)
|
EINA_LIST_FOREACH(gc->shared->tex.atlas[j], l, pt)
|
||||||
{
|
|
||||||
EINA_LIST_FOREACH(gc->shared->tex.atlas[i][j], l, pt)
|
|
||||||
evas_gl_texture_pool_empty(pt);
|
evas_gl_texture_pool_empty(pt);
|
||||||
eina_list_free(gc->shared->tex.atlas[i][j]);
|
eina_list_free(gc->shared->tex.atlas[j]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
EINA_LIST_FOREACH(gc->shared->tex.whole, l, pt)
|
EINA_LIST_FOREACH(gc->shared->tex.whole, l, pt)
|
||||||
evas_gl_texture_pool_empty(pt);
|
evas_gl_texture_pool_empty(pt);
|
||||||
|
|
|
@ -172,14 +172,6 @@ _tex_adjust(Evas_Engine_GL_Context *gc, int *w, int *h)
|
||||||
*h = _nearest_pow2(*h);
|
*h = _nearest_pow2(*h);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
_tex_round_slot(Evas_Engine_GL_Context *gc, int h)
|
|
||||||
{
|
|
||||||
if (!gc->shared->info.tex_npo2)
|
|
||||||
h = _nearest_pow2(h);
|
|
||||||
return (h + gc->shared->info.tune.atlas.slot_size - 1) /
|
|
||||||
gc->shared->info.tune.atlas.slot_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_tex_format_index(GLuint format)
|
_tex_format_index(GLuint format)
|
||||||
|
@ -314,7 +306,6 @@ _pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, GLenum intformat, GLenum
|
||||||
|
|
||||||
if (!no_rounding)
|
if (!no_rounding)
|
||||||
{
|
{
|
||||||
h = _tex_round_slot(gc, h) * gc->shared->info.tune.atlas.slot_size;
|
|
||||||
_tex_adjust(gc, &w, &h);
|
_tex_adjust(gc, &w, &h);
|
||||||
}
|
}
|
||||||
pt->gc = gc;
|
pt->gc = gc;
|
||||||
|
@ -324,6 +315,7 @@ _pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, GLenum intformat, GLenum
|
||||||
pt->format = format;
|
pt->format = format;
|
||||||
pt->dataformat = GL_UNSIGNED_BYTE;
|
pt->dataformat = GL_UNSIGNED_BYTE;
|
||||||
pt->references = 0;
|
pt->references = 0;
|
||||||
|
pt->eina_pool = eina_rectangle_pool_new(w, h);
|
||||||
|
|
||||||
glGenTextures(1, &(pt->texture));
|
glGenTextures(1, &(pt->texture));
|
||||||
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
||||||
|
@ -343,6 +335,8 @@ _pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, GLenum intformat, GLenum
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
glDeleteTextures(1, &(pt->texture));
|
glDeleteTextures(1, &(pt->texture));
|
||||||
|
if (pt->eina_pool)
|
||||||
|
eina_rectangle_pool_free(pt->eina_pool);
|
||||||
free(pt);
|
free(pt);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -366,59 +360,30 @@ _pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, GLenum intformat, GLenum
|
||||||
return pt;
|
return pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Evas_GL_Texture_Alloca *
|
static Eina_Rectangle *
|
||||||
_pool_tex_define(Evas_GL_Texture_Pool *pt, int lastx, int w, int *u, Eina_List *l)
|
_pool_tex_alloc(Evas_GL_Texture_Pool *pt, int w, int h, int *u, int *v)
|
||||||
{
|
{
|
||||||
Evas_GL_Texture_Alloca *napt;
|
Eina_Rectangle *r;
|
||||||
|
r = eina_rectangle_pool_request( pt->eina_pool, w, h);
|
||||||
*u = lastx;
|
if (r)
|
||||||
|
|
||||||
napt = malloc(sizeof (Evas_GL_Texture_Alloca));
|
|
||||||
if (!napt) return NULL;
|
|
||||||
|
|
||||||
napt->tex = NULL;
|
|
||||||
napt->x = lastx;
|
|
||||||
napt->w = w;
|
|
||||||
|
|
||||||
if (l == NULL)
|
|
||||||
pt->allocations = eina_list_append(pt->allocations, napt);
|
|
||||||
else
|
|
||||||
pt->allocations = eina_list_prepend_relative_list(pt->allocations, napt, l);
|
|
||||||
|
|
||||||
return napt;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Evas_GL_Texture_Alloca *
|
|
||||||
_pool_tex_alloc(Evas_GL_Texture_Pool *pt, int w, int h EINA_UNUSED, int *u, int *v)
|
|
||||||
{
|
|
||||||
Evas_GL_Texture_Alloca *apt;
|
|
||||||
Eina_List *l;
|
|
||||||
int lastx = 0;
|
|
||||||
|
|
||||||
*v = 0;
|
|
||||||
|
|
||||||
EINA_LIST_FOREACH(pt->allocations, l, apt)
|
|
||||||
{
|
{
|
||||||
if (apt->x - lastx >= w)
|
*v = r->y;
|
||||||
return _pool_tex_define(pt, lastx, w, u, l);
|
*u = r->x;
|
||||||
|
pt->allocations = eina_list_prepend(pt->allocations, r);
|
||||||
lastx = apt->x + apt->w;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pt->w - lastx >= w)
|
return r;
|
||||||
return _pool_tex_define(pt, lastx, w, u, NULL);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Evas_GL_Texture_Pool *
|
static Evas_GL_Texture_Pool *
|
||||||
_pool_tex_find(Evas_Engine_GL_Context *gc, int w, int h,
|
_pool_tex_find(Evas_Engine_GL_Context *gc, int w, int h,
|
||||||
GLenum intformat, GLenum format, int *u, int *v,
|
GLenum intformat, GLenum format, int *u, int *v,
|
||||||
Evas_GL_Texture_Alloca **apt, int atlas_w)
|
Eina_Rectangle **apt, int atlas_w)
|
||||||
{
|
{
|
||||||
Evas_GL_Texture_Pool *pt = NULL;
|
Evas_GL_Texture_Pool *pt = NULL;
|
||||||
Eina_List *l;
|
Eina_List *l;
|
||||||
int th, th2;
|
int th2;
|
||||||
|
int pool_h;
|
||||||
|
|
||||||
if (atlas_w > gc->shared->info.max_texture_size)
|
if (atlas_w > gc->shared->info.max_texture_size)
|
||||||
atlas_w = gc->shared->info.max_texture_size;
|
atlas_w = gc->shared->info.max_texture_size;
|
||||||
|
@ -429,32 +394,35 @@ _pool_tex_find(Evas_Engine_GL_Context *gc, int w, int h,
|
||||||
pt = _pool_tex_new(gc, w, h, intformat, format);
|
pt = _pool_tex_new(gc, w, h, intformat, format);
|
||||||
if (!pt) return NULL;
|
if (!pt) return NULL;
|
||||||
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, pt);
|
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, pt);
|
||||||
pt->slot = -1;
|
|
||||||
pt->fslot = -1;
|
pt->fslot = -1;
|
||||||
pt->whole = 1;
|
pt->whole = 1;
|
||||||
*apt = _pool_tex_alloc(pt, w, h, u, v);
|
*apt = _pool_tex_alloc(pt, w, h, u, v);
|
||||||
return pt;
|
return pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
th = _tex_round_slot(gc, h);
|
|
||||||
th2 = _tex_format_index(intformat);
|
th2 = _tex_format_index(intformat);
|
||||||
EINA_LIST_FOREACH(gc->shared->tex.atlas[th][th2], l, pt)
|
EINA_LIST_FOREACH(gc->shared->tex.atlas[th2], l, pt)
|
||||||
{
|
{
|
||||||
if ((*apt = _pool_tex_alloc(pt, w, h, u, v)) != NULL)
|
if ((*apt = _pool_tex_alloc(pt, w, h, u, v)) != NULL)
|
||||||
{
|
{
|
||||||
gc->shared->tex.atlas[th][th2] =
|
gc->shared->tex.atlas[th2] =
|
||||||
eina_list_remove_list(gc->shared->tex.atlas[th][th2], l);
|
eina_list_remove_list(gc->shared->tex.atlas[th2], l);
|
||||||
gc->shared->tex.atlas[th][th2] =
|
gc->shared->tex.atlas[th2] =
|
||||||
eina_list_prepend(gc->shared->tex.atlas[th][th2], pt);
|
eina_list_prepend(gc->shared->tex.atlas[th2], pt);
|
||||||
return pt;
|
return pt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pool_h = atlas_w;
|
||||||
|
if ( h > pool_h || w > atlas_w )
|
||||||
|
{
|
||||||
|
atlas_w = gc->shared->info.tune.atlas.max_w;
|
||||||
|
pool_h = gc->shared->info.tune.atlas.max_h;
|
||||||
|
}
|
||||||
|
pt = _pool_tex_new(gc, atlas_w, pool_h, intformat, format);
|
||||||
|
|
||||||
pt = _pool_tex_new(gc, atlas_w, h, intformat, format);
|
|
||||||
if (!pt) return NULL;
|
if (!pt) return NULL;
|
||||||
gc->shared->tex.atlas[th][th2] =
|
gc->shared->tex.atlas[th2] =
|
||||||
eina_list_prepend(gc->shared->tex.atlas[th][th2], pt);
|
eina_list_prepend(gc->shared->tex.atlas[th2], pt);
|
||||||
pt->slot = th;
|
|
||||||
pt->fslot = th2;
|
pt->fslot = th2;
|
||||||
|
|
||||||
*apt = _pool_tex_alloc(pt, w, h, u, v);
|
*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)
|
||||||
default:
|
default:
|
||||||
/* This need to be adjusted if we do something else than strip allocation */
|
/* This need to be adjusted if we do something else than strip allocation */
|
||||||
w = im->cache_entry.w + TEX_HREP + 2; /* one pixel stop gap and two pixels for the border */
|
w = im->cache_entry.w + TEX_HREP + 2; /* one pixel stop gap and two pixels for the border */
|
||||||
h = im->cache_entry.h + TEX_VREP; /* only one added border for security down */
|
h = im->cache_entry.h + TEX_VREP + 2; /* only one added border for security down */
|
||||||
}
|
}
|
||||||
|
|
||||||
tex->pt = _pool_tex_find(gc, w, h,
|
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)
|
||||||
evas_gl_common_texture_light_free(tex);
|
evas_gl_common_texture_light_free(tex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
tex->apt->tex = tex;
|
|
||||||
tex->x = u + 1;
|
tex->x = u + 1;
|
||||||
tex->y = v + yoffset;
|
tex->y = v + yoffset;
|
||||||
|
|
||||||
|
@ -542,6 +509,7 @@ _pool_tex_render_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, in
|
||||||
pt->dataformat = GL_UNSIGNED_BYTE;
|
pt->dataformat = GL_UNSIGNED_BYTE;
|
||||||
pt->render = 1;
|
pt->render = 1;
|
||||||
pt->references = 0;
|
pt->references = 0;
|
||||||
|
pt->eina_pool = eina_rectangle_pool_new(w, h);
|
||||||
#ifdef GL_GLES
|
#ifdef GL_GLES
|
||||||
# ifndef GL_FRAMEBUFFER
|
# ifndef GL_FRAMEBUFFER
|
||||||
# define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
|
# 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
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
glDeleteTextures(1, &(pt->texture));
|
glDeleteTextures(1, &(pt->texture));
|
||||||
|
if (pt->eina_pool)
|
||||||
|
eina_rectangle_pool_free(pt->eina_pool);
|
||||||
free(pt);
|
free(pt);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -630,6 +600,7 @@ _pool_tex_native_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, in
|
||||||
pt->dataformat = GL_UNSIGNED_BYTE;
|
pt->dataformat = GL_UNSIGNED_BYTE;
|
||||||
pt->references = 0;
|
pt->references = 0;
|
||||||
pt->native = 1;
|
pt->native = 1;
|
||||||
|
pt->eina_pool = eina_rectangle_pool_new(w, h);
|
||||||
glGenTextures(1, &(pt->texture));
|
glGenTextures(1, &(pt->texture));
|
||||||
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
||||||
glBindTexture(im->native.target, pt->texture);
|
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
|
||||||
|
|
||||||
pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
|
pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
|
||||||
if (!pt) return NULL;
|
if (!pt) return NULL;
|
||||||
h = _tex_round_slot(gc, h) * gc->shared->info.tune.atlas.slot_size;
|
|
||||||
_tex_adjust(gc, &w, &h);
|
_tex_adjust(gc, &w, &h);
|
||||||
pt->gc = gc;
|
pt->gc = gc;
|
||||||
pt->w = w;
|
pt->w = w;
|
||||||
|
@ -708,6 +678,7 @@ _pool_tex_dynamic_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, i
|
||||||
pt->dataformat = GL_UNSIGNED_BYTE;
|
pt->dataformat = GL_UNSIGNED_BYTE;
|
||||||
pt->render = 1;
|
pt->render = 1;
|
||||||
pt->references = 0;
|
pt->references = 0;
|
||||||
|
pt->eina_pool = eina_rectangle_pool_new(w, h);
|
||||||
texinfo.d.num++;
|
texinfo.d.num++;
|
||||||
texinfo.d.pix += pt->w * pt->h;
|
texinfo.d.pix += pt->w * pt->h;
|
||||||
|
|
||||||
|
@ -744,6 +715,8 @@ _pool_tex_dynamic_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, i
|
||||||
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
||||||
glDeleteTextures(1, &(pt->texture));
|
glDeleteTextures(1, &(pt->texture));
|
||||||
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
||||||
|
if (pt->eina_pool)
|
||||||
|
eina_rectangle_pool_free(pt->eina_pool);
|
||||||
free(pt);
|
free(pt);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -788,6 +761,8 @@ error:
|
||||||
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
||||||
glDeleteTextures(1, &(pt->texture));
|
glDeleteTextures(1, &(pt->texture));
|
||||||
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
||||||
|
if (pt->eina_pool)
|
||||||
|
eina_rectangle_pool_free(pt->eina_pool);
|
||||||
free(pt);
|
free(pt);
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -796,7 +771,7 @@ error:
|
||||||
void
|
void
|
||||||
evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt)
|
evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt)
|
||||||
{
|
{
|
||||||
Evas_GL_Texture_Alloca *apt;
|
Eina_Rectangle *apt;
|
||||||
|
|
||||||
if (!pt->gc) return;
|
if (!pt->gc) return;
|
||||||
|
|
||||||
|
@ -858,9 +833,8 @@ evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt)
|
||||||
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
||||||
pt->fb = 0;
|
pt->fb = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EINA_LIST_FREE(pt->allocations, apt)
|
EINA_LIST_FREE(pt->allocations, apt)
|
||||||
free(apt);
|
eina_rectangle_pool_release(apt);
|
||||||
pt->texture = 0;
|
pt->texture = 0;
|
||||||
pt->gc = NULL;
|
pt->gc = NULL;
|
||||||
pt->w = 0;
|
pt->w = 0;
|
||||||
|
@ -881,10 +855,12 @@ pt_unref(Evas_GL_Texture_Pool *pt)
|
||||||
pt->gc->shared->tex.whole =
|
pt->gc->shared->tex.whole =
|
||||||
eina_list_remove(pt->gc->shared->tex.whole, pt);
|
eina_list_remove(pt->gc->shared->tex.whole, pt);
|
||||||
else
|
else
|
||||||
pt->gc->shared->tex.atlas [pt->slot][pt->fslot] =
|
pt->gc->shared->tex.atlas [pt->fslot] =
|
||||||
eina_list_remove(pt->gc->shared->tex.atlas[pt->slot][pt->fslot], pt);
|
eina_list_remove(pt->gc->shared->tex.atlas[pt->fslot], pt);
|
||||||
}
|
}
|
||||||
evas_gl_texture_pool_empty(pt);
|
evas_gl_texture_pool_empty(pt);
|
||||||
|
if (pt->eina_pool)
|
||||||
|
eina_rectangle_pool_free(pt->eina_pool);
|
||||||
free(pt);
|
free(pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -892,7 +868,6 @@ static void
|
||||||
pt_link(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt)
|
pt_link(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt)
|
||||||
{
|
{
|
||||||
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, pt);
|
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, pt);
|
||||||
pt->slot = -1;
|
|
||||||
pt->fslot = -1;
|
pt->fslot = -1;
|
||||||
pt->whole = 1;
|
pt->whole = 1;
|
||||||
pt->references++;
|
pt->references++;
|
||||||
|
@ -1010,6 +985,28 @@ evas_gl_common_texture_upload(Evas_GL_Texture *tex, RGBA_Image *im, unsigned int
|
||||||
1, 1,
|
1, 1,
|
||||||
fmt, tex->pt->dataformat,
|
fmt, tex->pt->dataformat,
|
||||||
(unsigned char *) im->image.data + (((im->cache_entry.h - 1) * im->cache_entry.w) + (im->cache_entry.w - 1)) * bytes_count);
|
(unsigned char *) im->image.data + (((im->cache_entry.h - 1) * im->cache_entry.w) + (im->cache_entry.w - 1)) * bytes_count);
|
||||||
|
//2D packing
|
||||||
|
// ---
|
||||||
|
// xxx
|
||||||
|
// xxx
|
||||||
|
_tex_sub_2d(tex->gc, tex->x, tex->y - 1,
|
||||||
|
im->cache_entry.w, 1,
|
||||||
|
fmt, tex->pt->dataformat,
|
||||||
|
im->image.data);
|
||||||
|
// o
|
||||||
|
// xxx
|
||||||
|
// xxx
|
||||||
|
_tex_sub_2d(tex->gc, tex->x - 1, tex->y - 1,
|
||||||
|
1, 1,
|
||||||
|
fmt, tex->pt->dataformat,
|
||||||
|
im->image.data);
|
||||||
|
// o
|
||||||
|
// xxx
|
||||||
|
// xxx
|
||||||
|
_tex_sub_2d(tex->gc, tex->x + im->cache_entry.w, tex->y - 1,
|
||||||
|
1, 1,
|
||||||
|
fmt, tex->pt->dataformat,
|
||||||
|
im->image.data + (im->cache_entry.w - 1) * bytes_count);
|
||||||
if (tex->gc->shared->info.unpack_row_length)
|
if (tex->gc->shared->info.unpack_row_length)
|
||||||
{
|
{
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, im->cache_entry.w);
|
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)
|
||||||
int lformat;
|
int lformat;
|
||||||
|
|
||||||
tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex->apt);
|
tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex->apt);
|
||||||
pt_unref(tex->pt);
|
if (tex->apt)
|
||||||
tex->alpha = im->cache_entry.flags.alpha;
|
eina_rectangle_pool_release(tex->apt);
|
||||||
|
|
||||||
lformat = _evas_gl_texture_search_format(tex->alpha, tex->gc->shared->info.bgra, im->cache_entry.space);
|
lformat = _evas_gl_texture_search_format(tex->alpha, tex->gc->shared->info.bgra, im->cache_entry.space);
|
||||||
// FIXME: why a 'render' new here ??? Should already have been allocated, quite a weird path.
|
// 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)
|
||||||
tex->gc->shared->info.tune.atlas.max_alloc_size);
|
tex->gc->shared->info.tune.atlas.max_alloc_size);
|
||||||
if (!tex->ptt)
|
if (!tex->ptt)
|
||||||
goto upload;
|
goto upload;
|
||||||
tex->aptt->tex = tex;
|
|
||||||
|
|
||||||
tex->tx = u + 1;
|
tex->tx = u + 1;
|
||||||
tex->ty = v;
|
tex->ty = v;
|
||||||
|
@ -1327,14 +1323,16 @@ evas_gl_common_texture_free(Evas_GL_Texture *tex, Eina_Bool force EINA_UNUSED)
|
||||||
if (tex->pt)
|
if (tex->pt)
|
||||||
{
|
{
|
||||||
tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex->apt);
|
tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex->apt);
|
||||||
free(tex->apt);
|
if (tex->apt)
|
||||||
|
eina_rectangle_pool_release(tex->apt);
|
||||||
tex->apt = NULL;
|
tex->apt = NULL;
|
||||||
pt_unref(tex->pt);
|
pt_unref(tex->pt);
|
||||||
}
|
}
|
||||||
if (tex->ptt)
|
if (tex->ptt)
|
||||||
{
|
{
|
||||||
tex->ptt->allocations = eina_list_remove(tex->ptt->allocations, tex->aptt);
|
tex->ptt->allocations = eina_list_remove(tex->pt->allocations, tex->aptt);
|
||||||
free(tex->aptt);
|
if (tex->aptt)
|
||||||
|
eina_rectangle_pool_release(tex->aptt);
|
||||||
tex->aptt = NULL;
|
tex->aptt = NULL;
|
||||||
pt_unref(tex->ptt);
|
pt_unref(tex->ptt);
|
||||||
}
|
}
|
||||||
|
@ -1366,7 +1364,6 @@ evas_gl_common_texture_alpha_new(Evas_Engine_GL_Context *gc, DATA8 *pixels,
|
||||||
evas_gl_common_texture_light_free(tex);
|
evas_gl_common_texture_light_free(tex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
tex->apt->tex = tex;
|
|
||||||
tex->x = u + 1;
|
tex->x = u + 1;
|
||||||
tex->y = v;
|
tex->y = v;
|
||||||
tex->pt->references++;
|
tex->pt->references++;
|
||||||
|
@ -1435,7 +1432,6 @@ evas_gl_common_texture_yuv_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigne
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, tex->pt);
|
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, tex->pt);
|
||||||
tex->pt->slot = -1;
|
|
||||||
tex->pt->fslot = -1;
|
tex->pt->fslot = -1;
|
||||||
tex->pt->whole = 1;
|
tex->pt->whole = 1;
|
||||||
tex->pt->references++;
|
tex->pt->references++;
|
||||||
|
|
Loading…
Reference in New Issue