summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/geometry_func.cpp22
-rw-r--r--src/core/geometry_func.hpp12
-rw-r--r--src/video/sdl2_v.cpp38
3 files changed, 46 insertions, 26 deletions
diff --git a/src/core/geometry_func.cpp b/src/core/geometry_func.cpp
index 89e70fb5b..dccef72ec 100644
--- a/src/core/geometry_func.cpp
+++ b/src/core/geometry_func.cpp
@@ -26,3 +26,25 @@ Dimension maxdim(const Dimension &d1, const Dimension &d2)
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;
+}
diff --git a/src/core/geometry_func.hpp b/src/core/geometry_func.hpp
index cd136488a..41df35945 100644
--- a/src/core/geometry_func.hpp
+++ b/src/core/geometry_func.hpp
@@ -14,4 +14,16 @@
Dimension maxdim(const Dimension &d1, const Dimension &d2);
+/**
+ * Check if a rectangle is empty.
+ * @param r Rectangle to check.
+ * @return True if and only if the rectangle doesn't define space.
+ */
+static inline bool IsEmptyRect(const Rect &r)
+{
+ return (r.left | r.top | r.right | r.bottom) == 0;
+}
+
+Rect BoundingRect(const Rect &r1, const Rect &r2);
+
#endif /* GEOMETRY_FUNC_HPP */
diff --git a/src/video/sdl2_v.cpp b/src/video/sdl2_v.cpp
index ce6bbc93f..d41f79d54 100644
--- a/src/video/sdl2_v.cpp
+++ b/src/video/sdl2_v.cpp
@@ -17,6 +17,8 @@
#include "../progress.h"
#include "../core/random_func.hpp"
#include "../core/math_func.hpp"
+#include "../core/mem_func.hpp"
+#include "../core/geometry_func.hpp"
#include "../fileio_func.h"
#include "../framerate_type.h"
#include "../window_func.h"
@@ -54,19 +56,12 @@ static SDL_Palette *_sdl_palette;
static bool _cursor_new_in_window = false;
#endif
-#define MAX_DIRTY_RECTS 100
-static SDL_Rect _dirty_rects[MAX_DIRTY_RECTS];
-static int _num_dirty_rects;
+static Rect _dirty_rect;
void VideoDriver_SDL::MakeDirty(int left, int top, int width, int height)
{
- if (_num_dirty_rects < MAX_DIRTY_RECTS) {
- _dirty_rects[_num_dirty_rects].x = left;
- _dirty_rects[_num_dirty_rects].y = top;
- _dirty_rects[_num_dirty_rects].w = width;
- _dirty_rects[_num_dirty_rects].h = height;
- }
- _num_dirty_rects++;
+ Rect r = {left, top, left + width, top + height};
+ _dirty_rect = BoundingRect(_dirty_rect, r);
}
static void UpdatePalette()
@@ -133,7 +128,7 @@ static void Paint()
{
PerformanceMeasurer framerate(PFE_VIDEO);
- if (_num_dirty_rects == 0) return;
+ if (IsEmptyRect(_dirty_rect) && _cur_palette.count_dirty == 0) return;
if (_cur_palette.count_dirty != 0) {
Blitter *blitter = BlitterFactory::GetCurrentBlitter();
@@ -156,23 +151,14 @@ static void Paint()
_cur_palette.count_dirty = 0;
}
- if (_num_dirty_rects > MAX_DIRTY_RECTS) {
- if (_sdl_surface != _sdl_real_surface) {
- SDL_BlitSurface(_sdl_surface, nullptr, _sdl_real_surface, nullptr);
- }
+ SDL_Rect r = { _dirty_rect.left, _dirty_rect.top, _dirty_rect.right - _dirty_rect.left, _dirty_rect.bottom - _dirty_rect.top };
- SDL_UpdateWindowSurface(_sdl_window);
- } else {
- if (_sdl_surface != _sdl_real_surface) {
- for (int i = 0; i < _num_dirty_rects; i++) {
- SDL_BlitSurface(_sdl_surface, &_dirty_rects[i], _sdl_real_surface, &_dirty_rects[i]);
- }
- }
-
- SDL_UpdateWindowSurfaceRects(_sdl_window, _dirty_rects, _num_dirty_rects);
+ if (_sdl_surface != _sdl_real_surface) {
+ SDL_BlitSurface(_sdl_surface, &r, _sdl_real_surface, &r);
}
+ SDL_UpdateWindowSurfaceRects(_sdl_window, &r, 1);
- _num_dirty_rects = 0;
+ MemSetT(&_dirty_rect, 0);
}
static void PaintThread()
@@ -356,7 +342,7 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h, bool resize)
* gotten smaller, reset our dirty rects. GameSizeChanged() a bit lower
* will mark the whole screen dirty again anyway, but this time with the
* new dimensions. */
- _num_dirty_rects = 0;
+ MemSetT(&_dirty_rect, 0);
_screen.width = _sdl_surface->w;
_screen.height = _sdl_surface->h;