forked from enlightenment/efl
clean up map - move to #included worker and add mmx - just copied from normal
image scaler actually. SVN revision: 43336
This commit is contained in:
parent
e867666096
commit
422faf09fd
|
@ -631,6 +631,9 @@ evas_render_updates_internal(Evas *e,
|
||||||
#endif
|
#endif
|
||||||
if (!((obj->func->can_map) && (obj->func->can_map(obj))) &&
|
if (!((obj->func->can_map) && (obj->func->can_map(obj))) &&
|
||||||
((obj->cur.map) && (obj->cur.map->count == 4) && (obj->cur.usemap)))
|
((obj->cur.map) && (obj->cur.map->count == 4) && (obj->cur.usemap)))
|
||||||
|
{
|
||||||
|
if ((obj->cur.map->normal_geometry.w > 0) &&
|
||||||
|
(obj->cur.map->normal_geometry.h > 0))
|
||||||
{
|
{
|
||||||
const Evas_Map_Point *p, *p_end;
|
const Evas_Map_Point *p, *p_end;
|
||||||
RGBA_Map_Point pts[4], *pt;
|
RGBA_Map_Point pts[4], *pt;
|
||||||
|
@ -694,6 +697,7 @@ evas_render_updates_internal(Evas *e,
|
||||||
obj->cur.map->surface);
|
obj->cur.map->surface);
|
||||||
obj->cur.map->surface = NULL;
|
obj->cur.map->surface = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
obj->func->render(obj,
|
obj->func->render(obj,
|
||||||
|
|
|
@ -108,7 +108,8 @@ evas_scale_smooth_scaler_noscale.c \
|
||||||
evas_scale_smooth_scaler_up.c \
|
evas_scale_smooth_scaler_up.c \
|
||||||
evas_scale_span.h \
|
evas_scale_span.h \
|
||||||
evas_pipe.h \
|
evas_pipe.h \
|
||||||
evas_intl_utils.h
|
evas_intl_utils.h \
|
||||||
|
evas_map_image_internal.c
|
||||||
|
|
||||||
libevas_engine_common_la_DEPENDENCIES = \
|
libevas_engine_common_la_DEPENDENCIES = \
|
||||||
$(top_builddir)/config.h
|
$(top_builddir)/config.h
|
||||||
|
|
|
@ -5,6 +5,13 @@
|
||||||
#include "evas_common.h"
|
#include "evas_common.h"
|
||||||
#include "evas_blend_private.h"
|
#include "evas_blend_private.h"
|
||||||
|
|
||||||
|
#ifdef BUILD_SCALE_SMOOTH
|
||||||
|
# ifdef BUILD_MMX
|
||||||
|
# undef SCALE_USING_MMX
|
||||||
|
# define SCALE_USING_MMX
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define FPI 8
|
#define FPI 8
|
||||||
#define FPI1 (1 << (FPI))
|
#define FPI1 (1 << (FPI))
|
||||||
#define FPIH (1 << (FPI - 1))
|
#define FPIH (1 << (FPI - 1))
|
||||||
|
@ -26,12 +33,6 @@ struct _Line
|
||||||
Span span[2];
|
Span span[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
|
||||||
evas_common_map4_rgba_internal(RGBA_Image *src, RGBA_Image *dst,
|
|
||||||
RGBA_Draw_Context *dc,
|
|
||||||
RGBA_Map_Point *p,
|
|
||||||
int smooth, int level);
|
|
||||||
|
|
||||||
static FPc
|
static FPc
|
||||||
_interp(int x1, int x2, int p, FPc u1, FPc u2)
|
_interp(int x1, int x2, int p, FPc u1, FPc u2)
|
||||||
{
|
{
|
||||||
|
@ -63,47 +64,6 @@ _limit(Span *s, int c1, int c2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void
|
|
||||||
evas_common_map4_rgba(RGBA_Image *src, RGBA_Image *dst,
|
|
||||||
RGBA_Draw_Context *dc,
|
|
||||||
RGBA_Map_Point *p,
|
|
||||||
int smooth, int level)
|
|
||||||
{
|
|
||||||
Cutout_Rects *rects;
|
|
||||||
Cutout_Rect *r;
|
|
||||||
int c, cx, cy, cw, ch;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (src->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
|
|
||||||
evas_cache_image_load_data(&src->cache_entry);
|
|
||||||
evas_common_image_colorspace_normalize(src);
|
|
||||||
if (!src->image.data) return;
|
|
||||||
if (!dc->cutout.rects)
|
|
||||||
{
|
|
||||||
evas_common_map4_rgba_internal(src, dst, dc, p, smooth, level);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* save out clip info */
|
|
||||||
c = dc->clip.use; cx = dc->clip.x; cy = dc->clip.y; cw = dc->clip.w; ch = dc->clip.h;
|
|
||||||
evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
|
|
||||||
/* our clip is 0 size.. abort */
|
|
||||||
if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
|
|
||||||
{
|
|
||||||
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
rects = evas_common_draw_context_apply_cutouts(dc);
|
|
||||||
for (i = 0; i < rects->active; ++i)
|
|
||||||
{
|
|
||||||
r = rects->rects + i;
|
|
||||||
evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
|
|
||||||
evas_common_map4_rgba_internal(src, dst, dc, p, smooth, level);
|
|
||||||
}
|
|
||||||
evas_common_draw_context_apply_clear_cutouts(rects);
|
|
||||||
/* restore clip info */
|
|
||||||
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 12.63 % of time - this can improve
|
// 12.63 % of time - this can improve
|
||||||
static void
|
static void
|
||||||
_calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy, int cw, int ch)
|
_calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy, int cw, int ch)
|
||||||
|
@ -279,249 +239,78 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 66.74 % of time
|
#ifdef BUILD_SCALE_SMOOTH
|
||||||
static void
|
# ifdef BUILD_MMX
|
||||||
evas_common_map4_rgba_internal(RGBA_Image *src, RGBA_Image *dst,
|
# undef FUNC_NAME
|
||||||
|
# define FUNC_NAME evas_common_map4_rgba_internal_mmx
|
||||||
|
# undef SCALE_USING_MMX
|
||||||
|
# define SCALE_USING_MMX
|
||||||
|
# include "evas_map_image_internal.c"
|
||||||
|
# endif
|
||||||
|
# ifdef BUILD_C
|
||||||
|
# undef FUNC_NAME
|
||||||
|
# define FUNC_NAME evas_common_map4_rgba_internal
|
||||||
|
# undef SCALE_USING_MMX
|
||||||
|
# include "evas_map_image_internal.c"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
evas_common_map4_rgba(RGBA_Image *src, RGBA_Image *dst,
|
||||||
RGBA_Draw_Context *dc,
|
RGBA_Draw_Context *dc,
|
||||||
RGBA_Map_Point *p,
|
RGBA_Map_Point *p,
|
||||||
int smooth, int level)
|
int smooth, int level)
|
||||||
{
|
{
|
||||||
int i;
|
#ifdef BUILD_MMX
|
||||||
|
int mmx, sse, sse2;
|
||||||
|
#endif
|
||||||
|
Cutout_Rects *rects;
|
||||||
|
Cutout_Rect *r;
|
||||||
int c, cx, cy, cw, ch;
|
int c, cx, cy, cw, ch;
|
||||||
int ytop, ybottom, ystart, yend, y, yp, sw, sh, shp, swp, direct;
|
int i;
|
||||||
Line *spans;
|
|
||||||
DATA32 *buf, *sp;
|
|
||||||
RGBA_Gfx_Func func;
|
|
||||||
|
|
||||||
// get the clip
|
if (src->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
|
||||||
|
evas_cache_image_load_data(&src->cache_entry);
|
||||||
|
evas_common_image_colorspace_normalize(src);
|
||||||
|
if (!src->image.data) return;
|
||||||
|
evas_common_cpu_can_do(&mmx, &sse, &sse2);
|
||||||
|
|
||||||
|
if (!dc->cutout.rects)
|
||||||
|
{
|
||||||
|
#ifdef BUILD_MMX
|
||||||
|
if (mmx)
|
||||||
|
evas_common_map4_rgba_internal_mmx(src, dst, dc, p, smooth, level);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#ifdef BUILD_C
|
||||||
|
evas_common_map4_rgba_internal(src, dst, dc, p, smooth, level);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* save out clip info */
|
||||||
c = dc->clip.use; cx = dc->clip.x; cy = dc->clip.y; cw = dc->clip.w; ch = dc->clip.h;
|
c = dc->clip.use; cx = dc->clip.x; cy = dc->clip.y; cw = dc->clip.w; ch = dc->clip.h;
|
||||||
if (!c)
|
evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
|
||||||
|
/* our clip is 0 size.. abort */
|
||||||
|
if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
|
||||||
{
|
{
|
||||||
cx = 0;
|
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
|
||||||
cy = 0;
|
return;
|
||||||
cw = dst->cache_entry.w;
|
|
||||||
ch = dst->cache_entry.h;
|
|
||||||
}
|
}
|
||||||
|
rects = evas_common_draw_context_apply_cutouts(dc);
|
||||||
// find y yop line and y bottom line
|
for (i = 0; i < rects->active; ++i)
|
||||||
ytop = p[0].y;
|
|
||||||
for (i = 1; i < 4; i++)
|
|
||||||
{
|
{
|
||||||
if (p[i].y < ytop) ytop = p[i].y;
|
r = rects->rects + i;
|
||||||
}
|
evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
|
||||||
ybottom = p[0].y;
|
#ifdef BUILD_MMX
|
||||||
for (i = 1; i < 4; i++)
|
if (mmx)
|
||||||
{
|
evas_common_map4_rgba_internal_mmx(src, dst, dc, p, smooth, level);
|
||||||
if (p[i].y > ybottom) ybottom = p[i].y;
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert to screen space from fixed point
|
|
||||||
ytop = ytop >> FP;
|
|
||||||
ybottom = ybottom >> FP;
|
|
||||||
|
|
||||||
// if its outside the clip vertical bounds - don't bother
|
|
||||||
if ((ytop >= (cy + ch)) || (ybottom < cy)) return;
|
|
||||||
|
|
||||||
// limit to the clip vertical bounds
|
|
||||||
if (ytop < cy) ystart = cy;
|
|
||||||
else ystart = ytop;
|
|
||||||
if (ybottom >= (cy + ch)) yend = (cy + ch) - 1;
|
|
||||||
else yend = ybottom;
|
|
||||||
|
|
||||||
// get some source image information
|
|
||||||
sp = src->image.data;
|
|
||||||
sw = src->cache_entry.w;
|
|
||||||
swp = sw << (FP + FPI);
|
|
||||||
shp = src->cache_entry.h << (FP + FPI);
|
|
||||||
|
|
||||||
// limit u,v coords of points to be within the source image
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if (p[i].u < 0) p[i].u = 0;
|
|
||||||
else if (p[i].u > (src->cache_entry.w << FP))
|
|
||||||
p[i].u = src->cache_entry.w << FP;
|
|
||||||
|
|
||||||
if (p[i].v < 0) p[i].v = 0;
|
|
||||||
else if (p[i].v > (src->cache_entry.h << FP))
|
|
||||||
p[i].v = src->cache_entry.h << FP;
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate some spans to hold out span list
|
|
||||||
spans = alloca((yend - ystart + 1) * sizeof(Line));
|
|
||||||
if (!spans) return;
|
|
||||||
memset(spans, 0, (yend - ystart + 1) * sizeof(Line));
|
|
||||||
|
|
||||||
// calculate the spans list
|
|
||||||
_calc_spans(p, spans, ystart, yend, cx, cy, cw, ch);
|
|
||||||
|
|
||||||
// walk through spans and render
|
|
||||||
|
|
||||||
// if operation is solid, bypass buf and draw func and draw direct to dst
|
|
||||||
direct = 0;
|
|
||||||
if ((!src->cache_entry.flags.alpha) && (!dst->cache_entry.flags.alpha) &&
|
|
||||||
(!dc->mul.use))
|
|
||||||
direct = 1;
|
|
||||||
else
|
else
|
||||||
{
|
#endif
|
||||||
buf = alloca(cw * sizeof(DATA32));
|
#ifdef BUILD_C
|
||||||
if (!buf) return;
|
evas_common_map4_rgba_internal(src, dst, dc, p, smooth, level);
|
||||||
|
#endif
|
||||||
if (dc->mul.use)
|
|
||||||
func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, cw, dc->render_op);
|
|
||||||
else
|
|
||||||
func = evas_common_gfx_func_composite_pixel_span_get(src, dst, cw, dc->render_op);
|
|
||||||
}
|
|
||||||
if (smooth)
|
|
||||||
{
|
|
||||||
for (y = ystart; y <= yend; y++)
|
|
||||||
{
|
|
||||||
int x, w, ww;
|
|
||||||
FPc u, v, ud, vd, dv;
|
|
||||||
DATA32 *d, *s, *so[4], val1, val2;
|
|
||||||
yp = y - ystart;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
if (spans[yp].span[i].x1 >= 0)
|
|
||||||
{
|
|
||||||
long long tl;
|
|
||||||
|
|
||||||
x = spans[yp].span[i].x1;
|
|
||||||
w = (spans[yp].span[i].x2 - x);
|
|
||||||
|
|
||||||
if (w <= 0) continue;
|
|
||||||
|
|
||||||
dv = (spans[yp].span[i].o2 - spans[yp].span[i].o1);
|
|
||||||
|
|
||||||
ww = w;
|
|
||||||
u = spans[yp].span[i].u[0] << FPI;
|
|
||||||
v = spans[yp].span[i].v[0] << FPI;
|
|
||||||
ud = ((spans[yp].span[i].u[1] << FPI) - u) / w;
|
|
||||||
vd = ((spans[yp].span[i].v[1] << FPI) - v) / w;
|
|
||||||
tl = (long long)ud * (w << FP);
|
|
||||||
tl = tl / dv;
|
|
||||||
ud = tl;
|
|
||||||
u -= (ud * (spans[yp].span[i].o1 - (spans[yp].span[i].x1 << FP))) / FP1;
|
|
||||||
|
|
||||||
tl = (long long)vd * (w << FP);
|
|
||||||
tl = tl / dv;
|
|
||||||
vd = tl;
|
|
||||||
v -= (vd * (spans[yp].span[i].o1 - (spans[yp].span[i].x1 << FP))) / FP1;
|
|
||||||
|
|
||||||
if (ud < 0) u -= 1;
|
|
||||||
if (vd < 0) v -= 1;
|
|
||||||
|
|
||||||
if (direct)
|
|
||||||
d = dst->image.data + (y * dst->cache_entry.w) + x;
|
|
||||||
else
|
|
||||||
d = buf;
|
|
||||||
|
|
||||||
while (ww > 0)
|
|
||||||
{
|
|
||||||
FPc u1, v1, u2, v2;
|
|
||||||
FPc rv, ru;
|
|
||||||
DATA32 vala, valb, val1, val2;
|
|
||||||
|
|
||||||
u1 = u;
|
|
||||||
if (u1 < 0) u1 = 0;
|
|
||||||
else if (u1 >= swp) u1 = swp - 1;
|
|
||||||
|
|
||||||
v1 = v;
|
|
||||||
if (v1 < 0) v1 = 0;
|
|
||||||
else if (v1 >= shp) v1 = shp - 1;
|
|
||||||
|
|
||||||
u2 = u1 + FPFPI1;
|
|
||||||
if (u2 >= swp) u2 = swp - 1;
|
|
||||||
|
|
||||||
v2 = v1 + FPFPI1;
|
|
||||||
if (v2 >= shp) v2 = shp - 1;
|
|
||||||
|
|
||||||
ru = (u >> (FP + FPI - 8)) & 0xff;
|
|
||||||
rv = (v >> (FP + FPI - 8)) & 0xff;
|
|
||||||
|
|
||||||
s = sp + ((v1 >> (FP + FPI)) * sw) +
|
|
||||||
(u1 >> (FP + FPI));
|
|
||||||
val1 = *s;
|
|
||||||
s = sp + ((v1 >> (FP + FPI)) * sw) +
|
|
||||||
(u2 >> (FP + FPI));
|
|
||||||
val2 = *s;
|
|
||||||
vala = INTERP_256(ru, val2, val1);
|
|
||||||
|
|
||||||
s = sp + ((v2 >> (FP + FPI)) * sw) +
|
|
||||||
(u1 >> (FP + FPI));
|
|
||||||
val1 = *s;
|
|
||||||
s = sp + ((v2 >> (FP + FPI)) * sw) +
|
|
||||||
(u2 >> (FP + FPI));
|
|
||||||
val2 = *s;
|
|
||||||
valb = INTERP_256(ru, val2, val1);
|
|
||||||
|
|
||||||
*d++ = INTERP_256(rv, valb, vala);
|
|
||||||
|
|
||||||
u += ud;
|
|
||||||
v += vd;
|
|
||||||
ww--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!direct)
|
|
||||||
{
|
|
||||||
d = dst->image.data;
|
|
||||||
d += (y * dst->cache_entry.w) + x;
|
|
||||||
func(buf, NULL, dc->mul.col, d, w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (y = ystart; y <= yend; y++)
|
|
||||||
{
|
|
||||||
int x, w, ww;
|
|
||||||
FPc u, v, ud, vd;
|
|
||||||
DATA32 *d, *s;
|
|
||||||
yp = y - ystart;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
if (spans[yp].span[i].x1 >= 0)
|
|
||||||
{
|
|
||||||
x = spans[yp].span[i].x1;
|
|
||||||
w = (spans[yp].span[i].x2 - x);
|
|
||||||
|
|
||||||
if (w <= 0) continue;
|
|
||||||
ww = w;
|
|
||||||
u = spans[yp].span[i].u[0] << FPI;
|
|
||||||
v = spans[yp].span[i].v[0] << FPI;
|
|
||||||
ud = ((spans[yp].span[i].u[1] << FPI) - u) / w;
|
|
||||||
vd = ((spans[yp].span[i].v[1] << FPI) - v) / w;
|
|
||||||
if (ud < 0) u -= 1;
|
|
||||||
if (vd < 0) v -= 1;
|
|
||||||
|
|
||||||
if (direct)
|
|
||||||
d = dst->image.data + (y * dst->cache_entry.w) + x;
|
|
||||||
else
|
|
||||||
d = buf;
|
|
||||||
|
|
||||||
while (ww > 0)
|
|
||||||
{
|
|
||||||
s = sp + ((v >> (FP + FPI)) * sw) +
|
|
||||||
(u >> (FP + FPI));
|
|
||||||
*d++ = *s;
|
|
||||||
u += ud;
|
|
||||||
v += vd;
|
|
||||||
ww--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!direct)
|
|
||||||
{
|
|
||||||
d = dst->image.data;
|
|
||||||
d += (y * dst->cache_entry.w) + x;
|
|
||||||
func(buf, NULL, dc->mul.col, d, w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
evas_common_draw_context_apply_clear_cutouts(rects);
|
||||||
|
/* restore clip info */
|
||||||
|
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,278 @@
|
||||||
|
/*
|
||||||
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||||
|
*/
|
||||||
|
// 66.74 % of time
|
||||||
|
static void
|
||||||
|
FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
|
||||||
|
RGBA_Draw_Context *dc,
|
||||||
|
RGBA_Map_Point *p,
|
||||||
|
int smooth, int level)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int c, cx, cy, cw, ch;
|
||||||
|
int ytop, ybottom, ystart, yend, y, sw, sh, shp, swp, direct;
|
||||||
|
Line *spans;
|
||||||
|
DATA32 *buf, *sp;
|
||||||
|
RGBA_Gfx_Func func;
|
||||||
|
|
||||||
|
// get the clip
|
||||||
|
c = dc->clip.use; cx = dc->clip.x; cy = dc->clip.y; cw = dc->clip.w; ch = dc->clip.h;
|
||||||
|
if (!c)
|
||||||
|
{
|
||||||
|
cx = 0;
|
||||||
|
cy = 0;
|
||||||
|
cw = dst->cache_entry.w;
|
||||||
|
ch = dst->cache_entry.h;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find y yop line and y bottom line
|
||||||
|
ytop = p[0].y;
|
||||||
|
for (i = 1; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (p[i].y < ytop) ytop = p[i].y;
|
||||||
|
}
|
||||||
|
ybottom = p[0].y;
|
||||||
|
for (i = 1; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (p[i].y > ybottom) ybottom = p[i].y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert to screen space from fixed point
|
||||||
|
ytop = ytop >> FP;
|
||||||
|
ybottom = ybottom >> FP;
|
||||||
|
|
||||||
|
// if its outside the clip vertical bounds - don't bother
|
||||||
|
if ((ytop >= (cy + ch)) || (ybottom < cy)) return;
|
||||||
|
|
||||||
|
// limit to the clip vertical bounds
|
||||||
|
if (ytop < cy) ystart = cy;
|
||||||
|
else ystart = ytop;
|
||||||
|
if (ybottom >= (cy + ch)) yend = (cy + ch) - 1;
|
||||||
|
else yend = ybottom;
|
||||||
|
|
||||||
|
// get some source image information
|
||||||
|
sp = src->image.data;
|
||||||
|
sw = src->cache_entry.w;
|
||||||
|
swp = sw << (FP + FPI);
|
||||||
|
shp = src->cache_entry.h << (FP + FPI);
|
||||||
|
|
||||||
|
// limit u,v coords of points to be within the source image
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (p[i].u < 0) p[i].u = 0;
|
||||||
|
else if (p[i].u > (src->cache_entry.w << FP))
|
||||||
|
p[i].u = src->cache_entry.w << FP;
|
||||||
|
|
||||||
|
if (p[i].v < 0) p[i].v = 0;
|
||||||
|
else if (p[i].v > (src->cache_entry.h << FP))
|
||||||
|
p[i].v = src->cache_entry.h << FP;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate some spans to hold out span list
|
||||||
|
spans = alloca((yend - ystart + 1) * sizeof(Line));
|
||||||
|
if (!spans) return;
|
||||||
|
memset(spans, 0, (yend - ystart + 1) * sizeof(Line));
|
||||||
|
|
||||||
|
// calculate the spans list
|
||||||
|
_calc_spans(p, spans, ystart, yend, cx, cy, cw, ch);
|
||||||
|
|
||||||
|
// walk through spans and render
|
||||||
|
|
||||||
|
// if operation is solid, bypass buf and draw func and draw direct to dst
|
||||||
|
direct = 0;
|
||||||
|
if ((!src->cache_entry.flags.alpha) && (!dst->cache_entry.flags.alpha) &&
|
||||||
|
(!dc->mul.use))
|
||||||
|
direct = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf = alloca(cw * sizeof(DATA32));
|
||||||
|
if (!buf) return;
|
||||||
|
|
||||||
|
if (dc->mul.use)
|
||||||
|
func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, cw, dc->render_op);
|
||||||
|
else
|
||||||
|
func = evas_common_gfx_func_composite_pixel_span_get(src, dst, cw, dc->render_op);
|
||||||
|
}
|
||||||
|
if (smooth)
|
||||||
|
{
|
||||||
|
for (y = ystart; y <= yend; y++)
|
||||||
|
{
|
||||||
|
int x, w, ww;
|
||||||
|
FPc u, v, ud, vd, dv;
|
||||||
|
DATA32 *d, *s, *so[4], val1, val2;
|
||||||
|
Line *line;
|
||||||
|
#ifdef SCALE_USING_MMX
|
||||||
|
pxor_r2r(mm0, mm0);
|
||||||
|
MOV_A2R(ALPHA_255, mm5)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
line = &(spans[y - ystart]);
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
Span *span;
|
||||||
|
|
||||||
|
span = &(line->span[i]);
|
||||||
|
if (span->x1 >= 0)
|
||||||
|
{
|
||||||
|
long long tl;
|
||||||
|
|
||||||
|
x = span->x1;
|
||||||
|
w = (span->x2 - x);
|
||||||
|
if (w <= 0) continue;
|
||||||
|
dv = (span->o2 - span->o1);
|
||||||
|
if (dv <= 0) continue;
|
||||||
|
|
||||||
|
ww = w;
|
||||||
|
u = span->u[0] << FPI;
|
||||||
|
v = span->v[0] << FPI;
|
||||||
|
ud = ((span->u[1] << FPI) - u) / w;
|
||||||
|
vd = ((span->v[1] << FPI) - v) / w;
|
||||||
|
tl = (long long)ud * (w << FP);
|
||||||
|
tl = tl / dv;
|
||||||
|
ud = tl;
|
||||||
|
u -= (ud * (span->o1 - (span->x1 << FP))) / FP1;
|
||||||
|
|
||||||
|
tl = (long long)vd * (w << FP);
|
||||||
|
tl = tl / dv;
|
||||||
|
vd = tl;
|
||||||
|
v -= (vd * (span->o1 - (span->x1 << FP))) / FP1;
|
||||||
|
|
||||||
|
if (ud < 0) u -= 1;
|
||||||
|
if (vd < 0) v -= 1;
|
||||||
|
|
||||||
|
if (direct)
|
||||||
|
d = dst->image.data + (y * dst->cache_entry.w) + x;
|
||||||
|
else
|
||||||
|
d = buf;
|
||||||
|
|
||||||
|
while (ww > 0)
|
||||||
|
{
|
||||||
|
FPc u1, v1, u2, v2;
|
||||||
|
FPc rv, ru;
|
||||||
|
DATA32 val1, val2, val3, val4;
|
||||||
|
|
||||||
|
u1 = u;
|
||||||
|
if (u1 < 0) u1 = 0;
|
||||||
|
else if (u1 >= swp) u1 = swp - 1;
|
||||||
|
|
||||||
|
v1 = v;
|
||||||
|
if (v1 < 0) v1 = 0;
|
||||||
|
else if (v1 >= shp) v1 = shp - 1;
|
||||||
|
|
||||||
|
u2 = u1 + FPFPI1;
|
||||||
|
if (u2 >= swp) u2 = swp - 1;
|
||||||
|
|
||||||
|
v2 = v1 + FPFPI1;
|
||||||
|
if (v2 >= shp) v2 = shp - 1;
|
||||||
|
|
||||||
|
ru = (u >> (FP + FPI - 8)) & 0xff;
|
||||||
|
rv = (v >> (FP + FPI - 8)) & 0xff;
|
||||||
|
|
||||||
|
s = sp + ((v1 >> (FP + FPI)) * sw) +
|
||||||
|
(u1 >> (FP + FPI));
|
||||||
|
val1 = *s;
|
||||||
|
s = sp + ((v1 >> (FP + FPI)) * sw) +
|
||||||
|
(u2 >> (FP + FPI));
|
||||||
|
val2 = *s;
|
||||||
|
|
||||||
|
s = sp + ((v2 >> (FP + FPI)) * sw) +
|
||||||
|
(u1 >> (FP + FPI));
|
||||||
|
val3 = *s;
|
||||||
|
s = sp + ((v2 >> (FP + FPI)) * sw) +
|
||||||
|
(u2 >> (FP + FPI));
|
||||||
|
val4 = *s;
|
||||||
|
#ifdef SCALE_USING_MMX
|
||||||
|
MOV_A2R(rv, mm4);
|
||||||
|
MOV_A2R(ru, mm6);
|
||||||
|
MOV_P2R(val1, mm1, mm0);
|
||||||
|
if (val1 | val2)
|
||||||
|
{
|
||||||
|
MOV_P2R(val2, mm2, mm0);
|
||||||
|
INTERP_256_R2R(mm6, mm2, mm1, mm5);
|
||||||
|
}
|
||||||
|
MOV_P2R(val3, mm2, mm0);
|
||||||
|
if (val3 | val4)
|
||||||
|
{
|
||||||
|
MOV_P2R(val4, mm3, mm0);
|
||||||
|
INTERP_256_R2R(mm6, mm3, mm2, mm5);
|
||||||
|
}
|
||||||
|
INTERP_256_R2R(mm4, mm2, mm1, mm5);
|
||||||
|
MOV_R2P(mm1, *d, mm0);
|
||||||
|
d++;
|
||||||
|
#else
|
||||||
|
val1 = INTERP_256(ru, val2, val1);
|
||||||
|
val3 = INTERP_256(ru, val4, val3);
|
||||||
|
*d++ = INTERP_256(rv, val3, val1);
|
||||||
|
#endif
|
||||||
|
u += ud;
|
||||||
|
v += vd;
|
||||||
|
ww--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!direct)
|
||||||
|
{
|
||||||
|
d = dst->image.data;
|
||||||
|
d += (y * dst->cache_entry.w) + x;
|
||||||
|
func(buf, NULL, dc->mul.col, d, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (y = ystart; y <= yend; y++)
|
||||||
|
{
|
||||||
|
int x, w, ww;
|
||||||
|
FPc u, v, ud, vd;
|
||||||
|
DATA32 *d, *s;
|
||||||
|
Line *line;
|
||||||
|
|
||||||
|
line = &(spans[y - ystart]);
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
Span *span;
|
||||||
|
|
||||||
|
span = &(line->span[i]);
|
||||||
|
if (span->x1 >= 0)
|
||||||
|
{
|
||||||
|
x = span->x1;
|
||||||
|
w = (span->x2 - x);
|
||||||
|
|
||||||
|
if (w <= 0) continue;
|
||||||
|
ww = w;
|
||||||
|
u = span->u[0] << FPI;
|
||||||
|
v = span->v[0] << FPI;
|
||||||
|
ud = ((span->u[1] << FPI) - u) / w;
|
||||||
|
vd = ((span->v[1] << FPI) - v) / w;
|
||||||
|
if (ud < 0) u -= 1;
|
||||||
|
if (vd < 0) v -= 1;
|
||||||
|
|
||||||
|
if (direct)
|
||||||
|
d = dst->image.data + (y * dst->cache_entry.w) + x;
|
||||||
|
else
|
||||||
|
d = buf;
|
||||||
|
|
||||||
|
while (ww > 0)
|
||||||
|
{
|
||||||
|
s = sp + ((v >> (FP + FPI)) * sw) +
|
||||||
|
(u >> (FP + FPI));
|
||||||
|
*d++ = *s;
|
||||||
|
u += ud;
|
||||||
|
v += vd;
|
||||||
|
ww--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!direct)
|
||||||
|
{
|
||||||
|
d = dst->image.data;
|
||||||
|
d += (y * dst->cache_entry.w) + x;
|
||||||
|
func(buf, NULL, dc->mul.col, d, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue