From f1408d9966854cf55f15d59547f99d3aa2585fd4 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sun, 4 Oct 2020 21:19:32 +0200 Subject: 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 --- src/gui/painting/qcolorspace.cpp | 60 +++++++++++++++------------------------- src/gui/painting/qcolorspace.h | 20 +++++++++----- src/gui/painting/qcolorspace_p.h | 18 +++--------- src/gui/painting/qicc.cpp | 3 +- 4 files changed, 41 insertions(+), 60 deletions(-) (limited to 'src/gui/painting') 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; @@ -652,6 +625,17 @@ void QColorSpace::setPrimaries(const QPointF &whitePoint, const QPointF &redPoin d_ptr->identifyColorSpace(); } +/*! + \internal +*/ +void QColorSpace::detach() +{ + if (d_ptr) + d_ptr.detach(); + else + d_ptr = new QColorSpacePrivate; +} + /*! Returns an ICC profile representing the color space. @@ -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 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 -- cgit v1.2.3