summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2020-10-04 21:19:32 +0200
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2020-10-18 14:02:32 +0200
commitf1408d9966854cf55f15d59547f99d3aa2585fd4 (patch)
tree5d845cd07d63695ca0d633ed738f2f2bac84a440
parent9ceedd586321a2eeac4b63ee90d4e9726e143b78 (diff)
QColorSpace: port to QESDP
Replace the hand-rolled refcount management with QESDP. Since the class has a default-constructed / moved-from state where the d-pointer can be nullptr, add a in-class detach() that ensures a private object. Change-Id: Id81431fa60132dbc0eed45bb60b38d4f7d73833f Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--src/gui/image/qpnghandler.cpp2
-rw-r--r--src/gui/painting/qcolorspace.cpp60
-rw-r--r--src/gui/painting/qcolorspace.h20
-rw-r--r--src/gui/painting/qcolorspace_p.h18
-rw-r--r--src/gui/painting/qicc.cpp3
5 files changed, 42 insertions, 61 deletions
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index 6c05e0a567..de913af320 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -592,7 +592,7 @@ bool QPngHandlerPrivate::readPngHeader()
if (!colorSpace.isValid()) {
qCWarning(lcImageIo) << "QPngHandler: Failed to parse ICC profile";
} else {
- QColorSpacePrivate *csD = QColorSpacePrivate::getWritable(colorSpace);
+ QColorSpacePrivate *csD = QColorSpacePrivate::get(colorSpace);
if (csD->description.isEmpty())
csD->description = QString::fromLatin1((const char *)name);
colorSpaceState = Icc;
diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp
index baaac8b46d..a4ae294793 100644
--- a/src/gui/painting/qcolorspace.cpp
+++ b/src/gui/painting/qcolorspace.cpp
@@ -423,11 +423,10 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace
*/
/*!
+ \fn QColorSpace::QColorSpace()
+
Creates a new colorspace object that represents an undefined and invalid colorspace.
*/
-QColorSpace::QColorSpace()
-{
-}
/*!
Creates a new colorspace object that represents a \a namedColorSpace.
@@ -450,7 +449,6 @@ QColorSpace::QColorSpace(NamedColorSpace namedColorSpace)
delete tmp;
}
d_ptr = cspriv;
- d_ptr->ref.ref();
Q_ASSERT(isValid());
}
@@ -461,7 +459,6 @@ QColorSpace::QColorSpace(NamedColorSpace namedColorSpace)
QColorSpace::QColorSpace(QColorSpace::Primaries primaries, QColorSpace::TransferFunction fun, float gamma)
: d_ptr(new QColorSpacePrivate(primaries, fun, gamma))
{
- d_ptr->ref.ref();
}
/*!
@@ -471,7 +468,6 @@ QColorSpace::QColorSpace(QColorSpace::Primaries primaries, QColorSpace::Transfer
QColorSpace::QColorSpace(QColorSpace::Primaries primaries, float gamma)
: d_ptr(new QColorSpacePrivate(primaries, TransferFunction::Gamma, gamma))
{
- d_ptr->ref.ref();
}
/*!
@@ -485,36 +481,16 @@ QColorSpace::QColorSpace(const QPointF &whitePoint, const QPointF &redPoint,
QColorSpacePrimaries primaries(whitePoint, redPoint, greenPoint, bluePoint);
if (!primaries.areValid()) {
qWarning() << "QColorSpace attempted constructed from invalid primaries:" << whitePoint << redPoint << greenPoint << bluePoint;
- d_ptr = nullptr;
return;
}
d_ptr = new QColorSpacePrivate(primaries, fun, gamma);
- d_ptr->ref.ref();
}
-QColorSpace::~QColorSpace()
-{
- if (d_ptr && !d_ptr->ref.deref())
- delete d_ptr;
-}
+QColorSpace::~QColorSpace() = default;
-QColorSpace::QColorSpace(const QColorSpace &colorSpace)
- : d_ptr(colorSpace.d_ptr)
-{
- if (d_ptr)
- d_ptr->ref.ref();
-}
+QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QColorSpacePrivate)
-QColorSpace &QColorSpace::operator=(const QColorSpace &colorSpace)
-{
- QColorSpacePrivate *oldD = d_ptr;
- d_ptr = colorSpace.d_ptr;
- if (d_ptr)
- d_ptr->ref.ref();
- if (oldD && !oldD->ref.deref())
- delete oldD;
- return *this;
-}
+QColorSpace::QColorSpace(const QColorSpace &colorSpace) noexcept = default;
/*! \fn void QColorSpace::swap(QColorSpace &other)
@@ -571,12 +547,11 @@ void QColorSpace::setTransferFunction(QColorSpace::TransferFunction transferFunc
return;
if (!d_ptr) {
d_ptr = new QColorSpacePrivate(Primaries::Custom, transferFunction, gamma);
- d_ptr->ref.ref();
return;
}
if (d_ptr->transferFunction == transferFunction && d_ptr->gamma == gamma)
return;
- QColorSpacePrivate::getWritable(*this); // detach
+ detach();
d_ptr->description.clear();
d_ptr->transferFunction = transferFunction;
d_ptr->gamma = gamma;
@@ -612,12 +587,11 @@ void QColorSpace::setPrimaries(QColorSpace::Primaries primariesId)
return;
if (!d_ptr) {
d_ptr = new QColorSpacePrivate(primariesId, TransferFunction::Custom, 0.0f);
- d_ptr->ref.ref();
return;
}
if (d_ptr->primaries == primariesId)
return;
- QColorSpacePrivate::getWritable(*this); // detach
+ detach();
d_ptr->description.clear();
d_ptr->primaries = primariesId;
d_ptr->identifyColorSpace();
@@ -638,13 +612,12 @@ void QColorSpace::setPrimaries(const QPointF &whitePoint, const QPointF &redPoin
return;
if (!d_ptr) {
d_ptr = new QColorSpacePrivate(primaries, TransferFunction::Custom, 0.0f);
- d_ptr->ref.ref();
return;
}
QColorMatrix toXyz = primaries.toXyzMatrix();
if (QColorVector(primaries.whitePoint) == d_ptr->whitePoint && toXyz == d_ptr->toXyz)
return;
- QColorSpacePrivate::getWritable(*this); // detach
+ detach();
d_ptr->description.clear();
d_ptr->primaries = QColorSpace::Primaries::Custom;
d_ptr->toXyz = toXyz;
@@ -653,6 +626,17 @@ void QColorSpace::setPrimaries(const QPointF &whitePoint, const QPointF &redPoin
}
/*!
+ \internal
+*/
+void QColorSpace::detach()
+{
+ if (d_ptr)
+ d_ptr.detach();
+ else
+ d_ptr = new QColorSpacePrivate;
+}
+
+/*!
Returns an ICC profile representing the color space.
If the color space was generated from an ICC profile, that profile
@@ -691,8 +675,8 @@ QColorSpace QColorSpace::fromIccProfile(const QByteArray &iccProfile)
QColorSpace colorSpace;
if (QIcc::fromIccProfile(iccProfile, &colorSpace))
return colorSpace;
- QColorSpacePrivate *d = QColorSpacePrivate::getWritable(colorSpace);
- d->iccProfile = iccProfile;
+ colorSpace.detach();
+ colorSpace.d_ptr->iccProfile = iccProfile;
return colorSpace;
}
@@ -774,7 +758,7 @@ QColorTransform QColorSpace::transformationToColorSpace(const QColorSpace &color
if (!isValid() || !colorspace.isValid())
return QColorTransform();
- return d_ptr->transformationToColorSpace(colorspace.d_ptr);
+ return d_ptr->transformationToColorSpace(colorspace.d_ptr.get());
}
/*!
diff --git a/src/gui/painting/qcolorspace.h b/src/gui/painting/qcolorspace.h
index 07f1ae4c31..d31bf1a326 100644
--- a/src/gui/painting/qcolorspace.h
+++ b/src/gui/painting/qcolorspace.h
@@ -51,6 +51,8 @@ QT_BEGIN_NAMESPACE
class QColorSpacePrivate;
class QPointF;
+QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QColorSpacePrivate, Q_GUI_EXPORT)
+
class Q_GUI_EXPORT QColorSpace
{
Q_GADGET
@@ -80,7 +82,7 @@ public:
};
Q_ENUM(TransferFunction)
- QColorSpace();
+ QColorSpace() noexcept = default;
QColorSpace(NamedColorSpace namedColorSpace);
QColorSpace(Primaries primaries, TransferFunction fun, float gamma = 0.0f);
QColorSpace(Primaries primaries, float gamma);
@@ -89,12 +91,15 @@ public:
TransferFunction fun, float gamma = 0.0f);
~QColorSpace();
- QColorSpace(const QColorSpace &colorSpace);
- QColorSpace &operator=(const QColorSpace &colorSpace);
+ QColorSpace(const QColorSpace &colorSpace) noexcept;
+ QColorSpace &operator=(const QColorSpace &colorSpace) noexcept
+ {
+ QColorSpace copy(colorSpace);
+ swap(copy);
+ return *this;
+ }
- QColorSpace(QColorSpace &&colorSpace) noexcept
- : d_ptr(qExchange(colorSpace.d_ptr, nullptr))
- { }
+ QColorSpace(QColorSpace &&colorSpace) noexcept = default;
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QColorSpace)
void swap(QColorSpace &colorSpace) noexcept
@@ -111,6 +116,7 @@ public:
void setPrimaries(const QPointF &whitePoint, const QPointF &redPoint,
const QPointF &greenPoint, const QPointF &bluePoint);
+ void detach();
bool isValid() const noexcept;
friend Q_GUI_EXPORT bool operator==(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2);
@@ -125,7 +131,7 @@ public:
private:
friend class QColorSpacePrivate;
- QColorSpacePrivate *d_ptr = nullptr;
+ QExplicitlySharedDataPointer<QColorSpacePrivate> d_ptr;
#ifndef QT_NO_DEBUG_STREAM
friend Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QColorSpace &colorSpace);
diff --git a/src/gui/painting/qcolorspace_p.h b/src/gui/painting/qcolorspace_p.h
index e7add19ed3..a6c0616e4d 100644
--- a/src/gui/painting/qcolorspace_p.h
+++ b/src/gui/painting/qcolorspace_p.h
@@ -95,24 +95,14 @@ public:
QColorSpacePrivate(const QColorSpacePrimaries &primaries, QColorSpace::TransferFunction fun, float gamma);
QColorSpacePrivate(const QColorSpacePrivate &other) = default;
- // named different from get to avoid accidental detachs
- static QColorSpacePrivate *getWritable(QColorSpace &colorSpace)
+ static const QColorSpacePrivate *get(const QColorSpace &colorSpace)
{
- if (!colorSpace.d_ptr) {
- colorSpace.d_ptr = new QColorSpacePrivate;
- colorSpace.d_ptr->ref.ref();
- } else if (colorSpace.d_ptr->ref.loadRelaxed() != 1) {
- colorSpace.d_ptr->ref.deref();
- colorSpace.d_ptr = new QColorSpacePrivate(*colorSpace.d_ptr);
- colorSpace.d_ptr->ref.ref();
- }
- Q_ASSERT(colorSpace.d_ptr->ref.loadRelaxed() == 1);
- return colorSpace.d_ptr;
+ return colorSpace.d_ptr.get();
}
- static const QColorSpacePrivate *get(const QColorSpace &colorSpace)
+ static QColorSpacePrivate *get(QColorSpace &colorSpace)
{
- return colorSpace.d_ptr;
+ return colorSpace.d_ptr.get();
}
void initialize();
diff --git a/src/gui/painting/qicc.cpp b/src/gui/painting/qicc.cpp
index 746ef43692..5e30ace549 100644
--- a/src/gui/painting/qicc.cpp
+++ b/src/gui/painting/qicc.cpp
@@ -709,7 +709,8 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace)
}
}
- QColorSpacePrivate *colorspaceDPtr = QColorSpacePrivate::getWritable(*colorSpace);
+ colorSpace->detach();
+ QColorSpacePrivate *colorspaceDPtr = QColorSpacePrivate::get(*colorSpace);
if (header.inputColorSpace == uint(ColorSpaceType::Rgb)) {
// Parse XYZ tags