QWaylandDisplay: replace a QMap<pair<QString,int>, pointer*> with a std::vector<{QString, int, unique_ptr}>

The vector is sorted, so lookup performance is the same, or
better. Insertion performance is worse, of course, at least in big-O
terms, but probably not in practice.

But now the good part: saves a stunning 7.2KiB (0.6%) in text size on
optimized AMD 64 Linux GCC 9.1 builds.

Change-Id: Ie604f83d7d51111430db1d0bb89d8cc3a52301bf
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Marc Mutz 2019-06-05 17:27:10 +02:00
parent 3addd499bd
commit c962b8c2df
4 changed files with 45 additions and 11 deletions

View File

@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
QWaylandCursorTheme *QWaylandCursorTheme::create(QWaylandShm *shm, int size, const QString &themeName)
std::unique_ptr<QWaylandCursorTheme> QWaylandCursorTheme::create(QWaylandShm *shm, int size, const QString &themeName)
{
QByteArray nameBytes = themeName.toLocal8Bit();
struct ::wl_cursor_theme *theme = wl_cursor_theme_load(nameBytes.constData(), size, shm->object());
@ -64,7 +64,7 @@ QWaylandCursorTheme *QWaylandCursorTheme::create(QWaylandShm *shm, int size, con
return nullptr;
}
return new QWaylandCursorTheme(theme);
return std::unique_ptr<QWaylandCursorTheme>{new QWaylandCursorTheme(theme)};
}
QWaylandCursorTheme::~QWaylandCursorTheme()

View File

@ -57,6 +57,8 @@
#if QT_CONFIG(cursor)
#include <memory>
struct wl_cursor;
struct wl_cursor_image;
struct wl_cursor_theme;
@ -73,7 +75,7 @@ class QWaylandShm;
class Q_WAYLAND_CLIENT_EXPORT QWaylandCursorTheme
{
public:
static QWaylandCursorTheme *create(QWaylandShm *shm, int size, const QString &themeName);
static std::unique_ptr<QWaylandCursorTheme> create(QWaylandShm *shm, int size, const QString &themeName);
~QWaylandCursorTheme();
::wl_cursor *cursor(Qt::CursorShape shape);

View File

@ -85,6 +85,8 @@
#include <errno.h>
#include <tuple> // for std::tie
QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
@ -183,7 +185,7 @@ QWaylandDisplay::~QWaylandDisplay(void)
delete mDndSelectionHandler.take();
#endif
#if QT_CONFIG(cursor)
qDeleteAll(mCursorThemes);
mCursorThemes.clear();
#endif
if (mDisplay)
wl_display_disconnect(mDisplay);
@ -602,15 +604,30 @@ QWaylandCursor *QWaylandDisplay::waylandCursor()
return mCursor.data();
}
auto QWaylandDisplay::findExistingCursorTheme(const QString &name, int pixelSize) const noexcept
-> FindExistingCursorThemeResult
{
const auto byNameAndSize = [](const WaylandCursorTheme &lhs, const WaylandCursorTheme &rhs) {
return std::tie(lhs.pixelSize, lhs.name) < std::tie(rhs.pixelSize, rhs.name);
};
const WaylandCursorTheme prototype = {name, pixelSize, nullptr};
const auto it = std::lower_bound(mCursorThemes.cbegin(), mCursorThemes.cend(), prototype, byNameAndSize);
if (it != mCursorThemes.cend() && it->name == name && it->pixelSize == pixelSize)
return {it, true};
else
return {it, false};
}
QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int pixelSize)
{
if (auto *theme = mCursorThemes.value({name, pixelSize}, nullptr))
return theme;
const auto result = findExistingCursorTheme(name, pixelSize);
if (result.found)
return result.theme();
if (auto *theme = QWaylandCursorTheme::create(shm(), pixelSize, name)) {
mCursorThemes[{name, pixelSize}] = theme;
return theme;
}
if (auto theme = QWaylandCursorTheme::create(shm(), pixelSize, name))
return mCursorThemes.insert(result.position, {name, pixelSize, std::move(theme)})->theme.get();
return nullptr;
}

View File

@ -238,7 +238,22 @@ private:
QList<Listener> mRegistryListeners;
QWaylandIntegration *mWaylandIntegration = nullptr;
#if QT_CONFIG(cursor)
QMap<std::pair<QString, int>, QWaylandCursorTheme *> mCursorThemes; // theme name and size
struct WaylandCursorTheme {
QString name;
int pixelSize;
std::unique_ptr<QWaylandCursorTheme> theme;
};
std::vector<WaylandCursorTheme> mCursorThemes;
struct FindExistingCursorThemeResult {
std::vector<WaylandCursorTheme>::const_iterator position;
bool found;
QWaylandCursorTheme *theme() const noexcept
{ return found ? position->theme.get() : nullptr; }
};
FindExistingCursorThemeResult findExistingCursorTheme(const QString &name, int pixelSize) const;
QScopedPointer<QWaylandCursor> mCursor;
#endif
#if QT_CONFIG(wayland_datadevice)