sw_engine raster: fix a crash at the texmap clipping. 60/288760/1
authorHermet Park <chuneon.park@samsung.com>
Fri, 17 Dec 2021 08:23:55 +0000 (17:23 +0900)
committerMichal Szczecinski <m.szczecinsk@partner.samsung.com>
Wed, 22 Feb 2023 11:26:19 +0000 (12:26 +0100)
Handle correctly duplicated spans from the multiple y span data.

Previous logic only expected the one single y span data from the rle.
However rle might have multiple y span data if the anti-aliasing is applied.

This patch also removed the bad design of the common engine
which handles the anti-alising option to ignore the anti-aliasing rle generation.

Just realized, it's difficult to control that condition due to scene-composition.

Change-Id: I0caab0e22b0bb88bf0c7ed25b58229c216579086

src/lib/sw_engine/tvgSwRasterTexmapInternal.h
src/lib/sw_engine/tvgSwRenderer.cpp
src/lib/tvgPaint.cpp
src/lib/tvgRender.h

index 782c8f6cb368fec1a6d0c7099d4480540217b576..0c6bf13d1b2cf0cb76a379e5f4ee4f59da3e2486 100644 (file)
@@ -30,7 +30,7 @@
     int32_t dw = surface->stride;
     int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay;
     int32_t vv = 0, uu = 0;
-    int32_t minx = 0, maxx = 0;
+    int32_t minx, maxx;
     float dx, u, v, iptr;
     uint32_t* buf;
     SwSpan* span = nullptr;         //used only when rle based.
     if (!_arrange(image, region, yStart, yEnd)) return;
 
     //Loop through all lines in the segment
-    y = yStart;
+    uint32_t spanIdx = 0;
 
     if (region) {
         minx = region->min.x;
         maxx = region->max.x;
     } else {
-        span = image->rle->spans + (yStart - image->rle->spans->y);
+        span = image->rle->spans;
+        while (span->y < yStart) {
+            ++span;
+            ++spanIdx;
+        }
     }
 
+    y = yStart;
+
     while (y < yEnd) {
         x1 = _xa;
         x2 = _xb;
 
         if (!region) {
-            minx = span->x;
-            maxx = span->x + span->len;
+            minx = INT32_MAX;
+            maxx = INT32_MIN;
+            //one single row, could be consisted of multiple spans.
+            while (span->y == y && spanIdx < image->rle->size) {
+                if (minx > span->x) minx = span->x;
+                if (maxx < span->x + span->len) maxx = span->x + span->len;
+                ++span;
+                ++spanIdx;
+            }
         }
-             
         if (x1 < minx) x1 = minx;
         if (x2 > maxx) x2 = maxx;
 
@@ -138,12 +150,9 @@ next:
         _ua += _dudya;
         _va += _dvdya;
 
-        if (span) {
-            ++span;
-            y = span->y;
-        } else {
-            y++;
-        }
+        if (!region && spanIdx >= image->rle->size) break;
+
+        ++y;
     }
     xa = _xa;
     xb = _xb;
index 672b9388db15348ecece31febb2b7324b1599b94..78537e7726d8f535c0ae75055d3e451e281a8760 100644 (file)
@@ -111,13 +111,11 @@ struct SwShapeTask : SwTask
         //Fill
         if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) {
             if (visibleFill) {
-                auto antiAlias = (flags & RenderUpdateFlag::IgnoreAliasing) ? false : true;
-
                 /* We assume that if stroke width is bigger than 2,
                    shape outline below stroke could be full covered by stroke drawing.
                    Thus it turns off antialising in that condition.
                    Also, it shouldn't be dash style. */
-                if (strokeAlpha == 255 && sdata->strokeWidth() > 2 && sdata->strokeDash(nullptr) == 0) antiAlias = false;
+                auto antiAlias = (strokeAlpha == 255 && sdata->strokeWidth() > 2 && sdata->strokeDash(nullptr) == 0) ? false : true;
 
                 if (!shapeGenRle(&shape, sdata, antiAlias)) goto err;
             }
index d258dd54e9333990cb43d71a02babfe89a396f81..30e82fbc606abcdb8754fd0f29aeca866d0f7d1e 100644 (file)
@@ -223,15 +223,7 @@ void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransf
             }
         }
         if (!compFastTrack) {
-            //Bad design!: ignore anti-aliasing if the bitmap image is the source of the clip-path!
-            auto tempFlag = pFlag;
-
-            if (id == TVG_CLASS_ID_PICTURE) {
-                auto picture = static_cast<Picture*>(compData->source);
-                if (picture->data(nullptr, nullptr)) tempFlag |= RenderUpdateFlag::IgnoreAliasing;
-            }
-
-            tdata = target->pImpl->update(renderer, pTransform, 255, clips, tempFlag);            
+            tdata = target->pImpl->update(renderer, pTransform, 255, clips, pFlag);
             if (method == CompositeMethod::ClipPath) clips.push(tdata);
         }
     }
index 7621fe204338e4eb50e7971741b0eee7758bafa7..f927947aa62af1ee63d7aa067a645b0b3518754f 100644 (file)
@@ -28,7 +28,7 @@
 namespace tvg
 {
 
-enum RenderUpdateFlag {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, All = 255, IgnoreAliasing = 256};
+enum RenderUpdateFlag {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, All = 255};
 
 struct Surface
 {