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.
This commit is contained in:
Noel Berry 2022-08-21 14:48:46 -07:00
parent 1ef5a9c6ad
commit a1baaaf298
5 changed files with 54 additions and 45 deletions

View File

@ -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)

View File

@ -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();

View File

@ -2,6 +2,7 @@
#include "platform.h"
#include "renderer.h"
#include "internal.h"
#include <blah/input.h>
#include <blah/app.h>
#include <blah/filesystem.h>
@ -17,7 +18,6 @@
#if _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h> // for the following includes
#include <winuser.h> // for SetProcessDPIAware
#include <shellapi.h> // for ShellExecute for dir_explore
#include <SDL_syswm.h> // 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

View File

@ -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;

View File

@ -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);