Changeset - r24882:93b227b5ef29
[Not reviewed]
master
0 4 0
Michael Lutz - 4 years ago 2021-02-20 23:35:35
michi@icosahedron.de
Codechange: [OpenGL] Only update the dirty parts of the video buffer texture.
4 files changed with 20 insertions and 10 deletions:
0 comments (0 inline, 0 general)
src/video/opengl.cpp
Show inline comments
 
@@ -21,12 +21,13 @@
 
#	include <GL/gl.h>
 
#endif
 
#include "../3rdparty/opengl/glext.h"
 

	
 
#include "opengl.h"
 
#include "../core/mem_func.hpp"
 
#include "../core/geometry_func.hpp"
 
#include "../gfx_func.h"
 
#include "../debug.h"
 

	
 
#include "../safeguards.h"
 

	
 

	
 
@@ -289,22 +290,25 @@ bool OpenGLBackend::Resize(int w, int h,
 

	
 
	return true;
 
}
 

	
 
/**
 
 * 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);
 

	
 
	glClear(GL_COLOR_BUFFER_BIT);
 

	
 
	/* 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);
 
}
 

	
src/video/opengl.h
Show inline comments
 
@@ -10,12 +10,13 @@
 
/** @file opengl.h OpenGL video driver support. */
 

	
 
#ifndef VIDEO_OPENGL_H
 
#define VIDEO_OPENGL_H
 

	
 
#include "../core/alloc_type.hpp"
 
#include "../core/geometry_type.hpp"
 

	
 
typedef void (*OGLProc)();
 
typedef OGLProc (*GetOGLProcAddressProc)(const char *proc);
 

	
 
bool IsOpenGLVersionAtLeast(byte major, byte minor);
 

	
 
@@ -39,13 +40,13 @@ public:
 
		return OpenGLBackend::instance;
 
	}
 
	static const char *Create(GetOGLProcAddressProc get_proc);
 
	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.
 
	 * @return Pointer to draw on.
 
	 */
 
	void *GetVideoBuffer() { return this->vid_buffer; }
src/video/win32_v.cpp
Show inline comments
 
@@ -61,14 +61,12 @@ static std::recursive_mutex *_draw_mutex
 
/** Signal to draw the next frame. */
 
static std::condition_variable_any *_draw_signal = nullptr;
 
/** Should we keep continue drawing? */
 
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()
 
{
 
	MyShowCursor(false, true);
 
	return true;
 
}
 
@@ -883,13 +881,13 @@ void VideoDriver_Win32Base::Stop()
 
	if (this->fullscreen) ChangeDisplaySettings(nullptr, 0);
 
	MyShowCursor(true);
 
}
 
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()
 
{
 
	if (_cur_palette.count_dirty == 0) return;
 

	
 
@@ -1240,13 +1238,13 @@ void VideoDriver_Win32GDI::PaletteChange
 
}
 

	
 
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);
 

	
 
	HBITMAP old_bmp = (HBITMAP)SelectObject(dc2, this->dib_sect);
 
	HPALETTE old_palette = SelectPalette(dc, this->gdi_palette, FALSE);
 
@@ -1276,13 +1274,13 @@ void VideoDriver_Win32GDI::Paint()
 
	SelectPalette(dc, old_palette, TRUE);
 
	SelectObject(dc2, old_bmp);
 
	DeleteDC(dc2);
 

	
 
	ReleaseDC(this->main_wnd, dc);
 

	
 
	_dirty_rect = {};
 
	this->dirty_rect = {};
 
}
 

	
 
void VideoDriver_Win32GDI::PaintThread()
 
{
 
	/* First tell the main thread we're started */
 
	std::unique_lock<std::recursive_mutex> lock(*_draw_mutex);
 
@@ -1443,21 +1441,25 @@ bool VideoDriver_Win32OpenGL::AllocateBa
 

	
 
	_wnd.width = w = std::max(w, 64);
 
	_wnd.height = h = std::max(h, 64);
 

	
 
	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;
 
}
 

	
 
void VideoDriver_Win32OpenGL::Paint()
 
{
 
	PerformanceMeasurer framerate(PFE_VIDEO);
 

	
 
	if (IsEmptyRect(this->dirty_rect)) return;
 

	
 
	if (_cur_palette.count_dirty != 0) {
 
		Blitter *blitter = BlitterFactory::GetCurrentBlitter();
 

	
 
		switch (blitter->UsePaletteAnimation()) {
 
			case Blitter::PALETTE_ANIMATION_BLITTER:
 
				blitter->PaletteAnimate(_local_palette);
 
@@ -1470,11 +1472,13 @@ void VideoDriver_Win32OpenGL::Paint()
 
			default:
 
				NOT_REACHED();
 
		}
 
		_cur_palette.count_dirty = 0;
 
	}
 

	
 
	OpenGLBackend::Get()->Paint();
 
	OpenGLBackend::Get()->Paint(this->dirty_rect);
 
	SwapBuffers(this->dc);
 

	
 
	this->dirty_rect = {};
 
}
 

	
 
#endif /* WITH_OPENGL */
src/video/win32_v.h
Show inline comments
 
@@ -35,12 +35,13 @@ public:
 

	
 
	void EditBoxLostFocus() override;
 

	
 
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;
 
	void InputLoop() override;
 
	bool LockVideoBuffer() override;
 
	void UnlockVideoBuffer() override;
0 comments (0 inline, 0 general)