Changeset - r24890:b3530a2e5759
[Not reviewed]
master
0 2 0
Michael Lutz - 4 years ago 2021-01-16 15:43:18
michi@icosahedron.de
Change: [Win32] Disable VSync for OpenGL by default.
2 files changed with 13 insertions and 0 deletions:
0 comments (0 inline, 0 general)
src/video/win32_v.cpp
Show inline comments
 
@@ -1307,48 +1307,49 @@ void VideoDriver_Win32GDI::PaintThread()
 
	VideoDriver_Win32GDI *drv = static_cast<VideoDriver_Win32GDI *>(VideoDriver::GetInstance());
 

	
 
	_screen.dst_ptr = drv->GetVideoPointer();
 
	UpdateWindows();
 

	
 
	drv->Paint();
 
	GdiFlush();
 

	
 
	return _fooctr++;
 
}
 
#endif
 

	
 
#ifdef WITH_OPENGL
 

	
 
#include <GL/gl.h>
 
#include "../3rdparty/opengl/glext.h"
 
#include "../3rdparty/opengl/wglext.h"
 
#include "opengl.h"
 

	
 
#ifndef PFD_SUPPORT_COMPOSITION
 
#	define PFD_SUPPORT_COMPOSITION 0x00008000
 
#endif
 

	
 
static PFNWGLCREATECONTEXTATTRIBSARBPROC _wglCreateContextAttribsARB = nullptr;
 
static PFNWGLSWAPINTERVALEXTPROC _wglSwapIntervalEXT = nullptr;
 
static bool _hasWGLARBCreateContextProfile = false; ///< Is WGL_ARB_create_context_profile supported?
 

	
 
/** Platform-specific callback to get an OpenGL funtion pointer. */
 
static OGLProc GetOGLProcAddressCallback(const char *proc)
 
{
 
	return reinterpret_cast<OGLProc>(wglGetProcAddress(proc));
 
}
 

	
 
/**
 
 * Set the pixel format of a window-
 
 * @param dc Device context to set the pixel format of.
 
 * @param fullscreen Should the pixel format be used for fullscreen drawing?
 
 * @return nullptr on success, error message otherwise.
 
 */
 
static const char *SelectPixelFormat(HDC dc, bool fullscreen)
 
{
 
	PIXELFORMATDESCRIPTOR pfd = {
 
		sizeof(PIXELFORMATDESCRIPTOR), // Size of this struct.
 
		1,                             // Version of this struct.
 
		PFD_DRAW_TO_WINDOW |           // Require window support.
 
		PFD_SUPPORT_OPENGL |           // Require OpenGL support.
 
		PFD_DOUBLEBUFFER   |           // Use double buffering.
 
		PFD_DEPTH_DONTCARE,
 
		PFD_TYPE_RGBA,                 // Request RGBA format.
 
@@ -1377,66 +1378,70 @@ static void LoadWGLExtensions()
 
	/* Querying the supported WGL extensions and loading the matching
 
	 * functions requires a valid context, even for the extensions
 
	 * regarding context creation. To get around this, we create
 
	 * a dummy window with a dummy context. The extension functions
 
	 * remain valid even after this context is destroyed. */
 
	HWND wnd = CreateWindow(_T("STATIC"), _T("dummy"), WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, nullptr, nullptr, GetModuleHandle(nullptr), nullptr);
 
	HDC dc = GetDC(wnd);
 

	
 
	/* Set pixel format of the window. */
 
	if (SelectPixelFormat(dc, false) == nullptr) {
 
		/* Create rendering context. */
 
		HGLRC rc = wglCreateContext(dc);
 
		if (rc != nullptr) {
 
			wglMakeCurrent(dc, rc);
 

	
 
			/* Get list of WGL extensions. */
 
			PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
 
			if (wglGetExtensionsStringARB != nullptr) {
 
				const char *wgl_exts = wglGetExtensionsStringARB(dc);
 
				/* Bind supported functions. */
 
				if (FindStringInExtensionList(wgl_exts, "WGL_ARB_create_context") != nullptr) {
 
					_wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
 
				}
 
				_hasWGLARBCreateContextProfile = FindStringInExtensionList(wgl_exts, "WGL_ARB_create_context_profile") != nullptr;
 
				if (FindStringInExtensionList(wgl_exts, "WGL_EXT_swap_control") != nullptr) {
 
					_wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
 
				}
 
			}
 

	
 
			wglMakeCurrent(nullptr, nullptr);
 
			wglDeleteContext(rc);
 
		}
 
	}
 

	
 
	ReleaseDC(wnd, dc);
 
	DestroyWindow(wnd);
 
}
 

	
 
static FVideoDriver_Win32OpenGL iFVideoDriver_Win32OpenGL;
 

	
 
const char *VideoDriver_Win32OpenGL::Start(const StringList &param)
 
{
 
	if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 32) return "Only 32bpp blitters supported";
 

	
 
	Dimension old_res = _cur_resolution; // Save current screen resolution in case of errors, as MakeWindow invalidates it.
 
	this->vsync = GetDriverParamBool(param, "vsync");
 

	
 
	LoadWGLExtensions();
 

	
 
	this->Initialize();
 
	this->MakeWindow(_fullscreen);
 

	
 
	/* Create and initialize OpenGL context. */
 
	const char *err = this->AllocateContext();
 
	if (err != nullptr) {
 
		this->Stop();
 
		_cur_resolution = old_res;
 
		return err;
 
	}
 

	
 
	this->ClientSizeChanged(this->width, this->height, true);
 

	
 
	this->draw_threaded = false;
 
	MarkWholeScreenDirty();
 

	
 
	return nullptr;
 
}
 

	
 
void VideoDriver_Win32OpenGL::Stop()
 
{
 
@@ -1466,48 +1471,55 @@ const char *VideoDriver_Win32OpenGL::All
 
	const char *err = SelectPixelFormat(this->dc, this->fullscreen);
 
	if (err != nullptr) return err;
 

	
 
	HGLRC rc = nullptr;
 

	
 
	/* Create OpenGL device context. Try to get an 3.2+ context if possible. */
 
	if (_wglCreateContextAttribsARB != nullptr) {
 
		int attribs[] = {
 
			WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
 
			WGL_CONTEXT_MINOR_VERSION_ARB, 2,
 
			WGL_CONTEXT_FLAGS_ARB, _debug_driver_level >= 8 ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
 
			_hasWGLARBCreateContextProfile ? WGL_CONTEXT_PROFILE_MASK_ARB : 0, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, // Terminate list if WGL_ARB_create_context_profile isn't supported.
 
			0
 
		};
 
		rc = _wglCreateContextAttribsARB(this->dc, nullptr, attribs);
 
	}
 

	
 
	if (rc == nullptr) {
 
		/* Old OpenGL or old driver, let's hope for the best. */
 
		rc = wglCreateContext(this->dc);
 
		if (rc == nullptr) return "Can't create OpenGL context";
 
	}
 
	if (!wglMakeCurrent(this->dc, rc)) return "Can't active GL context";
 

	
 
	/* Enable/disable Vsync if supported. */
 
	if (_wglSwapIntervalEXT != nullptr) {
 
		_wglSwapIntervalEXT(this->vsync ? 1 : 0);
 
	} else if (vsync) {
 
		DEBUG(driver, 0, "OpenGL: Vsync requested, but not supported by driver");
 
	}
 

	
 
	this->gl_rc = rc;
 
	return OpenGLBackend::Create(&GetOGLProcAddressCallback);
 
}
 

	
 
bool VideoDriver_Win32OpenGL::ToggleFullscreen(bool full_screen)
 
{
 
	if (_screen.dst_ptr != nullptr) this->ReleaseVideoPointer();
 
	this->DestroyContext();
 
	bool res = this->VideoDriver_Win32Base::ToggleFullscreen(full_screen);
 
	res &= this->AllocateContext() == nullptr;
 
	this->ClientSizeChanged(this->width, this->height, true);
 
	return res;
 
}
 

	
 
bool VideoDriver_Win32OpenGL::AfterBlitterChange()
 
{
 
	assert(BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 0);
 
	this->ClientSizeChanged(this->width, this->height, true);
 
	return true;
 
}
 

	
 
bool VideoDriver_Win32OpenGL::AllocateBackingStore(int w, int h, bool force)
 
{
 
	if (!force && w == _screen.width && h == _screen.height) return false;
src/video/win32_v.h
Show inline comments
 
@@ -122,48 +122,49 @@ public:
 
	FVideoDriver_Win32GDI() : DriverFactoryBase(Driver::DT_VIDEO, 10, "win32", "Win32 GDI Video Driver") {}
 
	Driver *CreateInstance() const override { return new VideoDriver_Win32GDI(); }
 
};
 

	
 
#ifdef WITH_OPENGL
 

	
 
/** The OpenGL video driver for windows. */
 
class VideoDriver_Win32OpenGL : public VideoDriver_Win32Base {
 
public:
 
	VideoDriver_Win32OpenGL() : dc(nullptr), gl_rc(nullptr) {}
 

	
 
	const char *Start(const StringList &param) override;
 

	
 
	void Stop() override;
 

	
 
	bool ToggleFullscreen(bool fullscreen) override;
 

	
 
	bool AfterBlitterChange() override;
 

	
 
	const char *GetName() const override { return "win32-opengl"; }
 

	
 
protected:
 
	HDC   dc;          ///< Window device context.
 
	HGLRC gl_rc;       ///< OpenGL context.
 
	bool  vsync;       ///< Enable VSync?
 

	
 
	uint8 GetFullscreenBpp() override { return 32; } // OpenGL is always 32 bpp.
 

	
 
	void Paint() override;
 
	void PaintThread() override {}
 

	
 
	bool AllocateBackingStore(int w, int h, bool force = false) override;
 
	void *GetVideoPointer() override;
 
	void ReleaseVideoPointer() override;
 
	void PaletteChanged(HWND hWnd) override {}
 

	
 
	const char *AllocateContext();
 
	void DestroyContext();
 
};
 

	
 
/** The factory for Windows' OpenGL video driver. */
 
class FVideoDriver_Win32OpenGL : public DriverFactoryBase {
 
public:
 
	FVideoDriver_Win32OpenGL() : DriverFactoryBase(Driver::DT_VIDEO, 9, "win32-opengl", "Win32 OpenGL Video Driver") {}
 
	/* virtual */ Driver *CreateInstance() const override { return new VideoDriver_Win32OpenGL(); }
 
};
 

	
 
#endif /* WITH_OPENGL */
 

	
0 comments (0 inline, 0 general)