Plans: Improve performance of viewport plan rendering
This commit is contained in:
@@ -17,3 +17,33 @@ INSTANTIATE_POOL_METHODS(Plan)
|
|||||||
|
|
||||||
Plan *_current_plan = nullptr;
|
Plan *_current_plan = nullptr;
|
||||||
Plan *_new_plan = nullptr;
|
Plan *_new_plan = nullptr;
|
||||||
|
|
||||||
|
void PlanLine::UpdateVisualExtents()
|
||||||
|
{
|
||||||
|
if (_network_dedicated) return;
|
||||||
|
|
||||||
|
if (this->tiles.size() < 2) {
|
||||||
|
this->viewport_extents = { INT_MAX, INT_MAX, INT_MAX, INT_MAX };
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int min_x = INT_MAX;
|
||||||
|
int max_x = INT_MIN;
|
||||||
|
int min_y = INT_MAX;
|
||||||
|
int max_y = INT_MIN;
|
||||||
|
|
||||||
|
for (TileIndex t : this->tiles) {
|
||||||
|
const int tile_x = TileX(t);
|
||||||
|
const int tile_y = TileY(t);
|
||||||
|
const int x = tile_y - tile_x;
|
||||||
|
const int y = tile_y + tile_x;
|
||||||
|
|
||||||
|
if (x < min_x) min_x = x;
|
||||||
|
if (x > max_x) max_x = x;
|
||||||
|
if (y < min_y) min_y = y;
|
||||||
|
if (y > max_y) max_y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->viewport_extents = { (int)(min_x * TILE_SIZE * 2 * ZOOM_LVL_BASE), (int)(min_y * TILE_SIZE * ZOOM_LVL_BASE),
|
||||||
|
(int)((max_x + 1) * TILE_SIZE * 2 * ZOOM_LVL_BASE), (int)((max_y + 1) * TILE_SIZE * ZOOM_LVL_BASE) };
|
||||||
|
}
|
||||||
|
@@ -31,6 +31,7 @@ struct PlanLine {
|
|||||||
bool visible;
|
bool visible;
|
||||||
bool focused;
|
bool focused;
|
||||||
TileVector tiles;
|
TileVector tiles;
|
||||||
|
Rect viewport_extents;
|
||||||
|
|
||||||
PlanLine()
|
PlanLine()
|
||||||
{
|
{
|
||||||
@@ -153,6 +154,8 @@ struct PlanLine {
|
|||||||
if (count == 0) return INVALID_TILE;
|
if (count == 0) return INVALID_TILE;
|
||||||
return TileXY(x / count, y / count);
|
return TileXY(x / count, y / count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateVisualExtents();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Plan : PlanPool::PoolItem<&_plan_pool> {
|
struct Plan : PlanPool::PoolItem<&_plan_pool> {
|
||||||
|
@@ -69,6 +69,7 @@ CommandCost CmdAddPlanLine(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
|||||||
p->lines.pop_back();
|
p->lines.pop_back();
|
||||||
return CMD_ERROR;
|
return CMD_ERROR;
|
||||||
}
|
}
|
||||||
|
pl->UpdateVisualExtents();
|
||||||
if (p->IsListable()) {
|
if (p->IsListable()) {
|
||||||
pl->SetVisibility(p->visible);
|
pl->SetVisibility(p->visible);
|
||||||
if (p->visible) pl->MarkDirty();
|
if (p->visible) pl->MarkDirty();
|
||||||
|
@@ -60,6 +60,7 @@ static void Load_PLAN()
|
|||||||
const size_t tile_count = SlReadUint32();
|
const size_t tile_count = SlReadUint32();
|
||||||
pl->tiles.resize(tile_count);
|
pl->tiles.resize(tile_count);
|
||||||
SlArray(&pl->tiles[0], tile_count, SLE_UINT32);
|
SlArray(&pl->tiles[0], tile_count, SLE_UINT32);
|
||||||
|
pl->UpdateVisualExtents();
|
||||||
}
|
}
|
||||||
p->SetVisibility(false);
|
p->SetVisibility(false);
|
||||||
}
|
}
|
||||||
@@ -79,6 +80,7 @@ static void Load_PLANLINE()
|
|||||||
size_t plsz = SlGetFieldLength() / sizeof(TileIndex);
|
size_t plsz = SlGetFieldLength() / sizeof(TileIndex);
|
||||||
pl->tiles.resize(plsz);
|
pl->tiles.resize(plsz);
|
||||||
SlArray(&pl->tiles[0], plsz, SLE_UINT32);
|
SlArray(&pl->tiles[0], plsz, SLE_UINT32);
|
||||||
|
pl->UpdateVisualExtents();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Plan *p : Plan::Iterate()) {
|
for (Plan *p : Plan::Iterate()) {
|
||||||
|
@@ -2419,18 +2419,47 @@ void ViewportDrawPlans(const Viewport *vp)
|
|||||||
DrawPixelInfo *old_dpi = _cur_dpi;
|
DrawPixelInfo *old_dpi = _cur_dpi;
|
||||||
_cur_dpi = &_dpi_for_text;
|
_cur_dpi = &_dpi_for_text;
|
||||||
|
|
||||||
|
if (Plan::GetNumItems() != 0) {
|
||||||
|
const Rect bounds = {
|
||||||
|
ScaleByZoom(_dpi_for_text.left - 2, vp->zoom),
|
||||||
|
ScaleByZoom(_dpi_for_text.top - 2, vp->zoom),
|
||||||
|
ScaleByZoom(_dpi_for_text.left + _dpi_for_text.width + 2, vp->zoom),
|
||||||
|
ScaleByZoom(_dpi_for_text.top + _dpi_for_text.height + 2, vp->zoom) + (int)(ZOOM_LVL_BASE * TILE_HEIGHT * _settings_game.construction.max_heightlevel)
|
||||||
|
};
|
||||||
|
|
||||||
|
const int min_coord_delta = bounds.left / (int)(2 * ZOOM_LVL_BASE * TILE_SIZE);
|
||||||
|
const int max_coord_delta = (bounds.right / (int)(2 * ZOOM_LVL_BASE * TILE_SIZE)) + 1;
|
||||||
|
|
||||||
for (Plan *p : Plan::Iterate()) {
|
for (Plan *p : Plan::Iterate()) {
|
||||||
if (!p->IsVisible()) continue;
|
if (!p->IsVisible()) continue;
|
||||||
for (PlanLineVector::iterator it = p->lines.begin(); it != p->lines.end(); it++) {
|
for (PlanLineVector::iterator it = p->lines.begin(); it != p->lines.end(); it++) {
|
||||||
PlanLine *pl = *it;
|
PlanLine *pl = *it;
|
||||||
if (!pl->visible) continue;
|
if (!pl->visible) continue;
|
||||||
|
|
||||||
|
if (
|
||||||
|
bounds.left > pl->viewport_extents.right ||
|
||||||
|
bounds.right < pl->viewport_extents.left ||
|
||||||
|
bounds.top > pl->viewport_extents.bottom ||
|
||||||
|
bounds.bottom < pl->viewport_extents.top
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TileIndex to_tile = pl->tiles[0];
|
||||||
|
int to_coord_delta = (int)TileY(to_tile) - (int)TileX(to_tile);
|
||||||
for (uint i = 1; i < pl->tiles.size(); i++) {
|
for (uint i = 1; i < pl->tiles.size(); i++) {
|
||||||
const TileIndex from_tile = pl->tiles[i-1];
|
const TileIndex from_tile = to_tile;
|
||||||
|
const int from_coord_delta = to_coord_delta;
|
||||||
|
to_tile = pl->tiles[i];
|
||||||
|
to_coord_delta = (int)TileY(to_tile) - (int)TileX(to_tile);
|
||||||
|
|
||||||
|
if (to_coord_delta < min_coord_delta && from_coord_delta < min_coord_delta) continue;
|
||||||
|
if (to_coord_delta > max_coord_delta && from_coord_delta > max_coord_delta) continue;
|
||||||
|
|
||||||
const Point from_pt = RemapCoords2(TileX(from_tile) * TILE_SIZE + TILE_SIZE / 2, TileY(from_tile) * TILE_SIZE + TILE_SIZE / 2);
|
const Point from_pt = RemapCoords2(TileX(from_tile) * TILE_SIZE + TILE_SIZE / 2, TileY(from_tile) * TILE_SIZE + TILE_SIZE / 2);
|
||||||
const int from_x = UnScaleByZoom(from_pt.x, vp->zoom);
|
const int from_x = UnScaleByZoom(from_pt.x, vp->zoom);
|
||||||
const int from_y = UnScaleByZoom(from_pt.y, vp->zoom);
|
const int from_y = UnScaleByZoom(from_pt.y, vp->zoom);
|
||||||
|
|
||||||
const TileIndex to_tile = pl->tiles[i];
|
|
||||||
const Point to_pt = RemapCoords2(TileX(to_tile) * TILE_SIZE + TILE_SIZE / 2, TileY(to_tile) * TILE_SIZE + TILE_SIZE / 2);
|
const Point to_pt = RemapCoords2(TileX(to_tile) * TILE_SIZE + TILE_SIZE / 2, TileY(to_tile) * TILE_SIZE + TILE_SIZE / 2);
|
||||||
const int to_x = UnScaleByZoom(to_pt.x, vp->zoom);
|
const int to_x = UnScaleByZoom(to_pt.x, vp->zoom);
|
||||||
const int to_y = UnScaleByZoom(to_pt.y, vp->zoom);
|
const int to_y = UnScaleByZoom(to_pt.y, vp->zoom);
|
||||||
@@ -2444,6 +2473,7 @@ void ViewportDrawPlans(const Viewport *vp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_current_plan && _current_plan->temp_line->tiles.size() > 1) {
|
if (_current_plan && _current_plan->temp_line->tiles.size() > 1) {
|
||||||
for (uint i = 1; i < _current_plan->temp_line->tiles.size(); i++) {
|
for (uint i = 1; i < _current_plan->temp_line->tiles.size(); i++) {
|
||||||
|
Reference in New Issue
Block a user