canvas map: introduce a new texture mapping for better quality.
Summary:
This new implementation of evas map texture mapping
is designed for high quality rendering same level to GL.
If you use a high-end device, performance is not too bad, you can turn this on.
You might have practical image quality even in software rendering.
Since this implementation still have a few optimization points (+simd)
and stablizings, it may be useful in somewhat limited envrionments right now.
However the functionality definitely works fine, so please turn this on by
demand (anti_alias + smooth) for a while.
{F3667773} {F3667776} {F3667778}
Reviewers: #committers, devilhorns, raster
Reviewed By: #committers, raster
Subscribers: raster, devilhorns, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D8106
2019-04-07 21:21:07 -07:00
|
|
|
|
2009-10-28 23:52:51 -07:00
|
|
|
// 66.74 % of time
|
|
|
|
static void
|
|
|
|
FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
|
2012-12-17 13:30:07 -08:00
|
|
|
int clip_x, int clip_y, int clip_w, int clip_h,
|
|
|
|
DATA32 mul_col, int render_op,
|
|
|
|
RGBA_Map_Point *p,
|
2019-04-07 22:53:47 -07:00
|
|
|
int smooth, int anti_alias EINA_UNUSED, int level EINA_UNUSED, // level unused for now - for future use
|
2014-11-19 03:08:03 -08:00
|
|
|
RGBA_Image *mask_ie, int mask_x, int mask_y)
|
2009-10-28 23:52:51 -07:00
|
|
|
{
|
|
|
|
int i;
|
2012-12-17 13:30:07 -08:00
|
|
|
int cx, cy, cw, ch;
|
2010-01-21 22:51:27 -08:00
|
|
|
int ytop, ybottom, ystart, yend, y, sw, shp, swp, direct;
|
2009-10-28 23:52:51 -07:00
|
|
|
Line *spans;
|
2009-12-21 07:52:12 -08:00
|
|
|
DATA32 *buf = NULL, *sp;
|
2014-11-19 03:08:03 -08:00
|
|
|
RGBA_Gfx_Func func = NULL, func2 = NULL;
|
2014-02-06 20:39:11 -08:00
|
|
|
Eina_Bool havea = EINA_FALSE;
|
2014-11-19 03:08:03 -08:00
|
|
|
Eina_Bool sa, ssa, da;
|
2018-04-03 03:23:52 -07:00
|
|
|
Eina_Bool saa; //Source alpha overriding with anti-alias flag.
|
2009-10-31 18:32:23 -07:00
|
|
|
int havecol = 4;
|
2009-10-28 23:52:51 -07:00
|
|
|
|
2012-12-17 13:30:07 -08:00
|
|
|
cx = clip_x;
|
|
|
|
cy = clip_y;
|
|
|
|
cw = clip_w;
|
|
|
|
ch = clip_h;
|
|
|
|
|
2014-02-06 20:39:11 -08:00
|
|
|
// find y top line and collect point color info
|
2009-10-28 23:52:51 -07:00
|
|
|
ytop = p[0].y;
|
2014-02-06 20:39:11 -08:00
|
|
|
if ((p[0].col >> 24) < 0xff) havea = EINA_TRUE;
|
2009-10-31 18:32:23 -07:00
|
|
|
if (p[0].col == 0xffffffff) havecol--;
|
2009-10-28 23:52:51 -07:00
|
|
|
for (i = 1; i < 4; i++)
|
|
|
|
{
|
|
|
|
if (p[i].y < ytop) ytop = p[i].y;
|
2014-02-06 20:39:11 -08:00
|
|
|
if ((p[i].col >> 24) < 0xff) havea = EINA_TRUE;
|
2009-10-31 18:32:23 -07:00
|
|
|
if (p[i].col == 0xffffffff) havecol--;
|
2009-10-28 23:52:51 -07:00
|
|
|
}
|
2009-10-31 18:32:23 -07:00
|
|
|
|
2014-02-06 20:39:11 -08:00
|
|
|
// find y bottom line
|
2009-10-28 23:52:51 -07:00
|
|
|
ybottom = p[0].y;
|
|
|
|
for (i = 1; i < 4; i++)
|
|
|
|
{
|
|
|
|
if (p[i].y > ybottom) ybottom = p[i].y;
|
|
|
|
}
|
2013-12-30 20:29:57 -08:00
|
|
|
|
2009-10-28 23:52:51 -07:00
|
|
|
// convert to screen space from fixed point
|
|
|
|
ytop = ytop >> FP;
|
|
|
|
ybottom = ybottom >> FP;
|
2013-12-30 20:29:57 -08:00
|
|
|
|
2009-10-28 23:52:51 -07:00
|
|
|
// if its outside the clip vertical bounds - don't bother
|
|
|
|
if ((ytop >= (cy + ch)) || (ybottom < cy)) return;
|
2013-12-30 20:29:57 -08:00
|
|
|
|
2009-10-28 23:52:51 -07:00
|
|
|
// 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);
|
|
|
|
|
2014-11-19 03:08:03 -08:00
|
|
|
sa = src->cache_entry.flags.alpha;
|
|
|
|
ssa = src->cache_entry.flags.alpha_sparse;
|
|
|
|
da = dst->cache_entry.flags.alpha;
|
|
|
|
|
2009-10-28 23:52:51 -07:00
|
|
|
// 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;
|
2010-09-18 16:16:25 -07:00
|
|
|
else if (p[i].u > (int)(src->cache_entry.w << FP))
|
2009-10-28 23:52:51 -07:00
|
|
|
p[i].u = src->cache_entry.w << FP;
|
2013-12-30 20:29:57 -08:00
|
|
|
|
2009-10-28 23:52:51 -07:00
|
|
|
if (p[i].v < 0) p[i].v = 0;
|
2010-09-18 16:16:25 -07:00
|
|
|
else if (p[i].v > (int)(src->cache_entry.h << FP))
|
2009-10-28 23:52:51 -07:00
|
|
|
p[i].v = src->cache_entry.h << FP;
|
|
|
|
}
|
2013-12-30 20:29:57 -08:00
|
|
|
|
2009-10-28 23:52:51 -07:00
|
|
|
// allocate some spans to hold out span list
|
2015-01-07 00:21:46 -08:00
|
|
|
spans = alloca((yend - ystart + 3) * sizeof(Line));
|
|
|
|
memset(spans, 0, (yend - ystart + 3) * sizeof(Line));
|
2009-10-28 23:52:51 -07:00
|
|
|
|
|
|
|
// calculate the spans list
|
|
|
|
_calc_spans(p, spans, ystart, yend, cx, cy, cw, ch);
|
2013-12-30 20:29:57 -08:00
|
|
|
|
2009-10-28 23:52:51 -07:00
|
|
|
// walk through spans and render
|
2013-12-30 20:29:57 -08:00
|
|
|
|
2009-10-28 23:52:51 -07:00
|
|
|
// if operation is solid, bypass buf and draw func and draw direct to dst
|
|
|
|
direct = 0;
|
2014-11-25 22:12:25 -08:00
|
|
|
|
|
|
|
|
|
|
|
/* FIXME: even if anti-alias is enabled, only edges may require the
|
|
|
|
pixels composition. we can optimize it. */
|
|
|
|
|
2015-01-07 00:30:46 -08:00
|
|
|
if ((!sa) && (!da) &&
|
2019-04-07 22:53:47 -07:00
|
|
|
(mul_col == 0xffffffff) && (!havea) && (!mask_ie))
|
2009-10-31 18:32:23 -07:00
|
|
|
{
|
|
|
|
direct = 1;
|
|
|
|
}
|
2009-10-28 23:52:51 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
buf = alloca(cw * sizeof(DATA32));
|
2018-04-03 03:23:52 -07:00
|
|
|
if (havea) sa = EINA_TRUE;
|
|
|
|
|
2019-04-07 22:53:47 -07:00
|
|
|
saa = sa;
|
2018-04-03 03:23:52 -07:00
|
|
|
|
2014-11-19 03:08:03 -08:00
|
|
|
if (!mask_ie)
|
|
|
|
{
|
|
|
|
if (mul_col != 0xffffffff)
|
2018-04-03 03:23:52 -07:00
|
|
|
func = evas_common_gfx_func_composite_pixel_color_span_get(saa, ssa, mul_col, da, cw, render_op);
|
2014-11-19 03:08:03 -08:00
|
|
|
else
|
2018-04-03 03:23:52 -07:00
|
|
|
func = evas_common_gfx_func_composite_pixel_span_get(saa, ssa, da, cw, render_op);
|
2014-11-19 03:08:03 -08:00
|
|
|
}
|
2009-10-28 23:52:51 -07:00
|
|
|
else
|
2014-11-19 03:08:03 -08:00
|
|
|
{
|
2018-04-03 03:23:52 -07:00
|
|
|
func = evas_common_gfx_func_composite_pixel_mask_span_get(saa, ssa, da, cw, render_op);
|
2014-11-19 03:08:03 -08:00
|
|
|
if (mul_col != 0xffffffff)
|
2018-04-03 03:23:52 -07:00
|
|
|
func2 = evas_common_gfx_func_composite_pixel_color_span_get(saa, ssa, mul_col, da, cw, EVAS_RENDER_COPY);
|
2014-11-19 03:08:03 -08:00
|
|
|
}
|
2018-04-03 03:23:52 -07:00
|
|
|
if (sa) src->cache_entry.flags.alpha = EINA_TRUE;
|
2014-11-25 22:12:25 -08:00
|
|
|
}
|
2014-02-06 20:39:11 -08:00
|
|
|
if (havecol == 0)
|
2009-10-28 23:52:51 -07:00
|
|
|
{
|
2013-12-30 20:29:57 -08:00
|
|
|
#undef COLMUL
|
2009-10-31 18:32:23 -07:00
|
|
|
#include "evas_map_image_core.c"
|
2009-10-28 23:52:51 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-10-31 18:32:23 -07:00
|
|
|
#define COLMUL 1
|
|
|
|
#include "evas_map_image_core.c"
|
2009-10-28 23:52:51 -07:00
|
|
|
}
|
|
|
|
}
|
2012-07-04 02:39:23 -07:00
|
|
|
|
|
|
|
static void
|
|
|
|
FUNC_NAME_DO(RGBA_Image *src, RGBA_Image *dst,
|
|
|
|
RGBA_Draw_Context *dc,
|
|
|
|
const RGBA_Map_Spans *ms,
|
2019-04-07 22:53:47 -07:00
|
|
|
int smooth, int anti_alias EINA_UNUSED, int level EINA_UNUSED) // level unused for now - for future use
|
2012-07-04 02:39:23 -07:00
|
|
|
{
|
|
|
|
Line *spans;
|
|
|
|
DATA32 *buf = NULL, *sp;
|
2014-11-19 03:08:03 -08:00
|
|
|
RGBA_Gfx_Func func = NULL, func2 = NULL;
|
2012-07-04 02:39:23 -07:00
|
|
|
int cx, cy, cw, ch;
|
2012-12-17 13:30:07 -08:00
|
|
|
DATA32 mul_col;
|
2012-07-04 02:39:23 -07:00
|
|
|
int ystart, yend, y, sw, shp, swp, direct;
|
|
|
|
int havecol;
|
|
|
|
int i;
|
2014-11-19 03:08:03 -08:00
|
|
|
Eina_Bool sa, ssa, da;
|
2018-04-03 03:23:52 -07:00
|
|
|
Eina_Bool saa; //Source alpha overriding with anti-alias flag.
|
2014-11-19 03:08:03 -08:00
|
|
|
|
|
|
|
RGBA_Image *mask_ie = dc->clip.mask;
|
|
|
|
int mask_x = dc->clip.mask_x;
|
|
|
|
int mask_y = dc->clip.mask_y;
|
2012-12-17 13:30:07 -08:00
|
|
|
|
2012-07-04 02:39:23 -07:00
|
|
|
cx = dc->clip.x;
|
|
|
|
cy = dc->clip.y;
|
|
|
|
cw = dc->clip.w;
|
|
|
|
ch = dc->clip.h;
|
|
|
|
|
2012-12-17 13:30:07 -08:00
|
|
|
mul_col = dc->mul.use ? dc->mul.col : 0xffffffff;
|
|
|
|
|
2012-07-04 02:39:23 -07:00
|
|
|
if (ms->ystart < cy) ystart = cy;
|
|
|
|
else ystart = ms->ystart;
|
|
|
|
if (ms->yend >= (cy + ch)) yend = (cy + ch) - 1;
|
|
|
|
else yend = ms->yend;
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
havecol = ms->havecol;
|
|
|
|
direct = ms->direct;
|
|
|
|
|
2014-11-19 03:08:03 -08:00
|
|
|
sa = src->cache_entry.flags.alpha;
|
|
|
|
ssa = src->cache_entry.flags.alpha_sparse;
|
|
|
|
da = dst->cache_entry.flags.alpha;
|
|
|
|
|
2012-07-04 02:39:23 -07:00
|
|
|
// allocate some s to hold out span list
|
2015-01-07 04:04:14 -08:00
|
|
|
spans = alloca((yend - ystart + 3) * sizeof(Line));
|
2012-07-04 02:39:23 -07:00
|
|
|
memcpy(spans, &ms->spans[ystart - ms->ystart],
|
2015-01-07 04:04:14 -08:00
|
|
|
(yend - ystart + 3) * sizeof(Line));
|
2013-12-31 01:32:30 -08:00
|
|
|
_clip_spans(spans, ystart, yend, cx, cw, EINA_TRUE);
|
2012-07-04 02:39:23 -07:00
|
|
|
|
|
|
|
// if operation is solid, bypass buf and draw func and draw direct to dst
|
|
|
|
if (!direct)
|
|
|
|
{
|
|
|
|
buf = alloca(cw * sizeof(DATA32));
|
2018-04-03 03:23:52 -07:00
|
|
|
if (ms->havea) sa = EINA_TRUE;
|
|
|
|
|
2019-04-07 22:53:47 -07:00
|
|
|
saa = sa;
|
2018-04-03 03:23:52 -07:00
|
|
|
|
2015-02-09 04:34:04 -08:00
|
|
|
if (!mask_ie)
|
2014-11-19 03:08:03 -08:00
|
|
|
{
|
|
|
|
if (mul_col != 0xffffffff)
|
2018-04-03 03:23:52 -07:00
|
|
|
func = evas_common_gfx_func_composite_pixel_color_span_get(saa, ssa, dc->mul.col, da, cw, dc->render_op);
|
2014-11-19 03:08:03 -08:00
|
|
|
else
|
2018-04-03 03:23:52 -07:00
|
|
|
func = evas_common_gfx_func_composite_pixel_span_get(saa, ssa, da, cw, dc->render_op);
|
2014-11-19 03:08:03 -08:00
|
|
|
}
|
2012-07-04 02:39:23 -07:00
|
|
|
else
|
2014-11-19 03:08:03 -08:00
|
|
|
{
|
2018-04-03 03:23:52 -07:00
|
|
|
func = evas_common_gfx_func_composite_pixel_mask_span_get(saa, ssa, da, cw, dc->render_op);
|
2014-11-19 03:08:03 -08:00
|
|
|
if (mul_col != 0xffffffff)
|
2018-04-03 03:23:52 -07:00
|
|
|
func2 = evas_common_gfx_func_composite_pixel_color_span_get(saa, ssa, dc->mul.col, da, cw, EVAS_RENDER_COPY);
|
2014-11-19 03:08:03 -08:00
|
|
|
}
|
2018-04-03 03:23:52 -07:00
|
|
|
if (sa) src->cache_entry.flags.alpha = EINA_TRUE;
|
2012-07-04 02:39:23 -07:00
|
|
|
}
|
2013-12-30 20:29:57 -08:00
|
|
|
|
2014-02-06 20:39:11 -08:00
|
|
|
if (havecol == 0)
|
2012-07-04 02:39:23 -07:00
|
|
|
{
|
2013-12-30 20:29:57 -08:00
|
|
|
#undef COLMUL
|
2012-07-04 02:39:23 -07:00
|
|
|
#include "evas_map_image_core.c"
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#define COLMUL 1
|
|
|
|
#include "evas_map_image_core.c"
|
|
|
|
}
|
|
|
|
}
|