From 25fd02f86f3914344516798328c65bbe94fdd033 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Mon, 8 Apr 2019 13:21:07 +0900 Subject: [PATCH] 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 --- src/lib/evas/common/evas_map_image_internal_high.c | 160 ++++++++++++++++++++- 1 file changed, 159 insertions(+), 1 deletion(-) diff --git a/src/lib/evas/common/evas_map_image_internal_high.c b/src/lib/evas/common/evas_map_image_internal_high.c index f842c74..ac8ca1c 100644 --- a/src/lib/evas/common/evas_map_image_internal_high.c +++ b/src/lib/evas/common/evas_map_image_internal_high.c @@ -335,6 +335,162 @@ _map_aa_apply(AASpans *aa_spans, DATA32 *dst, int dw) } /************************** TEXTURE MAPPING CODE ******************************/ + +#if 0 //We only use biliear(smooth) mapping logic right now. +static void +_map_triangle_draw_point(RGBA_Image *src, RGBA_Image *dst, + int cx, int cy, int cw, int ch, + RGBA_Image *mask, int mx, int my, + int ystart, int yend, + DATA32 *tbuf, RGBA_Gfx_Func func, RGBA_Gfx_Func func2, + DATA32 mul_col, AASpans *aa_spans, + Eina_Bool col_blend) +{ + float _dudx = dudx, _dvdx = dvdx; + float _dxdya = dxdya, _dxdyb = dxdyb, _dudya = dudya, _dvdya = dvdya; + float _xa = xa, _xb = xb, _ua = ua, _va = va; + DATA32 *sbuf = src->image.data; + DATA32 *dbuf = dst->image.data; + int sw = src->cache_entry.w; + int sh = src->cache_entry.h; + int dw = dst->cache_entry.w; + int x, y, x1, x2, uu, vv, ay; + float dx, u, v; + float _dcdx[4], _dcdya[4], _ca[4], c[4]; + DATA32 *buf, *tmp; + DATA8 *mbuf; + + //Range exception handling + if (ystart >= (cy + ch)) return; + if (ystart < cy) ystart = cy; + if (yend > (cy + ch)) yend = (cy + ch); + + if (col_blend) + for (int i = 0; i < 4; i++) + { + _dcdx[i] = dcdx[i]; + _dcdya[i] = dcdya[i]; + _ca[i] = ca[i]; + } + + //Loop through all lines in the segment + y = ystart; + + while (y < yend) + { + x1 = _xa; + x2 = _xb; + + //Range exception handling + //OPTIMIZE ME, handle in advance? + if (x1 < cx) x1 = cx; + if (x2 > (cx + cw)) x2 = (cx + cw); + + if (aa_spans) + { + ay = y - aa_spans->ystart; + if (aa_spans->lines[ay].x[0] > x1) aa_spans->lines[ay].x[0] = x1; + if (aa_spans->lines[ay].x[1] < x2) aa_spans->lines[ay].x[1] = x2; + } + + if ((x2 - x1) < 1) goto next; + + //Perform subtexel pre-stepping on UV + dx = 1 - (_xa - x1); + u = _ua + dx * _dudx; + v = _va + dx * _dvdx; + if (col_blend) + { + c[0] = _ca[0] + dx * _dcdx[0]; + c[1] = _ca[1] + dx * _dcdx[1]; + c[2] = _ca[2] + dx * _dcdx[2]; + c[3] = _ca[3] + dx * _dcdx[3]; + } + + //Direct draw or blending intervention? + if (tbuf) buf = tbuf; + else buf = dbuf + ((y * dw) + x1); + + x = x1; + + //Draw horizontal line + while (x++ < x2) + { + uu = (int) u; + vv = (int) v; + + //Range exception handling + //FIXME: handle in advance? + if (uu >= sw) uu = sw - 1; + if (vv >= sh) vv = sh - 1; + + //Copy pixel from texture to screen + if (!col_blend) + { + *(buf) = sbuf[(vv * sw) + uu]; + } + //Vertex Color Blending + else + { + DATA32 tmp = (((int) c[0]) << 24) | (((int) c[1]) << 16) | (((int) c[2]) << 8) | ((int) c[3]); + *buf = MUL4_SYM(tmp, sbuf[(vv * sw) + uu]); + c[0] += _dcdx[0]; + c[1] += _dcdx[1]; + c[2] += _dcdx[2]; + c[3] += _dcdx[3]; + } + + //Step UV horizontally + u += _dudx; + v += _dvdx; + ++buf; + } + if (tbuf) + { + tmp = dbuf + ((y * dw) + x1); + int len = x2 - x1; + if (!mask) func(tbuf, NULL, mul_col, tmp, len); + else + { + mbuf = mask->image.data8 + + (y - my) * mask->cache_entry.w + (x1 - mx); + if (mul_col != 0xffffffff) + func2(tbuf, NULL, mul_col, tbuf, len); + func(tbuf, mbuf, 0, tmp, len); + } + } +next: + //Step along both edges + _xa += _dxdya; + _xb += _dxdyb; + _ua += _dudya; + _va += _dvdya; + + if (col_blend) + { + _ca[0] += _dcdya[0]; + _ca[1] += _dcdya[1]; + _ca[2] += _dcdya[2]; + _ca[3] += _dcdya[3]; + } + + y++; + } + xa = _xa; + xb = _xb; + ua = _ua; + va = _va; + + if (col_blend) + { + ca[0] = _ca[0]; + ca[1] = _ca[1]; + ca[2] = _ca[2]; + ca[3] = _ca[3]; + } +} +#endif + static void _map_triangle_draw_linear(RGBA_Image *src, RGBA_Image *dst, int cx, int cy, int cw, int ch, @@ -764,7 +920,9 @@ _evas_common_map_rgba_internal_high(RGBA_Image *src, RGBA_Image *dst, Eina_Bool dst_alpha = dst->cache_entry.flags.alpha; Eina_Bool col_blend = EINA_FALSE; //Necessary blending vertex color? - //FIXME: we cannot apply anti_aliasing per polygons. + /* FIXME: efl_ui_textpath should not use anti-aliasing. + If we have a proper method to select this function optionally, + we can enable AA then. */ anti_alias = EINA_FALSE; /* Prepare points data. -- 2.7.4