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.10 #97079

Merged
merged 1 commit into from
Sep 17, 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 @@ -907,7 +907,7 @@ instead of `miniz.h` as an external dependency.
## thorvg

- Upstream: https://github.com/thorvg/thorvg
- Version: 0.14.9 (81a0fbfd590873b21e53c3af77969c71d3d9b586, 2024)
- Version: 0.14.10 (366dcd72850c360b49e841e568fc5a154d7cce9e, 2024)
- License: MIT

Files extracted from upstream source:
Expand Down
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.14.9"
#define THORVG_VERSION_STRING "0.14.10"
#endif
25 changes: 0 additions & 25 deletions thirdparty/thorvg/patches/pr2716-text-drawing-reliability.patch

This file was deleted.

45 changes: 45 additions & 0 deletions thirdparty/thorvg/patches/pr2740-renderer-crash-hotfix.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
From 8009c75465e5b35da2d5f53532bc65f6df202a3a Mon Sep 17 00:00:00 2001
From: Hermet Park <hermet@lottiefiles.com>
Date: Tue, 17 Sep 2024 11:35:48 +0900
Subject: [PATCH] renderer: hotfix a crash

prevent a nullptr memory access
regression by f5337015e971d24379d2ee664895503ab8945e13

issue: https://github.com/godotengine/godot/issues/97078
---
src/renderer/tvgShape.h | 6 ++++--
2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/renderer/tvgShape.h b/src/renderer/tvgShape.h
index 221931dee..e120a85c6 100644
--- a/src/renderer/tvgShape.h
+++ b/src/renderer/tvgShape.h
@@ -51,8 +51,9 @@ struct Shape::Impl

bool render(RenderMethod* renderer)
{
+ if (!rd) return false;
+
Compositor* cmp = nullptr;
- bool ret;

renderer->blend(shape->blend());

@@ -61,7 +62,7 @@ struct Shape::Impl
renderer->beginComposite(cmp, CompositeMethod::None, opacity);
}

- ret = renderer->renderShape(rd);
+ auto ret = renderer->renderShape(rd);
if (cmp) renderer->endComposite(cmp);
return ret;
}
@@ -117,6 +118,7 @@ struct Shape::Impl

RenderRegion bounds(RenderMethod* renderer)
{
+ if (!rd) return {0, 0, 0, 0};
return renderer->region(rd);
}

8 changes: 8 additions & 0 deletions thirdparty/thorvg/src/common/tvgStr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,14 @@ char* strDuplicate(const char *str, size_t n)
return (char *) memcpy(ret, str, n);
}

char* strAppend(char* lhs, const char* rhs, size_t n)
{
if (!rhs) return lhs;
if (!lhs) return strDuplicate(rhs, n);
lhs = (char*)realloc(lhs, strlen(lhs) + n + 1);
return strncat(lhs, rhs, n);
}

char* strDirname(const char* path)
{
const char *ptr = strrchr(path, '/');
Expand Down
1 change: 1 addition & 0 deletions thirdparty/thorvg/src/common/tvgStr.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ namespace tvg
float strToFloat(const char *nPtr, char **endPtr); //convert to float
int str2int(const char* str, size_t n); //convert to integer
char* strDuplicate(const char *str, size_t n); //copy the string
char* strAppend(char* lhs, const char* rhs, size_t n); //append the rhs to the lhs
char* strDirname(const char* path); //return the full directory name

}
Expand Down
4 changes: 2 additions & 2 deletions thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2183,6 +2183,7 @@ static SvgNode* _createTextNode(SvgLoaderData* loader, SvgNode* parent, const ch
//TODO: support the def font and size as used in a system?
loader->svgParse->node->node.text.fontSize = 10.0f;
loader->svgParse->node->node.text.fontFamily = nullptr;
loader->svgParse->node->node.text.text = nullptr;

func(buf, bufLength, _attrParseTextNode, loader);

Expand Down Expand Up @@ -3400,8 +3401,7 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
static void _svgLoaderParserText(SvgLoaderData* loader, const char* content, unsigned int length)
{
auto text = &loader->svgParse->node->node.text;
if (text->text) free(text->text);
text->text = strDuplicate(content, length);
text->text = strAppend(text->text, content, length);
}


Expand Down
11 changes: 3 additions & 8 deletions thirdparty/thorvg/src/renderer/sw_engine/tvgSwCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ static inline uint32_t opBlendSrcOver(uint32_t s, TVG_UNUSED uint32_t d, TVG_UNU
}

//TODO: BlendMethod could remove the alpha parameter.
static inline uint32_t opBlendDifference(uint32_t s, uint32_t d, uint8_t a)
static inline uint32_t opBlendDifference(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
{
//if (s > d) => s - d
//else => d - s
Expand Down Expand Up @@ -404,7 +404,7 @@ static inline uint32_t opBlendScreen(uint32_t s, uint32_t d, TVG_UNUSED uint8_t
return JOIN(255, c1, c2, c3);
}

static inline uint32_t opBlendDirectMultiply(uint32_t s, uint32_t d, uint8_t a)
static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
{
// s * d
auto c1 = MULTIPLY(C1(s), C1(d));
Expand All @@ -413,11 +413,6 @@ static inline uint32_t opBlendDirectMultiply(uint32_t s, uint32_t d, uint8_t a)
return JOIN(255, c1, c2, c3);
}

static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, uint8_t a)
{
return opBlendDirectMultiply(s, d, a) + ALPHA_BLEND(d, IA(s));
}

static inline uint32_t opBlendOverlay(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
{
// if (2 * d < da) => 2 * s * d,
Expand Down Expand Up @@ -570,7 +565,7 @@ bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8
bool rasterImage(SwSurface* surface, SwImage* image, const Matrix& transform, const SwBBox& bbox, uint8_t opacity);
bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
bool rasterGradientStroke(SwSurface* surface, SwShape* shape, const Fill* fdata, uint8_t opacity);
bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h, pixel_t val = 0);
void rasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len);
void rasterGrayscale8(uint8_t *dst, uint8_t val, uint32_t offset, int32_t len);
void rasterUnpremultiply(Surface* surface);
Expand Down
87 changes: 59 additions & 28 deletions thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,12 +423,11 @@ static bool _rasterBlendingRect(SwSurface* surface, const SwBBox& region, uint8_
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
auto color = surface->join(r, g, b, a);
auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x;
auto ialpha = 255 - 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 = surface->blender(color, *dst, ialpha);
*dst = surface->blender(color, *dst, 255);
}
}
return true;
Expand Down Expand Up @@ -595,17 +594,16 @@ static bool _rasterBlendingRle(SwSurface* surface, const SwRleData* rle, uint8_t

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

for (uint32_t i = 0; i < rle->size; ++i, ++span) {
auto dst = &surface->buf32[span->y * surface->stride + span->x];
if (span->coverage == 255) {
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
*dst = surface->blender(color, *dst, ialpha);
*dst = surface->blender(color, *dst, 255);
}
} else {
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
auto tmp = surface->blender(color, *dst, ialpha);
auto tmp = surface->blender(color, *dst, 255);
*dst = INTERPOLATE(tmp, *dst, span->coverage);
}
}
Expand Down Expand Up @@ -813,9 +811,8 @@ 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) {
SCALED_IMAGE_RANGE_X
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
if (opacity < 255) src = ALPHA_BLEND(src, opacity);
auto tmp = surface->blender(src, *dst, 255);
*dst = INTERPOLATE(tmp, *dst, MULTIPLY(span->coverage, A(src)));
*dst = INTERPOLATE(tmp, *dst, MULTIPLY(alpha, A(src)));
}
}
}
Expand Down Expand Up @@ -981,18 +978,12 @@ static bool _rasterDirectBlendingRleImage(SwSurface* surface, const SwImage* ima
auto alpha = MULTIPLY(span->coverage, opacity);
if (alpha == 255) {
for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) {
*dst = surface->blender(*img, *dst, IA(*img));
}
} else if (opacity == 255) {
for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) {
auto tmp = surface->blender(*img, *dst, 255);
*dst = INTERPOLATE(tmp, *dst, MULTIPLY(span->coverage, A(*img)));
*dst = surface->blender(*img, *dst, 255);
}
} else {
for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) {
auto src = ALPHA_BLEND(*img, opacity);
auto tmp = surface->blender(src, *dst, IA(src));
*dst = INTERPOLATE(tmp, *dst, MULTIPLY(span->coverage, A(src)));
auto tmp = surface->blender(*img, *dst, 255);
*dst = INTERPOLATE(tmp, *dst, MULTIPLY(alpha, A(*img)));
}
}
}
Expand Down Expand Up @@ -1164,9 +1155,8 @@ static bool _rasterScaledBlendingImage(SwSurface* surface, const SwImage* image,
for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
SCALED_IMAGE_RANGE_X
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
if (opacity < 255) ALPHA_BLEND(src, opacity);
auto tmp = surface->blender(src, *dst, 255);
*dst = INTERPOLATE(tmp, *dst, A(src));
*dst = INTERPOLATE(tmp, *dst, MULTIPLY(opacity, A(src)));
}
}
return true;
Expand Down Expand Up @@ -1348,11 +1338,13 @@ static bool _rasterDirectMattedImage(SwSurface* surface, const SwImage* image, c
auto src = sbuffer;
if (opacity == 255) {
for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) {
*dst = MULTIPLY(A(*src), alpha(cmp));
auto tmp = MULTIPLY(A(*src), alpha(cmp));
*dst = tmp + MULTIPLY(*dst, 255 - tmp);
}
} else {
for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) {
*dst = MULTIPLY(A(*src), MULTIPLY(opacity, alpha(cmp)));
auto tmp = MULTIPLY(A(*src), MULTIPLY(opacity, alpha(cmp)));
*dst = tmp + MULTIPLY(*dst, 255 - tmp);
}
}
buffer += surface->stride;
Expand Down Expand Up @@ -1384,9 +1376,8 @@ static bool _rasterDirectBlendingImage(SwSurface* surface, const SwImage* image,
}
} else {
for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) {
auto tmp = ALPHA_BLEND(*src, opacity);
auto tmp2 = surface->blender(tmp, *dst, 255);
*dst = INTERPOLATE(tmp2, *dst, A(tmp));
auto tmp = surface->blender(*src, *dst, 255);
*dst = INTERPOLATE(tmp, *dst, MULTIPLY(opacity, A(*src)));
}
}
dbuffer += surface->stride;
Expand Down Expand Up @@ -1442,12 +1433,52 @@ static bool _rasterDirectImage(SwSurface* surface, const SwImage* image, const S
}


static bool _rasterDirectMattedBlendingImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity)
{
if (surface->channelSize == sizeof(uint8_t)) {
TVGERR("SW_ENGINE", "Not supported grayscale image!");
return false;
}

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 csize = surface->compositor->image.channelSize;
auto alpha = surface->alpha(surface->compositor->method);
auto sbuffer = image->buf32 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox);
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize; //compositor buffer
auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x;

for (uint32_t y = 0; y < h; ++y) {
auto dst = buffer;
auto cmp = cbuffer;
auto src = sbuffer;
if (opacity == 255) {
for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) {
auto tmp = ALPHA_BLEND(*src, alpha(cmp));
*dst = INTERPOLATE(surface->blender(tmp, *dst, 255), *dst, A(tmp));
}
} else {
for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) {
auto tmp = ALPHA_BLEND(*src, alpha(cmp));
*dst = INTERPOLATE(surface->blender(tmp, *dst, 255), *dst, MULTIPLY(opacity, A(tmp)));
}
}
buffer += surface->stride;
cbuffer += surface->compositor->image.stride * csize;
sbuffer += image->stride;
}
return true;
}


//Blenders for the following scenarios: [Composition / Non-Composition] * [Opaque / Translucent]
static bool _directImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity)
{
if (_compositing(surface)) {
if (_matting(surface)) return _rasterDirectMattedImage(surface, image, region, opacity);
else return _rasterDirectMaskedImage(surface, image, region, opacity);
if (_matting(surface)) {
if (_blending(surface)) return _rasterDirectMattedBlendingImage(surface, image, region, opacity);
else return _rasterDirectMattedImage(surface, image, region, opacity);
} else return _rasterDirectMaskedImage(surface, image, region, opacity);
} else if (_blending(surface)) {
return _rasterDirectBlendingImage(surface, image, region, opacity);
} else {
Expand Down Expand Up @@ -1843,19 +1874,19 @@ bool rasterCompositor(SwSurface* surface)
}


bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h, pixel_t val)
{
if (!surface || !surface->buf32 || surface->stride == 0 || surface->w == 0 || surface->h == 0) return false;

//32 bits
if (surface->channelSize == sizeof(uint32_t)) {
//full clear
if (w == surface->stride) {
rasterPixel32(surface->buf32, 0x00000000, surface->stride * y, w * h);
rasterPixel32(surface->buf32, val, surface->stride * y, w * h);
//partial clear
} else {
for (uint32_t i = 0; i < h; i++) {
rasterPixel32(surface->buf32, 0x00000000, (surface->stride * y + x) + (surface->stride * i), w);
rasterPixel32(surface->buf32, val, (surface->stride * y + x) + (surface->stride * i), w);
}
}
//8 bits
Expand Down
9 changes: 6 additions & 3 deletions thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ bool SwRenderer::renderShape(RenderData data)
}


bool SwRenderer::blend(BlendMethod method, bool direct)
bool SwRenderer::blend(BlendMethod method)
{
if (surface->blendMethod == method) return true;
surface->blendMethod = method;
Expand All @@ -459,7 +459,7 @@ bool SwRenderer::blend(BlendMethod method, bool direct)
surface->blender = opBlendScreen;
break;
case BlendMethod::Multiply:
surface->blender = direct ? opBlendDirectMultiply : opBlendMultiply;
surface->blender = opBlendMultiply;
break;
case BlendMethod::Overlay:
surface->blender = opBlendOverlay;
Expand Down Expand Up @@ -606,7 +606,10 @@ Compositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs)
cmp->w = cmp->compositor->image.w;
cmp->h = cmp->compositor->image.h;

rasterClear(cmp, x, y, w, h);
/* TODO: Currently, only blending might work.
Blending and composition must be handled together. */
auto color = (surface->blender && !surface->compositor) ? 0x00ffffff : 0x00000000;
rasterClear(cmp, x, y, w, h, color);

//Switch render target
surface = cmp;
Expand Down
2 changes: 1 addition & 1 deletion thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class SwRenderer : public RenderMethod
RenderRegion region(RenderData data) override;
RenderRegion viewport() override;
bool viewport(const RenderRegion& vp) override;
bool blend(BlendMethod method, bool direct) override;
bool blend(BlendMethod method) override;
ColorSpace colorSpace() override;
const Surface* mainSurface() override;

Expand Down
2 changes: 1 addition & 1 deletion thirdparty/thorvg/src/renderer/tvgPicture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ bool Picture::Impl::needComposition(uint8_t opacity)
bool Picture::Impl::render(RenderMethod* renderer)
{
bool ret = false;
renderer->blend(picture->blend(), true);
renderer->blend(picture->blend());

if (surface) return renderer->renderImage(rd);
else if (paint) {
Expand Down
Loading
Loading