OpenTTD/src/core/geometry_func.cpp
Patric Stout 8e0d48a0f6
Fix: [SDL2] simplify what to redraw to prevent tearing (#8685)
When there are a lot of rects to redraw, of which one of the last
ones is almost the full screen, visual tearing happens over the
vertical axis. This is most visible when scrolling the map.

This can be prevented by using less rects. To simplify the situation,
and as solutions like OpenGL need this anyway, keep a single rect
that shows the biggest size that updates everything correctly.

Although this means it needs a bit more time redrawing where it
is strictly seen not needed, it also means less commands have
to be executed in the backend. In the end, this is a trade-off,
and from experiments it seems the approach of this commit gives
a better result.
2021-02-17 21:19:32 +01:00

51 lines
1.7 KiB
C++

/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file geometry_func.cpp Geometry functions. */
#include "../stdafx.h"
#include "geometry_func.hpp"
#include "math_func.hpp"
#include "../safeguards.h"
/**
* Compute bounding box of both dimensions.
* @param d1 First dimension.
* @param d2 Second dimension.
* @return The bounding box of both dimensions, the smallest dimension that surrounds both arguments.
*/
Dimension maxdim(const Dimension &d1, const Dimension &d2)
{
Dimension d;
d.width = std::max(d1.width, d2.width);
d.height = std::max(d1.height, d2.height);
return d;
}
/**
* Compute the bounding rectangle around two rectangles.
* @param r1 First rectangle.
* @param r2 Second rectangle.
* @return The bounding rectangle, the smallest rectangle that contains both arguments.
*/
Rect BoundingRect(const Rect &r1, const Rect &r2)
{
/* If either the first or the second is empty, return the other. */
if (IsEmptyRect(r1)) return r2;
if (IsEmptyRect(r2)) return r1;
Rect r;
r.top = std::min(r1.top, r2.top);
r.bottom = std::max(r1.bottom, r2.bottom);
r.left = std::min(r1.left, r2.left);
r.right = std::max(r1.right, r2.right);
return r;
}