Cache list of active viewports instead of always iterating window list.

This is to speed up marking all viewports dirty, which is done very
frequently.
This commit is contained in:
Jonathan G Rennison
2016-09-09 21:19:05 +01:00
parent c20cf31514
commit c137303584

View File

@@ -96,6 +96,7 @@
#include "depot_base.h" #include "depot_base.h"
#include "tunnelbridge_map.h" #include "tunnelbridge_map.h"
#include "gui.h" #include "gui.h"
#include "core/container_func.hpp"
#include <map> #include <map>
#include <vector> #include <vector>
@@ -193,6 +194,8 @@ static void MarkRouteStepDirty(const TileIndex tile, uint order_nr);
static DrawPixelInfo _dpi_for_text; static DrawPixelInfo _dpi_for_text;
static ViewportDrawer _vd; static ViewportDrawer _vd;
static std::vector<ViewPort *> _viewport_window_cache;
RouteStepsMap _vp_route_steps; RouteStepsMap _vp_route_steps;
RouteStepsMap _vp_route_steps_last_mark_dirty; RouteStepsMap _vp_route_steps_last_mark_dirty;
uint _vp_route_step_width = 0; uint _vp_route_step_width = 0;
@@ -242,6 +245,7 @@ void DeleteWindowViewport(Window *w)
{ {
if (w->viewport == NULL) return; if (w->viewport == NULL) return;
container_unordered_remove(_viewport_window_cache, w->viewport);
delete w->viewport->overlay; delete w->viewport->overlay;
free(w->viewport); free(w->viewport);
w->viewport = NULL; w->viewport = NULL;
@@ -304,6 +308,7 @@ void InitializeWindowViewport(Window *w, int x, int y,
w->viewport = vp; w->viewport = vp;
vp->virtual_left = 0; // pt.x; vp->virtual_left = 0; // pt.x;
vp->virtual_top = 0; // pt.y; vp->virtual_top = 0; // pt.y;
_viewport_window_cache.push_back(vp);
} }
static Point _vp_move_offs; static Point _vp_move_offs;
@@ -1402,11 +1407,8 @@ void ViewportSign::MarkDirty(ZoomLevel maxzoom) const
zoomlevels[zoom].bottom = this->top + ScaleByZoom(VPSM_TOP + FONT_HEIGHT_NORMAL + VPSM_BOTTOM + 1, zoom); zoomlevels[zoom].bottom = this->top + ScaleByZoom(VPSM_TOP + FONT_HEIGHT_NORMAL + VPSM_BOTTOM + 1, zoom);
} }
Window *w; for (ViewPort *vp : _viewport_window_cache) {
FOR_ALL_WINDOWS_FROM_BACK(w) { if (vp->zoom <= maxzoom) {
ViewPort *vp = w->viewport;
if (vp != NULL && vp->zoom <= maxzoom) {
assert(vp->width != 0);
Rect &zl = zoomlevels[vp->zoom]; Rect &zl = zoomlevels[vp->zoom];
MarkViewportDirty(vp, zl.left, zl.top, zl.right, zl.bottom); MarkViewportDirty(vp, zl.left, zl.top, zl.right, zl.bottom);
} }
@@ -2799,32 +2801,22 @@ static void MarkViewportDirty(const ViewPort * const vp, int left, int top, int
*/ */
void MarkAllViewportsDirty(int left, int top, int right, int bottom, const ZoomLevel mark_dirty_if_zoomlevel_is_below) void MarkAllViewportsDirty(int left, int top, int right, int bottom, const ZoomLevel mark_dirty_if_zoomlevel_is_below)
{ {
Window *w; for (const ViewPort * const vp : _viewport_window_cache) {
FOR_ALL_WINDOWS_FROM_BACK(w) {
const ViewPort * const vp = w->viewport;
if (vp != NULL) {
assert(vp->width != 0);
if (vp->zoom >= mark_dirty_if_zoomlevel_is_below) continue; if (vp->zoom >= mark_dirty_if_zoomlevel_is_below) continue;
MarkViewportDirty(vp, left, top, right, bottom); MarkViewportDirty(vp, left, top, right, bottom);
} }
}
} }
static void MarkRouteStepDirty(const TileIndex tile, uint order_nr) static void MarkRouteStepDirty(const TileIndex tile, uint order_nr)
{ {
assert(tile != INVALID_TILE); assert(tile != INVALID_TILE);
Window *w;
const Point pt = RemapCoords2(TileX(tile) * TILE_SIZE + TILE_SIZE / 2, TileY(tile) * TILE_SIZE + TILE_SIZE / 2); const Point pt = RemapCoords2(TileX(tile) * TILE_SIZE + TILE_SIZE / 2, TileY(tile) * TILE_SIZE + TILE_SIZE / 2);
const int char_height = GetCharacterHeight(FS_SMALL) + 1; const int char_height = GetCharacterHeight(FS_SMALL) + 1;
FOR_ALL_WINDOWS_FROM_BACK(w) { for (const ViewPort * const vp : _viewport_window_cache) {
const ViewPort * const vp = w->viewport;
if (vp != NULL) {
assert(vp->width != 0);
const int half_width = ScaleByZoom((_vp_route_step_width / 2) + 1, vp->zoom); const int half_width = ScaleByZoom((_vp_route_step_width / 2) + 1, vp->zoom);
const int height = ScaleByZoom(_vp_route_step_height_top + char_height * order_nr + _vp_route_step_height_bottom, vp->zoom); const int height = ScaleByZoom(_vp_route_step_height_top + char_height * order_nr + _vp_route_step_height_bottom, vp->zoom);
MarkViewportDirty(vp, pt.x - half_width, pt.y - height, pt.x + half_width, pt.y); MarkViewportDirty(vp, pt.x - half_width, pt.y - height, pt.x + half_width, pt.y);
} }
}
} }
void MarkAllRouteStepsDirty(Window *vehicle_window) void MarkAllRouteStepsDirty(Window *vehicle_window)