QColorTransform: make fit for release

- Unexport the value class, export only out-of-line public member functions
  to give us more leeway in changing code later (otherwise, we'd be bound
  by BC with MSVC debug builds, which call even inline methods from the DLL.

- Don't use QSharedPointer as the d_ptr. It's twice the size of a pointer.
  Use a naked pointer-to-const. Derive Private from QSharedData. This
  requires some changes in QColorSpace, and, as usual, an out-of-line copy
  ctor.

- Add member-swap(), Q_DECLARE_SHARED().

- Drop noexcept from the dtor. It implicitly is, adding it explicitly looks
  weird.

- Pass QRgb and QRgba64 by value, not by cref. They're trivially-copyable,
  so passed in registers if passed by value. Passing by cref forces them
  onto the stack.

Change-Id: I669643d219ede6b7d07f15afbf8728e16150b3b2
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
bb10
Marc Mutz 2019-07-11 17:51:15 +02:00
parent 79f9adffc5
commit 389988c42f
5 changed files with 42 additions and 31 deletions

View File

@ -5067,12 +5067,12 @@ void QImage::applyColorTransform(const QColorTransform &transform)
if (depth() > 32) {
for (int i = 0; i < height(); ++i) {
QRgba64 *scanline = reinterpret_cast<QRgba64 *>(scanLine(i));
transform.d_func()->apply(scanline, scanline, width(), flags);
transform.d->apply(scanline, scanline, width(), flags);
}
} else {
for (int i = 0; i < height(); ++i) {
QRgb *scanline = reinterpret_cast<QRgb *>(scanLine(i));
transform.d_func()->apply(scanline, scanline, width(), flags);
transform.d->apply(scanline, scanline, width(), flags);
}
}

View File

@ -355,10 +355,11 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace
{
Q_ASSERT(out);
QColorTransform combined;
combined.d_ptr.reset(new QColorTransformPrivate);
combined.d_ptr->colorSpaceIn = this;
combined.d_ptr->colorSpaceOut = out;
combined.d_ptr->colorMatrix = out->toXyz.inverted() * toXyz;
auto ptr = new QColorTransformPrivate;
combined.d = ptr;
ptr->colorSpaceIn = this;
ptr->colorSpaceOut = out;
ptr->colorMatrix = out->toXyz.inverted() * toXyz;
return combined;
}

View File

@ -134,8 +134,18 @@ void QColorTransformPrivate::updateLutsOut() const
*/
QColorTransform::~QColorTransform() noexcept
QColorTransform::QColorTransform(const QColorTransform &colorTransform) noexcept
: d(colorTransform.d)
{
if (d)
d->ref.ref();
}
QColorTransform::~QColorTransform()
{
if (d && !d->ref.deref())
delete d;
}
/*!
@ -143,11 +153,10 @@ QColorTransform::~QColorTransform() noexcept
The input should be opaque or unpremultiplied.
*/
QRgb QColorTransform::map(const QRgb &argb) const
QRgb QColorTransform::map(QRgb argb) const
{
if (!d_ptr)
if (!d)
return argb;
Q_D(const QColorTransform);
constexpr float f = 1.0f / 255.0f;
QColorVector c = { qRed(argb) * f, qGreen(argb) * f, qBlue(argb) * f };
c.x = d->colorSpaceIn->trc[0].apply(c.x);
@ -175,11 +184,10 @@ QRgb QColorTransform::map(const QRgb &argb) const
The input should be opaque or unpremultiplied.
*/
QRgba64 QColorTransform::map(const QRgba64 &rgba64) const
QRgba64 QColorTransform::map(QRgba64 rgba64) const
{
if (!d_ptr)
if (!d)
return rgba64;
Q_D(const QColorTransform);
constexpr float f = 1.0f / 65535.0f;
QColorVector c = { rgba64.red() * f, rgba64.green() * f, rgba64.blue() * f };
c.x = d->colorSpaceIn->trc[0].apply(c.x);
@ -208,9 +216,8 @@ QRgba64 QColorTransform::map(const QRgba64 &rgba64) const
*/
QColor QColorTransform::map(const QColor &color) const
{
if (!d_ptr)
if (!d)
return color;
Q_D(const QColorTransform);
QColor clr = color;
if (color.spec() != QColor::ExtendedRgb || color.spec() != QColor::Rgb)
clr = clr.toRgb();
@ -228,7 +235,7 @@ QColor QColorTransform::map(const QColor &color) const
c = d->colorMatrix.map(c);
bool inGamut = c.x >= 0.0f && c.x <= 1.0f && c.y >= 0.0f && c.y <= 1.0f && c.z >= 0.0f && c.z <= 1.0f;
if (inGamut) {
if (d_ptr->colorSpaceOut->lut.generated.loadAcquire()) {
if (d->colorSpaceOut->lut.generated.loadAcquire()) {
c.x = d->colorSpaceOut->lut[0]->fromLinear(c.x);
c.y = d->colorSpaceOut->lut[1]->fromLinear(c.y);
c.z = d->colorSpaceOut->lut[2]->fromLinear(c.z);

View File

@ -51,41 +51,42 @@ class QRgba64;
class QColorSpacePrivate;
class QColorTransformPrivate;
class Q_GUI_EXPORT QColorTransform
class QColorTransform
{
public:
QColorTransform() noexcept : d_ptr(nullptr) { }
~QColorTransform() noexcept;
QColorTransform(const QColorTransform &colorTransform) noexcept
: d_ptr(colorTransform.d_ptr)
{ }
QColorTransform() noexcept : d(nullptr) { }
Q_GUI_EXPORT ~QColorTransform();
Q_GUI_EXPORT QColorTransform(const QColorTransform &colorTransform) noexcept;
QColorTransform(QColorTransform &&colorTransform) noexcept
: d_ptr(std::move(colorTransform.d_ptr))
: d{qExchange(colorTransform.d, nullptr)}
{ }
QColorTransform &operator=(const QColorTransform &other) noexcept
{
d_ptr = other.d_ptr;
QColorTransform{other}.swap(*this);
return *this;
}
QColorTransform &operator=(QColorTransform &&other) noexcept
{
d_ptr = std::move(other.d_ptr);
QColorTransform{std::move(other)}.swap(*this);
return *this;
}
QRgb map(const QRgb &argb) const;
QRgba64 map(const QRgba64 &rgba64) const;
QColor map(const QColor &color) const;
void swap(QColorTransform &other) noexcept { qSwap(d, other.d); }
Q_GUI_EXPORT QRgb map(QRgb argb) const;
Q_GUI_EXPORT QRgba64 map(QRgba64 rgba64) const;
Q_GUI_EXPORT QColor map(const QColor &color) const;
private:
friend class QColorSpace;
friend class QColorSpacePrivate;
friend class QImage;
Q_DECLARE_PRIVATE(QColorTransform)
QSharedPointer<QColorTransformPrivate> d_ptr;
const QColorTransformPrivate *d;
};
Q_DECLARE_SHARED(QColorTransform)
QT_END_NAMESPACE
#endif // QCOLORTRANSFORM_H

View File

@ -54,9 +54,11 @@
#include "qcolormatrix_p.h"
#include "qcolorspace_p.h"
#include <QtCore/qshareddata.h>
QT_BEGIN_NAMESPACE
class QColorTransformPrivate
class QColorTransformPrivate : public QSharedData
{
public:
QColorMatrix colorMatrix;