2013-06-20 03:53:29 -07:00
|
|
|
#include "evas_common_private.h"
|
2012-07-04 02:39:23 -07:00
|
|
|
#include "evas_private.h"
|
2009-10-17 03:25:51 -07:00
|
|
|
#include "evas_blend_private.h"
|
2014-12-16 22:28:50 -08:00
|
|
|
#ifdef BUILD_NEON
|
|
|
|
#include <arm_neon.h>
|
|
|
|
#endif
|
2009-10-17 03:25:51 -07:00
|
|
|
|
2012-10-15 20:15:40 -07:00
|
|
|
#ifdef BUILD_MMX
|
|
|
|
# undef SCALE_USING_MMX
|
|
|
|
# define SCALE_USING_MMX
|
2009-10-28 23:52:51 -07:00
|
|
|
#endif
|
|
|
|
|
2009-10-22 00:31:25 -07:00
|
|
|
#define FPI 8
|
|
|
|
#define FPI1 (1 << (FPI))
|
|
|
|
#define FPIH (1 << (FPI - 1))
|
|
|
|
|
|
|
|
#define FPFPI1 (1 << (FP + FPI))
|
|
|
|
|
2009-10-17 03:25:51 -07:00
|
|
|
typedef struct _Line Line;
|
|
|
|
typedef struct _Span Span;
|
|
|
|
|
|
|
|
struct _Span
|
|
|
|
{
|
2014-11-25 04:35:33 -08:00
|
|
|
int x[2];
|
2009-11-23 02:07:07 -08:00
|
|
|
FPc o1, o2, z1, z2;
|
2009-10-17 03:25:51 -07:00
|
|
|
FPc u[2], v[2];
|
2009-10-31 18:32:23 -07:00
|
|
|
DATA32 col[2];
|
2009-10-17 03:25:51 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
struct _Line
|
|
|
|
{
|
|
|
|
Span span[2];
|
2014-11-25 22:12:25 -08:00
|
|
|
int aa_cov[2];
|
|
|
|
int aa_len[2];
|
2009-10-17 03:25:51 -07:00
|
|
|
};
|
|
|
|
|
2012-07-04 02:39:23 -07:00
|
|
|
static inline FPc
|
2009-10-20 09:03:57 -07:00
|
|
|
_interp(int x1, int x2, int p, FPc u1, FPc u2)
|
|
|
|
{
|
|
|
|
FPc u;
|
2009-10-21 02:33:07 -07:00
|
|
|
|
2009-10-20 09:03:57 -07:00
|
|
|
x2 -= x1;
|
2013-12-31 01:19:41 -08:00
|
|
|
if (x2 == 0) x2 = 1;
|
2009-10-21 02:33:07 -07:00
|
|
|
p -= x1;
|
2009-10-20 09:03:57 -07:00
|
|
|
u = u2 - u1;
|
2013-12-31 01:19:41 -08:00
|
|
|
u = ((u * p) / x2);
|
2009-11-23 02:07:07 -08:00
|
|
|
// FIXME: do z persp
|
2009-10-21 02:33:07 -07:00
|
|
|
return u1 + u;
|
2009-10-20 09:03:57 -07:00
|
|
|
}
|
|
|
|
|
2012-07-04 02:39:23 -07:00
|
|
|
static inline DATA32
|
2009-10-31 18:32:23 -07:00
|
|
|
_interp_col(int x1, int x2, int p, DATA32 col1, DATA32 col2)
|
|
|
|
{
|
|
|
|
x2 -= x1;
|
2013-12-31 01:19:41 -08:00
|
|
|
if (x2 == 0) x2 = 1;
|
2009-10-31 18:32:23 -07:00
|
|
|
p -= x1;
|
2013-12-31 01:19:41 -08:00
|
|
|
p = ((p << 8) / x2);
|
2009-11-23 02:07:07 -08:00
|
|
|
// FIXME: do z persp
|
2009-10-31 18:32:23 -07:00
|
|
|
return INTERP_256(p, col2, col1);
|
|
|
|
}
|
|
|
|
|
2012-07-04 02:39:23 -07:00
|
|
|
static inline void
|
2013-12-31 01:32:30 -08:00
|
|
|
_interpolated_clip_span(Span *s, int c1, int c2, Eina_Bool interp_col)
|
2009-10-26 07:06:21 -07:00
|
|
|
{
|
2014-11-25 04:35:33 -08:00
|
|
|
if (s->x[0] < c1)
|
2009-10-26 07:06:21 -07:00
|
|
|
{
|
2014-11-25 04:35:33 -08:00
|
|
|
s->u[0] = _interp(s->x[0], s->x[1], c1, s->u[0], s->u[1]);
|
|
|
|
s->v[0] = _interp(s->x[0], s->x[1], c1, s->v[0], s->v[1]);
|
2013-12-31 01:32:30 -08:00
|
|
|
if (interp_col)
|
2014-11-25 04:35:33 -08:00
|
|
|
s->col[0] = _interp_col(s->x[0], s->x[1], c1, s->col[0], s->col[1]);
|
|
|
|
s->x[0] = c1;
|
2009-10-26 07:06:21 -07:00
|
|
|
s->o1 = c1 << FP;
|
2009-11-23 02:07:07 -08:00
|
|
|
// FIXME: do s->z1
|
2009-10-26 07:06:21 -07:00
|
|
|
}
|
2014-11-25 04:35:33 -08:00
|
|
|
if (s->x[1] > c2)
|
2009-10-26 07:06:21 -07:00
|
|
|
{
|
2014-11-25 04:35:33 -08:00
|
|
|
s->u[1] = _interp(s->x[0], s->x[1], c2, s->u[0], s->u[1]);
|
|
|
|
s->v[1] = _interp(s->x[0], s->x[1], c2, s->v[0], s->v[1]);
|
2013-12-31 01:32:30 -08:00
|
|
|
if (interp_col)
|
2014-11-25 04:35:33 -08:00
|
|
|
s->col[1] = _interp_col(s->x[0], s->x[1], c2, s->col[0], s->col[1]);
|
|
|
|
s->x[1] = c2;
|
2009-10-26 07:06:21 -07:00
|
|
|
s->o2 = c2 << FP;
|
2009-11-23 02:07:07 -08:00
|
|
|
// FIXME: do s->z2
|
2009-10-26 07:06:21 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-25 22:12:25 -08:00
|
|
|
#include "evas_map_image_aa.c"
|
|
|
|
|
2009-10-23 06:17:22 -07:00
|
|
|
// 12.63 % of time - this can improve
|
2009-10-21 02:33:07 -07:00
|
|
|
static void
|
2012-11-04 03:51:42 -08:00
|
|
|
_calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy EINA_UNUSED, int cw, int ch EINA_UNUSED)
|
2009-10-17 03:25:51 -07:00
|
|
|
{
|
2014-08-05 00:35:41 -07:00
|
|
|
int i, y, yp;
|
2009-10-17 03:25:51 -07:00
|
|
|
int py[4];
|
2013-12-31 04:11:58 -08:00
|
|
|
int edge[4][4], edge_num, order[4];
|
2014-08-05 00:35:41 -07:00
|
|
|
FPc uv[4][2], u, v, x, t, edge_h;
|
2009-10-31 18:32:23 -07:00
|
|
|
DATA32 col[4];
|
2013-12-31 01:32:30 -08:00
|
|
|
Eina_Bool interp_col = EINA_FALSE;
|
2013-12-31 04:11:58 -08:00
|
|
|
Eina_Bool swapped;
|
2013-12-31 01:32:30 -08:00
|
|
|
|
2014-02-07 00:46:57 -08:00
|
|
|
for (i = 0; i < 4; i++) py[i] = (p[i].y >> FP);
|
2013-12-31 01:32:30 -08:00
|
|
|
|
|
|
|
//Horizontal Line?
|
2014-02-07 00:46:57 -08:00
|
|
|
if ((py[0] == py[1]) && (py[0] == py[2]) && (py[0] == py[3]))
|
2009-10-17 03:25:51 -07:00
|
|
|
{
|
2009-10-26 07:06:21 -07:00
|
|
|
int leftp, rightp;
|
2013-12-31 01:32:30 -08:00
|
|
|
|
2009-10-26 07:06:21 -07:00
|
|
|
leftp = rightp = 0;
|
2013-12-31 01:32:30 -08:00
|
|
|
|
2009-10-26 07:06:21 -07:00
|
|
|
for (i = 1; i < 4; i++)
|
|
|
|
{
|
|
|
|
if (p[i].x < p[leftp].x) leftp = i;
|
|
|
|
if (p[i].x > p[rightp].x) rightp = i;
|
2013-12-31 01:32:30 -08:00
|
|
|
if (p[i].col != 0xffffffff) interp_col = EINA_TRUE;
|
2009-10-26 07:06:21 -07:00
|
|
|
}
|
2009-10-17 03:25:51 -07:00
|
|
|
for (y = ystart; y <= yend; y++)
|
|
|
|
{
|
2009-10-20 09:03:57 -07:00
|
|
|
yp = y - ystart;
|
2014-02-07 00:46:57 -08:00
|
|
|
if (y == py[0])
|
2009-10-17 03:25:51 -07:00
|
|
|
{
|
2009-10-26 07:06:21 -07:00
|
|
|
i = 0;
|
2014-11-25 04:35:33 -08:00
|
|
|
spans[yp].span[i].x[0] = p[leftp].x >> FP;
|
2009-10-26 07:06:21 -07:00
|
|
|
spans[yp].span[i].o1 = p[leftp].x;
|
|
|
|
spans[yp].span[i].u[0] = p[leftp].u;
|
|
|
|
spans[yp].span[i].v[0] = p[leftp].v;
|
2009-10-31 18:32:23 -07:00
|
|
|
spans[yp].span[i].col[0] = p[leftp].col;
|
2014-11-25 04:35:33 -08:00
|
|
|
spans[yp].span[i].x[1] = p[rightp].x >> FP;
|
2009-10-26 07:06:21 -07:00
|
|
|
spans[yp].span[i].o2 = p[rightp].x;
|
|
|
|
spans[yp].span[i].u[1] = p[rightp].u;
|
|
|
|
spans[yp].span[i].v[1] = p[rightp].v;
|
2009-10-31 18:32:23 -07:00
|
|
|
spans[yp].span[i].col[1] = p[rightp].col;
|
2013-12-31 01:32:30 -08:00
|
|
|
//Outside of the clipper
|
2014-11-25 04:35:33 -08:00
|
|
|
if ((spans[yp].span[i].x[0] > (cx + cw)) ||
|
|
|
|
(spans[yp].span[i].x[1] < cx))
|
|
|
|
spans[yp].span[i].x[0] = -1;
|
2009-10-26 07:06:21 -07:00
|
|
|
else
|
|
|
|
{
|
2013-12-31 01:32:30 -08:00
|
|
|
_interpolated_clip_span(&(spans[yp].span[i]), cx,
|
|
|
|
(cx + cw), interp_col);
|
2009-10-26 07:06:21 -07:00
|
|
|
i++;
|
2014-11-25 04:35:33 -08:00
|
|
|
spans[yp].span[i].x[0] = -1;
|
2009-10-26 07:06:21 -07:00
|
|
|
}
|
2009-10-17 03:25:51 -07:00
|
|
|
}
|
2014-02-07 23:32:52 -08:00
|
|
|
//The polygon shape seems not be completed definitely.
|
2009-10-26 07:06:21 -07:00
|
|
|
else
|
2014-11-25 04:35:33 -08:00
|
|
|
spans[yp].span[0].x[0] = -1;
|
2009-10-26 07:06:21 -07:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (y = ystart; y <= yend; y++)
|
|
|
|
{
|
|
|
|
edge_num = 0;
|
2013-12-31 01:32:30 -08:00
|
|
|
|
|
|
|
//Find edges that intersects with current scanline.
|
2009-10-26 07:06:21 -07:00
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
{
|
2014-02-07 00:46:57 -08:00
|
|
|
if ((py[i] <= y) && (py[(i + 1) % 4] > y))
|
2009-10-17 03:25:51 -07:00
|
|
|
{
|
2009-10-26 07:06:21 -07:00
|
|
|
edge[edge_num][0] = i;
|
|
|
|
edge[edge_num][1] = (i + 1) % 4;
|
2009-10-17 03:25:51 -07:00
|
|
|
edge_num++;
|
|
|
|
}
|
2014-02-07 00:46:57 -08:00
|
|
|
else if ((py[(i + 1) % 4] <= y) && (py[i] > y))
|
2009-10-17 03:25:51 -07:00
|
|
|
{
|
2009-10-26 07:06:21 -07:00
|
|
|
edge[edge_num][0] = (i + 1) % 4;
|
|
|
|
edge[edge_num][1] = i;
|
2009-10-17 03:25:51 -07:00
|
|
|
edge_num++;
|
|
|
|
}
|
2013-12-31 01:32:30 -08:00
|
|
|
if (p[i].col != 0xffffffff) interp_col = EINA_TRUE;
|
2009-10-26 07:06:21 -07:00
|
|
|
}
|
2013-12-31 01:32:30 -08:00
|
|
|
|
2009-10-26 07:06:21 -07:00
|
|
|
// calculate line x points for each edge
|
|
|
|
for (i = 0; i < edge_num; i++)
|
|
|
|
{
|
|
|
|
int e1 = edge[i][0];
|
|
|
|
int e2 = edge[i][1];
|
2009-10-31 18:32:23 -07:00
|
|
|
FPc t256;
|
2013-12-31 01:32:30 -08:00
|
|
|
|
2014-02-07 03:35:35 -08:00
|
|
|
// compute x point that proportionated to the y point offset
|
|
|
|
edge_h = (p[e2].y - p[e1].y) >> FP; //edge height
|
|
|
|
if (edge_h < 1) edge_h = 1;
|
2011-10-11 05:32:21 -07:00
|
|
|
t = (((y << FP) + (FP1 / 2) - 1) - p[e1].y) >> FP;
|
evas map: fix the rendering problem.
I got an issue report about map rendering.
After investigated, I found that was introduced by data overflow.
For fast computation, evas map uses integer data type rather than float,
that gives up some range of data size.
So, if vertex range is a little large but still reasonable,
polygon won'be properly displayed due to the integer overflow.
We can fix this by changing FPc data type to 64 bits (ie, long long)
But I didn't do yet though I can simply fix this costlessly.
By the way, my test case map points are below.
0: -1715, -5499
1: -83, -1011
2: 1957, 5721
3: 325, 1233
and gl result is perfect but sw is totally broken.
@fix
2016-09-12 00:50:00 -07:00
|
|
|
x = p[e2].x - p[e1].x; //edge width
|
|
|
|
|
|
|
|
FPc temp = (x * t);
|
|
|
|
|
|
|
|
// TODO: prevent data overflow. We can remove this exception if FPc type is more than integer.
|
|
|
|
if (temp < 0) temp = (((x >> FP) * t) / edge_h) << FP;
|
|
|
|
else temp /= edge_h;
|
|
|
|
|
|
|
|
x = p[e1].x + temp; // intersected x point
|
2009-11-23 02:07:07 -08:00
|
|
|
|
|
|
|
/*
|
|
|
|
// FIXME: 3d accuracy here
|
|
|
|
// XXX t needs adjusting. above its a linear interp point
|
|
|
|
// only.
|
|
|
|
//
|
|
|
|
// // FIXME: do in fixed pt. reduce divides
|
|
|
|
evas_common_cpu_end_opt();
|
|
|
|
//
|
|
|
|
int foc = 512, z0 = 0, px = 320, py = 240; // FIXME: need from map points
|
|
|
|
//
|
|
|
|
float focf, hf;
|
|
|
|
float z1, z2, y1, y2, dz, dy, zt, dydz, yt;
|
|
|
|
|
|
|
|
focf = foc;
|
|
|
|
hf = h;
|
2009-10-26 07:06:21 -07:00
|
|
|
|
2009-11-23 02:07:07 -08:00
|
|
|
// adjust for fixed point and focal length and z0 for map
|
|
|
|
z1 = (p[e1].z >> FP) - z0 + foc;
|
|
|
|
z2 = (p[e2].z >> FP) - z0 + foc;
|
|
|
|
// deltas
|
|
|
|
dz = z1 - z2;
|
|
|
|
|
|
|
|
if (dz != 0)
|
|
|
|
{
|
|
|
|
int pt;
|
|
|
|
|
|
|
|
// adjust for perspective point (being 0 0)
|
|
|
|
y1 = (p[e1].y >> FP) - py;
|
|
|
|
y2 = (p[e2].y >> FP) - py;
|
|
|
|
|
|
|
|
// correct for x &y not being in world coords - screen coords
|
|
|
|
y1 = (y1 * z1) / focf;
|
|
|
|
y2 = (y2 * z2) / focf;
|
|
|
|
|
|
|
|
// deltas
|
|
|
|
dy = y1 - y2;
|
|
|
|
|
|
|
|
yt = y - py;
|
|
|
|
dydz = dy / dz;
|
|
|
|
|
|
|
|
zt = (y2 - (dydz * z2)) / ((yt / focf) - dydz);
|
|
|
|
|
|
|
|
pt = t;
|
|
|
|
t = ((z1 - zt) * hf) / dz;
|
|
|
|
}
|
|
|
|
*/
|
2014-02-07 03:35:35 -08:00
|
|
|
//compute texture u coordinate
|
2009-10-26 07:06:21 -07:00
|
|
|
u = p[e2].u - p[e1].u;
|
2014-08-05 00:35:41 -07:00
|
|
|
u = p[e1].u + ((u * t) / edge_h);
|
2013-12-31 01:32:30 -08:00
|
|
|
|
2014-02-07 03:35:35 -08:00
|
|
|
//compute texture v coordinate
|
2009-10-26 07:06:21 -07:00
|
|
|
v = p[e2].v - p[e1].v;
|
2014-08-05 00:35:41 -07:00
|
|
|
v = p[e1].v + ((v * t) / edge_h);
|
2009-11-23 02:07:07 -08:00
|
|
|
|
|
|
|
// FIXME: 3d accuracy for color too
|
2014-02-07 03:35:35 -08:00
|
|
|
t256 = (t << 8) / edge_h; // maybe * 255?
|
2009-10-31 18:32:23 -07:00
|
|
|
col[i] = INTERP_256(t256, p[e2].col, p[e1].col);
|
2013-12-31 01:32:30 -08:00
|
|
|
|
2009-11-23 02:07:07 -08:00
|
|
|
// FIXME: store z persp
|
2009-10-26 07:06:21 -07:00
|
|
|
uv[i][0] = u;
|
2014-02-08 01:16:09 -08:00
|
|
|
uv[i][1] = v;
|
2009-10-26 07:06:21 -07:00
|
|
|
edge[i][2] = x >> FP;
|
|
|
|
edge[i][3] = x;
|
|
|
|
// also fill in order
|
|
|
|
order[i] = i;
|
|
|
|
}
|
2013-12-31 04:11:58 -08:00
|
|
|
|
2009-10-26 07:06:21 -07:00
|
|
|
// sort edges from left to right - bubble. its a small list!
|
|
|
|
do
|
|
|
|
{
|
2013-12-31 04:11:58 -08:00
|
|
|
swapped = EINA_FALSE;
|
2009-10-26 07:06:21 -07:00
|
|
|
for (i = 0; i < (edge_num - 1); i++)
|
2009-10-17 03:25:51 -07:00
|
|
|
{
|
2009-10-26 07:06:21 -07:00
|
|
|
if (edge[order[i]][2] > edge[order[i + 1]][2])
|
2009-10-17 03:25:51 -07:00
|
|
|
{
|
2009-10-26 07:06:21 -07:00
|
|
|
t = order[i];
|
|
|
|
order[i] = order[i + 1];
|
|
|
|
order[i + 1] = t;
|
2013-12-31 04:11:58 -08:00
|
|
|
swapped = EINA_TRUE;
|
2009-10-17 03:25:51 -07:00
|
|
|
}
|
|
|
|
}
|
2009-10-26 07:06:21 -07:00
|
|
|
}
|
|
|
|
while (swapped);
|
2013-12-31 04:11:58 -08:00
|
|
|
|
2014-02-07 03:35:35 -08:00
|
|
|
yp = y - ystart;
|
|
|
|
|
2009-10-26 07:06:21 -07:00
|
|
|
if (edge_num == 2)
|
|
|
|
{
|
|
|
|
i = 0;
|
2014-11-25 04:35:33 -08:00
|
|
|
spans[yp].span[i].x[0] = edge[order[0]][2];
|
2009-10-26 07:06:21 -07:00
|
|
|
spans[yp].span[i].o1 = edge[order[0]][3];
|
|
|
|
spans[yp].span[i].u[0] = uv[order[0]][0];
|
|
|
|
spans[yp].span[i].v[0] = uv[order[0]][1];
|
2009-10-31 18:32:23 -07:00
|
|
|
spans[yp].span[i].col[0] = col[order[0]];
|
2013-12-31 01:32:30 -08:00
|
|
|
|
2014-11-25 04:35:33 -08:00
|
|
|
spans[yp].span[i].x[1] = edge[order[1]][2];
|
2009-10-26 07:06:21 -07:00
|
|
|
spans[yp].span[i].o2 = edge[order[1]][3];
|
|
|
|
spans[yp].span[i].u[1] = uv[order[1]][0];
|
|
|
|
spans[yp].span[i].v[1] = uv[order[1]][1];
|
2009-10-31 18:32:23 -07:00
|
|
|
spans[yp].span[i].col[1] = col[order[1]];
|
2013-12-31 04:11:58 -08:00
|
|
|
|
|
|
|
//Outside of the clipper
|
2014-11-26 00:39:27 -08:00
|
|
|
if ((spans[yp].span[i].x[0] > (cx + cw)) ||
|
2014-11-25 04:35:33 -08:00
|
|
|
(spans[yp].span[i].x[1] < cx))
|
|
|
|
spans[yp].span[i].x[0] = -1;
|
2009-10-26 07:06:21 -07:00
|
|
|
else
|
2009-10-17 03:25:51 -07:00
|
|
|
{
|
2013-12-31 01:32:30 -08:00
|
|
|
_interpolated_clip_span(&(spans[yp].span[i]), cx, (cx + cw),
|
|
|
|
interp_col);
|
2009-10-26 07:06:21 -07:00
|
|
|
i++;
|
2014-11-25 04:35:33 -08:00
|
|
|
spans[yp].span[i].x[0] = -1;
|
2009-10-17 03:25:51 -07:00
|
|
|
}
|
2009-10-26 07:06:21 -07:00
|
|
|
}
|
|
|
|
else if (edge_num == 4)
|
|
|
|
{
|
|
|
|
i = 0;
|
2014-11-25 04:35:33 -08:00
|
|
|
spans[yp].span[i].x[0] = edge[order[0]][2];
|
2009-10-26 07:06:21 -07:00
|
|
|
spans[yp].span[i].u[0] = uv[order[0]][0];
|
|
|
|
spans[yp].span[i].v[0] = uv[order[0]][1];
|
2009-10-31 18:32:23 -07:00
|
|
|
spans[yp].span[i].col[0] = col[order[0]];
|
2013-12-31 01:32:30 -08:00
|
|
|
|
2014-11-25 04:35:33 -08:00
|
|
|
spans[yp].span[i].x[1] = edge[order[1]][2];
|
2009-10-26 07:06:21 -07:00
|
|
|
spans[yp].span[i].u[1] = uv[order[1]][0];
|
|
|
|
spans[yp].span[i].v[1] = uv[order[1]][1];
|
2009-10-31 18:32:23 -07:00
|
|
|
spans[yp].span[i].col[1] = col[order[1]];
|
2013-12-31 04:11:58 -08:00
|
|
|
|
|
|
|
//Outside of the clipper
|
2014-11-26 00:39:27 -08:00
|
|
|
if ((spans[yp].span[i].x[0] > (cx + cw)) ||
|
2014-11-25 04:35:33 -08:00
|
|
|
(spans[yp].span[i].x[1] < cx))
|
|
|
|
spans[yp].span[i].x[0] = -1;
|
2009-10-26 07:06:21 -07:00
|
|
|
else
|
2009-10-17 03:25:51 -07:00
|
|
|
{
|
2013-12-31 01:32:30 -08:00
|
|
|
_interpolated_clip_span(&(spans[yp].span[i]), cx, (cx + cw),
|
|
|
|
interp_col);
|
2009-10-26 07:06:21 -07:00
|
|
|
i++;
|
2009-10-17 03:25:51 -07:00
|
|
|
}
|
2013-12-31 04:11:58 -08:00
|
|
|
|
2014-11-25 04:35:33 -08:00
|
|
|
spans[yp].span[i].x[0] = edge[order[2]][2];
|
2009-10-26 07:06:21 -07:00
|
|
|
spans[yp].span[i].u[0] = uv[order[2]][0];
|
|
|
|
spans[yp].span[i].v[0] = uv[order[2]][1];
|
2009-10-31 18:32:23 -07:00
|
|
|
spans[yp].span[i].col[0] = col[order[2]];
|
2013-12-31 01:32:30 -08:00
|
|
|
|
2014-11-25 04:35:33 -08:00
|
|
|
spans[yp].span[i].x[1] = edge[order[3]][2];
|
2009-10-26 07:06:21 -07:00
|
|
|
spans[yp].span[i].u[1] = uv[order[3]][0];
|
|
|
|
spans[yp].span[i].v[1] = uv[order[3]][1];
|
2009-10-31 18:32:23 -07:00
|
|
|
spans[yp].span[i].col[1] = col[order[3]];
|
2013-12-31 04:11:58 -08:00
|
|
|
|
|
|
|
//Outside of the clipper
|
2014-11-26 00:39:27 -08:00
|
|
|
if ((spans[yp].span[i].x[0] > (cx + cw)) ||
|
2014-11-25 04:35:33 -08:00
|
|
|
(spans[yp].span[i].x[1] < cx))
|
|
|
|
spans[yp].span[i].x[0] = -1;
|
2009-10-17 03:25:51 -07:00
|
|
|
else
|
|
|
|
{
|
2009-10-26 07:06:21 -07:00
|
|
|
int l = cx;
|
2013-12-31 01:32:30 -08:00
|
|
|
|
2014-11-25 04:35:33 -08:00
|
|
|
if (i > 0) l = spans[yp].span[i - 1].x[1];
|
2013-12-31 01:32:30 -08:00
|
|
|
_interpolated_clip_span(&(spans[yp].span[i]), l, (cx + cw),
|
|
|
|
interp_col);
|
2009-10-17 03:25:51 -07:00
|
|
|
}
|
|
|
|
}
|
2014-02-07 23:32:52 -08:00
|
|
|
//The polygon shape seems not be completed definitely.
|
2009-10-26 07:06:21 -07:00
|
|
|
else
|
2014-11-25 04:35:33 -08:00
|
|
|
spans[yp].span[0].x[0] = -1;
|
2009-10-17 03:25:51 -07:00
|
|
|
}
|
2009-10-23 06:17:22 -07:00
|
|
|
}
|
|
|
|
|
2012-07-04 02:39:23 -07:00
|
|
|
/* FIXME: Account for 10% during pipe rendering, should be improved
|
|
|
|
* Could be computing the interpolation once somehow.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
_clip_spans(Line *spans, int ystart, int yend,
|
2013-12-31 01:32:30 -08:00
|
|
|
int cx, int cw, Eina_Bool interp_col)
|
2012-07-04 02:39:23 -07:00
|
|
|
{
|
|
|
|
int y, yp;
|
|
|
|
|
|
|
|
for (y = ystart, yp = 0; y <= yend; y++, yp++)
|
|
|
|
{
|
2014-11-25 04:35:33 -08:00
|
|
|
if (spans[yp].span[0].x[0] > -1)
|
2012-07-04 02:39:23 -07:00
|
|
|
{
|
2014-11-25 04:35:33 -08:00
|
|
|
if ((spans[yp].span[0].x[0] >= (cx + cw)) ||
|
|
|
|
(spans[yp].span[0].x[1] < cx))
|
2012-07-04 02:39:23 -07:00
|
|
|
{
|
2014-11-25 04:35:33 -08:00
|
|
|
spans[yp].span[0].x[0] = -1;
|
2012-07-04 02:39:23 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-12-31 01:32:30 -08:00
|
|
|
_interpolated_clip_span(&(spans[yp].span[0]), cx, (cx + cw),
|
|
|
|
interp_col);
|
2012-07-04 02:39:23 -07:00
|
|
|
|
2014-11-25 04:35:33 -08:00
|
|
|
if ((spans[yp].span[1].x[0] >= (cx + cw)) ||
|
|
|
|
(spans[yp].span[1].x[1] < cx))
|
2012-07-04 02:39:23 -07:00
|
|
|
{
|
2014-11-25 04:35:33 -08:00
|
|
|
spans[yp].span[1].x[0] = -1;
|
2012-07-04 02:39:23 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-12-31 01:32:30 -08:00
|
|
|
_interpolated_clip_span(&(spans[yp].span[1]),
|
2014-11-25 04:35:33 -08:00
|
|
|
spans[yp].span[0].x[1],
|
2013-12-31 01:32:30 -08:00
|
|
|
cx + cw, interp_col);
|
2012-07-04 02:39:23 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct _RGBA_Map_Spans RGBA_Map_Spans;
|
|
|
|
typedef struct _RGBA_Map_Cutout RGBA_Map_Cutout;
|
|
|
|
|
|
|
|
struct _RGBA_Map_Spans
|
|
|
|
{
|
|
|
|
Line *spans;
|
|
|
|
int size;
|
|
|
|
int ystart;
|
|
|
|
int yend;
|
|
|
|
|
|
|
|
int havecol;
|
|
|
|
Eina_Bool havea;
|
|
|
|
Eina_Bool direct;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _RGBA_Map_Cutout
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
|
|
|
|
Cutout_Rects *rects;
|
|
|
|
RGBA_Map_Spans spans[1];
|
|
|
|
};
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_common_map_rgba_clean(RGBA_Map *m)
|
|
|
|
{
|
|
|
|
RGBA_Map_Cutout *spans = m->engine_data;
|
|
|
|
|
|
|
|
if (spans)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (spans->rects)
|
|
|
|
evas_common_draw_context_apply_clear_cutouts(spans->rects);
|
|
|
|
for (i = 0; i < spans->count; i++)
|
|
|
|
free(spans->spans[i].spans);
|
|
|
|
free(spans);
|
|
|
|
}
|
|
|
|
|
|
|
|
m->engine_data = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_rgba_map_cutout_resize(RGBA_Map *m, int count)
|
|
|
|
{
|
|
|
|
RGBA_Map_Cutout *old = m->engine_data;
|
|
|
|
RGBA_Map_Cutout *r;
|
|
|
|
int size;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (count == 0)
|
|
|
|
goto empty;
|
|
|
|
|
|
|
|
if (old && old->count == count)
|
|
|
|
{
|
2013-06-20 04:28:18 -07:00
|
|
|
return;
|
2012-07-04 02:39:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
size = sizeof (RGBA_Map_Cutout) + sizeof (RGBA_Map_Spans) * (count - 1);
|
|
|
|
|
|
|
|
if (old)
|
|
|
|
{
|
|
|
|
for (i = 0; i < old->count; i++)
|
|
|
|
{
|
|
|
|
free(old->spans[i].spans);
|
|
|
|
old->spans[i].spans = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
r = realloc(old, size);
|
|
|
|
if (!r)
|
|
|
|
goto empty;
|
|
|
|
|
|
|
|
memset(r, 0, size);
|
|
|
|
m->engine_data = r;
|
|
|
|
r->count = count;
|
2013-06-20 04:28:18 -07:00
|
|
|
return;
|
2012-07-04 02:39:23 -07:00
|
|
|
|
|
|
|
empty:
|
|
|
|
evas_common_map_rgba_clean(m);
|
2013-06-20 04:28:18 -07:00
|
|
|
return;
|
2012-07-04 02:39:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_common_map_rgba_span(RGBA_Map_Spans *span,
|
|
|
|
RGBA_Image *src, RGBA_Image *dst,
|
|
|
|
RGBA_Draw_Context *dc,
|
|
|
|
RGBA_Map_Point *p,
|
|
|
|
int cx, int cy, int cw, int ch)
|
|
|
|
{
|
|
|
|
int ytop, ybottom, sw;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
span->havecol = 4;
|
|
|
|
span->havea = 0;
|
|
|
|
span->direct = 0;
|
|
|
|
|
2018-06-18 18:50:50 -07:00
|
|
|
// find y top line and y bottom line
|
2012-07-04 02:39:23 -07:00
|
|
|
ytop = p[0].y;
|
|
|
|
if ((p[0].col >> 24) < 0xff) span->havea = 1;
|
|
|
|
if (p[0].col == 0xffffffff) span->havecol--;
|
|
|
|
for (i = 1; i < 4; i++)
|
|
|
|
{
|
|
|
|
if (p[i].y < ytop) ytop = p[i].y;
|
|
|
|
if ((p[i].col >> 24) < 0xff) span->havea = 1;
|
|
|
|
if (p[i].col == 0xffffffff) span->havecol--;
|
|
|
|
}
|
|
|
|
|
|
|
|
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) span->ystart = cy;
|
|
|
|
else span->ystart = ytop;
|
|
|
|
if (ybottom >= (cy + ch)) span->yend = (cy + ch) - 1;
|
|
|
|
else span->yend = ybottom;
|
|
|
|
|
|
|
|
// get some source image information
|
|
|
|
sw = src->cache_entry.w;
|
|
|
|
|
|
|
|
// 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 > (int)(sw << FP))
|
|
|
|
p[i].u = src->cache_entry.w << FP;
|
|
|
|
|
|
|
|
if (p[i].v < 0) p[i].v = 0;
|
|
|
|
else if (p[i].v > (int)(sw << FP))
|
|
|
|
p[i].v = src->cache_entry.h << FP;
|
|
|
|
}
|
|
|
|
|
|
|
|
// allocate some spans to hold out span list
|
|
|
|
if (span->size < (span->yend - span->ystart + 1))
|
|
|
|
{
|
|
|
|
free(span->spans);
|
|
|
|
span->size = (span->yend - span->ystart + 1);
|
|
|
|
span->spans = calloc(1, span->size * sizeof(Line));
|
|
|
|
}
|
|
|
|
if (!span->spans) return;
|
|
|
|
|
|
|
|
// calculate the spans list
|
|
|
|
_calc_spans(p, span->spans, span->ystart, span->yend, cx, cy, cw, ch);
|
|
|
|
|
|
|
|
// if operation is solid, bypass buf and draw func and draw direct to dst
|
|
|
|
if ((!src->cache_entry.flags.alpha) && (!dst->cache_entry.flags.alpha) &&
|
|
|
|
(!dc->mul.use) && (!span->havea))
|
|
|
|
{
|
|
|
|
span->direct = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_Bool
|
|
|
|
evas_common_map_rgba_prepare(RGBA_Image *src, RGBA_Image *dst,
|
|
|
|
RGBA_Draw_Context *dc,
|
|
|
|
RGBA_Map *m)
|
|
|
|
{
|
|
|
|
RGBA_Map_Cutout *spans;
|
2013-12-14 01:28:56 -08:00
|
|
|
Cutout_Rects *rects = NULL;
|
2012-07-04 02:39:23 -07:00
|
|
|
Cutout_Rect *r;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if ((!dc->cutout.rects) && (!dc->clip.use))
|
|
|
|
{
|
|
|
|
evas_common_draw_context_clip_clip(dc, 0, 0,
|
|
|
|
dst->cache_entry.w, dst->cache_entry.h);
|
|
|
|
if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
|
|
|
|
{
|
|
|
|
_rgba_map_cutout_resize(m, 0);
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
_rgba_map_cutout_resize(m, 1);
|
|
|
|
if (!m->engine_data) return EINA_FALSE;
|
|
|
|
|
|
|
|
spans = m->engine_data;
|
|
|
|
|
|
|
|
_evas_common_map_rgba_span(&spans->spans[0], src, dst, dc, m->pts,
|
|
|
|
0, 0,
|
|
|
|
dst->cache_entry.w, dst->cache_entry.h);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
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))
|
|
|
|
{
|
|
|
|
_rgba_map_cutout_resize(m, 0);
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
spans = m->engine_data;
|
|
|
|
if (spans)
|
|
|
|
{
|
|
|
|
rects = spans->rects;
|
|
|
|
spans->rects = NULL;
|
|
|
|
}
|
|
|
|
rects = evas_common_draw_context_apply_cutouts(dc, rects);
|
|
|
|
_rgba_map_cutout_resize(m, rects->active);
|
|
|
|
|
|
|
|
spans = m->engine_data;
|
|
|
|
if (!spans)
|
|
|
|
{
|
|
|
|
evas_common_draw_context_apply_clear_cutouts(rects);
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
spans->rects = rects;
|
|
|
|
for (i = 0; i < spans->rects->active; ++i)
|
|
|
|
{
|
|
|
|
r = spans->rects->rects + i;
|
|
|
|
|
|
|
|
_evas_common_map_rgba_span(&spans->spans[i], src, dst, dc, m->pts,
|
|
|
|
r->x, r->y, r->w, r->h);
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2012-10-15 20:15:40 -07:00
|
|
|
#ifdef BUILD_MMX
|
|
|
|
# undef FUNC_NAME
|
|
|
|
# undef FUNC_NAME_DO
|
2012-12-17 13:28:08 -08:00
|
|
|
# define FUNC_NAME _evas_common_map_rgba_internal_mmx
|
2012-10-15 20:15:40 -07:00
|
|
|
# define FUNC_NAME_DO evas_common_map_rgba_internal_mmx_do
|
|
|
|
# undef SCALE_USING_MMX
|
|
|
|
# define SCALE_USING_MMX
|
|
|
|
# include "evas_map_image_internal.c"
|
2009-10-28 23:52:51 -07:00
|
|
|
#endif
|
2009-10-22 09:06:32 -07:00
|
|
|
|
2012-10-15 20:15:40 -07:00
|
|
|
#undef FUNC_NAME
|
|
|
|
#undef FUNC_NAME_DO
|
2012-12-17 13:30:07 -08:00
|
|
|
#define FUNC_NAME _evas_common_map_rgba_internal
|
2012-10-15 20:15:40 -07:00
|
|
|
#define FUNC_NAME_DO evas_common_map_rgba_internal_do
|
|
|
|
#undef SCALE_USING_MMX
|
|
|
|
#include "evas_map_image_internal.c"
|
|
|
|
|
2013-12-19 21:02:48 -08:00
|
|
|
# ifdef BUILD_NEON
|
|
|
|
# undef FUNC_NAME
|
|
|
|
# undef FUNC_NAME_DO
|
|
|
|
# define FUNC_NAME _evas_common_map_rgba_internal_neon
|
|
|
|
# define FUNC_NAME_DO evas_common_map_rgba_internal_neon_do
|
|
|
|
# undef SCALE_USING_NEON
|
|
|
|
# define SCALE_USING_NEON
|
|
|
|
# undef SCALE_USING_MMX
|
|
|
|
# include "evas_map_image_internal.c"
|
|
|
|
# undef SCALE_USING_NEON
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2012-12-17 13:30:07 -08:00
|
|
|
#ifdef BUILD_MMX
|
|
|
|
void evas_common_map_rgba_internal_mmx(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Map_Point *p, int smooth, int level)
|
|
|
|
{
|
|
|
|
int clip_x, clip_y, clip_w, clip_h;
|
|
|
|
DATA32 mul_col;
|
|
|
|
|
|
|
|
if (dc->clip.use)
|
|
|
|
{
|
|
|
|
clip_x = dc->clip.x;
|
|
|
|
clip_y = dc->clip.y;
|
|
|
|
clip_w = dc->clip.w;
|
|
|
|
clip_h = dc->clip.h;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
clip_x = clip_y = 0;
|
|
|
|
clip_w = dst->cache_entry.w;
|
|
|
|
clip_h = dst->cache_entry.h;
|
|
|
|
}
|
|
|
|
|
|
|
|
mul_col = dc->mul.use ? dc->mul.col : 0xffffffff;
|
|
|
|
|
|
|
|
_evas_common_map_rgba_internal_mmx(src, dst,
|
|
|
|
clip_x, clip_y, clip_w, clip_h,
|
|
|
|
mul_col, dc->render_op,
|
2014-11-19 03:08:03 -08:00
|
|
|
p, smooth, dc->anti_alias, level,
|
|
|
|
dc->clip.mask, dc->clip.mask_x, dc->clip.mask_y);
|
2012-12-17 13:30:07 -08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void evas_common_map_rgba_internal(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Map_Point *p, int smooth, int level)
|
|
|
|
{
|
|
|
|
int clip_x, clip_y, clip_w, clip_h;
|
|
|
|
DATA32 mul_col;
|
|
|
|
|
|
|
|
if (dc->clip.use)
|
|
|
|
{
|
|
|
|
clip_x = dc->clip.x;
|
|
|
|
clip_y = dc->clip.y;
|
|
|
|
clip_w = dc->clip.w;
|
|
|
|
clip_h = dc->clip.h;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
clip_x = clip_y = 0;
|
|
|
|
clip_w = dst->cache_entry.w;
|
|
|
|
clip_h = dst->cache_entry.h;
|
|
|
|
}
|
|
|
|
|
|
|
|
mul_col = dc->mul.use ? dc->mul.col : 0xffffffff;
|
|
|
|
|
|
|
|
_evas_common_map_rgba_internal(src, dst,
|
|
|
|
clip_x, clip_y, clip_w, clip_h,
|
|
|
|
mul_col, dc->render_op,
|
2014-11-19 03:08:03 -08:00
|
|
|
p, smooth, dc->anti_alias, level,
|
|
|
|
dc->clip.mask, dc->clip.mask_x, dc->clip.mask_y);
|
2012-12-17 13:30:07 -08:00
|
|
|
}
|
|
|
|
|
2013-12-19 23:09:10 -08:00
|
|
|
#ifdef BUILD_NEON
|
2013-12-19 21:02:48 -08:00
|
|
|
void evas_common_map_rgba_internal_neon(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Map_Point *p, int smooth, int level)
|
|
|
|
{
|
|
|
|
int clip_x, clip_y, clip_w, clip_h;
|
|
|
|
DATA32 mul_col;
|
|
|
|
|
|
|
|
if (dc->clip.use)
|
|
|
|
{
|
|
|
|
clip_x = dc->clip.x;
|
|
|
|
clip_y = dc->clip.y;
|
|
|
|
clip_w = dc->clip.w;
|
|
|
|
clip_h = dc->clip.h;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
clip_x = clip_y = 0;
|
|
|
|
clip_w = dst->cache_entry.w;
|
|
|
|
clip_h = dst->cache_entry.h;
|
|
|
|
}
|
|
|
|
|
|
|
|
mul_col = dc->mul.use ? dc->mul.col : 0xffffffff;
|
|
|
|
|
|
|
|
_evas_common_map_rgba_internal_neon(src, dst,
|
|
|
|
clip_x, clip_y, clip_w, clip_h,
|
|
|
|
mul_col, dc->render_op,
|
2014-11-19 03:08:03 -08:00
|
|
|
p, smooth, dc->anti_alias, level,
|
|
|
|
dc->clip.mask, dc->clip.mask_x, dc->clip.mask_y);
|
2013-12-19 21:02:48 -08:00
|
|
|
}
|
2013-12-19 23:09:10 -08:00
|
|
|
#endif
|
2013-12-19 21:02:48 -08:00
|
|
|
|
2009-10-28 23:52:51 -07:00
|
|
|
EAPI void
|
2012-11-29 12:55:16 -08:00
|
|
|
evas_common_map_rgba_cb(RGBA_Image *src, RGBA_Image *dst,
|
|
|
|
RGBA_Draw_Context *dc,
|
|
|
|
int npoints EINA_UNUSED, RGBA_Map_Point *p,
|
|
|
|
int smooth, int level,
|
|
|
|
Evas_Common_Map_RGBA_Cb cb)
|
2009-10-28 23:52:51 -07:00
|
|
|
{
|
|
|
|
Cutout_Rect *r;
|
|
|
|
int c, cx, cy, cw, ch;
|
|
|
|
int i;
|
2013-01-11 11:57:09 -08:00
|
|
|
|
2009-10-28 23:52:51 -07:00
|
|
|
if (src->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
|
2018-08-29 21:46:41 -07:00
|
|
|
evas_cache_image_load_data(&src->cache_entry);
|
2013-01-11 11:57:09 -08:00
|
|
|
|
2009-10-28 23:52:51 -07:00
|
|
|
evas_common_image_colorspace_normalize(src);
|
2014-01-09 19:47:27 -08:00
|
|
|
if ((!src->image.data) || (!dst->image.data)) return;
|
2012-11-29 12:55:16 -08:00
|
|
|
|
2010-05-01 06:27:05 -07:00
|
|
|
if ((!dc->cutout.rects) && (!dc->clip.use))
|
2009-10-23 06:17:22 -07:00
|
|
|
{
|
2012-11-29 12:55:16 -08:00
|
|
|
cb(src, dst, dc, p, smooth, level);
|
2009-10-28 23:52:51 -07:00
|
|
|
return;
|
2009-10-23 06:17:22 -07:00
|
|
|
}
|
2009-10-28 23:52:51 -07:00
|
|
|
/* 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))
|
2009-10-17 03:25:51 -07:00
|
|
|
{
|
2009-10-28 23:52:51 -07:00
|
|
|
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
|
|
|
|
return;
|
2009-10-22 08:51:18 -07:00
|
|
|
}
|
2016-11-16 16:05:56 -08:00
|
|
|
dc->cache.rects = evas_common_draw_context_apply_cutouts(dc, dc->cache.rects);
|
|
|
|
for (i = 0; i < dc->cache.rects->active; ++i)
|
2009-10-22 08:51:18 -07:00
|
|
|
{
|
2016-11-16 16:05:56 -08:00
|
|
|
r = dc->cache.rects->rects + i;
|
2009-10-28 23:52:51 -07:00
|
|
|
evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
|
2012-11-29 12:55:16 -08:00
|
|
|
cb(src, dst, dc, p, smooth, level);
|
2009-10-17 03:25:51 -07:00
|
|
|
}
|
2016-11-16 16:05:56 -08:00
|
|
|
evas_common_draw_context_cache_update(dc);
|
2009-10-28 23:52:51 -07:00
|
|
|
/* restore clip info */
|
|
|
|
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
|
2009-10-17 03:25:51 -07:00
|
|
|
}
|
2012-07-04 02:39:23 -07:00
|
|
|
|
2013-01-11 11:57:09 -08:00
|
|
|
EAPI Eina_Bool
|
2012-12-17 13:30:07 -08:00
|
|
|
evas_common_map_thread_rgba_cb(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Map *map, int smooth, int level, int offset, Evas_Common_Map_Thread_RGBA_Cb cb)
|
|
|
|
{
|
|
|
|
Cutout_Rect *r;
|
|
|
|
int c, cx, cy, cw, ch;
|
|
|
|
int i;
|
2013-01-11 11:57:09 -08:00
|
|
|
Eina_Bool ret = EINA_FALSE;
|
2012-12-17 13:30:07 -08:00
|
|
|
|
|
|
|
if (src->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
|
2018-08-29 21:46:41 -07:00
|
|
|
evas_cache_image_load_data(&src->cache_entry);
|
2012-12-17 13:30:07 -08:00
|
|
|
|
|
|
|
evas_common_image_colorspace_normalize(src);
|
|
|
|
|
2014-01-09 19:47:27 -08:00
|
|
|
if ((!src->image.data) || (!dst->image.data)) return EINA_FALSE;
|
2012-12-17 13:30:07 -08:00
|
|
|
|
|
|
|
if ((!dc->cutout.rects) && (!dc->clip.use))
|
|
|
|
{
|
2013-01-11 11:57:09 -08:00
|
|
|
return cb(src, dst, dc, map, smooth, level, offset);
|
2012-12-17 13:30:07 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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;
|
2013-01-11 11:57:09 -08:00
|
|
|
return EINA_FALSE;
|
2012-12-17 13:30:07 -08:00
|
|
|
}
|
|
|
|
|
2016-11-16 16:05:56 -08:00
|
|
|
dc->cache.rects = evas_common_draw_context_apply_cutouts(dc, dc->cache.rects);
|
|
|
|
for (i = 0; i < dc->cache.rects->active; ++i)
|
2012-12-17 13:30:07 -08:00
|
|
|
{
|
2016-11-16 16:05:56 -08:00
|
|
|
r = dc->cache.rects->rects + i;
|
2012-12-17 13:30:07 -08:00
|
|
|
evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
|
2013-01-11 11:57:09 -08:00
|
|
|
ret |= cb(src, dst, dc, map, smooth, level, offset);
|
2012-12-17 13:30:07 -08:00
|
|
|
}
|
2016-11-16 16:05:56 -08:00
|
|
|
evas_common_draw_context_cache_update(dc);
|
2012-12-17 13:30:07 -08:00
|
|
|
/* restore clip info */
|
|
|
|
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
|
2013-01-11 11:57:09 -08:00
|
|
|
|
|
|
|
return ret;
|
2012-12-17 13:30:07 -08:00
|
|
|
}
|
|
|
|
|
2012-11-29 12:55:16 -08:00
|
|
|
EAPI void
|
|
|
|
evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst,
|
|
|
|
RGBA_Draw_Context *dc,
|
|
|
|
int npoints EINA_UNUSED, RGBA_Map_Point *p,
|
|
|
|
int smooth, int level)
|
|
|
|
{
|
|
|
|
Evas_Common_Map_RGBA_Cb cb;
|
|
|
|
#ifdef BUILD_MMX
|
|
|
|
int mmx, sse, sse2;
|
|
|
|
|
|
|
|
evas_common_cpu_can_do(&mmx, &sse, &sse2);
|
|
|
|
if (mmx)
|
|
|
|
cb = evas_common_map_rgba_internal_mmx;
|
|
|
|
else
|
2013-12-19 21:02:48 -08:00
|
|
|
#endif
|
|
|
|
#ifdef BUILD_NEON
|
|
|
|
if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
|
|
|
|
cb = evas_common_map_rgba_internal_neon;
|
|
|
|
else
|
2012-11-29 12:55:16 -08:00
|
|
|
#endif
|
|
|
|
cb = evas_common_map_rgba_internal;
|
|
|
|
|
|
|
|
evas_common_map_rgba_cb(src, dst, dc, npoints, p, smooth, level, cb);
|
|
|
|
}
|
|
|
|
|
2012-12-17 13:30:07 -08:00
|
|
|
EAPI void
|
2014-11-19 03:08:03 -08:00
|
|
|
evas_common_map_rgba_draw(RGBA_Image *src, RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 mul_col, int render_op, int npoints EINA_UNUSED, RGBA_Map_Point *p, int smooth, Eina_Bool anti_alias, int level, RGBA_Image *mask_ie, int mask_x, int mask_y)
|
2012-12-17 13:30:07 -08:00
|
|
|
{
|
|
|
|
#ifdef BUILD_MMX
|
|
|
|
int mmx, sse, sse2;
|
|
|
|
|
|
|
|
evas_common_cpu_can_do(&mmx, &sse, &sse2);
|
|
|
|
if (mmx)
|
|
|
|
_evas_common_map_rgba_internal_mmx(src, dst,
|
|
|
|
clip_x, clip_y, clip_w, clip_h,
|
|
|
|
mul_col, render_op,
|
2014-11-19 03:08:03 -08:00
|
|
|
p, smooth, anti_alias, level,
|
|
|
|
mask_ie, mask_x, mask_y);
|
2012-12-17 13:30:07 -08:00
|
|
|
else
|
2013-12-19 21:02:48 -08:00
|
|
|
#endif
|
|
|
|
#ifdef BUILD_NEON
|
|
|
|
if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
|
|
|
|
_evas_common_map_rgba_internal_neon(src, dst,
|
|
|
|
clip_x, clip_y, clip_w, clip_h,
|
|
|
|
mul_col, render_op,
|
2014-11-19 03:08:03 -08:00
|
|
|
p, smooth, anti_alias, level,
|
|
|
|
mask_ie, mask_x, mask_y);
|
2013-12-19 21:02:48 -08:00
|
|
|
else
|
2012-12-17 13:30:07 -08:00
|
|
|
#endif
|
|
|
|
_evas_common_map_rgba_internal(src, dst,
|
|
|
|
clip_x, clip_y, clip_w, clip_h,
|
|
|
|
mul_col, render_op,
|
2014-11-19 03:08:03 -08:00
|
|
|
p, smooth, anti_alias, level,
|
|
|
|
mask_ie, mask_x, mask_y);
|
2012-12-17 13:30:07 -08:00
|
|
|
}
|
|
|
|
|
2012-07-04 02:39:23 -07:00
|
|
|
EAPI void
|
|
|
|
evas_common_map_rgba_do(const Eina_Rectangle *clip,
|
|
|
|
RGBA_Image *src, RGBA_Image *dst,
|
|
|
|
RGBA_Draw_Context *dc,
|
|
|
|
const RGBA_Map *m,
|
|
|
|
int smooth, int level)
|
|
|
|
{
|
|
|
|
#ifdef BUILD_MMX
|
|
|
|
int mmx, sse, sse2;
|
|
|
|
#endif
|
|
|
|
const Cutout_Rects *rects;
|
|
|
|
const RGBA_Map_Cutout *spans;
|
|
|
|
Eina_Rectangle area;
|
|
|
|
Cutout_Rect *r;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
#ifdef BUILD_MMX
|
|
|
|
evas_common_cpu_can_do(&mmx, &sse, &sse2);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
spans = m->engine_data;
|
|
|
|
rects = spans->rects;
|
|
|
|
if (rects->active == 0 &&
|
|
|
|
spans->count == 1)
|
|
|
|
{
|
|
|
|
evas_common_draw_context_set_clip(dc, clip->x, clip->y, clip->w, clip->h);
|
|
|
|
#ifdef BUILD_MMX
|
|
|
|
if (mmx)
|
|
|
|
evas_common_map_rgba_internal_mmx_do(src, dst, dc,
|
2014-11-25 19:22:55 -08:00
|
|
|
&spans->spans[0], smooth,
|
|
|
|
dc->anti_alias, level);
|
2012-07-04 02:39:23 -07:00
|
|
|
else
|
2013-12-19 21:02:48 -08:00
|
|
|
#endif
|
|
|
|
#ifdef BUILD_NEON
|
|
|
|
if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
|
|
|
|
evas_common_map_rgba_internal_neon_do(src, dst, dc,
|
2014-11-25 19:22:55 -08:00
|
|
|
&spans->spans[0], smooth,
|
|
|
|
dc->anti_alias, level);
|
2013-12-19 21:02:48 -08:00
|
|
|
else
|
2012-07-04 02:39:23 -07:00
|
|
|
#endif
|
|
|
|
evas_common_map_rgba_internal_do(src, dst, dc,
|
2014-11-25 19:22:55 -08:00
|
|
|
&spans->spans[0], smooth,
|
|
|
|
dc->anti_alias, level);
|
2012-10-15 20:15:40 -07:00
|
|
|
return;
|
2012-07-04 02:39:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < rects->active; ++i)
|
|
|
|
{
|
|
|
|
r = rects->rects + i;
|
|
|
|
|
|
|
|
EINA_RECTANGLE_SET(&area, r->x, r->y, r->w, r->h);
|
|
|
|
if (!eina_rectangle_intersection(&area, clip)) continue ;
|
|
|
|
evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h);
|
|
|
|
#ifdef BUILD_MMX
|
|
|
|
if (mmx)
|
2014-11-25 19:22:55 -08:00
|
|
|
{
|
|
|
|
evas_common_map_rgba_internal_mmx_do(src, dst, dc,
|
|
|
|
&spans->spans[i], smooth,
|
|
|
|
dc->anti_alias, level);
|
|
|
|
}
|
2012-07-04 02:39:23 -07:00
|
|
|
else
|
2013-12-19 21:02:48 -08:00
|
|
|
#endif
|
|
|
|
#ifdef BUILD_NEON
|
|
|
|
if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
|
|
|
|
evas_common_map_rgba_internal_neon_do(src, dst, dc,
|
2014-11-25 19:22:55 -08:00
|
|
|
&spans->spans[i], smooth,
|
|
|
|
dc->anti_alias, level);
|
2013-12-19 21:02:48 -08:00
|
|
|
else
|
2012-07-04 02:39:23 -07:00
|
|
|
#endif
|
|
|
|
evas_common_map_rgba_internal_do(src, dst, dc,
|
2014-11-25 19:22:55 -08:00
|
|
|
&spans->spans[i], smooth,
|
|
|
|
dc->anti_alias, level);
|
2012-07-04 02:39:23 -07:00
|
|
|
}
|
|
|
|
}
|