From 5f516b24426bd6e28035d9e3291903f817d9d9f1 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 28 Feb 2024 17:00:14 +0100 Subject: [PATCH] Optimize cuberoot using Newton-Raphson approximation Change-Id: I23a2515b42ef6592df0a18f04420670dc2b4ac1a Reviewed-by: Thiago Macieira --- src/gui/painting/qcolormatrix_p.h | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qcolormatrix_p.h b/src/gui/painting/qcolormatrix_p.h index 2d979bc5cb..d10346577f 100644 --- a/src/gui/painting/qcolormatrix_p.h +++ b/src/gui/painting/qcolormatrix_p.h @@ -80,15 +80,15 @@ public: float fx, fy, fz; if (xr > eps) - fx = std::cbrt(xr); + fx = fastCbrt(xr); else fx = (kap * xr + 16.f) / 116.f; if (yr > eps) - fy = std::cbrt(yr); + fy = fastCbrt(yr); else fy = (kap * yr + 16.f) / 116.f; if (zr > eps) - fz = std::cbrt(zr); + fz = fastCbrt(zr); else fz = (kap * zr + 16.f) / 116.f; @@ -135,6 +135,19 @@ public: } friend inline bool comparesEqual(const QColorVector &lhs, const QColorVector &rhs); Q_DECLARE_EQUALITY_COMPARABLE(QColorVector); + +private: + static float fastCbrt(float x) + { + // This gives us cube root within the precision we need. + float est = 0.25f + (x * 0.75f); // guessing a cube-root of numbers between 0.01 and 1. + est -= ((est * est * est) - x) / (3.f * (est * est)); + est -= ((est * est * est) - x) / (3.f * (est * est)); + est -= ((est * est * est) - x) / (3.f * (est * est)); + est -= ((est * est * est) - x) / (3.f * (est * est)); + // Q_ASSERT(qAbs(est - std::cbrt(x)) < 0.0001f); + return est; + } }; inline bool comparesEqual(const QColorVector &v1, const QColorVector &v2)