sw_engine raster: code refactoring

+neat and clean code
This commit is contained in:
Hermet Park 2021-11-24 20:25:47 +09:00 committed by Hermet Park
parent f7e52e93ed
commit e76091a283
4 changed files with 235 additions and 263 deletions

View file

@ -62,14 +62,6 @@ static inline uint32_t _argbJoin(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
}
static bool _translucent(const SwSurface* surface, uint8_t a)
{
if (a < 255) return true;
if (!surface->compositor || surface->compositor->method == CompositeMethod::None) return false;
return true;
}
static inline bool _compositing(const SwSurface* surface)
{
if (!surface->compositor || surface->compositor->method == CompositeMethod::None) return false;
@ -130,48 +122,27 @@ static uint32_t _interpDownScaler(const uint32_t *img, uint32_t w, uint32_t h, u
/* Rect */
/************************************************************************/
static bool _rasterTranslucentMaskedRect(SwSurface* surface, const SwBBox& region, uint32_t color, uint32_t (*blendMethod)(uint32_t))
static bool _rasterMaskedRect(SwSurface* surface, const SwBBox& region, uint32_t color, uint32_t (*blendMethod)(uint32_t))
{
auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x;
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
TVGLOG("SW_ENGINE", "Masked Rect");
TVGLOG("SW_ENGINE", "Translucent Masked Rect");
auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x;
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; //compositor buffer
for (uint32_t y = 0; y < h; ++y) {
auto dst = &buffer[y * surface->stride];
auto cmp = &cbuffer[y * surface->stride];
for (uint32_t x = 0; x < w; ++x) {
for (uint32_t x = 0; x < w; ++x, ++dst, ++cmp) {
auto tmp = ALPHA_BLEND(color, blendMethod(*cmp));
dst[x] = tmp + ALPHA_BLEND(dst[x], surface->blender.ialpha(tmp));
++cmp;
*dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
}
}
return true;
}
static bool _rasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color)
{
if (surface->compositor) {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterTranslucentMaskedRect(surface, region, color, surface->blender.alpha);
}
if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterTranslucentMaskedRect(surface, region, color, surface->blender.ialpha);
}
}
#if defined(THORVG_AVX_VECTOR_SUPPORT)
return avxRasterTranslucentRect(surface, region, color);
#elif defined(THORVG_NEON_VECTOR_SUPPORT)
return neonRasterTranslucentRect(surface, region, color);
#else
return cRasterTranslucentRect(surface, region, color);
#endif
}
static bool _rasterSolidRect(SwSurface* surface, const SwBBox& region, uint32_t color)
{
@ -186,79 +157,104 @@ static bool _rasterSolidRect(SwSurface* surface, const SwBBox& region, uint32_t
}
static bool _rasterRect(SwSurface* surface, const SwBBox& region, uint32_t color, uint8_t opacity)
{
if (_compositing(surface)) {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterMaskedRect(surface, region, color, surface->blender.alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterMaskedRect(surface, region, color, surface->blender.ialpha);
}
} else {
if (opacity == 255) {
return _rasterSolidRect(surface, region, color);
} else {
#if defined(THORVG_AVX_VECTOR_SUPPORT)
return avxRasterTranslucentRect(surface, region, color);
#elif defined(THORVG_NEON_VECTOR_SUPPORT)
return neonRasterTranslucentRect(surface, region, color);
#else
return cRasterTranslucentRect(surface, region, color);
#endif
}
}
return false;
}
/************************************************************************/
/* Rle */
/************************************************************************/
static bool _rasterTranslucentMaskedRle(SwSurface* surface, SwRleData* rle, uint32_t color, uint32_t (*blendMethod)(uint32_t))
static bool _rasterMaskedRle(SwSurface* surface, SwRleData* rle, uint32_t color, uint32_t (*blendMethod)(uint32_t))
{
TVGLOG("SW_ENGINE", "Translucent Masked Rle");
TVGLOG("SW_ENGINE", "Masked Rle");
auto span = rle->spans;
uint32_t src;
auto cbuffer = surface->compositor->image.data;
for (uint32_t i = 0; i < rle->size; ++i) {
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
auto dst = &surface->buffer[span->y * surface->stride + span->x];
auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage);
else src = color;
for (uint32_t x = 0; x < span->len; ++x) {
if (span->coverage == 255) src = color;
else src = ALPHA_BLEND(color, span->coverage);
for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) {
auto tmp = ALPHA_BLEND(src, blendMethod(*cmp));
dst[x] = tmp + ALPHA_BLEND(dst[x], surface->blender.ialpha(tmp));
++cmp;
*dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
}
++span;
}
return true;
}
static bool _rasterTranslucentRle(SwSurface* surface, SwRleData* rle, uint32_t color)
{
if (!rle) return false;
if (surface->compositor) {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterTranslucentMaskedRle(surface, rle, color, surface->blender.alpha);
}
if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterTranslucentMaskedRle(surface, rle, color, surface->blender.ialpha);
}
}
#if defined(THORVG_AVX_VECTOR_SUPPORT)
return avxRasterTranslucentRle(surface, rle, color);
#elif defined(THORVG_NEON_VECTOR_SUPPORT)
return neonRasterTranslucentRle(surface, rle, color);
#else
return cRasterTranslucentRle(surface, rle, color);
#endif
}
static bool _rasterSolidRle(SwSurface* surface, const SwRleData* rle, uint32_t color)
{
if (!rle) return false;
auto span = rle->spans;
for (uint32_t i = 0; i < rle->size; ++i) {
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
if (span->coverage == 255) {
rasterRGBA32(surface->buffer + span->y * surface->stride, color, span->x, span->len);
} else {
auto dst = &surface->buffer[span->y * surface->stride + span->x];
auto src = ALPHA_BLEND(color, span->coverage);
auto ialpha = 255 - span->coverage;
for (uint32_t i = 0; i < span->len; ++i) {
dst[i] = src + ALPHA_BLEND(dst[i], ialpha);
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
*dst = src + ALPHA_BLEND(*dst, ialpha);
}
}
++span;
}
return true;
}
static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint32_t color, uint8_t opacity)
{
if (!rle) return false;
if (_compositing(surface)) {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterMaskedRle(surface, rle, color, surface->blender.alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterMaskedRle(surface, rle, color, surface->blender.ialpha);
}
} else {
if (opacity == 255) {
return _rasterSolidRle(surface, rle, color);
} else {
#if defined(THORVG_AVX_VECTOR_SUPPORT)
return avxRasterTranslucentRle(surface, rle, color);
#elif defined(THORVG_NEON_VECTOR_SUPPORT)
return neonRasterTranslucentRle(surface, rle, color);
#else
return cRasterTranslucentRle(surface, rle, color);
#endif
}
}
return false;
}
/************************************************************************/
/* RLE Transformed RGBA Image */
/************************************************************************/
@ -1896,7 +1892,7 @@ static bool _rasterRGBAImage(SwSurface* surface, SwImage* image, const Matrix* t
/* Rect Linear Gradient */
/************************************************************************/
static bool _rasterTranslucentLinearGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill, uint32_t (*blendMethod)(uint32_t))
static bool _rasterLinearGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill, uint32_t (*blendMethod)(uint32_t))
{
if (fill->linear.len < FLT_EPSILON) return false;
@ -1924,7 +1920,7 @@ static bool _rasterTranslucentLinearGradientMaskedRect(SwSurface* surface, const
}
static bool __rasterTranslucentLinearGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
static bool _rasterTranslucentLinearGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
{
if (fill->linear.len < FLT_EPSILON) return false;
@ -1935,39 +1931,25 @@ static bool __rasterTranslucentLinearGradientRect(SwSurface* surface, const SwBB
auto sbuffer = static_cast<uint32_t*>(alloca(w * sizeof(uint32_t)));
if (!sbuffer) return false;
auto dst = buffer;
for (uint32_t y = 0; y < h; ++y) {
auto dst = buffer;
fillFetchLinear(fill, sbuffer, region.min.y + y, region.min.x, w);
for (uint32_t x = 0; x < w; ++x) {
dst[x] = sbuffer[x] + ALPHA_BLEND(dst[x], surface->blender.ialpha(sbuffer[x]));
for (uint32_t x = 0; x < w; ++x, ++dst) {
*dst = sbuffer[x] + ALPHA_BLEND(*dst, surface->blender.ialpha(sbuffer[x]));
}
dst += surface->stride;
buffer += surface->stride;
}
return true;
}
static bool _rasterTranslucentLinearGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
{
if (surface->compositor) {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterTranslucentLinearGradientMaskedRect(surface, region, fill, surface->blender.alpha);
}
if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterTranslucentLinearGradientMaskedRect(surface, region, fill, surface->blender.ialpha);
}
}
return __rasterTranslucentLinearGradientRect(surface, region, fill);
}
static bool _rasterSolidLinearGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
{
if (fill->linear.len < FLT_EPSILON) return false;
auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x;
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
for (uint32_t y = 0; y < h; ++y) {
fillFetchLinear(fill, buffer + y * surface->stride, region.min.y + y, region.min.x, w);
@ -1976,12 +1958,27 @@ static bool _rasterSolidLinearGradientRect(SwSurface* surface, const SwBBox& reg
}
static bool _rasterLinearGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
{
if (_compositing(surface)) {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterLinearGradientMaskedRect(surface, region, fill, surface->blender.alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterLinearGradientMaskedRect(surface, region, fill, surface->blender.ialpha);
}
} else {
if (fill->translucent) return _rasterTranslucentLinearGradientRect(surface, region, fill);
else _rasterSolidLinearGradientRect(surface, region, fill);
}
return false;
}
/************************************************************************/
/* Rle Linear Gradient */
/************************************************************************/
static bool _rasterTranslucentLinearGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill, uint32_t (*blendMethod)(uint32_t))
static bool _rasterLinearGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill, uint32_t (*blendMethod)(uint32_t))
{
if (fill->linear.len < FLT_EPSILON) return false;
@ -2013,7 +2010,7 @@ static bool _rasterTranslucentLinearGradientMaskedRle(SwSurface* surface, const
}
static bool __rasterTranslucentLinearGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill)
static bool _rasterTranslucentLinearGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill)
{
if (fill->linear.len < FLT_EPSILON) return false;
@ -2025,13 +2022,13 @@ static bool __rasterTranslucentLinearGradientRle(SwSurface* surface, const SwRle
auto dst = &surface->buffer[span->y * surface->stride + span->x];
fillFetchLinear(fill, buffer, span->y, span->x, span->len);
if (span->coverage == 255) {
for (uint32_t i = 0; i < span->len; ++i) {
dst[i] = buffer[i] + ALPHA_BLEND(dst[i], surface->blender.ialpha(buffer[i]));
for (uint32_t i = 0; i < span->len; ++i, ++dst) {
*dst = buffer[i] + ALPHA_BLEND(*dst, surface->blender.ialpha(buffer[i]));
}
} else {
for (uint32_t i = 0; i < span->len; ++i) {
for (uint32_t i = 0; i < span->len; ++i, ++dst) {
auto tmp = ALPHA_BLEND(buffer[i], span->coverage);
dst[i] = tmp + ALPHA_BLEND(dst[i], surface->blender.ialpha(tmp));
*dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
}
}
}
@ -2039,21 +2036,6 @@ static bool __rasterTranslucentLinearGradientRle(SwSurface* surface, const SwRle
}
static bool _rasterTranslucentLinearGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill)
{
if (!rle) return false;
if (surface->compositor) {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterTranslucentLinearGradientMaskedRle(surface, rle, fill, surface->blender.alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterTranslucentLinearGradientMaskedRle(surface, rle, fill, surface->blender.ialpha);
}
}
return __rasterTranslucentLinearGradientRle(surface, rle, fill);
}
static bool _rasterSolidLinearGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill)
{
if (fill->linear.len < FLT_EPSILON) return false;
@ -2079,11 +2061,29 @@ static bool _rasterSolidLinearGradientRle(SwSurface* surface, const SwRleData* r
}
static bool _rasterLinearGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill)
{
if (!rle) return false;
if (_compositing(surface)) {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterLinearGradientMaskedRle(surface, rle, fill, surface->blender.alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterLinearGradientMaskedRle(surface, rle, fill, surface->blender.ialpha);
}
} else {
if (fill->translucent) return _rasterTranslucentLinearGradientRle(surface, rle, fill);
else return _rasterSolidLinearGradientRle(surface, rle, fill);
}
return false;
}
/************************************************************************/
/* Rect Radial Gradient */
/************************************************************************/
static bool _rasterTranslucentRadialGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill, uint32_t (*blendMethod)(uint32_t))
static bool _rasterRadialGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill, uint32_t (*blendMethod)(uint32_t))
{
if (fill->radial.a < FLT_EPSILON) return false;
@ -2111,7 +2111,7 @@ static bool _rasterTranslucentRadialGradientMaskedRect(SwSurface* surface, const
}
static bool __rasterTranslucentRadialGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
static bool _rasterTranslucentRadialGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
{
if (fill->radial.a < FLT_EPSILON) return false;
@ -2122,31 +2122,18 @@ static bool __rasterTranslucentRadialGradientRect(SwSurface* surface, const SwBB
auto sbuffer = static_cast<uint32_t*>(alloca(w * sizeof(uint32_t)));
if (!sbuffer) return false;
auto dst = buffer;
for (uint32_t y = 0; y < h; ++y) {
auto dst = buffer;
fillFetchRadial(fill, sbuffer, region.min.y + y, region.min.x, w);
for (uint32_t x = 0; x < w; ++x) {
dst[x] = sbuffer[x] + ALPHA_BLEND(dst[x], surface->blender.ialpha(sbuffer[x]));
for (uint32_t x = 0; x < w; ++x, ++dst) {
*dst = sbuffer[x] + ALPHA_BLEND(*dst, surface->blender.ialpha(sbuffer[x]));
}
dst += surface->stride;
buffer += surface->stride;
}
return true;
}
static bool _rasterTranslucentRadialGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
{
if (surface->compositor) {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterTranslucentRadialGradientMaskedRect(surface, region, fill, surface->blender.alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterTranslucentRadialGradientMaskedRect(surface, region, fill, surface->blender.ialpha);
}
}
return __rasterTranslucentRadialGradientRect(surface, region, fill);
}
static bool _rasterSolidRadialGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
{
if (fill->radial.a < FLT_EPSILON) return false;
@ -2163,12 +2150,27 @@ static bool _rasterSolidRadialGradientRect(SwSurface* surface, const SwBBox& reg
}
static bool _rasterRadialGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
{
if (_compositing(surface)) {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterRadialGradientMaskedRect(surface, region, fill, surface->blender.alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterRadialGradientMaskedRect(surface, region, fill, surface->blender.ialpha);
}
} else {
if (fill->translucent) return _rasterTranslucentRadialGradientRect(surface, region, fill);
else return _rasterSolidRadialGradientRect(surface, region, fill);
}
return false;
}
/************************************************************************/
/* RLE Radial Gradient */
/************************************************************************/
static bool _rasterTranslucentRadialGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill, uint32_t (*blendMethod)(uint32_t))
static bool _rasterRadialGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill, uint32_t (*blendMethod)(uint32_t))
{
if (fill->radial.a < FLT_EPSILON) return false;
@ -2200,7 +2202,7 @@ static bool _rasterTranslucentRadialGradientMaskedRle(SwSurface* surface, const
}
static bool __rasterTranslucentRadialGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill)
static bool _rasterTranslucentRadialGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill)
{
if (fill->radial.a < FLT_EPSILON) return false;
@ -2212,13 +2214,13 @@ static bool __rasterTranslucentRadialGradientRle(SwSurface* surface, const SwRle
auto dst = &surface->buffer[span->y * surface->stride + span->x];
fillFetchRadial(fill, buffer, span->y, span->x, span->len);
if (span->coverage == 255) {
for (uint32_t i = 0; i < span->len; ++i) {
dst[i] = buffer[i] + ALPHA_BLEND(dst[i], surface->blender.ialpha(buffer[i]));
for (uint32_t i = 0; i < span->len; ++i, ++dst) {
*dst = buffer[i] + ALPHA_BLEND(*dst, surface->blender.ialpha(buffer[i]));
}
} else {
for (uint32_t i = 0; i < span->len; ++i) {
for (uint32_t i = 0; i < span->len; ++i, ++dst) {
auto tmp = ALPHA_BLEND(buffer[i], span->coverage);
dst[i] = tmp + ALPHA_BLEND(dst[i], surface->blender.ialpha(tmp));
*dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
}
}
}
@ -2226,21 +2228,6 @@ static bool __rasterTranslucentRadialGradientRle(SwSurface* surface, const SwRle
}
static bool _rasterTranslucentRadialGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill)
{
if (!rle) return false;
if (surface->compositor) {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterTranslucentRadialGradientMaskedRle(surface, rle, fill, surface->blender.alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterTranslucentRadialGradientMaskedRle(surface, rle, fill, surface->blender.ialpha);
}
}
return __rasterTranslucentRadialGradientRle(surface, rle, fill);
}
static bool _rasterSolidRadialGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill)
{
if (fill->radial.a < FLT_EPSILON) return false;
@ -2258,7 +2245,7 @@ static bool _rasterSolidRadialGradientRle(SwSurface* surface, const SwRleData* r
fillFetchRadial(fill, buf, span->y, span->x, span->len);
auto ialpha = 255 - span->coverage;
for (uint32_t i = 0; i < span->len; ++i) {
dst[i] = ALPHA_BLEND(buf[i], span->coverage) + ALPHA_BLEND(dst[i], ialpha);
*dst = ALPHA_BLEND(buf[i], span->coverage) + ALPHA_BLEND(*dst, ialpha);
}
}
}
@ -2266,6 +2253,24 @@ static bool _rasterSolidRadialGradientRle(SwSurface* surface, const SwRleData* r
}
static bool _rasterRadialGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill)
{
if (!rle) return false;
if (_compositing(surface)) {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterRadialGradientMaskedRle(surface, rle, fill, surface->blender.alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterRadialGradientMaskedRle(surface, rle, fill, surface->blender.ialpha);
}
} else {
if (fill->translucent) _rasterTranslucentRadialGradientRle(surface, rle, fill);
else return _rasterSolidRadialGradientRle(surface, rle, fill);
}
return false;
}
/************************************************************************/
/* External Class Implementation */
/************************************************************************/
@ -2299,92 +2304,6 @@ bool rasterCompositor(SwSurface* surface)
}
bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id)
{
if (!shape->fill) return false;
auto translucent = shape->fill->translucent || (surface->compositor && surface->compositor->method != CompositeMethod::None);
//Fast Track
if (shape->fastTrack) {
if (id == TVG_CLASS_ID_LINEAR) {
if (translucent) return _rasterTranslucentLinearGradientRect(surface, shape->bbox, shape->fill);
return _rasterSolidLinearGradientRect(surface, shape->bbox, shape->fill);
} else {
if (translucent) return _rasterTranslucentRadialGradientRect(surface, shape->bbox, shape->fill);
return _rasterSolidRadialGradientRect(surface, shape->bbox, shape->fill);
}
} else {
if (!shape->rle) return false;
if (id == TVG_CLASS_ID_LINEAR) {
if (translucent) return _rasterTranslucentLinearGradientRle(surface, shape->rle, shape->fill);
return _rasterSolidLinearGradientRle(surface, shape->rle, shape->fill);
} else {
if (translucent) return _rasterTranslucentRadialGradientRle(surface, shape->rle, shape->fill);
return _rasterSolidRadialGradientRle(surface, shape->rle, shape->fill);
}
}
return false;
}
bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
if (a < 255) {
r = _multiplyAlpha(r, a);
g = _multiplyAlpha(g, a);
b = _multiplyAlpha(b, a);
}
auto color = surface->blender.join(r, g, b, a);
auto translucent = _translucent(surface, a);
//Fast Track
if (shape->fastTrack) {
if (translucent) return _rasterTranslucentRect(surface, shape->bbox, color);
return _rasterSolidRect(surface, shape->bbox, color);
}
if (translucent) {
return _rasterTranslucentRle(surface, shape->rle, color);
}
return _rasterSolidRle(surface, shape->rle, color);
}
bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
if (a < 255) {
r = _multiplyAlpha(r, a);
g = _multiplyAlpha(g, a);
b = _multiplyAlpha(b, a);
}
auto color = surface->blender.join(r, g, b, a);
auto translucent = _translucent(surface, a);
if (translucent) return _rasterTranslucentRle(surface, shape->strokeRle, color);
return _rasterSolidRle(surface, shape->strokeRle, color);
}
bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id)
{
if (!shape->stroke || !shape->stroke->fill || !shape->strokeRle) return false;
auto translucent = shape->stroke->fill->translucent || (surface->compositor && surface->compositor->method != CompositeMethod::None);
if (id == TVG_CLASS_ID_LINEAR) {
if (translucent) return _rasterTranslucentLinearGradientRle(surface, shape->strokeRle, shape->stroke->fill);
return _rasterSolidLinearGradientRle(surface, shape->strokeRle, shape->stroke->fill);
} else {
if (translucent) return _rasterTranslucentRadialGradientRle(surface, shape->strokeRle, shape->stroke->fill);
return _rasterSolidRadialGradientRle(surface, shape->strokeRle, shape->stroke->fill);
}
return false;
}
bool rasterClear(SwSurface* surface)
{
if (!surface || !surface->buffer || surface->stride <= 0 || surface->w <= 0 || surface->h <= 0) return false;
@ -2425,6 +2344,61 @@ void rasterUnpremultiply(SwSurface* surface)
}
bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id)
{
if (!shape->fill) return false;
if (shape->fastTrack) {
if (id == TVG_CLASS_ID_LINEAR) return _rasterLinearGradientRect(surface, shape->bbox, shape->fill);
else if (id == TVG_CLASS_ID_RADIAL)return _rasterRadialGradientRect(surface, shape->bbox, shape->fill);
} else {
if (id == TVG_CLASS_ID_LINEAR) return _rasterLinearGradientRle(surface, shape->rle, shape->fill);
else if (id == TVG_CLASS_ID_RADIAL) return _rasterRadialGradientRle(surface, shape->rle, shape->fill);
}
return false;
}
bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id)
{
if (!shape->stroke || !shape->stroke->fill || !shape->strokeRle) return false;
if (id == TVG_CLASS_ID_LINEAR) return _rasterLinearGradientRle(surface, shape->strokeRle, shape->stroke->fill);
else if (id == TVG_CLASS_ID_RADIAL) return _rasterRadialGradientRle(surface, shape->strokeRle, shape->stroke->fill);
return false;
}
bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
if (a < 255) {
r = _multiplyAlpha(r, a);
g = _multiplyAlpha(g, a);
b = _multiplyAlpha(b, a);
}
auto color = surface->blender.join(r, g, b, a);
if (shape->fastTrack) return _rasterRect(surface, shape->bbox, color, a);
else return _rasterRle(surface, shape->rle, color, a);
}
bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
if (a < 255) {
r = _multiplyAlpha(r, a);
g = _multiplyAlpha(g, a);
b = _multiplyAlpha(b, a);
}
auto color = surface->blender.join(r, g, b, a);
return _rasterRle(surface, shape->strokeRle, color, a);
}
bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, const SwBBox& bbox, uint32_t opacity)
{
//Verify Boundary

View file

@ -62,7 +62,7 @@ static inline __m128i ALPHA_BLEND(__m128i c, __m128i a)
}
static inline void avxRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
static void avxRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
{
//1. calculate how many iterations we need to cover the length
uint32_t iterations = len / N_32BITS_IN_256REG;
@ -82,7 +82,7 @@ static inline void avxRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset,
}
static inline bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color)
static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color)
{
auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x;
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
@ -125,7 +125,7 @@ static inline bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& re
}
static inline bool avxRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color)
static bool avxRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color)
{
auto span = rle->spans;
uint32_t src;

View file

@ -21,45 +21,43 @@
*/
static inline void cRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
static void cRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
{
dst += offset;
while (len--) *dst++ = val;
}
static inline bool cRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color)
static bool cRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color)
{
auto span = rle->spans;
uint32_t src;
for (uint32_t i = 0; i < rle->size; ++i) {
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
auto dst = &surface->buffer[span->y * surface->stride + span->x];
if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage);
else src = color;
auto ialpha = 255 - surface->blender.alpha(src);
for (uint32_t x = 0; x < span->len; ++x)
dst[x] = src + ALPHA_BLEND(dst[x], ialpha);
++span;
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
}
}
return true;
}
static inline bool cRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color)
static bool cRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color)
{
auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x;
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
auto ialpha = 255 - surface->blender.alpha(color);
auto ialpha = surface->blender.ialpha(color);
for (uint32_t y = 0; y < h; ++y) {
auto dst = &buffer[y * surface->stride];
for (uint32_t x = 0; x < w; ++x) {
dst[x] = color + ALPHA_BLEND(dst[x], ialpha);
for (uint32_t x = 0; x < w; ++x, ++dst) {
*dst = color + ALPHA_BLEND(*dst, ialpha);
}
}
return true;

View file

@ -31,7 +31,7 @@ static inline uint8x8_t ALPHA_BLEND(uint8x8_t c, uint8x8_t a)
}
static inline void neonRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
static void neonRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
{
uint32_t iterations = len / 4;
uint32_t neonFilled = iterations * 4;
@ -49,7 +49,7 @@ static inline void neonRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset
}
static inline bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color)
static bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color)
{
auto span = rle->spans;
uint32_t src;
@ -88,7 +88,7 @@ static inline bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData*
}
static inline bool neonRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color)
static bool neonRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color)
{
auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x;
auto h = static_cast<uint32_t>(region.max.y - region.min.y);