Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ThorVG: Update to 0.14.0 #93655

Merged
merged 1 commit into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading