diff options
author | Jindrich Makovicka <makovick@gmail.com> | 2018-09-16 18:26:04 +0200 |
---|---|---|
committer | Michael Lutz <michi@icosahedron.de> | 2018-10-26 20:22:38 +0200 |
commit | 25ab9c1997f770f4a8a66bb3ad4b82ba87e3a977 (patch) | |
tree | ba3950e5d5d9994ff3763ec65d121254bb5b37cc /src/viewport.cpp | |
parent | 47ff673664a14e250bf01af6f29c65abb1e0975e (diff) | |
download | openttd-25ab9c1997f770f4a8a66bb3ad4b82ba87e3a977.tar.xz |
Codechange: Improve (un)zoom performance
When zooming out with a high res display, there can be about 150k sprites
to be sorted before displaying. With the O(n^2) complexity of the sprite
sorter, this can take several seconds.
This patch works around this by sorting the sprites by the xmin coordinate
first using QSort, which later allows an early bailout out of the inner
loop. This is enough to cut down the full unzoom time on a 4k display to a
fraction of second.
Diffstat (limited to 'src/viewport.cpp')
-rw-r--r-- | src/viewport.cpp | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/viewport.cpp b/src/viewport.cpp index cb0b36f40..6e7dfc495 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -88,6 +88,7 @@ #include "command_func.h" #include "network/network_func.h" #include "framerate_type.h" +#include "core/sort_func.hpp" #include <map> @@ -1379,11 +1380,22 @@ static bool ViewportSortParentSpritesChecker() return true; } +static int CDECL CompareParentSprites(ParentSpriteToDraw * const *psd, ParentSpriteToDraw * const *psd2) +{ + const ParentSpriteToDraw *ps = *psd; + const ParentSpriteToDraw *ps2 = *psd2; + return ps->xmin - ps2->xmin; +} + /** Sort parent sprites pointer array */ static void ViewportSortParentSprites(ParentSpriteToSortVector *psdv) { ParentSpriteToDraw **psdvend = psdv->End(); ParentSpriteToDraw **psd = psdv->Begin(); + + /* pre-sort by xmin in ascending order */ + QSortT(psd, psdvend - psd, CompareParentSprites); + while (psd != psdvend) { ParentSpriteToDraw *ps = *psd; @@ -1420,9 +1432,11 @@ static void ViewportSortParentSprites(ParentSpriteToSortVector *psdv) * I.e. every single order of X, Y, Z says ps2 is behind ps or they overlap. * That is: If one partial order says ps behind ps2, do not change the order. */ - if (ps->xmax < ps2->xmin || - ps->ymax < ps2->ymin || - ps->zmax < ps2->zmin) { + if (ps->xmax < ps2->xmin) { + /* all following sprites have xmin >= ps2->xmin */ + break; + } + if (ps->ymax < ps2->ymin || ps->zmax < ps2->zmin) { continue; } } |