From a1baaaf2980e1cf285c980dc3ee966d4558969d0 Mon Sep 17 00:00:00 2001 From: Noel Berry Date: Sun, 21 Aug 2022 14:48:46 -0700 Subject: [PATCH] updated to SDL 2.24.0, simplifies Windows High DPI Although it has an issue where the Drawable Size can't really be determined from SDL anymore with D3D11... So now the D3D11 renderer returns it's backbuffer size, until this issue is resolved in SDL / I learn what the correct thing to do is. --- CMakeLists.txt | 2 +- src/app.cpp | 14 ++++++++-- src/internal/platform_sdl2.cpp | 47 ++++++++------------------------- src/internal/renderer.h | 4 +++ src/internal/renderer_d3d11.cpp | 32 +++++++++++++++++----- 5 files changed, 54 insertions(+), 45 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fbcf257..ce2db97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,7 +78,7 @@ if (BLAH_PLATFORM_SDL2) FetchContent_Declare( SDL2 GIT_REPOSITORY https://github.com/libsdl-org/SDL - GIT_TAG release-2.0.20 # grab latest stable release + GIT_TAG release-2.24.0 # grab latest stable release GIT_PROGRESS TRUE ) FetchContent_MakeAvailable(SDL2) diff --git a/src/app.cpp b/src/app.cpp index 5e86512..e5b4120 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -30,6 +30,16 @@ namespace u64 app_time_accumulator = 0; TargetRef app_backbuffer; + void get_drawable_size(int* w, int* h) + { + // Some renderer implementations might return their own size + if (App::Internal::renderer->get_draw_size(w, h)) + return; + + // otherwise fallback to the platform size + App::Internal::platform->get_draw_size(w, h); + } + // A dummy Target that represents the Back Buffer. // It doesn't contain any data, rather it forwards calls along to the actual BackBuffer. class BackBuffer final : public Target @@ -38,8 +48,8 @@ namespace Attachments empty_textures; Attachments& textures() override { BLAH_ASSERT(false, "Backbuffer doesn't have any textures"); return empty_textures; } const Attachments& textures() const override { BLAH_ASSERT(false, "Backbuffer doesn't have any textures"); return empty_textures; } - int width() const override { int w, h; App::Internal::platform->get_draw_size(&w, &h); return w; } - int height() const override { int w, h; App::Internal::platform->get_draw_size(&w, &h); return h; } + int width() const override { int w, h; get_drawable_size(&w, &h); return w; } + int height() const override { int w, h; get_drawable_size(&w, &h); return h; } void clear(Color color, float depth, u8 stencil, ClearMask mask) override { BLAH_ASSERT_RENDERER(); diff --git a/src/internal/platform_sdl2.cpp b/src/internal/platform_sdl2.cpp index d125ea3..56cde6e 100644 --- a/src/internal/platform_sdl2.cpp +++ b/src/internal/platform_sdl2.cpp @@ -2,6 +2,7 @@ #include "platform.h" #include "renderer.h" +#include "internal.h" #include #include #include @@ -17,7 +18,6 @@ #if _WIN32 #define WIN32_LEAN_AND_MEAN #include // for the following includes -#include // for SetProcessDPIAware #include // for ShellExecute for dir_explore #include // for SDL_SysWMinfo for D3D11 #endif @@ -133,12 +133,6 @@ SDL2_Platform::SDL2_Platform() bool SDL2_Platform::init(const Config& config) { - // Required to call this for Windows - // I'm not sure why SDL2 doesn't do this on Windows automatically? -#if _WIN32 - SetProcessDPIAware(); -#endif - // TODO: // control this via some kind of config flag #ifndef __EMSCRIPTEN__ @@ -153,6 +147,10 @@ bool SDL2_Platform::init(const Config& config) SDL_GetVersion(&version); Log::info("SDL v%i.%i.%i", version.major, version.minor, version.patch); + // Make us DPI aware on Windows + SDL_SetHint(SDL_HINT_WINDOWS_DPI_AWARENESS, "permonitorv2"); + SDL_SetHint(SDL_HINT_WINDOWS_DPI_SCALING, "1"); + // initialize SDL if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) != 0) { @@ -168,7 +166,6 @@ bool SDL2_Platform::init(const Config& config) flags |= SDL_WINDOW_OPENGL; #ifdef __EMSCRIPTEN__ - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); #else @@ -195,29 +192,6 @@ bool SDL2_Platform::init(const Config& config) return false; } - // Scale Window to monitor for High DPI displays - // Other platforms do this automatically ... Windows we need to explitely do so -#if _WIN32 - { - // find the display index - int display = SDL_GetWindowDisplayIndex(window); - float ddpi, hdpi, vdpi; - if (SDL_GetDisplayDPI(display, &ddpi, &hdpi, &vdpi) == 0) - { - // scale the window up basesd on the display DPI - float hidpiRes = 96; - float dpi = (ddpi / hidpiRes); - if (dpi != 1) - { - SDL_DisplayMode mode; - SDL_GetDesktopDisplayMode(display, &mode); - SDL_SetWindowPosition(window, (int)(mode.w - config.width * dpi) / 2, (int)(mode.h - config.height * dpi) / 2); - SDL_SetWindowSize(window, (int)(config.width * dpi), (int)(config.height * dpi)); - } - } - } -#endif - // set window properties SDL_SetWindowResizable(window, SDL_TRUE); SDL_SetWindowMinimumSize(window, 256, 256); @@ -531,13 +505,15 @@ void SDL2_Platform::set_size(int width, int height) void SDL2_Platform::get_draw_size(int* width, int* height) { - if (App::renderer().type == RendererType::OpenGL) + switch (App::renderer().type) { + case RendererType::OpenGL: SDL_GL_GetDrawableSize(window, width, height); - } - else - { + break; + case RendererType::None: + case RendererType::D3D11: SDL_GetWindowSize(window, width, height); + break; } } @@ -736,4 +712,3 @@ Platform* Platform::try_make_platform(const Config& config) } #endif // BLAH_PLATFORM_SDL2 - diff --git a/src/internal/renderer.h b/src/internal/renderer.h index ade558b..37e50bf 100644 --- a/src/internal/renderer.h +++ b/src/internal/renderer.h @@ -32,6 +32,10 @@ namespace Blah // Called after renderings ends virtual void after_render() = 0; + // Optional implementation to get the drawable backbuffer size in pixels. + // Not all implementations will use this so it can be up to the Platform. + virtual bool get_draw_size(int* w, int* h) { return false; } + // Performs a draw call virtual void render(const DrawCall& pass) = 0; diff --git a/src/internal/renderer_d3d11.cpp b/src/internal/renderer_d3d11.cpp index b38c122..8434979 100644 --- a/src/internal/renderer_d3d11.cpp +++ b/src/internal/renderer_d3d11.cpp @@ -91,7 +91,8 @@ namespace Blah ID3D11DepthStencilView* backbuffer_depth_view = nullptr; // last backbuffer size - Point last_size; + Point drawable_size; + Point last_window_size; struct StoredInputLayout { @@ -136,6 +137,7 @@ namespace Blah void update() override; void before_render() override; void after_render() override; + bool get_draw_size(int* w, int* h) override; void render(const DrawCall& pass) override; void clear_backbuffer(Color color, float depth, u8 stencil, ClearMask mask) override; TextureRef create_texture(int width, int height, TextureFormat format) override; @@ -763,7 +765,7 @@ namespace Blah bool Renderer_D3D11::init() { - last_size = Point(App::backbuffer()->width(), App::backbuffer()->height()); + last_window_size = App::get_size(); // Define Swap Chain DXGI_SWAP_CHAIN_DESC desc = {}; @@ -808,6 +810,10 @@ namespace Blah swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&frame_buffer); if (frame_buffer) { + D3D11_TEXTURE2D_DESC desc; + frame_buffer->GetDesc(&desc); + drawable_size = Point(desc.Width, desc.Height); + device->CreateRenderTargetView(frame_buffer, nullptr, &backbuffer_view); frame_buffer->Release(); } @@ -886,23 +892,30 @@ namespace Blah { HRESULT hr; - auto next_size = Point(App::backbuffer()->width(), App::backbuffer()->height()); - if (last_size != next_size) + auto next_window_size = App::get_size(); + if (last_window_size != next_window_size) { + last_window_size = next_window_size; + // release old buffer if (backbuffer_view) backbuffer_view->Release(); // perform resize - hr = swap_chain->ResizeBuffers(0, next_size.x, next_size.y, DXGI_FORMAT_B8G8R8A8_UNORM, 0); + hr = swap_chain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0); BLAH_ASSERT(SUCCEEDED(hr), "Failed to update Backbuffer on Resize"); - last_size = next_size; // get the new buffer ID3D11Texture2D* frame_buffer = nullptr; hr = swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&frame_buffer); if (SUCCEEDED(hr) && frame_buffer) { + // get backbuffer drawable size + D3D11_TEXTURE2D_DESC desc; + frame_buffer->GetDesc(&desc); + drawable_size = Point(desc.Width, desc.Height); + + // create view hr = device->CreateRenderTargetView(frame_buffer, nullptr, &backbuffer_view); BLAH_ASSERT(SUCCEEDED(hr), "Failed to update Backbuffer on Resize"); frame_buffer->Release(); @@ -910,6 +923,13 @@ namespace Blah } } + bool Renderer_D3D11::get_draw_size(int* w, int* h) + { + *w = drawable_size.x; + *h = drawable_size.y; + return true; + } + void Renderer_D3D11::after_render() { auto hr = swap_chain->Present(1, 0);