sw_engine image: introduce the stride property for the image.
authorHermet Park <chuneon.park@samsung.com>
Thu, 11 Nov 2021 06:44:19 +0000 (15:44 +0900)
committerJunsuChoi <jsuya.choi@samsung.com>
Fri, 12 Nov 2021 01:46:50 +0000 (10:46 +0900)
we are considering the larger space of the image buffer,
in this case stride info is necessary.

src/lib/sw_engine/tvgSwCommon.h
src/lib/sw_engine/tvgSwRaster.cpp
src/lib/sw_engine/tvgSwRenderer.cpp

index 6fb9b71..31b6e3b 100644 (file)
@@ -223,7 +223,7 @@ struct SwImage
     SwOutline*   outline = nullptr;
     SwRleData*   rle = nullptr;
     uint32_t*    data = nullptr;
-    uint32_t     w, h;
+    uint32_t     w, h, stride;
 };
 
 struct SwBlender
index af55ef2..b5866b2 100644 (file)
@@ -241,7 +241,7 @@ static bool _translucentImageRle(SwSurface* surface, const SwImage* image, uint3
 
     for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
         auto dst = &surface->buffer[span->y * surface->stride + span->x];
-        auto src = image->data + span->x + span->y * image->w;    //TODO: need to use image's stride
+        auto src = image->data + span->x + span->y * image->stride;
         auto alpha = ALPHA_MULTIPLY(span->coverage, opacity);
         for (uint32_t x = 0; x < span->len; ++x, ++dst, ++src) {
             *src = ALPHA_BLEND(*src, alpha);
@@ -258,13 +258,12 @@ static bool _translucentImageRleMask(SwSurface* surface, const SwImage* image, u
 
     auto span = image->rle->spans;
     auto img = image->data;
-    auto w = image->w;
     auto cbuffer = surface->compositor->image.data;
 
     for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
         auto dst = &surface->buffer[span->y * surface->stride + span->x];
         auto cmp = &cbuffer[span->y * surface->stride + span->x];
-        auto src = img + span->y * w + span->x;    //TODO: need to use image's stride
+        auto src = img + span->y * image->stride + span->x;
         auto alpha = ALPHA_MULTIPLY(span->coverage, opacity);
         if (alpha == 255) {
             for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++src) {
@@ -312,7 +311,7 @@ static bool _translucentImageRle(SwSurface* surface, const SwImage* image, uint3
             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 * w + rX], alpha);     //TODO: need to use image's stride
+            auto src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
             *dst = src + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(src));
         }
     }
@@ -341,7 +340,7 @@ static bool _translucentImageRleMask(SwSurface* surface, const SwImage* image, u
                 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 * w + rX], blendMethod(*cmp)); //TODO: need to use image's stride
+                auto tmp = ALPHA_BLEND(img[rY * image->stride + rX], blendMethod(*cmp));
                 *dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
             }
         } else {
@@ -349,7 +348,7 @@ static bool _translucentImageRleMask(SwSurface* surface, const SwImage* image, u
                 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 * w + rX], alpha); //TODO: need to use image's stride
+                auto src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
                 auto tmp = ALPHA_BLEND(src, blendMethod(*cmp));
                 *dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
             }
@@ -392,8 +391,8 @@ static bool _translucentUpScaleImageRle(SwSurface* surface, const SwImage* image
             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 * w + rX], alpha);     //TODO: need to use image's stride
-            else src = ALPHA_BLEND(_applyBilinearInterpolation(img, w, h, fX, fY), alpha);     //TODO: need to use image's stride
+            if (rX == w - 1 || rY == h - 1) src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
+            else src = ALPHA_BLEND(_applyBilinearInterpolation(img, image->stride, h, fX, fY), alpha);
             *dst = src + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(src));
         }
     }
@@ -425,8 +424,8 @@ static bool _translucentUpScaleImageRleMask(SwSurface* surface, const SwImage* i
                 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 * w + rX], alpha);     //TODO: need to use image's stride
-                else src = ALPHA_BLEND(_applyBilinearInterpolation(img, w, h, fX, fY), alpha);     //TODO: need to use image's stride
+                if (rX == w - 1 || rY == h - 1) src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
+                else src = ALPHA_BLEND(_applyBilinearInterpolation(img, image->stride, h, fX, fY), alpha);
                 auto tmp = ALPHA_BLEND(src, blendMethod(*cmp));
                 *dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
             }
@@ -438,8 +437,8 @@ static bool _translucentUpScaleImageRleMask(SwSurface* surface, const SwImage* i
                 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 * w + rX], alpha);     //TODO: need to use image's stride
-                else src = ALPHA_BLEND(_applyBilinearInterpolation(img, w, h, fX, fY), alpha);     //TODO: need to use image's stride
+                if (rX == w - 1 || rY == h - 1) src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
+                else src = ALPHA_BLEND(_applyBilinearInterpolation(img, image->stride, h, fX, fY), alpha);
                 auto tmp = ALPHA_BLEND(src, ALPHA_MULTIPLY(alpha, blendMethod(*cmp)));
                 *dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
             }
@@ -480,8 +479,8 @@ static bool _translucentDownScaleImageRle(SwSurface* surface, const SwImage* ima
             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 * w + rX], alpha);     //TODO: need to use image's stride
-            else src = ALPHA_BLEND(_average2Nx2NPixel(surface, img, w, h, rX, rY, halfScale), alpha);     //TODO: need to use image's stride
+            if (rX < halfScale || rY < halfScale || rX >= w - halfScale || rY >= h - halfScale) src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
+            else src = ALPHA_BLEND(_average2Nx2NPixel(surface, img, image->stride, h, rX, rY, halfScale), alpha);
             *dst = src + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(src));
         }
     }
@@ -511,8 +510,8 @@ static bool _translucentDownScaleImageRleMask(SwSurface* surface, const SwImage*
                 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 * w + rX], alpha);     //TODO: need to use image's stride
-                else src = ALPHA_BLEND(_average2Nx2NPixel(surface, img, w, h, rX, rY, halfScale), alpha);     //TODO: need to use image's stride
+                if (rX < halfScale || rY < halfScale || rX >= w - halfScale || rY >= h - halfScale) src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
+                else src = ALPHA_BLEND(_average2Nx2NPixel(surface, img, image->stride, h, rX, rY, halfScale), alpha);
                 auto tmp = ALPHA_BLEND(src, blendMethod(*cmp));
                 *dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
             }
@@ -522,8 +521,8 @@ static bool _translucentDownScaleImageRleMask(SwSurface* surface, const SwImage*
                 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 * w + rX], alpha);     //TODO: need to use image's stride
-                else src = ALPHA_BLEND(_average2Nx2NPixel(surface, img, w, h, rX, rY, halfScale), alpha);     //TODO: need to use image's stride
+                if (rX < halfScale || rY < halfScale || rX >= w - halfScale || rY >= h - halfScale) src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
+                else src = ALPHA_BLEND(_average2Nx2NPixel(surface, img, image->stride, h, rX, rY, halfScale), alpha);
                 auto tmp = ALPHA_BLEND(src, ALPHA_MULTIPLY(alpha, blendMethod(*cmp)));
                 *dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
             }
@@ -553,7 +552,7 @@ static bool _rasterImageRle(SwSurface* surface, const SwImage* image)
 
     for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
         auto dst = &surface->buffer[span->y * surface->stride + span->x];
-        auto src = image->data + span->x + span->y * image->w;    //TODO: need to use image's stride
+        auto src = image->data + span->x + span->y * image->stride;
         for (uint32_t x = 0; x < span->len; ++x, ++dst, ++src) {
             *src = ALPHA_BLEND(*src, span->coverage);
             *dst = *src + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(*src));
@@ -578,7 +577,7 @@ static bool _rasterImageRle(SwSurface* surface, const SwImage* image, const Matr
             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 * w + rX], span->coverage);    //TODO: need to use image's stride
+            auto src = ALPHA_BLEND(img[rY * image->stride + rX], span->coverage);
             *dst = src + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(src));
         }
     }
@@ -604,8 +603,8 @@ static bool _rasterUpScaleImageRle(SwSurface* surface, const SwImage* image, con
             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 * w + rX], span->coverage);    //TODO: need to use image's stride
-            else src = ALPHA_BLEND(_applyBilinearInterpolation(img, w, h, fX, fY), span->coverage);    //TODO: need to use image's stride
+            if (rX == w - 1 || rY == h - 1) src = ALPHA_BLEND(img[rY * image->stride + rX], span->coverage);
+            else src = ALPHA_BLEND(_applyBilinearInterpolation(img, image->stride, h, fX, fY), span->coverage);
             *dst = src + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(src));
         }
     }
@@ -629,8 +628,8 @@ static bool _rasterDownScaleImageRle(SwSurface* surface, const SwImage* image, c
             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 * w + rX], span->coverage);    //TODO: need to use image's stride
-            else src = ALPHA_BLEND(_average2Nx2NPixel(surface, img, w, h, rX, rY, halfScale), span->coverage);    //TODO: need to use image's stride
+            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(_average2Nx2NPixel(surface, img, image->stride, h, rX, rY, halfScale), span->coverage);
             *dst = src + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(src));
         }
     }
@@ -653,7 +652,7 @@ static bool _translucentImage(SwSurface* surface, const SwImage* image, uint32_t
             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;
-            auto src = ALPHA_BLEND(img[rX + (rY * w)], opacity);    //TODO: need to use image's stride
+            auto src = ALPHA_BLEND(img[rX + (rY * image->stride)], opacity);
             *dst = src + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(src));
         }
         dbuffer += surface->stride;
@@ -681,7 +680,7 @@ static bool _translucentImageMask(SwSurface* surface, const SwImage* image, uint
             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;
-            auto src = ALPHA_BLEND(img[rX + (rY * w)], ALPHA_MULTIPLY(opacity, blendMethod(*cmp)));  //TODO: need to use image's stride
+            auto src = ALPHA_BLEND(img[rX + (rY * image->stride)], ALPHA_MULTIPLY(opacity, blendMethod(*cmp)));
             *dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
         }
         dbuffer += surface->stride;
@@ -723,8 +722,8 @@ static bool _translucentUpScaleImage(SwSurface* surface, const SwImage* image, u
             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[rX + (rY * w)], opacity);    //TODO: need to use image's stride
-            else src = ALPHA_BLEND(_applyBilinearInterpolation(img, w, h, fX, fY), opacity);    //TODO: need to use image's stride
+            if (rX == w - 1 || rY == h - 1) src = ALPHA_BLEND(img[rX + (rY * image->stride)], opacity);
+            else src = ALPHA_BLEND(_applyBilinearInterpolation(img, image->stride, h, fX, fY), opacity);
             *dst = src + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(src));
         }
         dbuffer += surface->stride;
@@ -755,8 +754,8 @@ static bool _translucentUpScaleImageMask(SwSurface* surface, const SwImage* imag
             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[rX + (rY * w)], ALPHA_MULTIPLY(opacity, blendMethod(*cmp)));  //TODO: need to use image's stride
-            else src = ALPHA_BLEND(_applyBilinearInterpolation(img, w, h, fX, fY), ALPHA_MULTIPLY(opacity, blendMethod(*cmp)));  //TODO: need to use image's stride
+            if (rX == w - 1 || rY == h - 1) src = ALPHA_BLEND(img[rX + (rY * image->stride)], ALPHA_MULTIPLY(opacity, blendMethod(*cmp)));
+            else src = ALPHA_BLEND(_applyBilinearInterpolation(img, image->stride, h, fX, fY), ALPHA_MULTIPLY(opacity, blendMethod(*cmp)));
             *dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
         }
         dbuffer += surface->stride;
@@ -826,8 +825,11 @@ static bool _translucentDownScaleImageMask(SwSurface* surface, const SwImage* im
             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[rX + (rY * w)], ALPHA_MULTIPLY(opacity, blendMethod(*cmp)));  //TODO: need to use image's stride
-            else src = ALPHA_BLEND(_average2Nx2NPixel(surface, img, w, h, rX, rY, halfScale), ALPHA_MULTIPLY(opacity, blendMethod(*cmp)));  //TODO: need to use image's stride
+            if (rX < halfScale || rY < halfScale || rX >= w - halfScale || rY >= h - halfScale) {
+                src = ALPHA_BLEND(img[rX + (rY * image->stride)], ALPHA_MULTIPLY(opacity, blendMethod(*cmp)));
+            } else {
+                src = ALPHA_BLEND(_average2Nx2NPixel(surface, img, image->stride, h, rX, rY, halfScale), ALPHA_MULTIPLY(opacity, blendMethod(*cmp)));
+            }
             *dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
         }
         dbuffer += surface->stride;
@@ -854,7 +856,7 @@ static bool _rasterTranslucentDownScaleImage(SwSurface* surface, const SwImage*
 static bool _translucentImage(SwSurface* surface, const SwImage* image, uint32_t opacity, const SwBBox& region)
 {
     auto dbuffer = &surface->buffer[region.min.y * surface->stride + region.min.x];
-    auto sbuffer = image->data + region.min.x + region.min.y * image->w;    //TODO: need to use image's stride
+    auto sbuffer = image->data + region.min.x + region.min.y * image->stride;
 
     for (auto y = region.min.y; y < region.max.y; ++y) {
         auto dst = dbuffer;
@@ -864,7 +866,7 @@ static bool _translucentImage(SwSurface* surface, const SwImage* image, uint32_t
             *dst = p + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(p));
         }
         dbuffer += surface->stride;
-        sbuffer += image->w;    //TODO: need to use image's stride
+        sbuffer += image->stride;
     }
     return true;
 }
@@ -891,7 +893,7 @@ static bool _translucentImageMask(SwSurface* surface, const SwImage* image, uint
         }
         buffer += surface->stride;
         cbuffer += surface->stride;
-        sbuffer += image->w;   //TODO: need to use image's stride
+        sbuffer += image->stride;
     }
     return true;
 }
@@ -914,7 +916,7 @@ static bool _rasterTranslucentImage(SwSurface* surface, const SwImage* image, ui
 static bool _rasterImage(SwSurface* surface, const SwImage* image, const SwBBox& region)
 {
     auto dbuffer = &surface->buffer[region.min.y * surface->stride + region.min.x];
-    auto sbuffer = image->data + region.min.x + region.min.y * image->w;   //TODO: need to use image's stride
+    auto sbuffer = image->data + region.min.x + region.min.y * image->stride;
 
     for (auto y = region.min.y; y < region.max.y; ++y) {
         auto dst = dbuffer;
@@ -923,7 +925,7 @@ static bool _rasterImage(SwSurface* surface, const SwImage* image, const SwBBox&
             *dst = *src + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(*src));
         }
         dbuffer += surface->stride;
-        sbuffer += image->w;    //TODO: need to use image's stride
+        sbuffer += image->stride;
     }
     return true;
 }
@@ -943,7 +945,7 @@ static bool _rasterImage(SwSurface* surface, const SwImage* image, const SwBBox&
             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;
-            auto src = img[rX + (rY * w)];    //TODO: need to use image's stride
+            auto src = img[rX + (rY * image->stride)];
             *dst = src + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(src));
         }
     }
index 02afb5f..b50aa62 100644 (file)
@@ -190,6 +190,7 @@ struct SwImageTask : SwTask
 
             image.data = const_cast<uint32_t*>(pdata->data(&image.w, &image.h));
             if (!image.data || image.w == 0 || image.h == 0) goto end;
+            image.stride = image.w;     //same, pixel buffer size.
 
             if (!imagePrepare(&image, transform, clipRegion, bbox, mpool, tid)) goto end;
 
@@ -500,7 +501,8 @@ Compositor* SwRenderer::target(const RenderRegion& region)
     cmp->compositor->bbox.min.y = y;
     cmp->compositor->bbox.max.x = x + w;
     cmp->compositor->bbox.max.y = y + h;
-    cmp->compositor->image.w = surface->stride;
+    cmp->compositor->image.stride = surface->stride;
+    cmp->compositor->image.w = surface->w;
     cmp->compositor->image.h = surface->h;
 
     //We know partial clear region