Skip to content

Commit

Permalink
Merge pull request #93655 from capnm/240627_tvg_v0.14.0
Browse files Browse the repository at this point in the history
ThorVG: Update to 0.14.0
  • Loading branch information
akien-mga committed Jun 28, 2024
2 parents 184a973 + 10406c8 commit af9bca9
Show file tree
Hide file tree
Showing 23 changed files with 373 additions and 374 deletions.
2 changes: 1 addition & 1 deletion thirdparty/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ instead of `miniz.h` as an external dependency.
## thorvg

- Upstream: https://github.com/thorvg/thorvg
- Version: 0.13.7 (d2c0428a99f7305c086caffe0c730add601ebd6e, 2024)
- Version: 0.14.0 (ae4e9d003c93325f1eba64319fa9852a0d764b4c, 2024)
- License: MIT

Files extracted from upstream source:
Expand Down
8 changes: 6 additions & 2 deletions thirdparty/thorvg/AUTHORS
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
Hermet Park <[email protected]>, <[email protected]>
Hermet Park <[email protected]>
Prudhvi Raj Vasireddi <[email protected]>
Junsu Choi <[email protected]>
Pranay Samanta <[email protected]>
Mateusz Palkowski <[email protected]>
Subhransu Mohanty <[email protected]>
Mira Grudzinska <[email protected]>, <m.grudzinska@samsung.com>
Mira Grudzinska <mira@lottiefiles.com>
Michal Szczecinski <[email protected]>
Shinwoo Kim <[email protected]>
Piotr Kalota <[email protected]>
Expand All @@ -27,3 +27,7 @@ Jinny You <[email protected]>
Nattu Adnan <[email protected]>
Gabor Kiss-Vamosi <[email protected]>
Lorcán Mc Donagh <[email protected]>
Lucas Niu <[email protected]>
Francisco Ramírez <[email protected]>
Abdelrahman Ashraf <[email protected]>
Neo Xu <[email protected]>
2 changes: 1 addition & 1 deletion thirdparty/thorvg/inc/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
// For internal debugging:
//#define THORVG_LOG_ENABLED

#define THORVG_VERSION_STRING "0.13.8"
#define THORVG_VERSION_STRING "0.14.0"
#endif
241 changes: 60 additions & 181 deletions thirdparty/thorvg/inc/thorvg.h

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions thirdparty/thorvg/src/common/tvgMath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,11 @@ void operator*=(Point& pt, const Matrix& m)
pt.x = tx;
pt.y = ty;
}


Point operator*(const Point& pt, const Matrix& m)
{
auto tx = pt.x * m.e11 + pt.y * m.e12 + m.e13;
auto ty = pt.x * m.e21 + pt.y * m.e22 + m.e23;
return {tx, ty};
}
10 changes: 8 additions & 2 deletions thirdparty/thorvg/src/common/tvgMath.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ static inline void operator*=(Matrix& lhs, const Matrix& rhs)
}


static inline void mathLog(Matrix* m)
static inline void mathLog(const Matrix& m)
{
TVGLOG("MATH", "Matrix: [%f %f %f] [%f %f %f] [%f %f %f]", m->e11, m->e12, m->e13, m->e21, m->e22, m->e23, m->e31, m->e32, m->e33);
TVGLOG("COMMON", "Matrix: [%f %f %f] [%f %f %f] [%f %f %f]", m.e11, m.e12, m.e13, m.e21, m.e22, m.e23, m.e31, m.e32, m.e33);
}


Expand All @@ -163,6 +163,7 @@ static inline void mathLog(Matrix* m)
/************************************************************************/

void operator*=(Point& pt, const Matrix& m);
Point operator*(const Point& pt, const Matrix& m);


static inline bool mathZero(const Point& p)
Expand Down Expand Up @@ -231,6 +232,11 @@ static inline Point operator/(const Point& lhs, const float rhs)
}


static inline void mathLog(const Point& pt)
{
TVGLOG("COMMON", "Point: [%f %f]", pt.x, pt.y);
}

/************************************************************************/
/* Interpolation functions */
/************************************************************************/
Expand Down
6 changes: 3 additions & 3 deletions thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -647,9 +647,9 @@ static bool _hslToRgb(float hue, float saturation, float brightness, uint8_t* re
}
}

*red = static_cast<uint8_t>(roundf(_red * 255.0f));
*green = static_cast<uint8_t>(roundf(_green * 255.0f));
*blue = static_cast<uint8_t>(roundf(_blue * 255.0f));
*red = static_cast<uint8_t>(ceil(_red * 255.0f));
*green = static_cast<uint8_t>(ceil(_green * 255.0f));
*blue = static_cast<uint8_t>(ceil(_blue * 255.0f));

return true;
}
Expand Down
164 changes: 93 additions & 71 deletions thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterAvx.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,47 +101,57 @@ static void avxRasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32

static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
if (surface->channelSize != sizeof(uint32_t)) {
TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize);
return false;
}

auto color = surface->join(r, g, b, a);
auto buffer = surface->buf32 + (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);

uint32_t ialpha = 255 - a;
//32bits channels
if (surface->channelSize == sizeof(uint32_t)) {
auto color = surface->join(r, g, b, a);
auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x;

auto avxColor = _mm_set1_epi32(color);
auto avxIalpha = _mm_set1_epi8(ialpha);
uint32_t ialpha = 255 - a;

for (uint32_t y = 0; y < h; ++y) {
auto dst = &buffer[y * surface->stride];
auto avxColor = _mm_set1_epi32(color);
auto avxIalpha = _mm_set1_epi8(ialpha);

//1. fill the not aligned memory (for 128-bit registers a 16-bytes alignment is required)
auto notAligned = ((uintptr_t)dst & 0xf) / 4;
if (notAligned) {
notAligned = (N_32BITS_IN_128REG - notAligned > w ? w : N_32BITS_IN_128REG - notAligned);
for (uint32_t x = 0; x < notAligned; ++x, ++dst) {
*dst = color + ALPHA_BLEND(*dst, ialpha);
for (uint32_t y = 0; y < h; ++y) {
auto dst = &buffer[y * surface->stride];

//1. fill the not aligned memory (for 128-bit registers a 16-bytes alignment is required)
auto notAligned = ((uintptr_t)dst & 0xf) / 4;
if (notAligned) {
notAligned = (N_32BITS_IN_128REG - notAligned > w ? w : N_32BITS_IN_128REG - notAligned);
for (uint32_t x = 0; x < notAligned; ++x, ++dst) {
*dst = color + ALPHA_BLEND(*dst, ialpha);
}
}
}

//2. fill the aligned memory - N_32BITS_IN_128REG pixels processed at once
uint32_t iterations = (w - notAligned) / N_32BITS_IN_128REG;
uint32_t avxFilled = iterations * N_32BITS_IN_128REG;
auto avxDst = (__m128i*)dst;
for (uint32_t x = 0; x < iterations; ++x, ++avxDst) {
*avxDst = _mm_add_epi32(avxColor, ALPHA_BLEND(*avxDst, avxIalpha));
}
//2. fill the aligned memory - N_32BITS_IN_128REG pixels processed at once
uint32_t iterations = (w - notAligned) / N_32BITS_IN_128REG;
uint32_t avxFilled = iterations * N_32BITS_IN_128REG;
auto avxDst = (__m128i*)dst;
for (uint32_t x = 0; x < iterations; ++x, ++avxDst) {
*avxDst = _mm_add_epi32(avxColor, ALPHA_BLEND(*avxDst, avxIalpha));
}

//3. fill the remaining pixels
int32_t leftovers = w - notAligned - avxFilled;
dst += avxFilled;
while (leftovers--) {
*dst = color + ALPHA_BLEND(*dst, ialpha);
dst++;
//3. fill the remaining pixels
int32_t leftovers = w - notAligned - avxFilled;
dst += avxFilled;
while (leftovers--) {
*dst = color + ALPHA_BLEND(*dst, ialpha);
dst++;
}
}
//8bit grayscale
} else if (surface->channelSize == sizeof(uint8_t)) {
TVGLOG("SW_ENGINE", "Require AVX Optimization, Channel Size = %d", surface->channelSize);
auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x;
auto ialpha = ~a;
for (uint32_t y = 0; y < h; ++y) {
auto dst = &buffer[y * surface->stride];
for (uint32_t x = 0; x < w; ++x, ++dst) {
*dst = a + MULTIPLY(*dst, ialpha);
}
}
}
return true;
Expand All @@ -150,56 +160,68 @@ static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, u

static bool avxRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
if (surface->channelSize != sizeof(uint32_t)) {
TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize);
return false;
}

auto color = surface->join(r, g, b, a);
auto span = rle->spans;
uint32_t src;

for (uint32_t i = 0; i < rle->size; ++i) {
auto dst = &surface->buf32[span->y * surface->stride + span->x];
//32bit channels
if (surface->channelSize == sizeof(uint32_t)) {
auto color = surface->join(r, g, b, a);
uint32_t src;

if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage);
else src = color;
for (uint32_t i = 0; i < rle->size; ++i) {
auto dst = &surface->buf32[span->y * surface->stride + span->x];

auto ialpha = IA(src);
if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage);
else src = color;

//1. fill the not aligned memory (for 128-bit registers a 16-bytes alignment is required)
auto notAligned = ((uintptr_t)dst & 0xf) / 4;
if (notAligned) {
notAligned = (N_32BITS_IN_128REG - notAligned > span->len ? span->len : N_32BITS_IN_128REG - notAligned);
for (uint32_t x = 0; x < notAligned; ++x, ++dst) {
*dst = src + ALPHA_BLEND(*dst, ialpha);
auto ialpha = IA(src);

//1. fill the not aligned memory (for 128-bit registers a 16-bytes alignment is required)
auto notAligned = ((uintptr_t)dst & 0xf) / 4;
if (notAligned) {
notAligned = (N_32BITS_IN_128REG - notAligned > span->len ? span->len : N_32BITS_IN_128REG - notAligned);
for (uint32_t x = 0; x < notAligned; ++x, ++dst) {
*dst = src + ALPHA_BLEND(*dst, ialpha);
}
}
}

//2. fill the aligned memory using avx - N_32BITS_IN_128REG pixels processed at once
//In order to avoid unneccessary avx variables declarations a check is made whether there are any iterations at all
uint32_t iterations = (span->len - notAligned) / N_32BITS_IN_128REG;
uint32_t avxFilled = 0;
if (iterations > 0) {
auto avxSrc = _mm_set1_epi32(src);
auto avxIalpha = _mm_set1_epi8(ialpha);
//2. fill the aligned memory using avx - N_32BITS_IN_128REG pixels processed at once
//In order to avoid unneccessary avx variables declarations a check is made whether there are any iterations at all
uint32_t iterations = (span->len - notAligned) / N_32BITS_IN_128REG;
uint32_t avxFilled = 0;
if (iterations > 0) {
auto avxSrc = _mm_set1_epi32(src);
auto avxIalpha = _mm_set1_epi8(ialpha);

avxFilled = iterations * N_32BITS_IN_128REG;
auto avxDst = (__m128i*)dst;
for (uint32_t x = 0; x < iterations; ++x, ++avxDst) {
*avxDst = _mm_add_epi32(avxSrc, ALPHA_BLEND(*avxDst, avxIalpha));
}
}

avxFilled = iterations * N_32BITS_IN_128REG;
auto avxDst = (__m128i*)dst;
for (uint32_t x = 0; x < iterations; ++x, ++avxDst) {
*avxDst = _mm_add_epi32(avxSrc, ALPHA_BLEND(*avxDst, avxIalpha));
//3. fill the remaining pixels
int32_t leftovers = span->len - notAligned - avxFilled;
dst += avxFilled;
while (leftovers--) {
*dst = src + ALPHA_BLEND(*dst, ialpha);
dst++;
}
}

//3. fill the remaining pixels
int32_t leftovers = span->len - notAligned - avxFilled;
dst += avxFilled;
while (leftovers--) {
*dst = src + ALPHA_BLEND(*dst, ialpha);
dst++;
++span;
}
//8bit grayscale
} else if (surface->channelSize == sizeof(uint8_t)) {
TVGLOG("SW_ENGINE", "Require AVX Optimization, Channel Size = %d", surface->channelSize);
uint8_t src;
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
auto dst = &surface->buf8[span->y * surface->stride + span->x];
if (span->coverage < 255) src = MULTIPLY(span->coverage, a);
else src = a;
auto ialpha = ~a;
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
*dst = src + MULTIPLY(*dst, ialpha);
}
}

++span;
}
return true;
}
Expand Down
Loading

0 comments on commit af9bca9

Please sign in to comment.