diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2019-07-21 18:34:48 +0300 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2019-07-23 14:37:00 +0300 |
commit | 08115accd9f57685fd2c4565063e5c395cc44daf (patch) | |
tree | 4d936b481284191e3fe4fced60ef3ab436f027c3 /src | |
parent | 781fa5d37ac8495f31de75332f25c1d602b9bc1d (diff) |
QWaylandCursor: replace a static QMap with a C array
The content of the QMultiMap cursorNameMaps is static, so using a
dynamic container is overkill.
Replace the map by a (sorted) C array of struct {Key, Value}, and use
std::equal_range to find matching cursors. This also avoids the
creation of a QList on each call (due to the use of QMap:values()
instead of QMap::equal_range), as well as the creation of QByteArrays,
which the underlying wayland C API doesn't know about, anyway.
The entries were already sorted, so the initializer_list stays the
same. Add an assert that the list is ordered.
Since this is library code, don't use the attractive struct {
WaylandCursor, const char *name }, as that causes relocations that
delay the loading of the shared object, and make sharing of the data
between processes impossible. This wastes some memory, due to all the
NUL padding up to the common maximum, and the next alignment step, but
can be optimized later when someone writes a C++-only version of
Q_STRINGTABLE.
Even so, this saves 10.5KiB in text size on optimized AMD64 Linux GCC
9.1 builds.
Change-Id: I19fa1742e2fcaf9de74af1e5908e796b0588d507
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/client/qwaylandcursor.cpp | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/src/client/qwaylandcursor.cpp b/src/client/qwaylandcursor.cpp index 165df7762..4356b23a0 100644 --- a/src/client/qwaylandcursor.cpp +++ b/src/client/qwaylandcursor.cpp @@ -48,6 +48,8 @@ #include <wayland-cursor.h> +#include <algorithm> + QT_BEGIN_NAMESPACE namespace QtWaylandClient { @@ -75,7 +77,10 @@ wl_cursor *QWaylandCursorTheme::requestCursor(WaylandCursor shape) if (struct wl_cursor *cursor = m_cursors.value(shape, nullptr)) return cursor; - static const QMultiMap<WaylandCursor, QByteArray>cursorNamesMap { + static Q_CONSTEXPR struct ShapeAndName { + WaylandCursor shape; + const char name[33]; + } cursorNamesMap[] = { {ArrowCursor, "left_ptr"}, {ArrowCursor, "default"}, {ArrowCursor, "top_left_arrow"}, @@ -193,9 +198,14 @@ wl_cursor *QWaylandCursorTheme::requestCursor(WaylandCursor shape) {ResizeSouthWestCursor, "bottom_left_corner"}, }; - QList<QByteArray> cursorNames = cursorNamesMap.values(shape); - for (auto &name : qAsConst(cursorNames)) { - if (wl_cursor *cursor = wl_cursor_theme_get_cursor(m_theme, name.constData())) { + const auto byShape = [](ShapeAndName lhs, ShapeAndName rhs) { + return lhs.shape < rhs.shape; + }; + Q_ASSERT(std::is_sorted(std::begin(cursorNamesMap), std::end(cursorNamesMap), byShape)); + const auto p = std::equal_range(std::begin(cursorNamesMap), std::end(cursorNamesMap), + ShapeAndName{shape, ""}, byShape); + for (auto it = p.first; it != p.second; ++it) { + if (wl_cursor *cursor = wl_cursor_theme_get_cursor(m_theme, it->name)) { m_cursors.insert(shape, cursor); return cursor; } |