QGradient: add a setStops fast-path for conformant QGradientStops
The setStops() docs state that the stops need to be sorted and the positions must be valid. But the implementation sorts the stops and filters out invalid ones, so we probably need to keep that behavior, which, however, causes memory allocations and, potentially, O(N²) behavior, because setColorAt() uses a form of Insertion Sort with linear scanning... Add a fast-path for the common case that users adhere to the docs and pass valid stops. Change-Id: I93099a57bc4f37d1240a9e9f763618fd5095bc64 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>bb10
parent
01cade5050
commit
3b0cd13222
|
|
@ -1419,6 +1419,25 @@ void QGradient::setColorAt(qreal pos, const QColor &color)
|
|||
m_stops.insert(index, QGradientStop(pos, color));
|
||||
}
|
||||
|
||||
static inline bool ok(QGradientStop stop)
|
||||
{
|
||||
return stop.first >= 0 && stop.first <= 1; // rejects NaNs
|
||||
}
|
||||
|
||||
static inline bool ok(const QGradientStops &stops)
|
||||
{
|
||||
qreal lastPos = -1;
|
||||
for (const QGradientStop &stop : stops) {
|
||||
if (Q_UNLIKELY(!ok(stop)))
|
||||
return false;
|
||||
const bool sorted = stop.first > lastPos; // rejects duplicates
|
||||
if (Q_UNLIKELY(!sorted))
|
||||
return false;
|
||||
lastPos = stop.first;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void QGradient::setStops(const QGradientStops &stopPoints)
|
||||
|
||||
|
|
@ -1430,6 +1449,14 @@ void QGradient::setColorAt(qreal pos, const QColor &color)
|
|||
*/
|
||||
void QGradient::setStops(const QGradientStops &stops)
|
||||
{
|
||||
// ## Qt 6: consider taking \a stops by value, so we can move into m_stops
|
||||
if (Q_LIKELY(ok(stops))) {
|
||||
// fast path for the common case: if everything is ok with the stops, just copy them
|
||||
m_stops = stops;
|
||||
return;
|
||||
}
|
||||
// otherwise, to keep the pre-5.9 behavior, add them one after another,
|
||||
// so each stop is checked, invalid ones are skipped, they are added in-order (which may be O(N^2)).
|
||||
m_stops.clear();
|
||||
for (int i=0; i<stops.size(); ++i)
|
||||
setColorAt(stops.at(i).first, stops.at(i).second);
|
||||
|
|
|
|||
Loading…
Reference in New Issue