mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
sw_engine fill: code clean up.
eliminate logic duplication by introducing direct blend operation.
This commit is contained in:
parent
fbe1b1fb5f
commit
3399da198f
3 changed files with 28 additions and 57 deletions
|
@ -332,6 +332,11 @@ static inline uint32_t opBlend(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
|||
return s + ALPHA_BLEND(d, IALPHA(s));
|
||||
}
|
||||
|
||||
static inline uint32_t opDirect(uint32_t s, TVG_UNUSED uint32_t d, TVG_UNUSED uint8_t a)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
static inline uint32_t opAddMask(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
||||
{
|
||||
return opBlend(s, d, a);
|
||||
|
@ -405,6 +410,7 @@ void imageFree(SwImage* image);
|
|||
bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, uint32_t opacity, bool ctable);
|
||||
void fillReset(SwFill* fill);
|
||||
void fillFree(SwFill* fill);
|
||||
//OPTIMIZE_ME: Skip the function pointer access
|
||||
void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlendOp op, uint8_t a); //blending 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); //masking ver.
|
||||
void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlendOp op, uint8_t a); //blending ver.
|
||||
|
|
|
@ -271,18 +271,10 @@ void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3
|
|||
auto detFirstDerivative = 2.0f * (fill->radial.a11 * rx + fill->radial.a21 * ry) + 0.5f * detSecondDerivative;
|
||||
auto det = rx * rx + ry * ry;
|
||||
|
||||
if (op) {
|
||||
for (uint32_t i = 0 ; i < len ; ++i, ++dst) {
|
||||
*dst = op(_pixel(fill, sqrtf(det)), *dst, a);
|
||||
det += detFirstDerivative;
|
||||
detFirstDerivative += detSecondDerivative;
|
||||
}
|
||||
} else {
|
||||
for (uint32_t i = 0 ; i < len ; ++i, ++dst) {
|
||||
*dst = _pixel(fill, sqrtf(det));
|
||||
det += detFirstDerivative;
|
||||
detFirstDerivative += detSecondDerivative;
|
||||
}
|
||||
for (uint32_t i = 0 ; i < len ; ++i, ++dst) {
|
||||
*dst = op(_pixel(fill, sqrtf(det)), *dst, a);
|
||||
det += detFirstDerivative;
|
||||
detFirstDerivative += detSecondDerivative;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,41 +377,21 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3
|
|||
auto vMin = -vMax;
|
||||
auto v = t + (inc * len);
|
||||
|
||||
if (op) {
|
||||
//we can use fixed point math
|
||||
if (v < vMax && v > vMin) {
|
||||
auto t2 = static_cast<int32_t>(t * FIXPT_SIZE);
|
||||
auto inc2 = static_cast<int32_t>(inc * FIXPT_SIZE);
|
||||
for (uint32_t j = 0; j < len; ++j, ++dst) {
|
||||
*dst = op(_fixedPixel(fill, t2), *dst, a);
|
||||
t2 += inc2;
|
||||
}
|
||||
//we have to fallback to float math
|
||||
} else {
|
||||
uint32_t counter = 0;
|
||||
while (counter++ < len) {
|
||||
*dst = op(_pixel(fill, t / GRADIENT_STOP_SIZE), *dst, a);
|
||||
++dst;
|
||||
t += inc;
|
||||
}
|
||||
//we can use fixed point math
|
||||
if (v < vMax && v > vMin) {
|
||||
auto t2 = static_cast<int32_t>(t * FIXPT_SIZE);
|
||||
auto inc2 = static_cast<int32_t>(inc * FIXPT_SIZE);
|
||||
for (uint32_t j = 0; j < len; ++j, ++dst) {
|
||||
*dst = op(_fixedPixel(fill, t2), *dst, a);
|
||||
t2 += inc2;
|
||||
}
|
||||
//we have to fallback to float math
|
||||
} else {
|
||||
//we can use fixed point math
|
||||
if (v < vMax && v > vMin) {
|
||||
auto t2 = static_cast<int32_t>(t * FIXPT_SIZE);
|
||||
auto inc2 = static_cast<int32_t>(inc * FIXPT_SIZE);
|
||||
for (uint32_t j = 0; j < len; ++j, ++dst) {
|
||||
*dst = _fixedPixel(fill, t2);
|
||||
t2 += inc2;
|
||||
}
|
||||
//we have to fallback to float math
|
||||
} else {
|
||||
uint32_t counter = 0;
|
||||
while (counter++ < len) {
|
||||
*dst = _pixel(fill, t / GRADIENT_STOP_SIZE);
|
||||
++dst;
|
||||
t += inc;
|
||||
}
|
||||
uint32_t counter = 0;
|
||||
while (counter++ < len) {
|
||||
*dst = op(_pixel(fill, t / GRADIENT_STOP_SIZE), *dst, a);
|
||||
++dst;
|
||||
t += inc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,11 +44,6 @@ struct FillLinear
|
|||
fillLinear(fill, dst, y, x, len, op, a);
|
||||
}
|
||||
|
||||
void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len)
|
||||
{
|
||||
fillLinear(fill, dst, y, x, len, nullptr, 255);
|
||||
}
|
||||
|
||||
void operator()(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)
|
||||
{
|
||||
fillLinear(fill, dst, y, x, len, cmp, alpha, csize, opacity);
|
||||
|
@ -62,11 +57,6 @@ struct FillRadial
|
|||
fillRadial(fill, dst, y, x, len, op, a);
|
||||
}
|
||||
|
||||
void operator()(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len)
|
||||
{
|
||||
fillRadial(fill, dst, y, x, len, nullptr, 255);
|
||||
}
|
||||
|
||||
void operator()(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)
|
||||
{
|
||||
fillRadial(fill, dst, y, x, len, cmp, alpha, csize, opacity);
|
||||
|
@ -216,7 +206,9 @@ static inline uint32_t _halfScale(float scale)
|
|||
return halfScale;
|
||||
}
|
||||
|
||||
|
||||
//Bilinear Interpolation
|
||||
//OPTIMIZE_ME: Skip the function pointer access
|
||||
static uint32_t _interpUpScaler(const uint32_t *img, TVG_UNUSED uint32_t stride, uint32_t w, uint32_t h, float sx, float sy, TVG_UNUSED uint32_t n)
|
||||
{
|
||||
auto rx = (uint32_t)(sx);
|
||||
|
@ -239,6 +231,7 @@ static uint32_t _interpUpScaler(const uint32_t *img, TVG_UNUSED uint32_t stride,
|
|||
|
||||
|
||||
//2n x 2n Mean Kernel
|
||||
//OPTIMIZE_ME: Skip the function pointer access
|
||||
static uint32_t _interpDownScaler(const uint32_t *img, uint32_t stride, uint32_t w, uint32_t h, float sx, float sy, uint32_t n)
|
||||
{
|
||||
uint32_t rx = sx;
|
||||
|
@ -1460,7 +1453,7 @@ static bool _rasterSolidGradientRect(SwSurface* surface, const SwBBox& region, c
|
|||
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
|
||||
|
||||
for (uint32_t y = 0; y < h; ++y) {
|
||||
fillMethod()(fill, buffer + y * surface->stride, region.min.y + y, region.min.x, w);
|
||||
fillMethod()(fill, buffer + y * surface->stride, region.min.y + y, region.min.x, w, opDirect, 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1597,7 +1590,7 @@ static bool _rasterSolidGradientRle(SwSurface* surface, const SwRleData* rle, co
|
|||
|
||||
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
|
||||
auto dst = &surface->buf32[span->y * surface->stride + span->x];
|
||||
if (span->coverage == 255) fillMethod()(fill, dst, span->y, span->x, span->len);
|
||||
if (span->coverage == 255) fillMethod()(fill, dst, span->y, span->x, span->len, opDirect, 0);
|
||||
else fillMethod()(fill, dst, span->y, span->x, span->len, opInterpolate, span->coverage);
|
||||
}
|
||||
return true;
|
||||
|
|
Loading…
Add table
Reference in a new issue