Skip to content

Commit

Permalink
Merge pull request #87612 from capnm/240126_thorvg_from_v0.12.1_to_0.…
Browse files Browse the repository at this point in the history
…12.3

ThorVG: update from v0.12.1 to v0.12.3
  • Loading branch information
akien-mga committed Jan 29, 2024
2 parents 563364d + 73589f6 commit 15c78ae
Show file tree
Hide file tree
Showing 14 changed files with 209 additions and 142 deletions.
2 changes: 1 addition & 1 deletion thirdparty/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@ instead of `miniz.h` as an external dependency.
## thorvg

- Upstream: https://github.com/thorvg/thorvg
- Version: 0.12.1 (d761e3c5622c0ffba2e5bb40da05751e2451e495, 2024)
- Version: 0.12.3 (9d79f0ccef632fd3b43b8ea02def529b6a8d2288, 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 @@ -9,5 +9,5 @@
// For internal debugging:
//#define THORVG_LOG_ENABLED

#define THORVG_VERSION_STRING "0.12.1"
#define THORVG_VERSION_STRING "0.12.3"
#endif
70 changes: 70 additions & 0 deletions thirdparty/thorvg/src/common/tvgLock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2024 the ThorVG project. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

#ifndef _TVG_LOCK_H_
#define _TVG_LOCK_H_

#ifdef THORVG_THREAD_SUPPORT

#include <mutex>

namespace tvg {

struct Key
{
std::mutex mtx;
};

struct ScopedLock
{
Key* key = nullptr;

ScopedLock(Key& key)
{
key.mtx.lock();
this->key = &key;
}

~ScopedLock()
{
key->mtx.unlock();
}
};

}

#else //THORVG_THREAD_SUPPORT

namespace tvg {

struct Key {};

struct ScopedLock
{
ScopedLock(Key& key) {}
};

}

#endif //THORVG_THREAD_SUPPORT

#endif //_TVG_LOCK_H_
52 changes: 18 additions & 34 deletions thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -683,32 +683,6 @@ static constexpr struct
};


static void _matrixCompose(const Matrix* m1, const Matrix* m2, Matrix* dst)
{
auto a11 = (m1->e11 * m2->e11) + (m1->e12 * m2->e21) + (m1->e13 * m2->e31);
auto a12 = (m1->e11 * m2->e12) + (m1->e12 * m2->e22) + (m1->e13 * m2->e32);
auto a13 = (m1->e11 * m2->e13) + (m1->e12 * m2->e23) + (m1->e13 * m2->e33);

auto a21 = (m1->e21 * m2->e11) + (m1->e22 * m2->e21) + (m1->e23 * m2->e31);
auto a22 = (m1->e21 * m2->e12) + (m1->e22 * m2->e22) + (m1->e23 * m2->e32);
auto a23 = (m1->e21 * m2->e13) + (m1->e22 * m2->e23) + (m1->e23 * m2->e33);

auto a31 = (m1->e31 * m2->e11) + (m1->e32 * m2->e21) + (m1->e33 * m2->e31);
auto a32 = (m1->e31 * m2->e12) + (m1->e32 * m2->e22) + (m1->e33 * m2->e32);
auto a33 = (m1->e31 * m2->e13) + (m1->e32 * m2->e23) + (m1->e33 * m2->e33);

dst->e11 = a11;
dst->e12 = a12;
dst->e13 = a13;
dst->e21 = a21;
dst->e22 = a22;
dst->e23 = a23;
dst->e31 = a31;
dst->e32 = a32;
dst->e33 = a33;
}


/* parse transform attribute
* https://www.w3.org/TR/SVG/coords.html#TransformAttribute
*/
Expand Down Expand Up @@ -751,14 +725,14 @@ static Matrix* _parseTransformationMatrix(const char* value)
if (state == MatrixState::Matrix) {
if (ptCount != 6) goto error;
Matrix tmp = {points[0], points[2], points[4], points[1], points[3], points[5], 0, 0, 1};
_matrixCompose(matrix, &tmp, matrix);
*matrix = mathMultiply(matrix, &tmp);
} else if (state == MatrixState::Translate) {
if (ptCount == 1) {
Matrix tmp = {1, 0, points[0], 0, 1, 0, 0, 0, 1};
_matrixCompose(matrix, &tmp, matrix);
*matrix = mathMultiply(matrix, &tmp);
} else if (ptCount == 2) {
Matrix tmp = {1, 0, points[0], 0, 1, points[1], 0, 0, 1};
_matrixCompose(matrix, &tmp, matrix);
*matrix = mathMultiply(matrix, &tmp);
} else goto error;
} else if (state == MatrixState::Rotate) {
//Transform to signed.
Expand All @@ -768,14 +742,14 @@ static Matrix* _parseTransformationMatrix(const char* value)
auto s = sinf(points[0] * (M_PI / 180.0));
if (ptCount == 1) {
Matrix tmp = { c, -s, 0, s, c, 0, 0, 0, 1 };
_matrixCompose(matrix, &tmp, matrix);
*matrix = mathMultiply(matrix, &tmp);
} else if (ptCount == 3) {
Matrix tmp = { 1, 0, points[1], 0, 1, points[2], 0, 0, 1 };
_matrixCompose(matrix, &tmp, matrix);
*matrix = mathMultiply(matrix, &tmp);
tmp = { c, -s, 0, s, c, 0, 0, 0, 1 };
_matrixCompose(matrix, &tmp, matrix);
*matrix = mathMultiply(matrix, &tmp);
tmp = { 1, 0, -points[1], 0, 1, -points[2], 0, 0, 1 };
_matrixCompose(matrix, &tmp, matrix);
*matrix = mathMultiply(matrix, &tmp);
} else {
goto error;
}
Expand All @@ -785,7 +759,17 @@ static Matrix* _parseTransformationMatrix(const char* value)
auto sy = sx;
if (ptCount == 2) sy = points[1];
Matrix tmp = { sx, 0, 0, 0, sy, 0, 0, 0, 1 };
_matrixCompose(matrix, &tmp, matrix);
*matrix = mathMultiply(matrix, &tmp);
} else if (state == MatrixState::SkewX) {
if (ptCount != 1) goto error;
auto deg = tanf(points[0] * (M_PI / 180.0));
Matrix tmp = { 1, deg, 0, 0, 1, 0, 0, 0, 1 };
*matrix = mathMultiply(matrix, &tmp);
} else if (state == MatrixState::SkewY) {
if (ptCount != 1) goto error;
auto deg = tanf(points[0] * (M_PI / 180.0));
Matrix tmp = { 1, 0, 0, deg, 1, 0, 0, 0, 1 };
*matrix = mathMultiply(matrix, &tmp);
}
}
return matrix;
Expand Down
28 changes: 15 additions & 13 deletions thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,8 @@ static uint32_t _interpUpScaler(const uint32_t *img, TVG_UNUSED uint32_t stride,
auto ry2 = ry + 1;
if (ry2 >= h) ry2 = h - 1;

auto dx = static_cast<size_t>((sx - rx) * 255.0f);
auto dy = static_cast<size_t>((sy - ry) * 255.0f);
auto dx = static_cast<uint8_t>((sx - rx) * 255.0f);
auto dy = static_cast<uint8_t>((sy - ry) * 255.0f);

auto c1 = img[rx + ry * w];
auto c2 = img[rx2 + ry * w];
Expand All @@ -281,21 +281,23 @@ static uint32_t _interpDownScaler(const uint32_t *img, uint32_t stride, uint32_t
int32_t maxx = (int32_t)sx + n;
if (maxx >= (int32_t)w) maxx = w;

int32_t inc = (n / 2) + 1;
n = 0;

auto src = img + minx + miny * stride;

for (auto y = miny; y < maxy; ++y) {
for (auto y = miny; y < maxy; y += inc) {
auto p = src;
for (auto x = minx; x < maxx; ++x, ++p) {
c[0] += *p >> 24;
c[1] += (*p >> 16) & 0xff;
c[2] += (*p >> 8) & 0xff;
c[3] += *p & 0xff;
for (auto x = minx; x < maxx; x += inc, p += inc) {
c[0] += A(*p);
c[1] += C1(*p);
c[2] += C2(*p);
c[3] += C3(*p);
++n;
}
src += stride;
src += (stride * inc);
}

n = (maxy - miny) * (maxx - minx);

c[0] /= n;
c[1] /= n;
c[2] /= n;
Expand Down Expand Up @@ -1855,7 +1857,7 @@ void rasterUnpremultiply(Surface* surface)

void rasterPremultiply(Surface* surface)
{
unique_lock<mutex> lock{surface->mtx};
ScopedLock lock(surface->key);
if (surface->premultiplied || (surface->channelSize != sizeof(uint32_t))) return;
surface->premultiplied = true;

Expand Down Expand Up @@ -1936,7 +1938,7 @@ bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, con

bool rasterConvertCS(Surface* surface, ColorSpace to)
{
unique_lock<mutex> lock{surface->mtx};
ScopedLock lock(surface->key);
if (surface->cs == to) return true;

//TOOD: Support SIMD accelerations
Expand Down
8 changes: 4 additions & 4 deletions thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterTexmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -528,8 +528,8 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image,
vv = (int) v;
if (vv >= sh) continue;

ar = (int)(255 * (1 - modff(u, &iptr)));
ab = (int)(255 * (1 - modff(v, &iptr)));
ar = (int)(255.0f * (1.0f - modff(u, &iptr)));
ab = (int)(255.0f * (1.0f - modff(v, &iptr)));
iru = uu + 1;
irv = vv + 1;

Expand Down Expand Up @@ -576,8 +576,8 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image,
uu = (int) u;
vv = (int) v;

ar = (int)(255 * (1 - modff(u, &iptr)));
ab = (int)(255 * (1 - modff(v, &iptr)));
ar = (int)(255.0f * (1.0f - modff(u, &iptr)));
ab = (int)(255.0f * (1.0f - modff(v, &iptr)));
iru = uu + 1;
irv = vv + 1;

Expand Down
3 changes: 2 additions & 1 deletion thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,8 @@ bool SwRenderer::target(pixel_t* data, uint32_t stride, uint32_t w, uint32_t h,
{
if (!data || stride == 0 || w == 0 || h == 0 || w > stride) return false;

clearCompositors();

if (!surface) surface = new SwSurface;

surface->data = data;
Expand Down Expand Up @@ -474,7 +476,6 @@ bool SwRenderer::postRender()
}
tasks.clear();

clearCompositors();
return true;
}

Expand Down
45 changes: 7 additions & 38 deletions thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,16 @@ static void _outlineEnd(SwOutline& outline)
{
if (outline.pts.empty()) return;
outline.cntrs.push(outline.pts.count - 1);
outline.closed.push(false);
}


static void _outlineMoveTo(SwOutline& outline, const Point* to, const Matrix* transform)
{
if (outline.pts.count > 0) outline.cntrs.push(outline.pts.count - 1);
if (outline.pts.count > 0) {
outline.cntrs.push(outline.pts.count - 1);
outline.closed.push(false);
}

outline.pts.push(mathTransform(to, transform));
outline.types.push(SW_CURVE_TYPE_POINT);
Expand Down Expand Up @@ -128,7 +132,7 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* trans
_outlineLineTo(*dash.outline, to, transform);
}
} else {
while (len > dash.curLen) {
while (len - dash.curLen > 0.0001f) {
Line left, right;
if (dash.curLen > 0) {
len -= dash.curLen;
Expand Down Expand Up @@ -185,7 +189,7 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct
_outlineCubicTo(*dash.outline, ctrl1, ctrl2, to, transform);
}
} else {
while (len > dash.curLen) {
while ((len - dash.curLen) > 0.0001f) {
Bezier left, right;
if (dash.curLen > 0) {
len -= dash.curLen;
Expand Down Expand Up @@ -315,21 +319,6 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans

dash.outline = mpoolReqDashOutline(mpool, tid);

//smart reservation
auto closeCnt = 0;
auto moveCnt = 0;

for (auto cmd = rshape->path.cmds.data; cmd < rshape->path.cmds.end(); ++cmd) {
if (*cmd == PathCommand::Close) ++closeCnt;
else if (*cmd == PathCommand::MoveTo) ++moveCnt;
}

//No idea exact count.... Reserve Approximitely 20x...
//OPTIMIZE: we can directly copy the path points when the close is occupied with a point.
dash.outline->pts.grow(20 * (closeCnt + ptsCnt + 1));
dash.outline->types.grow(20 * (closeCnt + ptsCnt + 1));
dash.outline->cntrs.grow(20 * (moveCnt + 1));

while (cmdCnt-- > 0) {
switch (*cmds) {
case PathCommand::Close: {
Expand Down Expand Up @@ -435,29 +424,9 @@ static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix*
//No actual shape data
if (cmdCnt == 0 || ptsCnt == 0) return false;

//smart reservation
auto moveCnt = 0;
auto closeCnt = 0;

for (auto cmd = rshape->path.cmds.data; cmd < rshape->path.cmds.end(); ++cmd) {
if (*cmd == PathCommand::Close) ++closeCnt;
else if (*cmd == PathCommand::MoveTo) ++moveCnt;
}

shape->outline = mpoolReqOutline(mpool, tid);
auto outline = shape->outline;

//OPTIMIZE: we can directly copy the path points when the close is occupied with a point.
outline->pts.grow(ptsCnt + closeCnt + 1);
outline->types.grow(ptsCnt + closeCnt + 1);
outline->cntrs.grow(moveCnt + 1);

//Dash outlines are always opened.
//Only normal outlines use this information, it sholud be same to their contour counts.
outline->closed.reserve(outline->cntrs.reserved);

memset(outline->closed.data, 0x0, sizeof(bool) * outline->closed.reserved);

//Generate Outlines
while (cmdCnt-- > 0) {
switch (*cmds) {
Expand Down
Loading

0 comments on commit 15c78ae

Please sign in to comment.