sw_engine raster: improve the transformed rle image rasterizer. 76/288376/1
authorHermet Park <chuneon.park@samsung.com>
Fri, 26 Nov 2021 03:10:23 +0000 (12:10 +0900)
committerjykeon <jykeon@samsung.com>
Thu, 16 Feb 2023 02:48:42 +0000 (11:48 +0900)
replace the transformed rle rgba image with the texmap raster.

this patch removes the several scattered transformed image rasterizer,
reuse the unified one texmap method instead.

yay, it's much clean and optimal.

Change-Id: Ie5c1a99b28c5242639618e1f4e41f8912c443b4c

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

index 9987aeb..9ef4cc0 100644 (file)
@@ -265,445 +265,16 @@ static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint32_t color, uint8
 /* RLE Transformed RGBA Image                                           */
 /************************************************************************/
 
-static bool _rasterTransformedMaskedTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
-{
-    TVGLOG("SW_ENGINE", "Transformed Masked Translucent Rle Image");
-
-    auto span = image->rle->spans;
-    auto img = image->data;
-    auto w = image->w;
-    auto h = image->h;
-    auto cbuffer = surface->compositor->image.data;
-
-    for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
-        auto ey1 = span->y * itransform->e12 + itransform->e13;
-        auto ey2 = span->y * itransform->e22 + itransform->e23;
-        auto dst = &surface->buffer[span->y * surface->stride + span->x];
-        auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
-        auto alpha = _multiplyAlpha(span->coverage, opacity);
-        for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) {
-            auto rX = static_cast<uint32_t>(roundf((span->x + x) * itransform->e11 + ey1));
-            auto rY = static_cast<uint32_t>(roundf((span->x + x) * itransform->e21 + ey2));
-            if (rX >= w || rY >= h) continue;
-            auto src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
-            auto tmp = ALPHA_BLEND(src, blendMethod(*cmp));
-            *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
-        }
-    }
-    return true;
-}
-
-
-static bool _rasterTransformedMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t (*blendMethod)(uint32_t))
-{
-    TVGLOG("SW_ENGINE", "Transformed Masked Rle Image");
-
-    auto span = image->rle->spans;
-    auto img = image->data;
-    auto w = image->w;
-    auto h = image->h;
-    auto cbuffer = surface->compositor->image.data;
-
-    for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
-        auto ey1 = span->y * itransform->e12 + itransform->e13;
-        auto ey2 = span->y * itransform->e22 + itransform->e23;
-        auto dst = &surface->buffer[span->y * surface->stride + span->x];
-        auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
-         if (span->coverage == 255) {
-            for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) {
-                auto rX = static_cast<uint32_t>(roundf((span->x + x) * itransform->e11 + ey1));
-                auto rY = static_cast<uint32_t>(roundf((span->x + x) * itransform->e21 + ey2));
-                if (rX >= w || rY >= h) continue;
-                auto tmp = ALPHA_BLEND(img[rY * image->stride + rX], blendMethod(*cmp));
-                *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
-            }
-        } else {
-            for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) {
-                auto rX = static_cast<uint32_t>(roundf((span->x + x) * itransform->e11 + ey1));
-                auto rY = static_cast<uint32_t>(roundf((span->x + x) * itransform->e21 + ey2));
-                if (rX >= w || rY >= h) continue;
-                auto src = ALPHA_BLEND(img[rY * image->stride + rX], span->coverage);
-                auto tmp = ALPHA_BLEND(src, blendMethod(*cmp));
-                *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
-            }
-        }
-    }
-    return true;
-}
-
-
-static bool _rasterTransformedTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t opacity)
-{
-    auto span = image->rle->spans;
-    auto img = image->data;
-    auto w = image->w;
-    auto h = image->h;
-
-    for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
-        auto ey1 = span->y * itransform->e12 + itransform->e13;
-        auto ey2 = span->y * itransform->e22 + itransform->e23;
-        auto dst = &surface->buffer[span->y * surface->stride + span->x];
-        auto alpha = _multiplyAlpha(span->coverage, opacity);
-        for (uint32_t x = 0; x < span->len; ++x, ++dst) {
-            auto rX = static_cast<uint32_t>(roundf((span->x + x) * itransform->e11 + ey1));
-            auto rY = static_cast<uint32_t>(roundf((span->x + x) * itransform->e21 + ey2));
-            if (rX >= w || rY >= h) continue;
-            auto src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
-            *dst = src + ALPHA_BLEND(*dst, _ialpha(src));
-        }
-    }
-    return true;
-}
-
-
-static bool _rasterDownScaledMaskedTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t opacity, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t))
-{
-    TVGLOG("SW_ENGINE", "Down Scaled Masked Translucent Rle Image");
-
-    auto span = image->rle->spans;
-    auto img = image->data;
-    auto w = image->w;
-    auto h = image->h;
-    auto cbuffer = surface->compositor->image.data;
-
-    for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
-        auto ey1 = span->y * itransform->e12 + itransform->e13;
-        auto ey2 = span->y * itransform->e22 + itransform->e23;
-        auto dst = &surface->buffer[span->y * surface->stride + span->x];
-        auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
-        auto alpha = _multiplyAlpha(span->coverage, opacity);
-        for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) {
-            auto rX = static_cast<uint32_t>(roundf((span->x + x) * itransform->e11 + ey1));
-            auto rY = static_cast<uint32_t>(roundf((span->x + x) * itransform->e21 + ey2));
-            if (rX >= w || rY >= h) continue;
-            uint32_t src;
-            if (rX < halfScale || rY < halfScale || rX >= w - halfScale || rY >= h - halfScale) src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
-            else src = ALPHA_BLEND(_interpDownScaler(img, image->stride, h, rX, rY, halfScale), alpha);
-            auto tmp = ALPHA_BLEND(src, _multiplyAlpha(alpha, blendMethod(*cmp)));
-            *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
-        }
-    }
-    return true;
-}
-
-
-static bool _rasterDownScaledMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t))
-{
-    TVGLOG("SW_ENGINE", "Down Scaled Masked Rle Image");
-
-    auto span = image->rle->spans;
-    auto img = image->data;
-    auto w = image->w;
-    auto h = image->h;
-    auto cbuffer = surface->compositor->image.data;
-
-    for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
-        auto ey1 = span->y * itransform->e12 + itransform->e13;
-        auto ey2 = span->y * itransform->e22 + itransform->e23;
-        auto dst = &surface->buffer[span->y * surface->stride + span->x];
-        auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
-        if (span->coverage == 255) {
-            for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) {
-                auto rX = static_cast<uint32_t>(roundf((span->x + x) * itransform->e11 + ey1));
-                auto rY = static_cast<uint32_t>(roundf((span->x + x) * itransform->e21 + ey2));
-                if (rX >= w || rY >= h) continue;
-                uint32_t src;
-                if (rX < halfScale || rY < halfScale || rX >= w - halfScale || rY >= h - halfScale) src = img[rY * image->stride + rX];
-                else src = _interpDownScaler(img, image->stride, h, rX, rY, halfScale);
-                auto tmp = ALPHA_BLEND(src, blendMethod(*cmp));
-                *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
-            }
-        } else {
-            for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) {
-                auto rX = static_cast<uint32_t>(roundf((span->x + x) * itransform->e11 + ey1));
-                auto rY = static_cast<uint32_t>(roundf((span->x + x) * itransform->e21 + ey2));
-                if (rX >= w || rY >= h) continue;
-                uint32_t src;
-                if (rX < halfScale || rY < halfScale || rX >= w - halfScale || rY >= h - halfScale) src = ALPHA_BLEND(img[rY * image->stride + rX], span->coverage);
-                else src = ALPHA_BLEND(_interpDownScaler(img, image->stride, h, rX, rY, halfScale), span->coverage);
-                auto tmp = ALPHA_BLEND(src, _multiplyAlpha(span->coverage, blendMethod(*cmp)));
-                *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
-            }
-        }
-    }
-    return true;
-}
-
-
-static bool _rasterDownScaledTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t opacity, uint32_t halfScale)
-{
-    auto span = image->rle->spans;
-    auto img = image->data;
-    auto w = image->w;
-    auto h = image->h;
-
-    for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
-        auto ey1 = span->y * itransform->e12 + itransform->e13;
-        auto ey2 = span->y * itransform->e22 + itransform->e23;
-        auto dst = &surface->buffer[span->y * surface->stride + span->x];
-        auto alpha = _multiplyAlpha(span->coverage, opacity);
-        for (uint32_t x = 0; x < span->len; ++x, ++dst) {
-            auto rX = static_cast<uint32_t>(roundf((span->x + x) * itransform->e11 + ey1));
-            auto rY = static_cast<uint32_t>(roundf((span->x + x) * itransform->e21 + ey2));
-            if (rX >= w || rY >= h) continue;
-            uint32_t src;
-            if (rX < halfScale || rY < halfScale || rX >= w - halfScale || rY >= h - halfScale) src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
-            else src = ALPHA_BLEND(_interpDownScaler(img, image->stride, h, rX, rY, halfScale), alpha);
-            *dst = src + ALPHA_BLEND(*dst, _ialpha(src));
-        }
-    }
-    return true;
-}
-
-
-static bool _rasterUpScaledMaskedTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
-{
-    TVGLOG("SW_ENGINE", "Up Scaled Masked Translucent Rle Image");
-
-    auto span = image->rle->spans;
-    auto img = image->data;
-    auto w = image->w;
-    auto h = image->h;
-    auto cbuffer = surface->compositor->image.data;
-
-    for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
-        auto ey1 = span->y * itransform->e12 + itransform->e13;
-        auto ey2 = span->y * itransform->e22 + itransform->e23;
-        auto dst = &surface->buffer[span->y * surface->stride + span->x];
-        auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
-        auto alpha = _multiplyAlpha(span->coverage, opacity);
-        for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) {
-            auto fX = (span->x + x) * itransform->e11 + ey1;
-            auto fY = (span->x + x) * itransform->e21 + ey2;
-            auto rX = static_cast<uint32_t>(roundf(fX));
-            auto rY = static_cast<uint32_t>(roundf(fY));
-            if (rX >= w || rY >= h) continue;
-            uint32_t src;
-            if (rX == w - 1 || rY == h - 1) src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
-            else src = ALPHA_BLEND(_interpUpScaler(img, image->stride, h, fX, fY), alpha);
-            auto tmp = ALPHA_BLEND(src, _multiplyAlpha(alpha, blendMethod(*cmp)));
-            *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
-        }
-    }
-    return true;
-}
-
-
-static bool _rasterUpScaledMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t (*blendMethod)(uint32_t))
-{
-    TVGLOG("SW_ENGINE", "Up Scaled Masked Rle Image");
-
-    auto span = image->rle->spans;
-    auto img = image->data;
-    auto w = image->w;
-    auto h = image->h;
-    auto cbuffer = surface->compositor->image.data;
-
-    for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
-        auto ey1 = span->y * itransform->e12 + itransform->e13;
-        auto ey2 = span->y * itransform->e22 + itransform->e23;
-        auto dst = &surface->buffer[span->y * surface->stride + span->x];
-        auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
-        if (span->coverage == 255) {
-            for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) {
-                auto fX = (span->x + x) * itransform->e11 + ey1;
-                auto fY = (span->x + x) * itransform->e21 + ey2;
-                auto rX = static_cast<uint32_t>(roundf(fX));
-                auto rY = static_cast<uint32_t>(roundf(fY));
-                if (rX >= w || rY >= h) continue;
-                uint32_t src;
-                if (rX == w - 1 || rY == h - 1) src = img[rY * image->stride + rX];
-                else src = _interpUpScaler(img, image->stride, h, fX, fY);
-                auto tmp = ALPHA_BLEND(src, blendMethod(*cmp));
-                *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
-            }
-        } else {
-            for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) {
-                auto fX = (span->x + x) * itransform->e11 + ey1;
-                auto fY = (span->x + x) * itransform->e21 + ey2;
-                auto rX = static_cast<uint32_t>(roundf(fX));
-                auto rY = static_cast<uint32_t>(roundf(fY));
-                if (rX >= w || rY >= h) continue;
-                uint32_t src;
-                if (rX == w - 1 || rY == h - 1) src = ALPHA_BLEND(img[rY * image->stride + rX], span->coverage);
-                else src = ALPHA_BLEND(_interpUpScaler(img, image->stride, h, fX, fY), span->coverage);
-                auto tmp = ALPHA_BLEND(src, _multiplyAlpha(span->coverage, blendMethod(*cmp)));
-                *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
-            }
-        }
-    }
-    return true;
-}
-
-
-static bool _rasterUpScaledTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t opacity)
-{
-    auto span = image->rle->spans;
-    auto img = image->data;
-    auto w = image->w;
-    auto h = image->h;
-
-    for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
-        auto ey1 = span->y * itransform->e12 + itransform->e13;
-        auto ey2 = span->y * itransform->e22 + itransform->e23;
-        auto dst = &surface->buffer[span->y * surface->stride + span->x];
-        auto alpha = _multiplyAlpha(span->coverage, opacity);
-        for (uint32_t x = 0; x < span->len; ++x, ++dst) {
-            auto fX = (span->x + x) * itransform->e11 + ey1;
-            auto fY = (span->x + x) * itransform->e21 + ey2;
-            auto rX = static_cast<uint32_t>(roundf(fX));
-            auto rY = static_cast<uint32_t>(roundf(fY));
-            if (rX >= w || rY >= h) continue;
-            uint32_t src;
-            if (rX == w - 1 || rY == h - 1) src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
-            else src = ALPHA_BLEND(_interpUpScaler(img, image->stride, h, fX, fY), alpha);
-            *dst = src + ALPHA_BLEND(*dst, _ialpha(src));
-        }
-    }
-    return true;
-}
-
-
-static bool _rasterTransformedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform)
-{
-    auto span = image->rle->spans;
-
-    for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
-        auto ey1 = span->y * itransform->e12 + itransform->e13;
-        auto ey2 = span->y * itransform->e22 + itransform->e23;
-        auto dst = &surface->buffer[span->y * surface->stride + span->x];
-
-        for (uint32_t x = 0; x < span->len; ++x, ++dst) {
-            auto rX = static_cast<uint32_t>(roundf((span->x + x) * itransform->e11 + ey1));
-            auto rY = static_cast<uint32_t>(roundf((span->x + x) * itransform->e21 + ey2));
-            if (rX >= image->w || rY >= image->h) continue;
-            auto src = ALPHA_BLEND(image->data[rY * image->stride + rX], span->coverage);
-            *dst = src + ALPHA_BLEND(*dst, _ialpha(src));
-        }
-    }
-    return true;
-}
-
-
-static bool _rasterDownScaledRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t halfScale)
-{
-    auto span = image->rle->spans;
-    auto img = image->data;
-    auto w = image->w;
-    auto h = image->h;
-
-    for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
-        auto ey1 = span->y * itransform->e12 + itransform->e13;
-        auto ey2 = span->y * itransform->e22 + itransform->e23;
-        auto dst = &surface->buffer[span->y * surface->stride + span->x];
-        for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) {
-            auto rX = static_cast<uint32_t>(roundf(x * itransform->e11 + ey1));
-            auto rY = static_cast<uint32_t>(roundf(x * itransform->e21 + ey2));
-            if (rX >= w || rY >= h) continue;
-
-            uint32_t src;
-            if (rX < halfScale || rY < halfScale || rX >= w - halfScale || rY >= h - halfScale) src = ALPHA_BLEND(img[rY * image->stride + rX], span->coverage);
-            else src = ALPHA_BLEND(_interpDownScaler(img, image->stride, h, rX, rY, halfScale), span->coverage);
-            *dst = src + ALPHA_BLEND(*dst, _ialpha(src));
-        }
-    }
-    return true;
-}
-
-
-static bool _rasterUpScaledRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform)
-{
-    auto span = image->rle->spans;
-    auto img = image->data;
-    auto w = image->w;
-    auto h = image->h;
-
-    for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
-        auto ey1 = span->y * itransform->e12 + itransform->e13;
-        auto ey2 = span->y * itransform->e22 + itransform->e23;
-        auto dst = &surface->buffer[span->y * surface->stride + span->x];
-        for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) {
-            auto fX = x * itransform->e11 + ey1;
-            auto fY = x * itransform->e21 + ey2;
-            auto rX = static_cast<uint32_t>(roundf(fX));
-            auto rY = static_cast<uint32_t>(roundf(fY));
-            if (rX >= w || rY >= h) continue;
-            uint32_t src;
-            if (rX == w - 1 || rY == h - 1) src = ALPHA_BLEND(img[rY * image->stride + rX], span->coverage);
-            else src = ALPHA_BLEND(_interpUpScaler(img, image->stride, h, fX, fY), span->coverage);
-            *dst = src + ALPHA_BLEND(*dst, _ialpha(src));
-        }
-    }
-    return true;
-}
-
-
 static bool _transformedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* transform, uint32_t opacity)
 {
-    Matrix itransform;
-    mathIdentity(&itransform);
-    if (transform && !mathInverse(transform, &itransform)) return false;
-
-    auto halfScale = _halfScale(image->scale);
-
     if (_compositing(surface)) {
-        if (opacity == 255) {
-            //Transformed
-            if (mathEqual(image->scale, 1.0f)) {
-                if (surface->compositor->method == CompositeMethod::AlphaMask) {
-                    return _rasterTransformedMaskedRleRGBAImage(surface, image, &itransform, _alpha);
-                } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
-                    return _rasterTransformedMaskedRleRGBAImage(surface, image, &itransform, _ialpha);
-                }
-            //Transformed + Down Scaled
-            } else if (image->scale < DOWN_SCALE_TOLERANCE) {
-                if (surface->compositor->method == CompositeMethod::AlphaMask) {
-                    return _rasterDownScaledMaskedRleRGBAImage(surface, image, &itransform, halfScale, _alpha);
-                } else  if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
-                    return _rasterDownScaledMaskedRleRGBAImage(surface, image, &itransform, halfScale, _ialpha);
-                }
-            //Transformed + Up Scaled
-            } else {
-                if (surface->compositor->method == CompositeMethod::AlphaMask) {
-                    return _rasterUpScaledMaskedRleRGBAImage(surface, image, &itransform, _alpha);
-                } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
-                    return _rasterUpScaledMaskedRleRGBAImage(surface, image, &itransform, _ialpha);
-                }
-            }
-        } else {
-            //Transformed
-            if (mathEqual(image->scale, 1.0f)) {
-                if (surface->compositor->method == CompositeMethod::AlphaMask) {
-                    return _rasterTransformedMaskedTranslucentRleRGBAImage(surface, image, &itransform, opacity, _alpha);
-                } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
-                    return _rasterTransformedMaskedTranslucentRleRGBAImage(surface, image, &itransform, opacity, _ialpha);
-                }
-            //Transformed + Down Scaled
-            } else if (image->scale < DOWN_SCALE_TOLERANCE) {
-                if (surface->compositor->method == CompositeMethod::AlphaMask) {
-                    return _rasterDownScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, opacity, halfScale, _alpha);
-                } else  if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
-                    return _rasterDownScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, opacity, halfScale, _ialpha);
-                }
-            //Transformed + Up Scaled
-            } else {
-                if (surface->compositor->method == CompositeMethod::AlphaMask) {
-                    return _rasterUpScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, opacity, _alpha);
-                } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
-                    return _rasterUpScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, opacity, _ialpha);
-                }
-            }
+        if (surface->compositor->method == CompositeMethod::AlphaMask) {
+            return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, _alpha);
+        } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
+            return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, _ialpha);
         }
     } else {
-        if (opacity == 255) {
-            if (mathEqual(image->scale, 1.0f)) return _rasterTransformedRleRGBAImage(surface, image, &itransform);
-            else if (image->scale < DOWN_SCALE_TOLERANCE) return _rasterDownScaledRleRGBAImage(surface, image, &itransform, halfScale);
-            else return _rasterUpScaledRleRGBAImage(surface, image, &itransform);
-        } else {
-            if (mathEqual(image->scale, 1.0f)) return _rasterTransformedTranslucentRleRGBAImage(surface, image, &itransform, opacity);
-            else if (image->scale < DOWN_SCALE_TOLERANCE) return _rasterDownScaledTranslucentRleRGBAImage(surface, image, &itransform, opacity, halfScale);
-            else return _rasterUpScaledTranslucentRleRGBAImage(surface, image, &itransform, opacity);
-        }
+        return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, nullptr);
     }
     return false;
 }
@@ -1066,12 +637,12 @@ static bool _transformedRGBAImage(SwSurface* surface, const SwImage* image, cons
 {
     if (_compositing(surface)) {
         if (surface->compositor->method == CompositeMethod::AlphaMask) {
-            return _rasterTexmapPolygon(surface, image, transform, region, opacity, _alpha);
+            return _rasterTexmapPolygon(surface, image, transform, &region, opacity, _alpha);
         } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
-            return _rasterTexmapPolygon(surface, image, transform, region, opacity, _ialpha);
+            return _rasterTexmapPolygon(surface, image, transform, &region, opacity, _ialpha);
         }
     } else {
-        return _rasterTexmapPolygon(surface, image, transform, region, opacity, nullptr);
+        return _rasterTexmapPolygon(surface, image, transform, &region, opacity, nullptr);
     }
     return false;
 }
@@ -1385,7 +956,6 @@ static bool _rasterRGBAImage(SwSurface* surface, SwImage* image, const Matrix* t
     if (image->rle) {
         if (image->direct) return _directRleRGBAImage(surface, image, opacity);
         else if (image->scaled) return _scaledRleRGBAImage(surface, image, transform, region, opacity);
-        //OPTIMIZE_ME: Replace with the TexMap Rasterizer
         else return _transformedRleRGBAImage(surface, image, transform, opacity);
     //Whole Image
     } else {
index ca4e303..c7d225d 100644 (file)
@@ -31,6 +31,7 @@ struct Polygon
    Vertex vertex[3];
 };
 
+
 static inline void _swap(float& a, float& b, float& tmp)
 {
     tmp = a;
@@ -44,7 +45,7 @@ static float dxdya, dxdyb, dudya, dvdya;
 static float xa, xb, ua, va;
 
 
-static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox& region, int ystart, int yend, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
+static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
 {
 #define TEXMAP_TRANSLUCENT
 #define TEXMAP_MASKING
@@ -54,7 +55,7 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image,
 }
 
 
-static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox& region, int ystart, int yend, uint32_t (*blendMethod)(uint32_t))
+static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, uint32_t (*blendMethod)(uint32_t))
 {
 #define TEXMAP_MASKING
     #include "tvgSwRasterTexmapInternal.h"
@@ -62,7 +63,7 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image,
 }
 
 
-static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox& region, int ystart, int yend, uint32_t opacity)
+static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, uint32_t opacity)
 {
 #define TEXMAP_TRANSLUCENT
      #include "tvgSwRasterTexmapInternal.h"
@@ -70,14 +71,15 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image,
 }
 
 
-static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox& region, int ystart, int yend)
+static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd)
 {
     #include "tvgSwRasterTexmapInternal.h"
 }
 
 
+
 /* This mapping algorithm is based on Mikael Kalms's. */
-static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t opacity, Polygon& polygon, uint32_t (*blendMethod)(uint32_t))
+static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const SwBBox* region, uint32_t opacity, Polygon& polygon, uint32_t (*blendMethod)(uint32_t))
 {
     float x[3] = {polygon.vertex[0].pt.x, polygon.vertex[1].pt.x, polygon.vertex[2].pt.x};
     float y[3] = {polygon.vertex[0].pt.y, polygon.vertex[1].pt.y, polygon.vertex[2].pt.y};
@@ -139,6 +141,8 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const
     if (mathEqual(y[0], y[1])) side = x[0] > x[1];
     if (mathEqual(y[1], y[2])) side = x[2] > x[1];
 
+    auto regionTop = region ? region->min.y : image->rle->spans->y;  //Normal Image or Rle Image?
+
     //Longer edge is on the left side
     if (!side) {
         //Calculate slopes along left edge
@@ -154,7 +158,7 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const
 
         //Draw upper segment if possibly visible
         if (yi[0] < yi[1]) {
-            off_y = y[0] < region.min.y ? (region.min.y - y[0]) : 0;
+            off_y = y[0] < regionTop ? (regionTop - y[0]) : 0;
             xa += (off_y * dxdya);
             ua += (off_y * dudya);
             va += (off_y * dvdya);
@@ -175,7 +179,7 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const
         }
         //Draw lower segment if possibly visible
         if (yi[1] < yi[2]) {
-            off_y = y[1] < region.min.y ? (region.min.y - y[1]) : 0;
+            off_y = y[1] < regionTop ? (regionTop - y[1]) : 0;
             if (!upper) {
                 xa += (off_y * dxdya);
                 ua += (off_y * dudya);
@@ -201,7 +205,7 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const
 
         //Draw upper segment if possibly visible
         if (yi[0] < yi[1]) {
-            off_y = y[0] < region.min.y ? (region.min.y - y[0]) : 0;
+            off_y = y[0] < regionTop ? (regionTop - y[0]) : 0;
             xb += (off_y *dxdyb);
 
             // Set slopes along left edge and perform subpixel pre-stepping
@@ -225,7 +229,7 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const
         }
         //Draw lower segment if possibly visible
         if (yi[1] < yi[2]) {
-            off_y = y[1] < region.min.y ? (region.min.y - y[1]) : 0;
+            off_y = y[1] < regionTop ? (regionTop - y[1]) : 0;
             if (!upper) xb += (off_y *dxdyb);
 
             // Set slopes along left edge and perform subpixel pre-stepping
@@ -259,8 +263,11 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const
     | /  |
     3 -- 2 
 */
-static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
+static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox* region, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
 {
+    //Exceptions: No dedicated drawing area?
+    if (!region && image->rle->size == 0) return false;
+
    /* Prepare vertices.
       shift XY coordinates to match the sub-pixeling technique. */
     Vertex vertices[4];
@@ -286,6 +293,6 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const
     polygon.vertex[2] = vertices[3];
 
     _rasterPolygonImage(surface, image, region, opacity, polygon, blendMethod);
-    
+
     return true;
 }
\ No newline at end of file
index ce234cf..0a93530 100644 (file)
     int uu = 0;
     float dx, u, v, iptr;
     uint32_t* buf;
+    int regionTop;
+    int regionBottom;
+    SwSpan* span = nullptr;         //used only when rle based.
+
 #ifdef TEXMAP_MASKING
     uint32_t* cmp;
 #endif
 
+    if (region) {
+        regionTop = region->min.y;
+        regionBottom = region->max.y;
+    } else {
+        regionTop = image->rle->spans->y;
+        regionBottom = image->rle->spans[image->rle->size - 1].y;
+    }
+
     //Range exception handling
-    if (ystart >= region.max.y) return;
-    if (ystart < region.min.y) ystart = region.min.y;
-    if (yend > region.max.y) yend = region.max.y;
+    if (yStart >= regionBottom) return;
+    if (yStart < regionTop) yStart = regionTop;
+    if (yEnd > regionBottom) yEnd = regionBottom;
 
     //Loop through all lines in the segment
-    y = ystart;
+    y = yStart;
+
+    if (!region) span = image->rle->spans + (yStart - regionTop);
 
-    while (y < yend) {
+    while (y < yEnd) {
         x1 = _xa;
         x2 = _xb;
 
         //Range exception handling
-        if (x1 < region.min.x) x1 = region.min.x;
-        if (x2 > region.max.x) x2 = region.max.x;
-
-        if ((x2 - x1) < 1) goto next;
-        if ((x1 >= region.max.x) || (x2 <= region.min.x)) goto next;
+        if (region) {
+            if (x1 < region->min.x) x1 = region->min.x;
+            if (x2 > region->max.x) x2 = region->max.x;
+            if ((x2 - x1) < 1) goto next;
+            if ((x1 >= region->max.x) || (x2 <= region->min.x)) goto next;
+        } else {
+            if (x1 < span->x) x1 = span->x;
+            if (x2 > span->x + span->len) x2 = (span->x + span->len);
+            if ((x2 - x1) < 1) goto next;
+            if ((x1 >= (span->x + span->len)) || (x2 <= span->x)) goto next;
+        }
 
         //Perform subtexel pre-stepping on UV
         dx = 1 - (_xa - x1);
 #elif defined(TEXMAP_TRANSLUCENT)
             auto src = ALPHA_BLEND(px, opacity);
 #else
-            auto src = px;            
+            auto src = px;
 #endif
             *buf = src + ALPHA_BLEND(*buf, _ialpha(src));
             ++buf;
@@ -123,7 +143,12 @@ next:
         _ua += _dudya;
         _va += _dvdya;
 
-        y++;
+        if (span) {
+            ++span;
+            y = span->y;
+        } else {
+            y++;
+        }
     }
     xa = _xa;
     xb = _xb;
index 1c0c3c2..672b938 100644 (file)
@@ -111,11 +111,14 @@ 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. */
-                auto antiAlias = (strokeAlpha == 255 && sdata->strokeWidth() > 2 && sdata->strokeDash(nullptr) == 0) ? false : true;
+                if (strokeAlpha == 255 && sdata->strokeWidth() > 2 && sdata->strokeDash(nullptr) == 0) antiAlias = false;
+
                 if (!shapeGenRle(&shape, sdata, antiAlias)) goto err;
             }
             if (auto fill = sdata->fill()) {
index 909e6be..d258dd5 100644 (file)
@@ -201,7 +201,7 @@ void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransf
     if (compData) {
         auto target = compData->target;
         auto method = compData->method;
-        target->pImpl->ctxFlag = ContextFlag::Invalid;   //reset
+        target->pImpl->ctxFlag &= ~ContextFlag::FastTrack;   //reset
 
         /* If transform has no rotation factors && ClipPath / AlphaMasking is a simple rectangle,
            we can avoid regular ClipPath / AlphaMasking sequence but use viewport for performance */
@@ -223,7 +223,15 @@ void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransf
             }
         }
         if (!compFastTrack) {
-            tdata = target->pImpl->update(renderer, pTransform, 255, clips, pFlag);
+            //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);            
             if (method == CompositeMethod::ClipPath) clips.push(tdata);
         }
     }
@@ -249,6 +257,7 @@ void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransf
     return edata;
 }
 
+
 bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transformed)
 {
     Matrix* m = nullptr;
index 1f36ec3..4003bdb 100644 (file)
@@ -67,7 +67,8 @@ namespace tvg
         uint32_t id;
         uint8_t opacity = 255;
 
-        ~Impl() {
+        ~Impl()
+        {
             if (compData) {
                 delete(compData->target);
                 free(compData);
index 955816e..7621fe2 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 = 127};
+enum RenderUpdateFlag {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, All = 255, IgnoreAliasing = 256};
 
 struct Surface
 {