From db9ee23a86766d48e65d5f2df96801829b50d7dd Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 28 Nov 2021 21:58:48 +1100 Subject: [PATCH] OpenGL: Go into reduced performance mode when window is obscured --- src/Window.h | 3 +++ src/Window_Android.c | 2 ++ src/Window_Carbon.c | 2 ++ src/Window_SDL.c | 2 ++ src/Window_Web.c | 2 ++ src/Window_Win.c | 2 ++ src/Window_X11.c | 2 ++ src/_GLShared.h | 10 +++++++++- src/interop_cocoa.m | 2 ++ src/interop_ios.m | 1 + 10 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/Window.h b/src/Window.h index 480ebd870..b8bfef7f3 100644 --- a/src/Window.h +++ b/src/Window.h @@ -103,6 +103,9 @@ int Window_GetWindowState(void); cc_result Window_EnterFullscreen(void); /* Attempts to restore the window to before it entered full screen. */ cc_result Window_ExitFullscreen(void); +/* Returns non-zero if the window is obscured (occluded or minimised) */ +/* NOTE: Not supported by all windowing backends */ +int Window_IsObscured(void); /* Makes the window visible and focussed on screen. */ void Window_Show(void); diff --git a/src/Window_Android.c b/src/Window_Android.c index a0435b1c9..04b21f3d9 100644 --- a/src/Window_Android.c +++ b/src/Window_Android.c @@ -322,6 +322,8 @@ cc_result Window_ExitFullscreen(void) { return 0; } +int Window_IsObscured(void) { return 0; } + void Window_Show(void) { } /* Window already visible */ void Window_SetSize(int width, int height) { } diff --git a/src/Window_Carbon.c b/src/Window_Carbon.c index 34c09d6da..47f5bf93e 100644 --- a/src/Window_Carbon.c +++ b/src/Window_Carbon.c @@ -543,6 +543,8 @@ cc_result Window_ExitFullscreen(void) { return res; } +int Window_IsObscured(void) { return 0; } + void Window_Show(void) { ShowWindow(win_handle); /* TODO: Do we actually need to reposition */ diff --git a/src/Window_SDL.c b/src/Window_SDL.c index d4193ea3c..720415ee8 100644 --- a/src/Window_SDL.c +++ b/src/Window_SDL.c @@ -83,6 +83,8 @@ cc_result Window_EnterFullscreen(void) { } cc_result Window_ExitFullscreen(void) { SDL_RestoreWindow(win_handle); return 0; } +int Window_IsObscured(void) { return 0; } + void Window_Show(void) { SDL_ShowWindow(win_handle); } void Window_SetSize(int width, int height) { diff --git a/src/Window_Web.c b/src/Window_Web.c index 22e351d22..7eb14d503 100644 --- a/src/Window_Web.c +++ b/src/Window_Web.c @@ -466,6 +466,8 @@ cc_result Window_ExitFullscreen(void) { return 0; } +int Window_IsObscured(void) { return 0; } + void Window_Show(void) { } void Window_SetSize(int width, int height) { diff --git a/src/Window_Win.c b/src/Window_Win.c index 040370bdb..2c4792850 100644 --- a/src/Window_Win.c +++ b/src/Window_Win.c @@ -447,6 +447,8 @@ cc_result Window_ExitFullscreen(void) { return 0; } +int Window_IsObscured(void) { return 0; } + void Window_Show(void) { ShowWindow(win_handle, SW_SHOW); BringWindowToTop(win_handle); diff --git a/src/Window_X11.c b/src/Window_X11.c index fd206188c..234d2f848 100644 --- a/src/Window_X11.c +++ b/src/Window_X11.c @@ -433,6 +433,8 @@ cc_result Window_ExitFullscreen(void) { ToggleFullscreen(_NET_WM_STATE_REMOVE); return 0; } +int Window_IsObscured(void) { return 0; } + void Window_Show(void) { XMapWindow(win_display, win_handle); } void Window_SetSize(int width, int height) { diff --git a/src/_GLShared.h b/src/_GLShared.h index 293bb5d82..231744a60 100644 --- a/src/_GLShared.h +++ b/src/_GLShared.h @@ -275,7 +275,15 @@ void Gfx_SetFpsLimit(cc_bool vsync, float minFrameMs) { void Gfx_BeginFrame(void) { frameStart = Stopwatch_Measure(); } void Gfx_Clear(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } -void Gfx_EndFrame(void) { +void Gfx_EndFrame(void) { +#ifndef CC_BUILD_GLMODERN + if (Window_IsObscured()) { + TickReducedPerformance(); + } else { + EndReducedPerformance(); + } +#endif + if (!GLContext_SwapBuffers()) Gfx_LoseContext("GLContext lost"); if (gfx_minFrameMs) LimitFPS(); } diff --git a/src/interop_cocoa.m b/src/interop_cocoa.m index 98737939f..6e24efd73 100644 --- a/src/interop_cocoa.m +++ b/src/interop_cocoa.m @@ -323,6 +323,8 @@ cc_result Window_ExitFullscreen(void) { return 0; } +int Window_IsObscured(void) { return 0; } + void Window_Show(void) { [winHandle makeKeyAndOrderFront:appHandle]; RefreshWindowBounds(); // TODO: even necessary? diff --git a/src/interop_ios.m b/src/interop_ios.m index 254437453..4646c6351 100644 --- a/src/interop_ios.m +++ b/src/interop_ios.m @@ -248,6 +248,7 @@ void Window_CloseKeyboard(void) { int Window_GetWindowState(void) { return WINDOW_STATE_NORMAL; } cc_result Window_EnterFullscreen(void) { return ERR_NOT_SUPPORTED; } cc_result Window_ExitFullscreen(void) { return ERR_NOT_SUPPORTED; } +int Window_IsObscured(void) { return 0; } void Window_EnableRawMouse(void) { } void Window_UpdateRawMouse(void) { }