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 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 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 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; return s;
} }
//TODO: BlendMethod could remove the alpha parameter. static inline uint32_t opBlendDifference(uint32_t s, uint32_t d)
static inline uint32_t opBlendDifference(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
{ {
if (d == 0) return s; 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))); 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; 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))); 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; 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))); 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; 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))); 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; RenderColor o;
if (!BLEND_UPRE(d, o)) return s; 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; RenderColor o;
if (!BLEND_UPRE(d, o)) return s; 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); 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; RenderColor o;
if (!BLEND_UPRE(d, o)) return s; 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); 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; 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))); 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; RenderColor o;
if (!BLEND_UPRE(d, o)) return s; 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); 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; RenderColor o;
if (!BLEND_UPRE(d, o)) return s; 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); 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; RenderColor o;
if (!BLEND_UPRE(d, o)) return s; 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); 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; RenderColor o;
if (!BLEND_UPRE(d, o)) return s; if (!BLEND_UPRE(d, o)) return s;
@ -617,14 +617,14 @@ void fillFree(SwFill* fill);
//OPTIMIZE_ME: Skip the function pointer access //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, 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, 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, SwBlenderA 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, 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 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, 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, 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, SwBlenderA 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, 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. 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); 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) { if (fill->radial.a < RADIAL_A_THRESHOLD) {
auto radial = &fill->radial; 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) { if (fill->radial.a < RADIAL_A_THRESHOLD) {
auto radial = &fill->radial; 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) { 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 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 tmp = op(_pixel(fill, x0), *dst, 255);
*dst = op2(tmp, *dst, 255); *dst = op2(tmp, *dst);
rx += radial->a11; rx += radial->a11;
ry += radial->a21; 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) { 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 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 tmp = op(_pixel(fill, x0), *dst, 255);
auto tmp2 = op2(tmp, *dst, 255); auto tmp2 = op2(tmp, *dst);
*dst = INTERPOLATE(tmp2, *dst, a); *dst = INTERPOLATE(tmp2, *dst, a);
rx += radial->a11; rx += radial->a11;
ry += radial->a21; 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) { if (a == 255) {
for (uint32_t i = 0 ; i < len ; ++i, ++dst) { for (uint32_t i = 0 ; i < len ; ++i, ++dst) {
auto tmp = op(_pixel(fill, sqrtf(det) - b), *dst, 255); auto tmp = op(_pixel(fill, sqrtf(det) - b), *dst, 255);
*dst = op2(tmp, *dst, 255); *dst = op2(tmp, *dst);
det += deltaDet; det += deltaDet;
deltaDet += deltaDeltaDet; deltaDet += deltaDeltaDet;
b += deltaB; b += deltaB;
@ -487,7 +487,7 @@ void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3
} else { } else {
for (uint32_t i = 0 ; i < len ; ++i, ++dst) { for (uint32_t i = 0 ; i < len ; ++i, ++dst) {
auto tmp = op(_pixel(fill, sqrtf(det) - b), *dst, 255); 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); *dst = INTERPOLATE(tmp2, *dst, a);
det += deltaDet; det += deltaDet;
deltaDet += deltaDeltaDet; 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 //Rotation
float rx = x + 0.5f; 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 //Rotation
float rx = x + 0.5f; 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) { if (a == 255) {
for (uint32_t i = 0; i < len; ++i, ++dst) { for (uint32_t i = 0; i < len; ++i, ++dst) {
auto tmp = op(color, *dst, a); auto tmp = op(color, *dst, a);
*dst = op2(tmp, *dst, 255); *dst = op2(tmp, *dst);
} }
} else { } else {
for (uint32_t i = 0; i < len; ++i, ++dst) { for (uint32_t i = 0; i < len; ++i, ++dst) {
auto tmp = op(color, *dst, a); auto tmp = op(color, *dst, a);
auto tmp2 = op2(tmp, *dst, 255); auto tmp2 = op2(tmp, *dst);
*dst = INTERPOLATE(tmp2, *dst, a); *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); auto inc2 = static_cast<int32_t>(inc * FIXPT_SIZE);
for (uint32_t j = 0; j < len; ++j, ++dst) { for (uint32_t j = 0; j < len; ++j, ++dst) {
auto tmp = op(_fixedPixel(fill, t2), *dst, 255); auto tmp = op(_fixedPixel(fill, t2), *dst, 255);
*dst = op2(tmp, *dst, 255); *dst = op2(tmp, *dst);
t2 += inc2; t2 += inc2;
} }
//we have to fallback to float math //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; uint32_t counter = 0;
while (counter++ < len) { while (counter++ < len) {
auto tmp = op(_pixel(fill, t / GRADIENT_STOP_SIZE), *dst, 255); auto tmp = op(_pixel(fill, t / GRADIENT_STOP_SIZE), *dst, 255);
*dst = op2(tmp, *dst, 255); *dst = op2(tmp, *dst);
++dst; ++dst;
t += inc; 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); auto inc2 = static_cast<int32_t>(inc * FIXPT_SIZE);
for (uint32_t j = 0; j < len; ++j, ++dst) { for (uint32_t j = 0; j < len; ++j, ++dst) {
auto tmp = op(_fixedPixel(fill, t2), *dst, 255); auto tmp = op(_fixedPixel(fill, t2), *dst, 255);
auto tmp2 = op2(tmp, *dst, 255); auto tmp2 = op2(tmp, *dst);
*dst = INTERPOLATE(tmp2, *dst, a); *dst = INTERPOLATE(tmp2, *dst, a);
t2 += inc2; 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; uint32_t counter = 0;
while (counter++ < len) { while (counter++ < len) {
auto tmp = op(_pixel(fill, t / GRADIENT_STOP_SIZE), *dst, 255); 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 = INTERPOLATE(tmp2, *dst, a);
++dst; ++dst;
t += inc; t += inc;

View file

@ -42,7 +42,7 @@ struct FillLinear
fillLinear(fill, dst, y, x, len, cmp, op, a); 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); fillLinear(fill, dst, y, x, len, op, a);
} }
@ -52,7 +52,7 @@ struct FillLinear
fillLinear(fill, dst, y, x, len, cmp, alpha, csize, opacity); 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); fillLinear(fill, dst, y, x, len, op, op2, a);
} }
@ -71,7 +71,7 @@ struct FillRadial
fillRadial(fill, dst, y, x, len, cmp, op, a); 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); fillRadial(fill, dst, y, x, len, op, a);
} }
@ -81,7 +81,7 @@ struct FillRadial
fillRadial(fill, dst, y, x, len, cmp, alpha, csize, opacity); 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); 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) { for (uint32_t y = 0; y < bbox.h(); ++y) {
auto dst = &buffer[y * surface->stride]; auto dst = &buffer[y * surface->stride];
for (uint32_t x = 0; x < bbox.w(); ++x, ++dst) { for (uint32_t x = 0; x < bbox.w(); ++x, ++dst) {
*dst = surface->blender(color, *dst, 255); *dst = surface->blender(color, *dst);
} }
} }
return true; 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]; auto dst = &surface->buf32[span->y * surface->stride + x];
if (span->coverage == 255) { if (span->coverage == 255) {
for (auto x = 0; x < len; ++x, ++dst) { for (auto x = 0; x < len; ++x, ++dst) {
*dst = surface->blender(color, *dst, 255); *dst = surface->blender(color, *dst);
} }
} else { } else {
for (auto x = 0; x < len; ++x, ++dst) { 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) { 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 SCALED_IMAGE_RANGE_X
auto src = scaleMethod(image.buf32, image.stride, image.w, image.h, sx, sy, miny, maxy, sampleSize); 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 { } else {
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) { 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 SCALED_IMAGE_RANGE_X
auto src = scaleMethod(image.buf32, image.stride, image.w, image.h, sx, sy, miny, maxy, sampleSize); 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); auto alpha = MULTIPLY(span->coverage, opacity);
if (alpha == 255) { if (alpha == 255) {
for (auto x = 0; x < len; ++x, ++dst, ++src) { for (auto x = 0; x < len; ++x, ++dst, ++src) {
*dst = surface->blender(rasterUnpremultiply(*src), *dst, 255); *dst = surface->blender(rasterUnpremultiply(*src), *dst);
} }
} else { } else {
for (auto x = 0; x < len; ++x, ++dst, ++src) { 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) { for (auto x = bbox.min.x; x < bbox.max.x; ++x, ++dst) {
SCALED_IMAGE_RANGE_X SCALED_IMAGE_RANGE_X
auto src = scaleMethod(image.buf32, image.stride, image.w, image.h, sx, sy, miny, maxy, sampleSize); 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; return true;
@ -1033,11 +1033,11 @@ static bool _rasterDirectBlendingImage(SwSurface* surface, const SwImage& image,
auto src = sbuffer; auto src = sbuffer;
if (opacity == 255) { if (opacity == 255) {
for (auto dst = dbuffer; dst < dbuffer + w; dst++, src++) { 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 { } else {
for (auto dst = dbuffer; dst < dbuffer + w; dst++, src++) { 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; auto src = sbuffer;
if (opacity == 255) { if (opacity == 255) {
for (auto dst = dbuffer; dst < dbuffer + w; ++dst, ++src, cmp += csize) { 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 { } else {
for (auto dst = dbuffer; dst < dbuffer + w; ++dst, ++src, cmp += csize) { 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; cbuffer += surface->compositor->image.stride * csize;

View file

@ -136,8 +136,7 @@ static void _rasterBlendingPolygonImageSegment(SwSurface* surface, const SwImage
} }
px = INTERPOLATE(px, px2, ab); px = INTERPOLATE(px, px2, ab);
} }
auto tmp = surface->blender(rasterUnpremultiply(px), *buf, 255); *buf = INTERPOLATE(surface->blender(rasterUnpremultiply(px), *buf), *buf, MULTIPLY(opacity, A(px)));
*buf = INTERPOLATE(tmp, *buf, MULTIPLY(opacity, A(px)));
++buf; ++buf;
//Step UV horizontally //Step UV horizontally