summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qrgbafloat.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/painting/qrgbafloat.h')
-rw-r--r--src/gui/painting/qrgbafloat.h96
1 files changed, 59 insertions, 37 deletions
diff --git a/src/gui/painting/qrgbafloat.h b/src/gui/painting/qrgbafloat.h
index 04b2115399..da74328f71 100644
--- a/src/gui/painting/qrgbafloat.h
+++ b/src/gui/painting/qrgbafloat.h
@@ -19,7 +19,13 @@ class alignas(sizeof(F) * 4) QRgbaFloat
static_assert(std::is_same<F, qfloat16>::value || std::is_same<F, float>::value);
public:
using Type = F;
+#if defined(__AVX512FP16__) && QFLOAT16_IS_NATIVE
+ // AVX512FP16 has multiplication instructions
+ using FastType = F;
+#else
+ // use FP32 for multiplications
using FastType = float;
+#endif
F r;
F g;
F b;
@@ -28,21 +34,23 @@ public:
static constexpr
QRgbaFloat fromRgba64(quint16 red, quint16 green, quint16 blue, quint16 alpha)
{
+ constexpr FastType scale = FastType(1.0f / 65535.0f);
return QRgbaFloat{
- red * (1.0f / 65535.0f),
- green * (1.0f / 65535.0f),
- blue * (1.0f / 65535.0f),
- alpha * (1.0f / 65535.0f) };
+ F(red * scale),
+ F(green * scale),
+ F(blue * scale),
+ F(alpha * scale) };
}
static constexpr
QRgbaFloat fromRgba(quint8 red, quint8 green, quint8 blue, quint8 alpha)
{
+ constexpr FastType scale = FastType(1.0f / 255.0f);
return QRgbaFloat{
- red * (1.0f / 255.0f),
- green * (1.0f / 255.0f),
- blue * (1.0f / 255.0f),
- alpha * (1.0f / 255.0f) };
+ F(red * scale),
+ F(green * scale),
+ F(blue * scale),
+ F(alpha * scale) };
}
static constexpr
QRgbaFloat fromArgb32(uint rgb)
@@ -50,36 +58,36 @@ public:
return fromRgba(quint8(rgb >> 16), quint8(rgb >> 8), quint8(rgb), quint8(rgb >> 24));
}
- constexpr bool isOpaque() const { return a >= 1.0f; }
- constexpr bool isTransparent() const { return a <= 0.0f; }
-
- constexpr FastType red() const { return r; }
- constexpr FastType green() const { return g; }
- constexpr FastType blue() const { return b; }
- constexpr FastType alpha() const { return a; }
- void setRed(FastType _red) { r = _red; }
- void setGreen(FastType _green) { g = _green; }
- void setBlue(FastType _blue) { b = _blue; }
- void setAlpha(FastType _alpha) { a = _alpha; }
-
- constexpr FastType redNormalized() const { return std::clamp(static_cast<FastType>(r), 0.0f, 1.0f); }
- constexpr FastType greenNormalized() const { return std::clamp(static_cast<FastType>(g), 0.0f, 1.0f); }
- constexpr FastType blueNormalized() const { return std::clamp(static_cast<FastType>(b), 0.0f, 1.0f); }
- constexpr FastType alphaNormalized() const { return std::clamp(static_cast<FastType>(a), 0.0f, 1.0f); }
-
- constexpr quint8 red8() const { return std::lround(redNormalized() * 255.0f); }
- constexpr quint8 green8() const { return std::lround(greenNormalized() * 255.0f); }
- constexpr quint8 blue8() const { return std::lround(blueNormalized() * 255.0f); }
- constexpr quint8 alpha8() const { return std::lround(alphaNormalized() * 255.0f); }
+ constexpr bool isOpaque() const { return a >= FastType(1.0f); }
+ constexpr bool isTransparent() const { return a <= FastType(0.0f); }
+
+ constexpr float red() const { return r; }
+ constexpr float green() const { return g; }
+ constexpr float blue() const { return b; }
+ constexpr float alpha() const { return a; }
+ void setRed(float _red) { r = F(_red); }
+ void setGreen(float _green) { g = F(_green); }
+ void setBlue(float _blue) { b = F(_blue); }
+ void setAlpha(float _alpha) { a = F(_alpha); }
+
+ constexpr float redNormalized() const { return clamp01(r); }
+ constexpr float greenNormalized() const { return clamp01(g); }
+ constexpr float blueNormalized() const { return clamp01(b); }
+ constexpr float alphaNormalized() const { return clamp01(a); }
+
+ constexpr quint8 red8() const { return qRound(redNormalized() * FastType(255.0f)); }
+ constexpr quint8 green8() const { return qRound(greenNormalized() * FastType(255.0f)); }
+ constexpr quint8 blue8() const { return qRound(blueNormalized() * FastType(255.0f)); }
+ constexpr quint8 alpha8() const { return qRound(alphaNormalized() * FastType(255.0f)); }
constexpr uint toArgb32() const
{
return uint((alpha8() << 24) | (red8() << 16) | (green8() << 8) | blue8());
}
- constexpr quint16 red16() const { return std::lround(redNormalized() * 65535.0f); }
- constexpr quint16 green16() const { return std::lround(greenNormalized() * 65535.0f); }
- constexpr quint16 blue16() const { return std::lround(blueNormalized() * 65535.0f); }
- constexpr quint16 alpha16() const { return std::lround(alphaNormalized() * 65535.0f); }
+ constexpr quint16 red16() const { return qRound(redNormalized() * FastType(65535.0f)); }
+ constexpr quint16 green16() const { return qRound(greenNormalized() * FastType(65535.0f)); }
+ constexpr quint16 blue16() const { return qRound(blueNormalized() * FastType(65535.0f)); }
+ constexpr quint16 alpha16() const { return qRound(alphaNormalized() * FastType(65535.0f)); }
constexpr Q_ALWAYS_INLINE QRgbaFloat premultiplied() const
{
@@ -87,12 +95,26 @@ public:
}
constexpr Q_ALWAYS_INLINE QRgbaFloat unpremultiplied() const
{
- if (a <= 0.0f)
- return QRgbaFloat{0.0f, 0.0f, 0.0f, 0.0f};
- if (a >= 1.0f)
+ if (a <= F{0.0f})
+ return QRgbaFloat{}; // default-initialization: zeroes
+ if (a >= F{1.0f})
return *this;
const FastType ia = 1.0f / a;
- return QRgbaFloat{r * ia, g * ia, b * ia, a};
+ return QRgbaFloat{F(r * ia), F(g * ia), F(b * ia), F(a)};
+ }
+ constexpr bool operator==(QRgbaFloat f) const
+ {
+ return r == f.r && g == f.g && b == f.b && a == f.a;
+ }
+ constexpr bool operator!=(QRgbaFloat f) const
+ {
+ return !(*this == f);
+ }
+
+private:
+ constexpr static FastType clamp01(Type f)
+ {
+ return std::clamp(FastType(f), FastType(0.0f), FastType(1.0f));
}
};