sw_engine: trimmed out unnecessary blending parameters

This commit is contained in:
Hermet Park 2025-07-16 17:59:25 +09:00
parent 15aafbfe62
commit 1b6bbf78a3
4 changed files with 49 additions and 50 deletions

View file

@ -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);

View file

@ -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<int32_t>(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<int32_t>(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;

View file

@ -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<uint32_t>(span->x); x < static_cast<uint32_t>(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<uint32_t>(span->x); x < static_cast<uint32_t>(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;

View file

@ -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