From cb8163081685fd97deba3c800bb8f10841b555a1 Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Fri, 8 Apr 2022 02:21:52 -0400 Subject: [PATCH] render: Update the size/scale/viewport on moves, in addition to resizes. For OpenGL this means resetting the viewport state shadowing flag too. Fixes #1504 --- src/render/SDL_render.c | 12 +++++++++++- src/render/opengl/SDL_render_gl.c | 22 +++++++++++++++------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 471e8c050..9bb953edd 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -698,7 +698,17 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) renderer->WindowEvent(renderer, &event->window); } - if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { + /* In addition to size changes, we also want to do this block for + * moves as well, for two reasons: + * + * 1. The window could be moved to a new display, which has a new + * DPI and therefore a new window/drawable ratio + * 2. For whatever reason, the viewport can get messed up during + * window movement (this has been observed on macOS), so this is + * also a good opportunity to force viewport updates + */ + if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED || + event->window.event == SDL_WINDOWEVENT_MOVED) { /* Make sure we're operating on the default render target */ SDL_Texture *saved_target = SDL_GetRenderTarget(renderer); if (saved_target) { diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c index e7c5169eb..a0ff1e272 100644 --- a/src/render/opengl/SDL_render_gl.c +++ b/src/render/opengl/SDL_render_gl.c @@ -324,6 +324,20 @@ GL_GetFBO(GL_RenderData *data, Uint32 w, Uint32 h) return result; } +static void +GL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) +{ + /* If the window x/y/w/h changed at all, assume the viewport has been + * changed behind our backs. x/y changes might seem weird but viewport + * resets have been observed on macOS at minimum! + */ + if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED || + event->event == SDL_WINDOWEVENT_MOVED) { + GL_RenderData *data = (GL_RenderData *) renderer->driverdata; + data->drawstate.viewport_dirty = SDL_TRUE; + } +} + static int GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) { @@ -1216,13 +1230,6 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic } } -#ifdef __MACOSX__ - // On macOS, moving the window seems to invalidate the OpenGL viewport state, - // so don't bother trying to persist it across frames; always reset it. - // Workaround for: https://github.com/libsdl-org/SDL/issues/1504 - data->drawstate.viewport_dirty = SDL_TRUE; -#endif - while (cmd) { switch (cmd->command) { case SDL_RENDERCMD_SETDRAWCOLOR: { @@ -1767,6 +1774,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) goto error; } + renderer->WindowEvent = GL_WindowEvent; renderer->GetOutputSize = GL_GetOutputSize; renderer->SupportsBlendMode = GL_SupportsBlendMode; renderer->CreateTexture = GL_CreateTexture;