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 <girish.1.ramakrishnan@nokia.com>
Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2012-04-05 14:49:02 +02:00 committed by Qt by Nokia
parent b0aa023aa2
commit fa36d81bbc
2 changed files with 50 additions and 32 deletions

View File

@ -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<<cr);
data.resolve_mask |= (1<<cr);
return;
} else if(cg == Current) {
cg = (ColorGroup)current_group;
cg = (ColorGroup)data.current_group;
} else {
qWarning("QPalette::setBrush: Unknown ColorGroup: %d", (int)cg);
cg = Active;
}
}
d->br[cg][cr] = b;
resolve_mask |= (1<<cr);
data.resolve_mask |= (1<<cr);
}
/*!
@ -756,7 +763,7 @@ void QPalette::setBrush(ColorGroup cg, ColorRole cr, const QBrush &b)
bool QPalette::isBrushSet(ColorGroup cg, ColorRole cr) const
{
Q_UNUSED(cg);
return (resolve_mask & (1<<cr));
return (data.resolve_mask & (1<<cr));
}
/*!
@ -821,7 +828,7 @@ bool QPalette::isEqual(QPalette::ColorGroup group1, QPalette::ColorGroup group2)
{
if(group1 >= (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<<role)))
if (!(data.resolve_mask & (1<<role)))
for(int grp = 0; grp < (int)NColorGroups; grp++)
palette.d->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);
}

View File

@ -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<ColorGroup>(current_group); }
inline void setCurrentColorGroup(ColorGroup cg) { current_group = cg; }
inline ColorGroup currentColorGroup() const { return static_cast<ColorGroup>(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);
};