summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Lutz <michi@icosahedron.de>2021-02-21 00:35:35 +0100
committerMichael Lutz <michi@icosahedron.de>2021-02-22 22:16:07 +0100
commit5ad545dcc16a27cdabd8636f4970ee12b9cec54b (patch)
tree561181a7db959808c8f6cb04d49ab9032a175453
parent3a77ade6b25d34890f51931e874fbe0e3b48a744 (diff)
downloadopenttd-5ad545dcc16a27cdabd8636f4970ee12b9cec54b.tar.xz
Codechange: [OpenGL] Only update the dirty parts of the video buffer texture.
-rw-r--r--src/video/opengl.cpp10
-rw-r--r--src/video/opengl.h3
-rw-r--r--src/video/win32_v.cpp16
-rw-r--r--src/video/win32_v.h1
4 files changed, 20 insertions, 10 deletions
diff --git a/src/video/opengl.cpp b/src/video/opengl.cpp
index dbb5ee01a..7fc9c33b0 100644
--- a/src/video/opengl.cpp
+++ b/src/video/opengl.cpp
@@ -24,6 +24,7 @@
#include "opengl.h"
#include "../core/mem_func.hpp"
+#include "../core/geometry_func.hpp"
#include "../gfx_func.h"
#include "../debug.h"
@@ -292,8 +293,9 @@ bool OpenGLBackend::Resize(int w, int h, bool force)
/**
* Render video buffer to the screen.
+ * @param update_rect Rectangle encompassing the dirty region of the video buffer.
*/
-void OpenGLBackend::Paint()
+void OpenGLBackend::Paint(Rect update_rect)
{
assert(this->vid_buffer != nullptr);
@@ -301,8 +303,10 @@ void OpenGLBackend::Paint()
/* Update changed rect of the video buffer texture. */
glBindTexture(GL_TEXTURE_2D, this->vid_texture);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, _screen.pitch);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _screen.width, _screen.height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, this->vid_buffer);
+ if (!IsEmptyRect(update_rect)) {
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, _screen.pitch);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, update_rect.left, update_rect.top, update_rect.right - update_rect.left, update_rect.bottom - update_rect.top, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, (uint32 *)this->vid_buffer + update_rect.top * _screen.pitch + update_rect.left);
+ }
/* Blit video buffer to screen. */
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
diff --git a/src/video/opengl.h b/src/video/opengl.h
index 08ef56b9a..80555ca0b 100644
--- a/src/video/opengl.h
+++ b/src/video/opengl.h
@@ -13,6 +13,7 @@
#define VIDEO_OPENGL_H
#include "../core/alloc_type.hpp"
+#include "../core/geometry_type.hpp"
typedef void (*OGLProc)();
typedef OGLProc (*GetOGLProcAddressProc)(const char *proc);
@@ -42,7 +43,7 @@ public:
static void Destroy();
bool Resize(int w, int h, bool force = false);
- void Paint();
+ void Paint(Rect update_rect);
/**
* Get a pointer to the memory for the video driver to draw to.
diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp
index ddfe365f7..6df1d3528 100644
--- a/src/video/win32_v.cpp
+++ b/src/video/win32_v.cpp
@@ -64,8 +64,6 @@ static std::condition_variable_any *_draw_signal = nullptr;
static volatile bool _draw_continue;
/** Local copy of the palette for use in the drawing thread. */
static Palette _local_palette;
-/** Region of the screen that needs redrawing. */
-static Rect _dirty_rect;
bool VideoDriver_Win32Base::ClaimMousePointer()
{
@@ -886,7 +884,7 @@ void VideoDriver_Win32Base::Stop()
void VideoDriver_Win32Base::MakeDirty(int left, int top, int width, int height)
{
Rect r = {left, top, left + width, top + height};
- _dirty_rect = BoundingRect(_dirty_rect, r);
+ this->dirty_rect = BoundingRect(this->dirty_rect, r);
}
void VideoDriver_Win32Base::CheckPaletteAnim()
@@ -1243,7 +1241,7 @@ void VideoDriver_Win32GDI::Paint()
{
PerformanceMeasurer framerate(PFE_VIDEO);
- if (IsEmptyRect(_dirty_rect)) return;
+ if (IsEmptyRect(this->dirty_rect)) return;
HDC dc = GetDC(this->main_wnd);
HDC dc2 = CreateCompatibleDC(dc);
@@ -1279,7 +1277,7 @@ void VideoDriver_Win32GDI::Paint()
ReleaseDC(this->main_wnd, dc);
- _dirty_rect = {};
+ this->dirty_rect = {};
}
void VideoDriver_Win32GDI::PaintThread()
@@ -1446,6 +1444,8 @@ bool VideoDriver_Win32OpenGL::AllocateBackingStore(int w, int h, bool force)
if (this->gl_rc == nullptr) return false;
+ this->dirty_rect = {};
+
bool res = OpenGLBackend::Get()->Resize(w, h);
_wnd.buffer_bits = OpenGLBackend::Get()->GetVideoBuffer();
return res;
@@ -1455,6 +1455,8 @@ void VideoDriver_Win32OpenGL::Paint()
{
PerformanceMeasurer framerate(PFE_VIDEO);
+ if (IsEmptyRect(this->dirty_rect)) return;
+
if (_cur_palette.count_dirty != 0) {
Blitter *blitter = BlitterFactory::GetCurrentBlitter();
@@ -1473,8 +1475,10 @@ void VideoDriver_Win32OpenGL::Paint()
_cur_palette.count_dirty = 0;
}
- OpenGLBackend::Get()->Paint();
+ OpenGLBackend::Get()->Paint(this->dirty_rect);
SwapBuffers(this->dc);
+
+ this->dirty_rect = {};
}
#endif /* WITH_OPENGL */
diff --git a/src/video/win32_v.h b/src/video/win32_v.h
index 1840bbe86..dd68f968f 100644
--- a/src/video/win32_v.h
+++ b/src/video/win32_v.h
@@ -38,6 +38,7 @@ public:
protected:
HWND main_wnd; ///< Handle to system window.
bool fullscreen; ///< Whether to use (true) fullscreen mode.
+ Rect dirty_rect; ///< Region of the screen that needs redrawing.
Dimension GetScreenSize() const override;
float GetDPIScale() override;