forked from enlightenment/efl
1. gustavo';s fuzzy rect implementation for updates. fixed so del's work,
tuned for best performance on my core2 duo desktop - for now. will check more. also make the yuv colorspace code be a bit more robust and fix leak in gl engine with shaders. SVN revision: 30192
This commit is contained in:
parent
a4c53227fb
commit
a730b4be5d
|
@ -1,8 +1,723 @@
|
|||
#include "evas_common.h"
|
||||
|
||||
#ifdef EVAS_RECT_SPLIT
|
||||
|
||||
static const list_node_t list_node_zeroed = {.next = NULL};
|
||||
static const list_t list_zeroed = {.head = NULL, .tail = NULL};
|
||||
|
||||
inline void
|
||||
rect_init(rect_t *r, int x, int y, int w, int h)
|
||||
{
|
||||
r->area = w * h;
|
||||
|
||||
r->left = x;
|
||||
r->top = y;
|
||||
|
||||
r->right = x + w;
|
||||
r->bottom = y + h;
|
||||
|
||||
r->width = w;
|
||||
r->height = h;
|
||||
}
|
||||
|
||||
void
|
||||
rect_print(const rect_t r)
|
||||
{
|
||||
printf("<rect(%d, %d, %d, %d)>", r.left, r.top, r.width, r.height);
|
||||
}
|
||||
|
||||
void
|
||||
rect_list_print(const list_t rects)
|
||||
{
|
||||
list_node_t *node;
|
||||
int len;
|
||||
|
||||
len = 0;
|
||||
for (node = rects.head; node != NULL; node = node->next) len++;
|
||||
|
||||
printf("[");
|
||||
for (node = rects.head; node != NULL; node = node->next)
|
||||
{
|
||||
rect_print(((rect_node_t *)node)->rect);
|
||||
if (node->next)
|
||||
{
|
||||
putchar(',');
|
||||
if (len < 4) putchar(' ');
|
||||
else
|
||||
{
|
||||
putchar('\n');
|
||||
putchar(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("]\n");
|
||||
}
|
||||
|
||||
inline void
|
||||
rect_list_append_node(list_t *rects, list_node_t *node)
|
||||
{
|
||||
if (rects->tail)
|
||||
{
|
||||
rects->tail->next = node;
|
||||
rects->tail = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
rects->head = node;
|
||||
rects->tail = node;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
rect_list_append(list_t *rects, const rect_t r)
|
||||
{
|
||||
rect_node_t *rect_node;
|
||||
|
||||
rect_node = malloc(sizeof(rect_node_t));
|
||||
rect_node->rect = r;
|
||||
rect_node->_lst = list_node_zeroed;
|
||||
|
||||
rect_list_append_node(rects, (list_node_t *)rect_node);
|
||||
}
|
||||
|
||||
inline void
|
||||
rect_list_append_xywh(list_t *rects, int x, int y, int w, int h)
|
||||
{
|
||||
rect_t r;
|
||||
|
||||
rect_init(&r, x, y, w, h);
|
||||
rect_list_append(rects, r);
|
||||
}
|
||||
|
||||
inline void
|
||||
rect_list_concat(list_t *rects, list_t *other)
|
||||
{
|
||||
if (!other->head)
|
||||
return;
|
||||
|
||||
if (rects->tail)
|
||||
{
|
||||
rects->tail->next = other->head;
|
||||
rects->tail = other->tail;
|
||||
}
|
||||
else
|
||||
{
|
||||
rects->head = other->head;
|
||||
rects->tail = other->tail;
|
||||
}
|
||||
*other = list_zeroed;
|
||||
}
|
||||
|
||||
inline list_node_t *
|
||||
rect_list_unlink_next(list_t *rects, list_node_t *parent_node)
|
||||
{
|
||||
list_node_t *node;
|
||||
|
||||
if (parent_node)
|
||||
{
|
||||
node = parent_node->next;
|
||||
parent_node->next = node->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
node = rects->head;
|
||||
rects->head = node->next;
|
||||
}
|
||||
|
||||
if (rects->tail == node) rects->tail = parent_node;
|
||||
*node = list_node_zeroed;
|
||||
return node;
|
||||
}
|
||||
|
||||
inline void
|
||||
rect_list_del_next(list_t *rects, list_node_t *parent_node)
|
||||
{
|
||||
list_node_t *node;
|
||||
|
||||
node = rect_list_unlink_next(rects, parent_node);
|
||||
free(node);
|
||||
}
|
||||
|
||||
void
|
||||
rect_list_clear(list_t *rects)
|
||||
{
|
||||
list_node_t *node;
|
||||
|
||||
node = rects->head;
|
||||
while (node)
|
||||
{
|
||||
list_node_t *aux;
|
||||
|
||||
aux = node->next;
|
||||
free(node);
|
||||
node = aux;
|
||||
}
|
||||
*rects = list_zeroed;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_calc_intra_rect_area(const rect_t a, const rect_t b, int *width, int *height)
|
||||
{
|
||||
int max_left, min_right, max_top, min_bottom;
|
||||
|
||||
if (a.left < b.left) max_left = b.left;
|
||||
else max_left = a.left;
|
||||
|
||||
if (a.right < b.right) min_right = a.right;
|
||||
else min_right = b.right;
|
||||
|
||||
*width = min_right - max_left;
|
||||
|
||||
if (a.top < b.top) max_top = b.top;
|
||||
else max_top = a.top;
|
||||
|
||||
if (a.bottom < b.bottom) min_bottom = a.bottom;
|
||||
else min_bottom = b.bottom;
|
||||
|
||||
*height = min_bottom - max_top;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_split_strict(list_t *dirty, const rect_t current, rect_t r)
|
||||
{
|
||||
int h_1, h_2, w_1, w_2;
|
||||
|
||||
h_1 = current.top - r.top;
|
||||
h_2 = r.bottom - current.bottom;
|
||||
w_1 = current.left - r.left;
|
||||
w_2 = r.right - current.right;
|
||||
|
||||
if (h_1 > 0)
|
||||
{
|
||||
/* .--.r (b) .---.r2
|
||||
* | | | |
|
||||
* .-------.cur (a) .---.r '---'
|
||||
* | | | | -> | | +
|
||||
* | `--' | `---'
|
||||
* `-------'
|
||||
*/
|
||||
rect_list_append_xywh(dirty, r.left, r.top, r.width, h_1);
|
||||
r.height -= h_1;
|
||||
r.top = current.top;
|
||||
}
|
||||
|
||||
if (h_2 > 0)
|
||||
{
|
||||
/* .-------.cur (a)
|
||||
* | .---. | .---.r
|
||||
* | | | | -> | |
|
||||
* `-------' `---' + .---.r2
|
||||
* | | | |
|
||||
* `---'r (b) `---'
|
||||
*/
|
||||
rect_list_append_xywh(dirty, r.left, current.bottom, r.width, h_2);
|
||||
r.height -= h_2;
|
||||
}
|
||||
|
||||
if (w_1 > 0)
|
||||
{
|
||||
/* (b) r .----.cur (a)
|
||||
* .--|-. | .--.r2 .-.r
|
||||
* | | | | -> | | + | |
|
||||
* `--|-' | `--' `-'
|
||||
* `----'
|
||||
*/
|
||||
rect_list_append_xywh(dirty, r.left, r.top, w_1, r.height);
|
||||
/* not necessary to keep these, r (b) will be destroyed */
|
||||
/* r.width -= w_1; */
|
||||
/* r.left = current.left; */
|
||||
}
|
||||
|
||||
if (w_2 > 0)
|
||||
{
|
||||
/* .----.cur (a)
|
||||
* | |
|
||||
* | .-|--.r (b) .-.r .--.r2
|
||||
* | | | | -> | | + | |
|
||||
* | `-|--' `-' `--'
|
||||
* `----'
|
||||
*/
|
||||
rect_list_append_xywh(dirty, current.right, r.top, w_2, r.height);
|
||||
/* not necessary to keep this, r (b) will be destroyed */
|
||||
/* r.width -= w_2; */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rect_list_add_split_strict(list_t *rects, list_node_t *node)
|
||||
{
|
||||
list_t dirty = list_zeroed;
|
||||
list_t new_dirty = list_zeroed;
|
||||
list_node_t *cur_node;
|
||||
|
||||
if (!rects->head)
|
||||
{
|
||||
rect_list_append_node(rects, node);
|
||||
return;
|
||||
}
|
||||
|
||||
rect_list_append_node(&dirty, node);
|
||||
|
||||
cur_node = rects->head;
|
||||
while (dirty.head)
|
||||
{
|
||||
rect_t current;
|
||||
|
||||
if (!cur_node)
|
||||
{
|
||||
rect_list_concat(rects, &dirty);
|
||||
break;
|
||||
}
|
||||
|
||||
current = ((rect_node_t*)cur_node)->rect;
|
||||
|
||||
while (dirty.head)
|
||||
{
|
||||
int intra_width, intra_height;
|
||||
rect_t r;
|
||||
|
||||
r = ((rect_node_t *)dirty.head)->rect;
|
||||
_calc_intra_rect_area(r, current, &intra_width, &intra_height);
|
||||
if ((intra_width == r.width) && (intra_height == r.height))
|
||||
/* .-------.cur
|
||||
* | .---.r|
|
||||
* | | | |
|
||||
* | `---' |
|
||||
* `-------'
|
||||
*/
|
||||
rect_list_del_next(&dirty, NULL);
|
||||
else if ((intra_width <= 0) || (intra_height <= 0))
|
||||
{
|
||||
/* .---.cur .---.r
|
||||
* | | | |
|
||||
* `---+---.r `---+---.cur
|
||||
* | | | |
|
||||
* `---' `---'
|
||||
*/
|
||||
list_node_t *tmp;
|
||||
tmp = rect_list_unlink_next(&dirty, NULL);
|
||||
rect_list_append_node(&new_dirty, tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
_split_strict(&new_dirty, current, r);
|
||||
rect_list_del_next(&dirty, NULL);
|
||||
}
|
||||
}
|
||||
dirty = new_dirty;
|
||||
new_dirty = list_zeroed;
|
||||
|
||||
cur_node = cur_node->next;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_calc_intra_outer_rect_area(const rect_t a, const rect_t b,
|
||||
rect_t *intra, rect_t *outer)
|
||||
{
|
||||
int min_left, max_left, min_right, max_right;
|
||||
int min_top, max_top, min_bottom, max_bottom;
|
||||
|
||||
if (a.left < b.left)
|
||||
{
|
||||
max_left = b.left;
|
||||
min_left = a.left;
|
||||
}
|
||||
else
|
||||
{
|
||||
max_left = a.left;
|
||||
min_left = b.left;
|
||||
}
|
||||
|
||||
if (a.right < b.right)
|
||||
{
|
||||
min_right = a.right;
|
||||
max_right = b.right;
|
||||
}
|
||||
else
|
||||
{
|
||||
min_right = b.right;
|
||||
max_right = a.right;
|
||||
}
|
||||
|
||||
intra->left = max_left;
|
||||
intra->right = min_right;
|
||||
intra->width = min_right - max_left;
|
||||
|
||||
outer->left = min_left;
|
||||
outer->right = max_right;
|
||||
outer->width = max_right - min_left;
|
||||
|
||||
if (a.top < b.top)
|
||||
{
|
||||
max_top = b.top;
|
||||
min_top = a.top;
|
||||
}
|
||||
else
|
||||
{
|
||||
max_top = a.top;
|
||||
min_top = b.top;
|
||||
}
|
||||
|
||||
if (a.bottom < b.bottom)
|
||||
{
|
||||
min_bottom = a.bottom;
|
||||
max_bottom = b.bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
min_bottom = b.bottom;
|
||||
max_bottom = a.bottom;
|
||||
}
|
||||
|
||||
intra->top = max_top;
|
||||
intra->bottom = min_bottom;
|
||||
intra->height = min_bottom - max_top;
|
||||
if ((intra->width > 0) && (intra->height > 0))
|
||||
intra->area = intra->width * intra->height;
|
||||
else
|
||||
intra->area = 0;
|
||||
|
||||
outer->top = min_top;
|
||||
outer->bottom = max_bottom;
|
||||
outer->height = max_bottom - min_top;
|
||||
outer->area = outer->width * outer->height;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
SPLIT_FUZZY_ACTION_NONE,
|
||||
SPLIT_FUZZY_ACTION_SPLIT,
|
||||
SPLIT_FUZZY_ACTION_MERGE
|
||||
};
|
||||
|
||||
static inline int
|
||||
_split_fuzzy(list_t *dirty, const rect_t a, rect_t *b)
|
||||
{
|
||||
int h_1, h_2, w_1, w_2, action;
|
||||
|
||||
h_1 = a.top - b->top;
|
||||
h_2 = b->bottom - a.bottom;
|
||||
w_1 = a.left - b->left;
|
||||
w_2 = b->right - a.right;
|
||||
|
||||
action = SPLIT_FUZZY_ACTION_NONE;
|
||||
|
||||
if (h_1 > 0)
|
||||
{
|
||||
/* .--.r (b) .---.r2
|
||||
* | | | |
|
||||
* .-------.cur (a) .---.r '---'
|
||||
* | | | | -> | | +
|
||||
* | `--' | `---'
|
||||
* `-------'
|
||||
*/
|
||||
rect_list_append_xywh(dirty, b->left, b->top, b->width, h_1);
|
||||
b->height -= h_1;
|
||||
b->top = a.top;
|
||||
action = SPLIT_FUZZY_ACTION_SPLIT;
|
||||
}
|
||||
|
||||
if (h_2 > 0)
|
||||
{
|
||||
/* .-------.cur (a)
|
||||
* | .---. | .---.r
|
||||
* | | | | -> | |
|
||||
* `-------' `---' + .---.r2
|
||||
* | | | |
|
||||
* `---'r (b) `---'
|
||||
*/
|
||||
rect_list_append_xywh(dirty, b->left, a.bottom, b->width, h_2);
|
||||
b->height -= h_2;
|
||||
action = SPLIT_FUZZY_ACTION_SPLIT;
|
||||
}
|
||||
|
||||
if (((w_1 > 0) || (w_2 > 0)) && (a.height == b->height))
|
||||
return SPLIT_FUZZY_ACTION_MERGE;
|
||||
|
||||
if (w_1 > 0)
|
||||
{
|
||||
/* (b) r .----.cur (a)
|
||||
* .--|-. | .--.r2 .-.r
|
||||
* | | | | -> | | + | |
|
||||
* `--|-' | `--' `-'
|
||||
* `----'
|
||||
*/
|
||||
rect_list_append_xywh(dirty, b->left, b->top, w_1, b->height);
|
||||
/* not necessary to keep these, r (b) will be destroyed */
|
||||
/* b->width -= w_1; */
|
||||
/* b->left = a.left; */
|
||||
action = SPLIT_FUZZY_ACTION_SPLIT;
|
||||
}
|
||||
|
||||
if (w_2 > 0)
|
||||
{
|
||||
/* .----.cur (a)
|
||||
* | |
|
||||
* | .-|--.r (b) .-.r .--.r2
|
||||
* | | | | -> | | + | |
|
||||
* | `-|--' `-' `--'
|
||||
* `----'
|
||||
*/
|
||||
rect_list_append_xywh(dirty, a.right, b->top, w_2, b->height);
|
||||
/* not necessary to keep these, r (b) will be destroyed */
|
||||
/* b->width -= w_2; */
|
||||
action = SPLIT_FUZZY_ACTION_SPLIT;
|
||||
}
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
list_node_t *
|
||||
rect_list_add_split_fuzzy(list_t *rects, const rect_t r, int accepted_error)
|
||||
{
|
||||
list_t dirty = list_zeroed;
|
||||
list_node_t *old_last;
|
||||
|
||||
old_last = rects->tail;
|
||||
|
||||
if (!rects->head)
|
||||
{
|
||||
rect_list_append(rects, r);
|
||||
return old_last;
|
||||
}
|
||||
|
||||
rect_list_append(&dirty, r);
|
||||
while (dirty.head)
|
||||
{
|
||||
list_node_t *d_node, *cur_node, *prev_cur_node;
|
||||
int keep_dirty;
|
||||
rect_t r;
|
||||
|
||||
d_node = rect_list_unlink_next(&dirty, NULL);
|
||||
r = ((rect_node_t *)d_node)->rect;
|
||||
|
||||
prev_cur_node = NULL;
|
||||
cur_node = rects->head;
|
||||
keep_dirty = 1;
|
||||
while (cur_node)
|
||||
{
|
||||
int area, action;
|
||||
rect_t current, intra, outer;
|
||||
|
||||
current = ((rect_node_t *)cur_node)->rect;
|
||||
|
||||
_calc_intra_outer_rect_area(r, current, &intra, &outer);
|
||||
area = current.area + r.area - intra.area;
|
||||
|
||||
if ((intra.width == r.width) && (intra.height == r.height))
|
||||
{
|
||||
/* .-------.cur
|
||||
* | .---.r|
|
||||
* | | | |
|
||||
* | `---' |
|
||||
* `-------'
|
||||
*/
|
||||
keep_dirty = 0;
|
||||
break;
|
||||
}
|
||||
else if ((intra.width == current.width) &&
|
||||
(intra.height == current.height))
|
||||
{
|
||||
/* .-------.r
|
||||
* | .---.cur
|
||||
* | | | |
|
||||
* | `---' |
|
||||
* `-------'
|
||||
*/
|
||||
if (old_last == cur_node)
|
||||
old_last = prev_cur_node;
|
||||
cur_node = cur_node->next;
|
||||
rect_list_del_next(rects, prev_cur_node);
|
||||
}
|
||||
else if ((outer.area - area) <= accepted_error)
|
||||
{
|
||||
/* .-----------. bounding box (outer)
|
||||
* |.---. .---.|
|
||||
* ||cur| |r ||
|
||||
* || | | ||
|
||||
* |`---' `---'|
|
||||
* `-----------'
|
||||
* merge them, remove both and add merged
|
||||
*/
|
||||
rect_node_t *n;
|
||||
|
||||
if (old_last == cur_node)
|
||||
old_last = prev_cur_node;
|
||||
|
||||
n = (rect_node_t *)rect_list_unlink_next(rects, prev_cur_node);
|
||||
n->rect = outer;
|
||||
rect_list_append_node(&dirty, (list_node_t *)n);
|
||||
|
||||
keep_dirty = 0;
|
||||
break;
|
||||
}
|
||||
else if (intra.area <= accepted_error)
|
||||
{
|
||||
/* .---.cur .---.r
|
||||
* | | | |
|
||||
* `---+---.r `---+---.cur
|
||||
* | | | |
|
||||
* `---' `---'
|
||||
* no split, no merge
|
||||
*/
|
||||
prev_cur_node = cur_node;
|
||||
cur_node = cur_node->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* split is required */
|
||||
action = _split_fuzzy(&dirty, current, &r);
|
||||
if (action == SPLIT_FUZZY_ACTION_MERGE)
|
||||
{
|
||||
/* horizontal merge is possible: remove both, add merged */
|
||||
rect_node_t *n;
|
||||
|
||||
if (old_last == cur_node)
|
||||
old_last = prev_cur_node;
|
||||
|
||||
n = (rect_node_t *)
|
||||
rect_list_unlink_next(rects, prev_cur_node);
|
||||
|
||||
n->rect.left = outer.left;
|
||||
n->rect.width = outer.width;
|
||||
n->rect.right = outer.right;
|
||||
n->rect.area = outer.width * r.height;
|
||||
rect_list_append_node(&dirty, (list_node_t *)n);
|
||||
}
|
||||
else if (action == SPLIT_FUZZY_ACTION_NONE)
|
||||
{
|
||||
/*
|
||||
* this rect check was totally useless,
|
||||
* should never happen
|
||||
*/
|
||||
/* prev_cur_node = cur_node; */
|
||||
/* cur_node = cur_node->next; */
|
||||
printf("Should not get here!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
keep_dirty = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (keep_dirty) rect_list_append_node(rects, d_node);
|
||||
else free(d_node);
|
||||
}
|
||||
|
||||
return old_last;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_calc_outer_rect_area(const rect_t a, const rect_t b, rect_t *outer)
|
||||
{
|
||||
int min_left, max_right;
|
||||
int min_top, max_bottom;
|
||||
|
||||
if (a.left < b.left) min_left = a.left;
|
||||
else min_left = b.left;
|
||||
|
||||
if (a.right < b.right) max_right = b.right;
|
||||
else max_right = a.right;
|
||||
|
||||
outer->left = min_left;
|
||||
outer->right = max_right;
|
||||
outer->width = max_right - min_left;
|
||||
|
||||
if (a.top < b.top) min_top = a.top;
|
||||
else min_top = b.top;
|
||||
|
||||
if (a.bottom < b.bottom) max_bottom = b.bottom;
|
||||
else max_bottom = a.bottom;
|
||||
|
||||
outer->top = min_top;
|
||||
outer->bottom = max_bottom;
|
||||
outer->height = max_bottom - min_top;
|
||||
|
||||
outer->area = outer->width * outer->height;
|
||||
}
|
||||
|
||||
void
|
||||
rect_list_merge_rects(list_t *rects, list_t *to_merge, int accepted_error)
|
||||
{
|
||||
while (to_merge->head)
|
||||
{
|
||||
list_node_t *node, *parent_node;
|
||||
rect_t r1;
|
||||
int merged;
|
||||
|
||||
r1 = ((rect_node_t *)to_merge->head)->rect;
|
||||
|
||||
merged = 0;
|
||||
parent_node = NULL;
|
||||
node = rects->head;
|
||||
while (node != NULL)
|
||||
{
|
||||
rect_t r2, outer;
|
||||
int area;
|
||||
|
||||
r2 = ((rect_node_t *)node)->rect;
|
||||
|
||||
_calc_outer_rect_area(r1, r2, &outer);
|
||||
area = r1.area + r2.area; /* intra area is taken as 0 */
|
||||
if (outer.area - area <= accepted_error)
|
||||
{
|
||||
/*
|
||||
* remove both r1 and r2, create r3
|
||||
* actually r3 uses r2 instance, saves memory
|
||||
*/
|
||||
rect_node_t *n;
|
||||
|
||||
n = (rect_node_t *)rect_list_unlink_next(rects, parent_node);
|
||||
n->rect = outer;
|
||||
rect_list_append_node(to_merge, (list_node_t *)n);
|
||||
merged = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
parent_node = node;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
if (!merged)
|
||||
{
|
||||
list_node_t *n;
|
||||
n = rect_list_unlink_next(to_merge, NULL);
|
||||
rect_list_append_node(rects, n);
|
||||
}
|
||||
else
|
||||
rect_list_del_next(to_merge, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rect_list_add_split_fuzzy_and_merge(list_t *rects, const rect_t r,
|
||||
int split_accepted_error,
|
||||
int merge_accepted_error)
|
||||
{
|
||||
list_node_t *n;
|
||||
|
||||
n = rect_list_add_split_fuzzy(rects, r, split_accepted_error);
|
||||
if (n && n->next)
|
||||
{
|
||||
list_t to_merge;
|
||||
|
||||
/* split list into 2 segments, already merged and to merge */
|
||||
to_merge.head = n->next;
|
||||
to_merge.tail = rects->tail;
|
||||
rects->tail = n;
|
||||
n->next = NULL;
|
||||
|
||||
rect_list_merge_rects(rects, &to_merge, merge_accepted_error);
|
||||
}
|
||||
}
|
||||
#endif /* EVAS_RECT_SPLIT */
|
||||
|
||||
#define TILE(tb, x, y) ((tb)->tiles.tiles[((y) * (tb)->tiles.w) + (x)])
|
||||
|
||||
#ifdef RECTUPDATE
|
||||
#elif defined(EVAS_RECT_SPLIT)
|
||||
#else
|
||||
static int tilebuf_x_intersect(Tilebuf *tb, int x, int w, int *x1, int *x2, int *x1_fill, int *x2_fill);
|
||||
static int tilebuf_y_intersect(Tilebuf *tb, int y, int h, int *y1, int *y2, int *y1_fill, int *y2_fill);
|
||||
|
@ -36,6 +751,8 @@ evas_common_tilebuf_free(Tilebuf *tb)
|
|||
{
|
||||
#ifdef RECTUPDATE
|
||||
evas_common_regionbuf_free(tb->rb);
|
||||
#elif defined(EVAS_RECT_SPLIT)
|
||||
rect_list_clear(&tb->rects);
|
||||
#else
|
||||
if (tb->tiles.tiles) free(tb->tiles.tiles);
|
||||
#endif
|
||||
|
@ -69,6 +786,25 @@ evas_common_tilebuf_add_redraw(Tilebuf *tb, int x, int y, int w, int h)
|
|||
for (i = 0; i < h; i++)
|
||||
evas_common_regionbuf_span_add(tb->rb, x, x + w - 1, y + i);
|
||||
return 1;
|
||||
#elif defined(EVAS_RECT_SPLIT)
|
||||
rect_t r;
|
||||
if ((w <= 0) || (h <= 0)) return 0;
|
||||
RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
|
||||
if ((w <= 0) || (h <= 0)) return 0;
|
||||
|
||||
x >>= 1;
|
||||
y >>= 1;
|
||||
w += 2;
|
||||
w >>= 1;
|
||||
h += 2;
|
||||
h >>= 1;
|
||||
|
||||
rect_init(&r, x, y, w, h);
|
||||
//fprintf(stderr, "ACCOUNTING: add_redraw: %4d,%4d %3dx%3d\n", x, y, w, h);
|
||||
//testing on my core2 duo desktop - fuzz of 48 is best.
|
||||
#define FUZZ 48
|
||||
rect_list_add_split_fuzzy_and_merge(&tb->rects, r, FUZZ * FUZZ, FUZZ * FUZZ);
|
||||
return 1;
|
||||
#else
|
||||
int tx1, tx2, ty1, ty2, tfx1, tfx2, tfy1, tfy2, xx, yy;
|
||||
int num;
|
||||
|
@ -114,6 +850,50 @@ evas_common_tilebuf_del_redraw(Tilebuf *tb, int x, int y, int w, int h)
|
|||
|
||||
for (i = 0; i < h; i++)
|
||||
evas_common_regionbuf_span_del(tb->rb, x, x + w - 1, y + i);
|
||||
#elif defined(EVAS_RECT_SPLIT)
|
||||
list_node_t *lst;
|
||||
rect_node_t n;
|
||||
|
||||
|
||||
if (!tb->rects.head) return 0;
|
||||
if ((w <= 0) || (h <= 0)) return 0;
|
||||
RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
|
||||
if ((w <= 0) || (h <= 0)) return 0;
|
||||
|
||||
x += 1;
|
||||
y += 1;
|
||||
x >>= 1;
|
||||
y >>= 1;
|
||||
w -= 1;
|
||||
w >>= 1;
|
||||
h -= 1;
|
||||
h >>= 1;
|
||||
|
||||
if ((w <= 0) || (h <= 0)) return 0;
|
||||
|
||||
rect_init(&n.rect, x, y, w, h);
|
||||
//fprintf(stderr, "ACCOUNTING: del_redraw: %4d,%4d %3dx%3d\n", x, y, w, h);
|
||||
|
||||
lst = tb->rects.head;
|
||||
|
||||
n._lst = list_node_zeroed;
|
||||
tb->rects.head = (list_node_t *)&n;
|
||||
tb->rects.tail = (list_node_t *)&n;
|
||||
|
||||
while (lst)
|
||||
{
|
||||
list_node_t *tmp;
|
||||
rect_t r;
|
||||
|
||||
tmp = lst->next;
|
||||
lst->next = NULL;
|
||||
rect_list_add_split_strict(&tb->rects, lst);
|
||||
lst = tmp;
|
||||
}
|
||||
/* remove deleted rectangle */
|
||||
rect_list_unlink_next(&tb->rects, NULL);
|
||||
|
||||
return 0;
|
||||
#else
|
||||
int tx1, tx2, ty1, ty2, tfx1, tfx2, tfy1, tfy2, xx, yy;
|
||||
int num;
|
||||
|
@ -170,6 +950,8 @@ evas_common_tilebuf_clear(Tilebuf *tb)
|
|||
{
|
||||
#ifdef RECTUPDATE
|
||||
evas_common_regionbuf_clear(tb->rb);
|
||||
#elif defined(EVAS_RECT_SPLIT)
|
||||
rect_list_clear(&tb->rects);
|
||||
#else
|
||||
if (!tb->tiles.tiles) return;
|
||||
memset(tb->tiles.tiles, 0, tb->tiles.w * tb->tiles.h * sizeof(Tilebuf_Tile));
|
||||
|
@ -181,6 +963,32 @@ evas_common_tilebuf_get_render_rects(Tilebuf *tb)
|
|||
{
|
||||
#ifdef RECTUPDATE
|
||||
return evas_common_regionbuf_rects_get(tb->rb);
|
||||
#elif defined(EVAS_RECT_SPLIT)
|
||||
|
||||
list_node_t *n;
|
||||
Tilebuf_Rect *rects = NULL;
|
||||
for (n = tb->rects.head; n != NULL; n = n->next) {
|
||||
rect_t cur;
|
||||
Tilebuf_Rect *r;
|
||||
|
||||
cur = ((rect_node_t *)n)->rect;
|
||||
|
||||
r = malloc(sizeof(Tilebuf_Rect));
|
||||
r->_list_data.next = NULL;
|
||||
r->_list_data.prev = NULL;
|
||||
r->_list_data.last = NULL;
|
||||
r->x = cur.left << 1;
|
||||
r->y = cur.top << 1;
|
||||
r->w = cur.width << 1;
|
||||
r->h = cur.height << 1;
|
||||
|
||||
/* fprintf(stderr, "\tclear: %4d,%4d %3dx%3d\n", */
|
||||
/* r->x, r->y, r->w, r->h); */
|
||||
|
||||
rects = evas_object_list_append(rects, r);
|
||||
}
|
||||
return rects;
|
||||
|
||||
#else
|
||||
Tilebuf_Rect *rects = NULL;
|
||||
Tilebuf_Tile *tbt;
|
||||
|
@ -294,6 +1102,8 @@ tilebuf_setup(Tilebuf *tb)
|
|||
if ((tb->outbuf_w <= 0) || (tb->outbuf_h <= 0)) return;
|
||||
#ifdef RECTUPDATE
|
||||
tb->rb = evas_common_regionbuf_new(tb->outbuf_w, tb->outbuf_h);
|
||||
#elif defined(EVAS_RECT_SPLIT)
|
||||
tb->rects = list_zeroed;
|
||||
#else
|
||||
if (tb->tiles.tiles) free(tb->tiles.tiles);
|
||||
tb->tiles.tiles = NULL;
|
||||
|
@ -314,6 +1124,7 @@ tilebuf_setup(Tilebuf *tb)
|
|||
}
|
||||
|
||||
#ifdef RECTUPDATE
|
||||
#elif defined(EVAS_RECT_SPLIT)
|
||||
#else
|
||||
static int
|
||||
tilebuf_x_intersect(Tilebuf *tb, int x, int w, int *x1, int *x2, int *x1_fill, int *x2_fill)
|
||||
|
|
|
@ -531,6 +531,58 @@ struct _RGBA_Gfx_Compositor
|
|||
RGBA_Gfx_Pt_Func (*composite_pixel_mask_pt_get)(int src_flags, RGBA_Image *dst);
|
||||
};
|
||||
|
||||
#define EVAS_RECT_SPLIT 1
|
||||
#ifdef EVAS_RECT_SPLIT
|
||||
typedef struct list_node list_node_t;
|
||||
typedef struct list list_t;
|
||||
typedef struct rect rect_t;
|
||||
typedef struct rect_node rect_node_t;
|
||||
|
||||
struct list_node
|
||||
{
|
||||
struct list_node *next;
|
||||
};
|
||||
|
||||
struct list
|
||||
{
|
||||
struct list_node *head;
|
||||
struct list_node *tail;
|
||||
};
|
||||
|
||||
struct rect
|
||||
{
|
||||
short left;
|
||||
short top;
|
||||
short right;
|
||||
short bottom;
|
||||
short width;
|
||||
short height;
|
||||
int area;
|
||||
};
|
||||
|
||||
struct rect_node
|
||||
{
|
||||
struct list_node _lst;
|
||||
struct rect rect;
|
||||
};
|
||||
|
||||
|
||||
void rect_init(rect_t *r, int x, int y, int w, int h);
|
||||
void rect_list_append_node(list_t *rects, list_node_t *node);
|
||||
void rect_list_append(list_t *rects, const rect_t r);
|
||||
void rect_list_append_xywh(list_t *rects, int x, int y, int w, int h);
|
||||
void rect_list_concat(list_t *rects, list_t *other);
|
||||
list_node_t *rect_list_unlink_next(list_t *rects, list_node_t *parent_node);
|
||||
void rect_list_del_next(list_t *rects, list_node_t *parent_node);
|
||||
void rect_list_clear(list_t *rects);
|
||||
void rect_list_add_split_strict(list_t *rects, list_node_t *node);
|
||||
list_node_t *rect_list_add_split_fuzzy(list_t *rects, const rect_t r, int accepted_error);
|
||||
void rect_list_merge_rects(list_t *rects, list_t *to_merge, int accepted_error);void rect_list_add_split_fuzzy_and_merge(list_t *rects, const rect_t r, int split_accepted_error, int merge_accepted_error);
|
||||
|
||||
void rect_print(const rect_t r);
|
||||
void rect_list_print(const list_t rects);
|
||||
#endif /* EVAS_RECT_SPLIT */
|
||||
|
||||
struct _Tilebuf
|
||||
{
|
||||
int outbuf_w;
|
||||
|
@ -542,6 +594,8 @@ struct _Tilebuf
|
|||
|
||||
#ifdef RECTUPDATE
|
||||
Regionbuf *rb;
|
||||
#elif defined(EVAS_RECT_SPLIT)
|
||||
list_t rects;
|
||||
#else
|
||||
struct {
|
||||
int w, h;
|
||||
|
|
|
@ -86,6 +86,10 @@ struct _Evas_GL_Context
|
|||
Evas_List *tex_pool;
|
||||
|
||||
RGBA_Draw_Context *dc;
|
||||
|
||||
struct {
|
||||
GLhandleARB prog, fshad;
|
||||
} yuv422p;
|
||||
};
|
||||
|
||||
struct _Evas_GL_Texture
|
||||
|
@ -96,7 +100,6 @@ struct _Evas_GL_Texture
|
|||
int uw, uh;
|
||||
|
||||
GLuint texture, texture2, texture3;
|
||||
GLhandleARB prog;
|
||||
|
||||
unsigned char smooth : 1;
|
||||
unsigned char changed : 1;
|
||||
|
@ -106,6 +109,7 @@ struct _Evas_GL_Texture
|
|||
unsigned char opt : 1;
|
||||
|
||||
int references;
|
||||
GLhandleARB prog;
|
||||
};
|
||||
|
||||
struct _Evas_GL_Image
|
||||
|
|
|
@ -39,6 +39,41 @@ evas_gl_common_context_new(void)
|
|||
gc->change.clip = 1;
|
||||
gc->change.buf = 1;
|
||||
gc->change.other = 1;
|
||||
|
||||
gc->yuv422p.prog = glCreateProgramObjectARB();
|
||||
// on an nv 6600gt this is fast - but on a 5500fx its DEAD SLOW!!!!!
|
||||
// if (!gc->ext.arb_texture_non_power_of_two) return NULL;
|
||||
/* BEGIN LEAK */
|
||||
gc->yuv422p.fshad = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
|
||||
{
|
||||
const char *code =
|
||||
"uniform sampler2D ytex, utex, vtex;\n"
|
||||
"void main(void) {\n"
|
||||
" float r, g, b, y, u, v;\n"
|
||||
" y = texture2D(ytex, gl_TexCoord[0].st).r;\n"
|
||||
" u = texture2D(utex, gl_TexCoord[0].st).r;\n"
|
||||
" v = texture2D(vtex, gl_TexCoord[0].st).r;\n"
|
||||
" y = (y - 0.0625) * 1.164;\n"
|
||||
" u = u - 0.5;\n"
|
||||
" v = v - 0.5;\n"
|
||||
" r = y + (1.402 * v);\n"
|
||||
" g = y - (0.34414 * u) - (0.71414 * v);\n"
|
||||
" b = y + (1.772 * u);\n"
|
||||
" gl_FragColor = vec4(r * gl_Color.r * gl_Color.a, g * gl_Color.g * gl_Color.a, b * gl_Color.b * gl_Color.a, gl_Color.a);\n"
|
||||
"}\n";
|
||||
glShaderSourceARB(gc->yuv422p.fshad, 1, &code, NULL);
|
||||
}
|
||||
glCompileShaderARB(gc->yuv422p.fshad);
|
||||
glAttachObjectARB(gc->yuv422p.prog, gc->yuv422p.fshad);
|
||||
/* END LEAK - something in the above leaks... beats me what. */
|
||||
glLinkProgramARB(gc->yuv422p.prog);
|
||||
|
||||
glUseProgramObjectARB(gc->yuv422p.prog);
|
||||
glUniform1iARB(glGetUniformLocationARB(gc->yuv422p.prog, "ytex"), 0);
|
||||
glUniform1iARB(glGetUniformLocationARB(gc->yuv422p.prog, "utex"), 1);
|
||||
glUniform1iARB(glGetUniformLocationARB(gc->yuv422p.prog, "vtex"), 2);
|
||||
glUseProgramObjectARB(0);
|
||||
|
||||
return gc;
|
||||
}
|
||||
|
||||
|
@ -47,7 +82,15 @@ evas_gl_common_context_free(Evas_GL_Context *gc)
|
|||
{
|
||||
gc->references--;
|
||||
if (gc->references > 0) return;
|
||||
|
||||
if (gc->yuv422p.fshad)
|
||||
{
|
||||
glDeleteObjectARB(gc->yuv422p.fshad);
|
||||
}
|
||||
if (gc->yuv422p.prog)
|
||||
{
|
||||
glDeleteObjectARB(gc->yuv422p.prog);
|
||||
}
|
||||
|
||||
if (gc == _evas_gl_common_context) _evas_gl_common_context = NULL;
|
||||
free(gc);
|
||||
}
|
||||
|
|
|
@ -105,6 +105,7 @@ evas_gl_common_image_new_from_data(Evas_GL_Context *gc, int w, int h, int *data,
|
|||
im->cached = 1;
|
||||
gc->images = evas_list_prepend(gc->images, im);
|
||||
*/
|
||||
printf("new im cs = %i\n", im->cs.space);
|
||||
return im;
|
||||
}
|
||||
|
||||
|
@ -166,6 +167,33 @@ evas_gl_common_image_new(Evas_GL_Context *gc, int w, int h, int alpha, int cspac
|
|||
free(im);
|
||||
return NULL;
|
||||
}
|
||||
im->gc = gc;
|
||||
im->cs.space = cspace;
|
||||
if (alpha)
|
||||
im->im->flags |= RGBA_IMAGE_HAS_ALPHA;
|
||||
else
|
||||
im->im->flags &= ~RGBA_IMAGE_HAS_ALPHA;
|
||||
switch (cspace)
|
||||
{
|
||||
case EVAS_COLORSPACE_ARGB8888:
|
||||
// if (data)
|
||||
// memcpy(im->im->image->data, data, w * h * sizeof(DATA32));
|
||||
break;
|
||||
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
||||
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
||||
evas_common_image_surface_dealloc(im->im->image);
|
||||
im->im->image->data = NULL;
|
||||
// if (im->tex) evas_gl_common_texture_free(im->tex);
|
||||
im->tex = NULL;
|
||||
im->cs.no_free = 0;
|
||||
im->cs.data = calloc(1, im->im->image->h * sizeof(unsigned char *) * 2);
|
||||
// if ((data) && (im->cs.data))
|
||||
// memcpy(im->cs.data, data, im->im->image->h * sizeof(unsigned char *) * 2);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
return im;
|
||||
}
|
||||
|
||||
|
@ -215,6 +243,7 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy
|
|||
r = g = b = a = 255;
|
||||
}
|
||||
evas_common_load_image_data_from_file(im->im);
|
||||
/* leak in this switch */
|
||||
switch (im->cs.space)
|
||||
{
|
||||
case EVAS_COLORSPACE_ARGB8888:
|
||||
|
@ -251,7 +280,9 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy
|
|||
im->dirty = 0;
|
||||
}
|
||||
if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data)))
|
||||
im->tex = evas_gl_common_ycbcr601pl_texture_new(gc, im->cs.data, im->im->image->w, im->im->image->h, smooth);
|
||||
{
|
||||
im->tex = evas_gl_common_ycbcr601pl_texture_new(gc, im->cs.data, im->im->image->w, im->im->image->h, smooth);
|
||||
}
|
||||
if (!im->tex) return;
|
||||
ow = (dw * im->tex->tw) / sw;
|
||||
oh = (dh * im->tex->th) / sh;
|
||||
|
@ -270,11 +301,13 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy
|
|||
ty2 = (double)(sy + sh) / (double)(im->tex->h);
|
||||
}
|
||||
evas_gl_common_context_texture_set(gc, im->tex, smooth, ow, oh);
|
||||
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
|
||||
// if ((!im->tex->have_mipmaps) && (smooth) &&
|
||||
// ((im->tex->uw < im->tex->tw) || (im->tex->uh < im->tex->th)) &&
|
||||
// (!gc->ext.sgis_generate_mipmap))
|
||||
|
|
|
@ -296,8 +296,16 @@ evas_gl_common_texture_free(Evas_GL_Texture *tex)
|
|||
glDeleteTextures(1, &tex->texture);
|
||||
if (tex->texture2) glDeleteTextures(1, &tex->texture2);
|
||||
if (tex->texture3) glDeleteTextures(1, &tex->texture3);
|
||||
/*
|
||||
if (tex->fshad)
|
||||
{
|
||||
glDeleteObjectARB(tex->fshad);
|
||||
}
|
||||
if (tex->prog)
|
||||
glDeleteObjectARB(tex->prog);
|
||||
{
|
||||
glDeleteObjectARB(tex->prog);
|
||||
}
|
||||
*/
|
||||
free(tex);
|
||||
}
|
||||
|
||||
|
@ -418,7 +426,6 @@ evas_gl_common_ycbcr601pl_texture_new(Evas_GL_Context *gc, unsigned char **rows,
|
|||
Evas_GL_Texture *tex;
|
||||
int im_w, im_h, tw, th, y;
|
||||
GLenum texfmt;
|
||||
GLhandleARB fshad;
|
||||
|
||||
// on an nv 6600gt this is fast - but on a 5500fx its DEAD SLOW!!!!!
|
||||
// if (!gc->ext.arb_texture_non_power_of_two) return NULL;
|
||||
|
@ -436,40 +443,13 @@ evas_gl_common_ycbcr601pl_texture_new(Evas_GL_Context *gc, unsigned char **rows,
|
|||
tex->references = 0;
|
||||
tex->smooth = 0;
|
||||
tex->changed = 1;
|
||||
|
||||
tex->prog = glCreateProgramObjectARB();
|
||||
fshad = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
|
||||
|
||||
{
|
||||
const char *code =
|
||||
"uniform sampler2D ytex, utex, vtex;\n"
|
||||
"void main(void) {\n"
|
||||
" float r, g, b, y, u, v;\n"
|
||||
" y = texture2D(ytex, gl_TexCoord[0].st).r;\n"
|
||||
" u = texture2D(utex, gl_TexCoord[0].st).r;\n"
|
||||
" v = texture2D(vtex, gl_TexCoord[0].st).r;\n"
|
||||
" y = (y - 0.0625) * 1.164;\n"
|
||||
" u = u - 0.5;\n"
|
||||
" v = v - 0.5;\n"
|
||||
" r = y + (1.402 * v);\n"
|
||||
" g = y - (0.34414 * u) - (0.71414 * v);\n"
|
||||
" b = y + (1.772 * u);\n"
|
||||
" gl_FragColor = vec4(r * gl_Color.r * gl_Color.a, g * gl_Color.g * gl_Color.a, b * gl_Color.b * gl_Color.a, gl_Color.a);\n"
|
||||
"}\n";
|
||||
glShaderSourceARB(fshad, 1, &code, NULL);
|
||||
}
|
||||
|
||||
glCompileShaderARB(fshad);
|
||||
glAttachObjectARB(tex->prog, fshad);
|
||||
glLinkProgramARB(tex->prog);
|
||||
tex->prog = gc->yuv422p.prog;
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
texfmt = GL_LUMINANCE;
|
||||
|
||||
glUseProgramObjectARB(tex->prog);
|
||||
glUniform1iARB(glGetUniformLocationARB(tex->prog, "ytex"), 0);
|
||||
glUniform1iARB(glGetUniformLocationARB(tex->prog, "utex"), 1);
|
||||
glUniform1iARB(glGetUniformLocationARB(tex->prog, "vtex"), 2);
|
||||
|
||||
glGenTextures(1, &(tex->texture));
|
||||
glBindTexture(GL_TEXTURE_2D, tex->texture);
|
||||
|
|
|
@ -718,6 +718,9 @@ eng_image_size_set(void *data, void *image, int w, int h)
|
|||
if (!image) return NULL;
|
||||
eng_window_use(re->win);
|
||||
im_old = image;
|
||||
if ((eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422P601_PL) ||
|
||||
(eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422P709_PL))
|
||||
w &= ~0x1;
|
||||
if ((im_old) && (im_old->im->image->w == w) && (im_old->im->image->h == h))
|
||||
return image;
|
||||
if (im_old)
|
||||
|
|
|
@ -512,6 +512,7 @@ eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha,
|
|||
break;
|
||||
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
||||
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
||||
w &= ~0x1;
|
||||
im->image->w = w;
|
||||
im->image->h = h;
|
||||
evas_common_image_surface_alloc(im->image);
|
||||
|
@ -546,6 +547,7 @@ eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int
|
|||
break;
|
||||
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
||||
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
||||
w &= ~0x1;
|
||||
im = evas_common_image_create(w, h);
|
||||
im->cs.data = calloc(1, im->image->h * sizeof(unsigned char *) * 2);
|
||||
if ((image_data) && (im->cs.data))
|
||||
|
@ -582,13 +584,22 @@ eng_image_size_set(void *data, void *image, int w, int h)
|
|||
RGBA_Image *im, *im_old;
|
||||
|
||||
im_old = image;
|
||||
if ((im_old->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
|
||||
(im_old->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
|
||||
w &= ~0x1;
|
||||
if ((im_old) && (im_old->image->w == w) && (im_old->image->h == h))
|
||||
return image;
|
||||
im = evas_common_image_create(w, h);
|
||||
if (!im) return im_old;
|
||||
if (im_old)
|
||||
{
|
||||
im->cs.space = im_old->cs.space;
|
||||
im->flags = im_old->flags;
|
||||
/*
|
||||
im->cs.no_free = 0;
|
||||
if ((im_old->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
|
||||
(im_old->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
|
||||
im->cs.data = calloc(1, im->image->h * sizeof(unsigned char *) * 2);
|
||||
/*
|
||||
evas_common_load_image_data_from_file(im_old);
|
||||
evas_common_image_colorspace_normalize(im);
|
||||
if (im_old->image->data)
|
||||
|
@ -596,8 +607,9 @@ eng_image_size_set(void *data, void *image, int w, int h)
|
|||
evas_common_blit_rectangle(im_old, im, 0, 0, w, h, 0, 0);
|
||||
evas_common_cpu_end_opt();
|
||||
}
|
||||
*/
|
||||
*/
|
||||
evas_common_image_unref(im_old);
|
||||
evas_common_image_colorspace_dirty(im);
|
||||
}
|
||||
return im;
|
||||
}
|
||||
|
|
|
@ -559,7 +559,7 @@ evas_software_x11_outbuf_debug_show(Outbuf * buf, Drawable draw, int x, int y, i
|
|||
XGetWindowAttributes(buf->priv.x.disp, root, &wattr);
|
||||
screen_num = XScreenNumberOfScreen(wattr.screen);
|
||||
}
|
||||
for (i = 0; i < 10; i++)
|
||||
for (i = 0; i < 20; i++)
|
||||
{
|
||||
XImage *xim;
|
||||
|
||||
|
@ -567,19 +567,19 @@ evas_software_x11_outbuf_debug_show(Outbuf * buf, Drawable draw, int x, int y, i
|
|||
BlackPixel(buf->priv.x.disp, screen_num));
|
||||
XFillRectangle(buf->priv.x.disp, draw, buf->priv.x.gc, x, y, w, h);
|
||||
XSync(buf->priv.x.disp, False);
|
||||
xim =
|
||||
XGetImage(buf->priv.x.disp, draw, x, y, w, h, 0xffffffff, ZPixmap);
|
||||
if (xim)
|
||||
XDestroyImage(xim);
|
||||
// xim =
|
||||
// XGetImage(buf->priv.x.disp, draw, x, y, w, h, 0xffffffff, ZPixmap);
|
||||
// if (xim)
|
||||
// XDestroyImage(xim);
|
||||
XSync(buf->priv.x.disp, False);
|
||||
XSetForeground(buf->priv.x.disp, buf->priv.x.gc,
|
||||
WhitePixel(buf->priv.x.disp, screen_num));
|
||||
XFillRectangle(buf->priv.x.disp, draw, buf->priv.x.gc, x, y, w, h);
|
||||
XSync(buf->priv.x.disp, False);
|
||||
xim =
|
||||
XGetImage(buf->priv.x.disp, draw, x, y, w, h, 0xffffffff, ZPixmap);
|
||||
if (xim)
|
||||
XDestroyImage(xim);
|
||||
// xim =
|
||||
// XGetImage(buf->priv.x.disp, draw, x, y, w, h, 0xffffffff, ZPixmap);
|
||||
// if (xim)
|
||||
// XDestroyImage(xim);
|
||||
XSync(buf->priv.x.disp, False);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -645,6 +645,9 @@ eng_image_size_set(void *data, void *image, int w, int h)
|
|||
|
||||
if (!image) return NULL;
|
||||
im_old = image;
|
||||
if ((im_old->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
|
||||
(im_old->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
|
||||
w &= ~0x1;
|
||||
if ((im_old) && (im_old->w == w) && (im_old->h == h))
|
||||
return image;
|
||||
if ((w <= 0) || (h <= 0))
|
||||
|
|
Loading…
Reference in New Issue