canvas map: introduce a new texture mapping for better quality.
authorHermet Park <hermetpark@gmail.com>
Mon, 8 Apr 2019 04:21:07 +0000 (13:21 +0900)
committerShinwoo Kim <cinoo.kim@samsung.com>
Wed, 17 Apr 2019 01:03:21 +0000 (10:03 +0900)
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

index f842c74..ac8ca1c 100644 (file)
@@ -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.