diff --git a/src/renderer/sw_engine/tvgSwCommon.h b/src/renderer/sw_engine/tvgSwCommon.h index 401eb711..5c1e9ca6 100644 --- a/src/renderer/sw_engine/tvgSwCommon.h +++ b/src/renderer/sw_engine/tvgSwCommon.h @@ -266,7 +266,8 @@ struct SwImage }; typedef uint8_t(*SwMask)(uint8_t s, uint8_t d, uint8_t a); //src, dst, alpha -typedef uint32_t(*SwBlender)(uint32_t s, uint32_t d, uint8_t a); //src, dst, alpha +typedef uint32_t(*SwBlender)(uint32_t s, uint32_t d); //src, dst +typedef uint32_t(*SwBlenderA)(uint32_t s, uint32_t d, uint8_t a); //src, dst, alpha typedef uint32_t(*SwJoin)(uint8_t r, uint8_t g, uint8_t b, uint8_t a); //color channel join typedef uint8_t(*SwAlpha)(uint8_t*); //blending alpha @@ -423,8 +424,7 @@ static inline uint32_t opBlendSrcOver(uint32_t s, TVG_UNUSED uint32_t d, TVG_UNU return s; } -//TODO: BlendMethod could remove the alpha parameter. -static inline uint32_t opBlendDifference(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +static inline uint32_t opBlendDifference(uint32_t s, uint32_t d) { if (d == 0) return s; @@ -435,7 +435,7 @@ static inline uint32_t opBlendDifference(uint32_t s, uint32_t d, TVG_UNUSED uint return JOIN(255, f(C1(s), C1(d)), f(C2(s), C2(d)), f(C3(s), C3(d))); } -static inline uint32_t opBlendExclusion(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +static inline uint32_t opBlendExclusion(uint32_t s, uint32_t d) { if (d == 0) return s; @@ -446,7 +446,7 @@ static inline uint32_t opBlendExclusion(uint32_t s, uint32_t d, TVG_UNUSED uint8 return JOIN(255, f(C1(s), C1(d)), f(C2(s), C2(d)), f(C3(s), C3(d))); } -static inline uint32_t opBlendAdd(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +static inline uint32_t opBlendAdd(uint32_t s, uint32_t d) { if (d == 0) return s; @@ -457,7 +457,7 @@ static inline uint32_t opBlendAdd(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) return JOIN(255, f(C1(s), C1(d)), f(C2(s), C2(d)), f(C3(s), C3(d))); } -static inline uint32_t opBlendScreen(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +static inline uint32_t opBlendScreen(uint32_t s, uint32_t d) { if (d == 0) return s; @@ -468,7 +468,7 @@ static inline uint32_t opBlendScreen(uint32_t s, uint32_t d, TVG_UNUSED uint8_t return JOIN(255, f(C1(s), C1(d)), f(C2(s), C2(d)), f(C3(s), C3(d))); } -static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d) { RenderColor o; if (!BLEND_UPRE(d, o)) return s; @@ -481,7 +481,7 @@ static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, TVG_UNUSED uint8_ } -static inline uint32_t opBlendOverlay(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +static inline uint32_t opBlendOverlay(uint32_t s, uint32_t d) { RenderColor o; if (!BLEND_UPRE(d, o)) return s; @@ -493,7 +493,7 @@ static inline uint32_t opBlendOverlay(uint32_t s, uint32_t d, TVG_UNUSED uint8_t return BLEND_PRE(JOIN(255, f(C1(s), o.r), f(C2(s), o.g), f(C3(s), o.b)), s, o.a); } -static inline uint32_t opBlendDarken(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +static inline uint32_t opBlendDarken(uint32_t s, uint32_t d) { RenderColor o; if (!BLEND_UPRE(d, o)) return s; @@ -505,7 +505,7 @@ static inline uint32_t opBlendDarken(uint32_t s, uint32_t d, TVG_UNUSED uint8_t return BLEND_PRE(JOIN(255, f(C1(s), o.r), f(C2(s), o.g), f(C3(s), o.b)), s, o.a); } -static inline uint32_t opBlendLighten(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +static inline uint32_t opBlendLighten(uint32_t s, uint32_t d) { if (d == 0) return s; @@ -516,7 +516,7 @@ static inline uint32_t opBlendLighten(uint32_t s, uint32_t d, TVG_UNUSED uint8_t return JOIN(255, f(C1(s), C1(d)), f(C2(s), C2(d)), f(C3(s), C3(d))); } -static inline uint32_t opBlendColorDodge(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +static inline uint32_t opBlendColorDodge(uint32_t s, uint32_t d) { RenderColor o; if (!BLEND_UPRE(d, o)) return s; @@ -528,7 +528,7 @@ static inline uint32_t opBlendColorDodge(uint32_t s, uint32_t d, TVG_UNUSED uint return BLEND_PRE(JOIN(255, f(C1(s), o.r), f(C2(s), o.g), f(C3(s), o.b)), s, o.a); } -static inline uint32_t opBlendColorBurn(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +static inline uint32_t opBlendColorBurn(uint32_t s, uint32_t d) { RenderColor o; if (!BLEND_UPRE(d, o)) return s; @@ -540,7 +540,7 @@ static inline uint32_t opBlendColorBurn(uint32_t s, uint32_t d, TVG_UNUSED uint8 return BLEND_PRE(JOIN(255, f(C1(s), o.r), f(C2(s), o.g), f(C3(s), o.b)), s, o.a); } -static inline uint32_t opBlendHardLight(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +static inline uint32_t opBlendHardLight(uint32_t s, uint32_t d) { RenderColor o; if (!BLEND_UPRE(d, o)) return s; @@ -552,7 +552,7 @@ static inline uint32_t opBlendHardLight(uint32_t s, uint32_t d, TVG_UNUSED uint8 return BLEND_PRE(JOIN(255, f(C1(s), o.r), f(C2(s), o.g), f(C3(s), o.b)), s, o.a); } -static inline uint32_t opBlendSoftLight(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a) +static inline uint32_t opBlendSoftLight(uint32_t s, uint32_t d) { RenderColor o; if (!BLEND_UPRE(d, o)) return s; @@ -617,14 +617,14 @@ void fillFree(SwFill* fill); //OPTIMIZE_ME: Skip the function pointer access void fillLinear(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32_t len, SwMask maskOp, uint8_t opacity); //composite masking ver. void fillLinear(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwMask maskOp, uint8_t opacity); //direct masking ver. -void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a); //blending ver. -void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, SwBlender op2, uint8_t a); //blending + BlendingMethod(op2) ver. +void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlenderA op, uint8_t a); //blending ver. +void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlenderA op, SwBlender op2, uint8_t a); //blending + BlendingMethod(op2) ver. void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwAlpha alpha, uint8_t csize, uint8_t opacity); //matting ver. void fillRadial(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32_t len, SwMask op, uint8_t a); //composite masking ver. void fillRadial(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwMask op, uint8_t a) ; //direct masking ver. -void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a); //blending ver. -void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, SwBlender op2, uint8_t a); //blending + BlendingMethod(op2) ver. +void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlenderA op, uint8_t a); //blending ver. +void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlenderA op, SwBlender op2, uint8_t a); //blending + BlendingMethod(op2) ver. void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwAlpha alpha, uint8_t csize, uint8_t opacity); //matting ver. SwRle* rleRender(SwRle* rle, const SwOutline* outline, const RenderRegion& bbox, bool antiAlias); diff --git a/src/renderer/sw_engine/tvgSwFill.cpp b/src/renderer/sw_engine/tvgSwFill.cpp index 368f68b1..9978baf9 100644 --- a/src/renderer/sw_engine/tvgSwFill.cpp +++ b/src/renderer/sw_engine/tvgSwFill.cpp @@ -364,7 +364,7 @@ void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3 } -void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a) +void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlenderA op, uint8_t a) { if (fill->radial.a < RADIAL_A_THRESHOLD) { auto radial = &fill->radial; @@ -448,7 +448,7 @@ void fillRadial(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32 } -void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, SwBlender op2, uint8_t a) +void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlenderA op, SwBlender op2, uint8_t a) { if (fill->radial.a < RADIAL_A_THRESHOLD) { auto radial = &fill->radial; @@ -459,7 +459,7 @@ void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3 for (uint32_t i = 0; i < len; ++i, ++dst) { auto x0 = 0.5f * (rx * rx + ry * ry - radial->fr * radial->fr) / (radial->dr * radial->fr + rx * radial->dx + ry * radial->dy); auto tmp = op(_pixel(fill, x0), *dst, 255); - *dst = op2(tmp, *dst, 255); + *dst = op2(tmp, *dst); rx += radial->a11; ry += radial->a21; } @@ -467,7 +467,7 @@ void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3 for (uint32_t i = 0; i < len; ++i, ++dst) { auto x0 = 0.5f * (rx * rx + ry * ry - radial->fr * radial->fr) / (radial->dr * radial->fr + rx * radial->dx + ry * radial->dy); auto tmp = op(_pixel(fill, x0), *dst, 255); - auto tmp2 = op2(tmp, *dst, 255); + auto tmp2 = op2(tmp, *dst); *dst = INTERPOLATE(tmp2, *dst, a); rx += radial->a11; ry += radial->a21; @@ -479,7 +479,7 @@ void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3 if (a == 255) { for (uint32_t i = 0 ; i < len ; ++i, ++dst) { auto tmp = op(_pixel(fill, sqrtf(det) - b), *dst, 255); - *dst = op2(tmp, *dst, 255); + *dst = op2(tmp, *dst); det += deltaDet; deltaDet += deltaDeltaDet; b += deltaB; @@ -487,7 +487,7 @@ void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3 } else { for (uint32_t i = 0 ; i < len ; ++i, ++dst) { auto tmp = op(_pixel(fill, sqrtf(det) - b), *dst, 255); - auto tmp2 = op2(tmp, *dst, 255); + auto tmp2 = op2(tmp, *dst); *dst = INTERPOLATE(tmp2, *dst, a); det += deltaDet; deltaDet += deltaDeltaDet; @@ -661,7 +661,7 @@ void fillLinear(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32 } -void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a) +void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlenderA op, uint8_t a) { //Rotation float rx = x + 0.5f; @@ -701,7 +701,7 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3 } -void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, SwBlender op2, uint8_t a) +void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlenderA op, SwBlender op2, uint8_t a) { //Rotation float rx = x + 0.5f; @@ -714,12 +714,12 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3 if (a == 255) { for (uint32_t i = 0; i < len; ++i, ++dst) { auto tmp = op(color, *dst, a); - *dst = op2(tmp, *dst, 255); + *dst = op2(tmp, *dst); } } else { for (uint32_t i = 0; i < len; ++i, ++dst) { auto tmp = op(color, *dst, a); - auto tmp2 = op2(tmp, *dst, 255); + auto tmp2 = op2(tmp, *dst); *dst = INTERPOLATE(tmp2, *dst, a); } } @@ -737,7 +737,7 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3 auto inc2 = static_cast(inc * FIXPT_SIZE); for (uint32_t j = 0; j < len; ++j, ++dst) { auto tmp = op(_fixedPixel(fill, t2), *dst, 255); - *dst = op2(tmp, *dst, 255); + *dst = op2(tmp, *dst); t2 += inc2; } //we have to fallback to float math @@ -745,7 +745,7 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3 uint32_t counter = 0; while (counter++ < len) { auto tmp = op(_pixel(fill, t / GRADIENT_STOP_SIZE), *dst, 255); - *dst = op2(tmp, *dst, 255); + *dst = op2(tmp, *dst); ++dst; t += inc; } @@ -757,7 +757,7 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3 auto inc2 = static_cast(inc * FIXPT_SIZE); for (uint32_t j = 0; j < len; ++j, ++dst) { auto tmp = op(_fixedPixel(fill, t2), *dst, 255); - auto tmp2 = op2(tmp, *dst, 255); + auto tmp2 = op2(tmp, *dst); *dst = INTERPOLATE(tmp2, *dst, a); t2 += inc2; } @@ -766,7 +766,7 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3 uint32_t counter = 0; while (counter++ < len) { auto tmp = op(_pixel(fill, t / GRADIENT_STOP_SIZE), *dst, 255); - auto tmp2 = op2(tmp, *dst, 255); + auto tmp2 = op2(tmp, *dst); *dst = INTERPOLATE(tmp2, *dst, a); ++dst; t += inc; diff --git a/src/renderer/sw_engine/tvgSwRaster.cpp b/src/renderer/sw_engine/tvgSwRaster.cpp index 7fcc1fd2..37b46349 100644 --- a/src/renderer/sw_engine/tvgSwRaster.cpp +++ b/src/renderer/sw_engine/tvgSwRaster.cpp @@ -42,7 +42,7 @@ struct FillLinear fillLinear(fill, dst, y, x, len, cmp, op, a); } - void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a) + void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlenderA op, uint8_t a) { fillLinear(fill, dst, y, x, len, op, a); } @@ -52,7 +52,7 @@ struct FillLinear fillLinear(fill, dst, y, x, len, cmp, alpha, csize, opacity); } - void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, SwBlender op2, uint8_t a) + void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlenderA op, SwBlender op2, uint8_t a) { fillLinear(fill, dst, y, x, len, op, op2, a); } @@ -71,7 +71,7 @@ struct FillRadial fillRadial(fill, dst, y, x, len, cmp, op, a); } - void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, uint8_t a) + void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlenderA op, uint8_t a) { fillRadial(fill, dst, y, x, len, op, a); } @@ -81,7 +81,7 @@ struct FillRadial fillRadial(fill, dst, y, x, len, cmp, alpha, csize, opacity); } - void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, SwBlender op2, uint8_t a) + void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlenderA op, SwBlender op2, uint8_t a) { fillRadial(fill, dst, y, x, len, op, op2, a); } @@ -412,7 +412,7 @@ static bool _rasterBlendingRect(SwSurface* surface, const RenderRegion& bbox, co for (uint32_t y = 0; y < bbox.h(); ++y) { auto dst = &buffer[y * surface->stride]; for (uint32_t x = 0; x < bbox.w(); ++x, ++dst) { - *dst = surface->blender(color, *dst, 255); + *dst = surface->blender(color, *dst); } } return true; @@ -587,11 +587,11 @@ static bool _rasterBlendingRle(SwSurface* surface, const SwRle* rle, const Rende auto dst = &surface->buf32[span->y * surface->stride + x]; if (span->coverage == 255) { for (auto x = 0; x < len; ++x, ++dst) { - *dst = surface->blender(color, *dst, 255); + *dst = surface->blender(color, *dst); } } else { for (auto x = 0; x < len; ++x, ++dst) { - *dst = INTERPOLATE(surface->blender(color, *dst, 255), *dst, span->coverage); + *dst = INTERPOLATE(surface->blender(color, *dst), *dst, span->coverage); } } } @@ -732,13 +732,13 @@ static bool _rasterScaledBlendingRleImage(SwSurface* surface, const SwImage& ima for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst) { SCALED_IMAGE_RANGE_X auto src = scaleMethod(image.buf32, image.stride, image.w, image.h, sx, sy, miny, maxy, sampleSize); - *dst = INTERPOLATE(surface->blender(rasterUnpremultiply(src), *dst, 255), *dst, A(src)); + *dst = INTERPOLATE(surface->blender(rasterUnpremultiply(src), *dst), *dst, A(src)); } } else { for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst) { SCALED_IMAGE_RANGE_X auto src = scaleMethod(image.buf32, image.stride, image.w, image.h, sx, sy, miny, maxy, sampleSize); - *dst = INTERPOLATE(surface->blender(rasterUnpremultiply(src), *dst, 255), *dst, MULTIPLY(alpha, A(src))); + *dst = INTERPOLATE(surface->blender(rasterUnpremultiply(src), *dst), *dst, MULTIPLY(alpha, A(src))); } } } @@ -815,11 +815,11 @@ static bool _rasterDirectBlendingRleImage(SwSurface* surface, const SwImage& ima auto alpha = MULTIPLY(span->coverage, opacity); if (alpha == 255) { for (auto x = 0; x < len; ++x, ++dst, ++src) { - *dst = surface->blender(rasterUnpremultiply(*src), *dst, 255); + *dst = surface->blender(rasterUnpremultiply(*src), *dst); } } else { for (auto x = 0; x < len; ++x, ++dst, ++src) { - *dst = INTERPOLATE(surface->blender(rasterUnpremultiply(*src), *dst, 255), *dst, MULTIPLY(alpha, A(*src))); + *dst = INTERPOLATE(surface->blender(rasterUnpremultiply(*src), *dst), *dst, MULTIPLY(alpha, A(*src))); } } } @@ -914,7 +914,7 @@ static bool _rasterScaledBlendingImage(SwSurface* surface, const SwImage& image, for (auto x = bbox.min.x; x < bbox.max.x; ++x, ++dst) { SCALED_IMAGE_RANGE_X auto src = scaleMethod(image.buf32, image.stride, image.w, image.h, sx, sy, miny, maxy, sampleSize); - *dst = INTERPOLATE(surface->blender(rasterUnpremultiply(src), *dst, 255), *dst, MULTIPLY(opacity, A(src))); + *dst = INTERPOLATE(surface->blender(rasterUnpremultiply(src), *dst), *dst, MULTIPLY(opacity, A(src))); } } return true; @@ -1033,11 +1033,11 @@ static bool _rasterDirectBlendingImage(SwSurface* surface, const SwImage& image, auto src = sbuffer; if (opacity == 255) { for (auto dst = dbuffer; dst < dbuffer + w; dst++, src++) { - *dst = INTERPOLATE(surface->blender(rasterUnpremultiply(*src), *dst, 255), *dst, A(*src)); + *dst = INTERPOLATE(surface->blender(rasterUnpremultiply(*src), *dst), *dst, A(*src)); } } else { for (auto dst = dbuffer; dst < dbuffer + w; dst++, src++) { - *dst = INTERPOLATE(surface->blender(rasterUnpremultiply(*src), *dst, 255), *dst, MULTIPLY(opacity, A(*src))); + *dst = INTERPOLATE(surface->blender(rasterUnpremultiply(*src), *dst), *dst, MULTIPLY(opacity, A(*src))); } } } @@ -1093,11 +1093,11 @@ static bool _rasterDirectMattedBlendingImage(SwSurface* surface, const SwImage& auto src = sbuffer; if (opacity == 255) { for (auto dst = dbuffer; dst < dbuffer + w; ++dst, ++src, cmp += csize) { - *dst = INTERPOLATE(surface->blender(*src, *dst, 255), *dst, MULTIPLY(A(*src), alpha(cmp))); + *dst = INTERPOLATE(surface->blender(*src, *dst), *dst, MULTIPLY(A(*src), alpha(cmp))); } } else { for (auto dst = dbuffer; dst < dbuffer + w; ++dst, ++src, cmp += csize) { - *dst = INTERPOLATE(surface->blender(*src, *dst, 255), *dst, MULTIPLY(MULTIPLY(A(*src), alpha(cmp)), opacity)); + *dst = INTERPOLATE(surface->blender(*src, *dst), *dst, MULTIPLY(MULTIPLY(A(*src), alpha(cmp)), opacity)); } } cbuffer += surface->compositor->image.stride * csize; diff --git a/src/renderer/sw_engine/tvgSwRasterTexmap.h b/src/renderer/sw_engine/tvgSwRasterTexmap.h index d58a1d2c..52c05ce5 100644 --- a/src/renderer/sw_engine/tvgSwRasterTexmap.h +++ b/src/renderer/sw_engine/tvgSwRasterTexmap.h @@ -136,8 +136,7 @@ static void _rasterBlendingPolygonImageSegment(SwSurface* surface, const SwImage } px = INTERPOLATE(px, px2, ab); } - auto tmp = surface->blender(rasterUnpremultiply(px), *buf, 255); - *buf = INTERPOLATE(tmp, *buf, MULTIPLY(opacity, A(px))); + *buf = INTERPOLATE(surface->blender(rasterUnpremultiply(px), *buf), *buf, MULTIPLY(opacity, A(px))); ++buf; //Step UV horizontally