Merge pull request #88094 from capnm/240208_thorvg_from_v0.12.4_to_0.12.5

ThorVG: update from v0.12.4 to v0.12.5
This commit is contained in:
Rémi Verschelde 2024-02-08 13:46:00 +01:00
commit 3405400951
No known key found for this signature in database
GPG key ID: C3336907360768E1
13 changed files with 113 additions and 67 deletions

View file

@ -856,13 +856,13 @@ instead of `miniz.h` as an external dependency.
## thorvg ## thorvg
- Upstream: https://github.com/thorvg/thorvg - Upstream: https://github.com/thorvg/thorvg
- Version: 0.12.4 (331839d49368e19ca15f35abee5ac541dbf23637, 2024) - Version: 0.12.5 (9c8eeaab9629b5d241b1092a3398fe6351c259cd, 2024)
- License: MIT - License: MIT
Files extracted from upstream source: Files extracted from upstream source:
See `thorvg/update-thorvg.sh` for extraction instructions. Set the version See `thorvg/update-thorvg.sh` for extraction instructions. Set the version
number and run the script. number and run the script and apply patches from the `patches` folder.
## vhacd ## vhacd

View file

@ -10,5 +10,5 @@
// For internal debugging: // For internal debugging:
//#define THORVG_LOG_ENABLED //#define THORVG_LOG_ENABLED
#define THORVG_VERSION_STRING "0.12.4" #define THORVG_VERSION_STRING "0.12.5"
#endif #endif

View file

@ -0,0 +1,23 @@
diff --git a/thirdparty/thorvg/src/common/tvgLock.h b/thirdparty/thorvg/src/common/tvgLock.h
index e6d993a41e..5dd3d5a624 100644
--- a/thirdparty/thorvg/src/common/tvgLock.h
+++ b/thirdparty/thorvg/src/common/tvgLock.h
@@ -38,10 +38,10 @@ namespace tvg {
{
Key* key = nullptr;
- ScopedLock(Key& key)
+ ScopedLock(Key& k)
{
- key.mtx.lock();
- this->key = &key;
+ k.mtx.lock();
+ key = &k;
}
~ScopedLock()
@@ -68,3 +68,4 @@ namespace tvg {
#endif //THORVG_THREAD_SUPPORT
#endif //_TVG_LOCK_H_
+

View file

@ -38,10 +38,10 @@ namespace tvg {
{ {
Key* key = nullptr; Key* key = nullptr;
ScopedLock(Key& p_key) ScopedLock(Key& k)
{ {
p_key.mtx.lock(); k.mtx.lock();
key = &p_key; key = &k;
} }
~ScopedLock() ~ScopedLock()

View file

@ -84,14 +84,15 @@ bool PngLoader::read()
if (w == 0 || h == 0) return false; if (w == 0 || h == 0) return false;
png_bytep buffer; if (cs == ColorSpace::ARGB8888 || cs == ColorSpace::ARGB8888S) {
image->format = PNG_FORMAT_BGRA; image->format = PNG_FORMAT_BGRA;
buffer = static_cast<png_bytep>(malloc(PNG_IMAGE_SIZE((*image)))); surface.cs = ColorSpace::ARGB8888;
if (!buffer) { } else {
//out of memory, only time when libpng doesnt free its data image->format = PNG_FORMAT_RGBA;
png_image_free(image); surface.cs = ColorSpace::ABGR8888;
return false;
} }
auto buffer = static_cast<png_bytep>(malloc(PNG_IMAGE_SIZE((*image))));
if (!png_image_finish_read(image, NULL, buffer, 0, NULL)) { if (!png_image_finish_read(image, NULL, buffer, 0, NULL)) {
free(buffer); free(buffer);
return false; return false;
@ -103,7 +104,7 @@ bool PngLoader::read()
surface.w = (uint32_t)w; surface.w = (uint32_t)w;
surface.h = (uint32_t)h; surface.h = (uint32_t)h;
surface.channelSize = sizeof(uint32_t); surface.channelSize = sizeof(uint32_t);
surface.cs = ColorSpace::ARGB8888; //TODO: we can acquire a pre-multiplied image. See "png_structrp"
surface.premultiplied = false; surface.premultiplied = false;
clear(); clear();

View file

@ -35,6 +35,8 @@ void PngLoader::run(unsigned tid)
auto width = static_cast<unsigned>(w); auto width = static_cast<unsigned>(w);
auto height = static_cast<unsigned>(h); auto height = static_cast<unsigned>(h);
state.info_raw.colortype = LCT_RGBA; //request this image format
if (lodepng_decode(&surface.buf8, &width, &height, &state, data, size)) { if (lodepng_decode(&surface.buf8, &width, &height, &state, data, size)) {
TVGERR("PNG", "Failed to decode image"); TVGERR("PNG", "Failed to decode image");
} }
@ -43,8 +45,11 @@ void PngLoader::run(unsigned tid)
surface.stride = width; surface.stride = width;
surface.w = width; surface.w = width;
surface.h = height; surface.h = height;
surface.cs = ColorSpace::ABGR8888;
surface.channelSize = sizeof(uint32_t); surface.channelSize = sizeof(uint32_t);
surface.premultiplied = false;
if (state.info_png.color.colortype == LCT_RGBA) surface.premultiplied = false;
else surface.premultiplied = true;
} }
@ -93,9 +98,6 @@ bool PngLoader::open(const string& path)
w = static_cast<float>(width); w = static_cast<float>(width);
h = static_cast<float>(height); h = static_cast<float>(height);
if (state.info_png.color.colortype == LCT_RGBA) surface.cs = ColorSpace::ABGR8888;
else surface.cs = ColorSpace::ARGB8888;
ret = true; ret = true;
goto finalize; goto finalize;
@ -125,8 +127,6 @@ bool PngLoader::open(const char* data, uint32_t size, bool copy)
h = static_cast<float>(height); h = static_cast<float>(height);
this->size = size; this->size = size;
surface.cs = ColorSpace::ABGR8888;
return true; return true;
} }

View file

@ -257,15 +257,15 @@ static uint32_t _interpUpScaler(const uint32_t *img, TVG_UNUSED uint32_t stride,
auto ry2 = ry + 1; auto ry2 = ry + 1;
if (ry2 >= h) ry2 = h - 1; if (ry2 >= h) ry2 = h - 1;
auto dx = static_cast<uint8_t>((sx - rx) * 255.0f); auto dx = (sx > 0.0f) ? static_cast<uint8_t>((sx - rx) * 255.0f) : 0;
auto dy = static_cast<uint8_t>((sy - ry) * 255.0f); auto dy = (sy > 0.0f) ? static_cast<uint8_t>((sy - ry) * 255.0f) : 0;
auto c1 = img[rx + ry * w]; auto c1 = img[rx + ry * w];
auto c2 = img[rx2 + ry * w]; auto c2 = img[rx2 + ry * w];
auto c3 = img[rx2 + ry2 * w]; auto c3 = img[rx + ry2 * w];
auto c4 = img[rx + ry2 * w]; auto c4 = img[rx2 + ry2 * w];
return INTERPOLATE(INTERPOLATE(c3, c4, dx), INTERPOLATE(c2, c1, dx), dy); return INTERPOLATE(INTERPOLATE(c4, c3, dx), INTERPOLATE(c2, c1, dx), dy);
} }
@ -671,10 +671,10 @@ static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g,
/************************************************************************/ /************************************************************************/
#define SCALED_IMAGE_RANGE_Y(y) \ #define SCALED_IMAGE_RANGE_Y(y) \
auto sy = (y) * itransform->e22 + itransform->e23; \ auto sy = (y) * itransform->e22 + itransform->e23 - 0.49f; \
auto my = (int32_t)round(sy); \ if (sy <= -0.5f || (uint32_t)(sy + 0.5f) >= image->h) continue; \
if (my < 0 || (uint32_t)sy >= image->h) continue; \
if (scaleMethod == _interpDownScaler) { \ if (scaleMethod == _interpDownScaler) { \
auto my = (int32_t)round(sy); \
miny = my - (int32_t)sampleSize; \ miny = my - (int32_t)sampleSize; \
if (miny < 0) miny = 0; \ if (miny < 0) miny = 0; \
maxy = my + (int32_t)sampleSize; \ maxy = my + (int32_t)sampleSize; \
@ -682,8 +682,8 @@ static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g,
} }
#define SCALED_IMAGE_RANGE_X \ #define SCALED_IMAGE_RANGE_X \
auto sx = x * itransform->e11 + itransform->e13; \ auto sx = (x) * itransform->e11 + itransform->e13 - 0.49f; \
if ((int32_t)round(sx) < 0 || (uint32_t) sx >= image->w) continue; if (sx <= -0.5f || (uint32_t)(sx + 0.5f) >= image->w) continue; \
#if 0 //Enable it when GRAYSCALE image is supported #if 0 //Enable it when GRAYSCALE image is supported
@ -1928,8 +1928,8 @@ bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint
bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& bbox, uint8_t opacity) bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& bbox, uint8_t opacity)
{ {
//Verify Boundary //Outside of the viewport, skip the rendering
if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= static_cast<SwCoord>(surface->w) || bbox.min.y >= static_cast<SwCoord>(surface->h)) return false; if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= static_cast<SwCoord>(surface->w) || bbox.min.y >= static_cast<SwCoord>(surface->h)) return true;
if (mesh && mesh->triangleCnt > 0) return _rasterTexmapPolygonMesh(surface, image, mesh, transform, &bbox, opacity); if (mesh && mesh->triangleCnt > 0) return _rasterTexmapPolygonMesh(surface, image, mesh, transform, &bbox, opacity);
else return _rasterImage(surface, image, transform, bbox, opacity); else return _rasterImage(surface, image, transform, bbox, opacity);

View file

@ -63,7 +63,7 @@ using namespace tvg;
#define TVG_CLASS_ID_RADIAL 5 #define TVG_CLASS_ID_RADIAL 5
#define TVG_CLASS_ID_TEXT 6 #define TVG_CLASS_ID_TEXT 6
enum class FileType { Tvg = 0, Svg, Ttf, Lottie, Raw, Png, Jpg, Webp, Gif, Unknown }; enum class FileType { Png = 0, Jpg, Webp, Tvg, Svg, Lottie, Ttf, Raw, Gif, Unknown };
using Size = Point; using Size = Point;

View file

@ -68,6 +68,8 @@ struct LoadModule
struct ImageLoader : LoadModule struct ImageLoader : LoadModule
{ {
static ColorSpace cs; //desired value
float w = 0, h = 0; //default image size float w = 0, h = 0; //default image size
Surface surface; Surface surface;

View file

@ -66,6 +66,8 @@ uint64_t HASH_KEY(const char* data, uint64_t size)
/* Internal Class Implementation */ /* Internal Class Implementation */
/************************************************************************/ /************************************************************************/
ColorSpace ImageLoader::cs = ColorSpace::ARGB8888;
static Key key; static Key key;
static Inlist<LoadModule> _activeLoaders; static Inlist<LoadModule> _activeLoaders;
@ -73,6 +75,24 @@ static Inlist<LoadModule> _activeLoaders;
static LoadModule* _find(FileType type) static LoadModule* _find(FileType type)
{ {
switch(type) { switch(type) {
case FileType::Png: {
#ifdef THORVG_PNG_LOADER_SUPPORT
return new PngLoader;
#endif
break;
}
case FileType::Jpg: {
#ifdef THORVG_JPG_LOADER_SUPPORT
return new JpgLoader;
#endif
break;
}
case FileType::Webp: {
#ifdef THORVG_WEBP_LOADER_SUPPORT
return new WebpLoader;
#endif
break;
}
case FileType::Tvg: { case FileType::Tvg: {
#ifdef THORVG_TVG_LOADER_SUPPORT #ifdef THORVG_TVG_LOADER_SUPPORT
return new TvgLoader; return new TvgLoader;
@ -101,24 +121,6 @@ static LoadModule* _find(FileType type)
return new RawLoader; return new RawLoader;
break; break;
} }
case FileType::Png: {
#ifdef THORVG_PNG_LOADER_SUPPORT
return new PngLoader;
#endif
break;
}
case FileType::Jpg: {
#ifdef THORVG_JPG_LOADER_SUPPORT
return new JpgLoader;
#endif
break;
}
case FileType::Webp: {
#ifdef THORVG_WEBP_LOADER_SUPPORT
return new WebpLoader;
#endif
break;
}
default: { default: {
break; break;
} }
@ -305,8 +307,22 @@ LoadModule* LoaderMgr::loader(const string& path, bool* invalid)
return loader; return loader;
} }
delete(loader); delete(loader);
*invalid = true;
} }
//Unkown MimeType. Try with the candidates in the order
for (int i = 0; i < static_cast<int>(FileType::Raw); i++) {
if (auto loader = _find(static_cast<FileType>(i))) {
if (loader->open(path)) {
loader->hashpath = strdup(path.c_str());
{
ScopedLock lock(key);
_activeLoaders.back(loader);
}
return loader;
}
delete(loader);
}
}
*invalid = true;
return nullptr; return nullptr;
} }
@ -349,21 +365,20 @@ LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const string& mim
delete(loader); delete(loader);
} }
} }
}
//Unkown MimeType. Try with the candidates in the order //Unkown MimeType. Try with the candidates in the order
} else { for (int i = 0; i < static_cast<int>(FileType::Raw); i++) {
for (int i = 0; i < static_cast<int>(FileType::Unknown); i++) { auto loader = _find(static_cast<FileType>(i));
auto loader = _find(static_cast<FileType>(i)); if (loader) {
if (loader) { if (loader->open(data, size, copy)) {
if (loader->open(data, size, copy)) { loader->hashkey = HASH_KEY(data, size);
loader->hashkey = HASH_KEY(data, size); {
{ ScopedLock lock(key);
ScopedLock lock(key); _activeLoaders.back(loader);
_activeLoaders.back(loader);
}
return loader;
} }
delete(loader); return loader;
} }
delete(loader);
} }
} }
return nullptr; return nullptr;

View file

@ -128,6 +128,7 @@ struct Scene::Impl
bool render(RenderMethod* renderer) bool render(RenderMethod* renderer)
{ {
Compositor* cmp = nullptr; Compositor* cmp = nullptr;
auto ret = true;
if (needComp) { if (needComp) {
cmp = renderer->target(bounds(renderer), renderer->colorSpace()); cmp = renderer->target(bounds(renderer), renderer->colorSpace());
@ -136,12 +137,12 @@ struct Scene::Impl
} }
for (auto paint : paints) { for (auto paint : paints) {
if (!paint->pImpl->render(renderer)) return false; ret &= paint->pImpl->render(renderer);
} }
if (cmp) renderer->endComposite(cmp); if (cmp) renderer->endComposite(cmp);
return true; return ret;
} }
RenderRegion bounds(RenderMethod* renderer) const RenderRegion bounds(RenderMethod* renderer) const

View file

@ -21,6 +21,7 @@
*/ */
#include "tvgCanvas.h" #include "tvgCanvas.h"
#include "tvgLoadModule.h"
#ifdef THORVG_SW_RASTER_SUPPORT #ifdef THORVG_SW_RASTER_SUPPORT
#include "tvgSwRenderer.h" #include "tvgSwRenderer.h"
@ -90,6 +91,9 @@ Result SwCanvas::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t
//Paints must be updated again with this new target. //Paints must be updated again with this new target.
Canvas::pImpl->needRefresh(); Canvas::pImpl->needRefresh();
//FIXME: The value must be associated with an individual canvas instance.
ImageLoader::cs = static_cast<ColorSpace>(cs);
return Result::Success; return Result::Success;
#endif #endif
return Result::NonSupport; return Result::NonSupport;

View file

@ -1,6 +1,6 @@
#!/bin/bash -e #!/bin/bash -e
VERSION=0.12.4 VERSION=0.12.5
cd thirdparty/thorvg/ || true cd thirdparty/thorvg/ || true
rm -rf AUTHORS LICENSE inc/ src/ *.zip *.tar.gz tmp/ rm -rf AUTHORS LICENSE inc/ src/ *.zip *.tar.gz tmp/