mirror of
https://github.com/libretro/ppsspp.git
synced 2025-01-31 13:52:21 +00:00
Windows: Pause the rendering thread while switching to full screen
This commit is contained in:
parent
5f18390c04
commit
1410d7f6d5
@ -300,7 +300,12 @@ namespace MainWindow
|
||||
|
||||
void ToggleFullscreen(HWND hWnd, bool goingFullscreen) {
|
||||
// Make sure no rendering is happening during the switch.
|
||||
Core_NotifyWindowHidden(true);
|
||||
|
||||
bool isOpenGL = g_Config.iGPUBackend == GPU_BACKEND_OPENGL;
|
||||
|
||||
if (isOpenGL) {
|
||||
GL_Pause();
|
||||
}
|
||||
|
||||
int oldWindowState = g_WindowState;
|
||||
g_IgnoreWM_SIZE = true;
|
||||
@ -361,8 +366,11 @@ namespace MainWindow
|
||||
ShowOwnedPopups(hwndMain, goingFullscreen ? FALSE : TRUE);
|
||||
W32Util::MakeTopMost(hwndMain, g_Config.bTopMost);
|
||||
|
||||
Core_NotifyWindowHidden(false);
|
||||
WindowsRawInput::NotifyMenu();
|
||||
|
||||
if (isOpenGL) {
|
||||
GL_Resume();
|
||||
}
|
||||
}
|
||||
|
||||
RECT DetermineWindowRectangle() {
|
||||
|
@ -33,6 +33,10 @@
|
||||
static HDC hDC; // Private GDI Device Context
|
||||
static HGLRC hRC; // Permanent Rendering Context
|
||||
static HWND hWnd; // Holds Our Window Handle
|
||||
static volatile bool pauseRequested;
|
||||
static volatile bool resumeRequested;
|
||||
static HANDLE pauseEvent;
|
||||
static HANDLE resumeEvent;
|
||||
|
||||
static int xres, yres;
|
||||
|
||||
@ -42,11 +46,47 @@ static bool enableGLDebug = false;
|
||||
void GL_SwapBuffers() {
|
||||
SwapBuffers(hDC);
|
||||
|
||||
if (pauseRequested) {
|
||||
SetEvent(pauseEvent);
|
||||
resumeRequested = true;
|
||||
DWORD result = WaitForSingleObject(resumeEvent, INFINITE);
|
||||
if (result == WAIT_TIMEOUT) {
|
||||
ERROR_LOG(G3D, "Wait for resume timed out. Resuming rendering");
|
||||
}
|
||||
pauseRequested = false;
|
||||
}
|
||||
|
||||
// According to some sources, doing this *after* swapbuffers can reduce frame latency
|
||||
// at a large performance cost.
|
||||
// at a large performance cost. So let's not.
|
||||
// glFinish();
|
||||
}
|
||||
|
||||
void GL_Pause() {
|
||||
if (!hRC) {
|
||||
return;
|
||||
}
|
||||
|
||||
pauseRequested = true;
|
||||
DWORD result = WaitForSingleObject(pauseEvent, INFINITE);
|
||||
if (result == WAIT_TIMEOUT) {
|
||||
ERROR_LOG(G3D, "Wait for pause timed out");
|
||||
}
|
||||
// OK, we now know the rendering thread is paused.
|
||||
}
|
||||
|
||||
void GL_Resume() {
|
||||
if (!hRC) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!resumeRequested) {
|
||||
ERROR_LOG(G3D, "Not waiting to get resumed");
|
||||
} else {
|
||||
SetEvent(resumeEvent);
|
||||
}
|
||||
resumeRequested = false;
|
||||
}
|
||||
|
||||
void FormatDebugOutputARB(char outStr[], size_t outStrSize, GLenum source, GLenum type,
|
||||
GLuint id, GLenum severity, const char *msg) {
|
||||
char sourceStr[32];
|
||||
@ -270,6 +310,14 @@ bool GL_Init(HWND window, std::string *error_message) {
|
||||
glDebugMessageCallbackARB((GLDEBUGPROCARB)&DebugCallbackARB, 0); // print debug output to stderr
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
|
||||
}
|
||||
|
||||
pauseRequested = false;
|
||||
resumeRequested = false;
|
||||
|
||||
// These are auto-reset events.
|
||||
pauseEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
resumeEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
|
||||
return true; // Success
|
||||
}
|
||||
|
||||
@ -280,6 +328,8 @@ void GL_SwapInterval(int interval) {
|
||||
}
|
||||
|
||||
void GL_Shutdown() {
|
||||
CloseHandle(pauseEvent);
|
||||
CloseHandle(resumeEvent);
|
||||
if (hRC) {
|
||||
// Are we able to release the DC and RC contexts?
|
||||
if (!wglMakeCurrent(NULL,NULL)) {
|
||||
|
@ -6,3 +6,8 @@ bool GL_Init(HWND window, std::string *error_message);
|
||||
void GL_Shutdown();
|
||||
void GL_SwapInterval(int interval);
|
||||
void GL_SwapBuffers();
|
||||
|
||||
// Used during window resize. Must be called from the window thread,
|
||||
// not the rendering thread or CPU thread.
|
||||
void GL_Pause();
|
||||
void GL_Resume();
|
Loading…
x
Reference in New Issue
Block a user