From 875846decf78623d0cc0e623ef391d66b6fc3d38 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 17 Dec 2021 17:23:55 +0900 Subject: [PATCH] sw_engine raster: fix a crash at the texmap clipping. 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 | 33 +++++++++++++++++---------- src/lib/sw_engine/tvgSwRenderer.cpp | 4 +--- src/lib/tvgPaint.cpp | 10 +------- src/lib/tvgRender.h | 2 +- 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/lib/sw_engine/tvgSwRasterTexmapInternal.h b/src/lib/sw_engine/tvgSwRasterTexmapInternal.h index 782c8f6..0c6bf13 100644 --- a/src/lib/sw_engine/tvgSwRasterTexmapInternal.h +++ b/src/lib/sw_engine/tvgSwRasterTexmapInternal.h @@ -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. @@ -42,24 +42,36 @@ 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; diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index 672b938..78537e7 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -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; } diff --git a/src/lib/tvgPaint.cpp b/src/lib/tvgPaint.cpp index d258dd5..30e82fb 100644 --- a/src/lib/tvgPaint.cpp +++ b/src/lib/tvgPaint.cpp @@ -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(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); } } diff --git a/src/lib/tvgRender.h b/src/lib/tvgRender.h index 7621fe2..f927947 100644 --- a/src/lib/tvgRender.h +++ b/src/lib/tvgRender.h @@ -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 { -- 2.7.4