From fa36d81bbcbe9cecaaa20922dd278f7b14fc3d3c Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 5 Apr 2012 14:49:02 +0200 Subject: QPalette: add member-swap Implemented as in other shared classes (e.g. QPen), except that I wrapped the bitfield in a union to speed up swapping. (GCC didn't manage to optimize (hand-rolled) swaps of adjacent bit field elements into an integer one, even at -O2). GCC -pedantic complains about anonymous structs, so I had to give the struct in the union a name. Change-Id: I519e1c2f88f6ae2dffed38b493991189d67073b8 Reviewed-by: Girish Ramakrishnan Reviewed-by: Gunnar Sletta Reviewed-by: Thiago Macieira --- src/gui/kernel/qpalette.cpp | 55 +++++++++++++++++++++++++-------------------- src/gui/kernel/qpalette.h | 27 +++++++++++++++------- 2 files changed, 50 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp index d8585711b5..7d0bc8c0c5 100644 --- a/src/gui/kernel/qpalette.cpp +++ b/src/gui/kernel/qpalette.cpp @@ -512,8 +512,10 @@ static void qt_palette_from_color(QPalette &pal, const QColor &button) \sa QApplication::setPalette(), QApplication::palette() */ QPalette::QPalette() - : d(0), current_group(Active), resolve_mask(0) + : d(0) { + data.current_group = Active; + data.resolve_mask = 0; // Initialize to application palette if present, else default to black. // This makes it possible to instantiate QPalette outside QGuiApplication, // for example in the platform plugins. @@ -523,7 +525,7 @@ QPalette::QPalette() } else { init(); qt_palette_from_color(*this, Qt::black); - resolve_mask = 0; + data.resolve_mask = 0; } } @@ -627,11 +629,9 @@ QPalette::QPalette(const QColor &button, const QColor &window) This constructor is fast thanks to \l{implicit sharing}. */ QPalette::QPalette(const QPalette &p) + : d(p.d), data(p.data) { - d = p.d; d->ref.ref(); - resolve_mask = p.resolve_mask; - current_group = p.current_group; } /*! @@ -646,8 +646,8 @@ QPalette::~QPalette() /*!\internal*/ void QPalette::init() { d = new QPalettePrivate; - resolve_mask = 0; - current_group = Active; //as a default.. + data.resolve_mask = 0; + data.current_group = Active; //as a default.. } /*! @@ -659,14 +659,21 @@ void QPalette::init() { QPalette &QPalette::operator=(const QPalette &p) { p.d->ref.ref(); - resolve_mask = p.resolve_mask; - current_group = p.current_group; + data = p.data; if(!d->ref.deref()) delete d; d = p.d; return *this; } +/*! + \fn void QPalette::swap(QPalette &other) + \since 5.0 + + Swaps this palette instance with \a other. This function is very + fast and never fails. +*/ + /*! Returns the palette as a QVariant */ @@ -697,7 +704,7 @@ const QBrush &QPalette::brush(ColorGroup gr, ColorRole cr) const Q_ASSERT(cr < NColorRoles); if(gr >= (int)NColorGroups) { if(gr == Current) { - gr = (ColorGroup)current_group; + gr = (ColorGroup)data.current_group; } else { qWarning("QPalette::brush: Unknown ColorGroup: %d", (int)gr); gr = Active; @@ -732,17 +739,17 @@ void QPalette::setBrush(ColorGroup cg, ColorRole cr, const QBrush &b) if(cg == All) { for(int i = 0; i < (int)NColorGroups; i++) d->br[i][cr] = b; - resolve_mask |= (1<br[cg][cr] = b; - resolve_mask |= (1<= (int)NColorGroups) { if(group1 == Current) { - group1 = (ColorGroup)current_group; + group1 = (ColorGroup)data.current_group; } else { qWarning("QPalette::brush: Unknown ColorGroup(1): %d", (int)group1); group1 = Active; @@ -829,7 +836,7 @@ bool QPalette::isEqual(QPalette::ColorGroup group1, QPalette::ColorGroup group2) } if(group2 >= (int)NColorGroups) { if(group2 == Current) { - group2 = (ColorGroup)current_group; + group2 = (ColorGroup)data.current_group; } else { qWarning("QPalette::brush: Unknown ColorGroup(2): %d", (int)group2); group2 = Active; @@ -879,10 +886,10 @@ qint64 QPalette::cacheKey() const */ QPalette QPalette::resolve(const QPalette &other) const { - if ((*this == other && resolve_mask == other.resolve_mask) - || resolve_mask == 0) { + if ((*this == other && data.resolve_mask == other.data.resolve_mask) + || data.resolve_mask == 0) { QPalette o = other; - o.resolve_mask = resolve_mask; + o.data.resolve_mask = data.resolve_mask; return o; } @@ -890,7 +897,7 @@ QPalette QPalette::resolve(const QPalette &other) const palette.detach(); for(int role = 0; role < (int)NColorRoles; role++) - if (!(resolve_mask & (1<br[grp][role] = other.d->br[grp][role]; @@ -1032,10 +1039,10 @@ void QPalette::setColorGroup(ColorGroup cg, const QBrush &windowText, const QBru QBrush(Qt::blue), QBrush(Qt::magenta), QBrush(toolTipBase), QBrush(toolTipText)); - resolve_mask &= ~(1 << Highlight); - resolve_mask &= ~(1 << HighlightedText); - resolve_mask &= ~(1 << LinkVisited); - resolve_mask &= ~(1 << Link); + data.resolve_mask &= ~(1 << Highlight); + data.resolve_mask &= ~(1 << HighlightedText); + data.resolve_mask &= ~(1 << LinkVisited); + data.resolve_mask &= ~(1 << Link); } diff --git a/src/gui/kernel/qpalette.h b/src/gui/kernel/qpalette.h index 96295ab5db..4b71af813b 100644 --- a/src/gui/kernel/qpalette.h +++ b/src/gui/kernel/qpalette.h @@ -74,11 +74,17 @@ public: #ifdef Q_COMPILER_RVALUE_REFS inline QPalette &operator=(QPalette &&other) { - resolve_mask = other.resolve_mask; - current_group = other.current_group; + data.resolve_mask = other.data.resolve_mask; + data.current_group = other.data.current_group; qSwap(d, other.d); return *this; } #endif + + void swap(QPalette &other) { + qSwap(d, other.d); + qSwap(for_faster_swapping_dont_use, other.for_faster_swapping_dont_use); + } + operator QVariant() const; // Do not change the order, the serialization format depends on it @@ -94,8 +100,8 @@ public: Foreground = WindowText, Background = Window }; - inline ColorGroup currentColorGroup() const { return static_cast(current_group); } - inline void setCurrentColorGroup(ColorGroup cg) { current_group = cg; } + inline ColorGroup currentColorGroup() const { return static_cast(data.current_group); } + inline void setCurrentColorGroup(ColorGroup cg) { data.current_group = cg; } inline const QColor &color(ColorGroup cg, ColorRole cr) const { return brush(cg, cr).color(); } @@ -145,8 +151,8 @@ public: qint64 cacheKey() const; QPalette resolve(const QPalette &) const; - inline uint resolve() const { return resolve_mask; } - inline void resolve(uint mask) { resolve_mask = mask; } + inline uint resolve() const { return data.resolve_mask; } + inline void resolve(uint mask) { data.resolve_mask = mask; } private: void setColorGroup(ColorGroup cr, const QBrush &windowText, const QBrush &button, @@ -170,8 +176,13 @@ private: void detach(); QPalettePrivate *d; - uint current_group : 4; - uint resolve_mask : 28; + union { + struct { + uint current_group : 4; + uint resolve_mask : 28; + } data; + quint32 for_faster_swapping_dont_use; + }; friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &s, const QPalette &p); }; -- cgit v1.2.3