test if renderer re-initialization is really necessary

This commit is contained in:
Louis Kruger 2019-10-15 16:18:38 -04:00
parent 6b64d92837
commit f4a7757fd0
3 changed files with 47 additions and 3 deletions

View file

@ -146,8 +146,10 @@ handle_event(SDL_Event *event, bool control) {
switch (event->window.event) {
case SDL_WINDOWEVENT_SIZE_CHANGED:
#ifdef HIDPI_SUPPORT
LOGD("Reinitializing renderer");
screen_init_renderer_and_texture(&screen);
if (!screen_test_correct_hidpi_ratio(&screen)) {
LOGW("Reinitializing renderer due to incorrect hidpi ratio");
screen_init_renderer_and_texture(&screen);
}
#endif
// fall-through no break
case SDL_WINDOWEVENT_EXPOSED:

View file

@ -47,7 +47,10 @@ set_window_size(struct screen *screen, struct size new_size) {
} else {
SDL_SetWindowSize(screen->window, new_size.width, new_size.height);
#ifdef HIDPI_SUPPORT
screen_init_renderer_and_texture(screen);
if (!screen_test_correct_hidpi_ratio(screen)) {
LOGW("Reinitializing renderer due to incorrect hidpi ratio");
screen_init_renderer_and_texture(screen);
}
#endif
}
}
@ -164,6 +167,14 @@ screen_init_renderer_and_texture(struct screen *screen) {
return false;
}
#ifdef HIDPI_SUPPORT
int window_w, window_h, renderer_w, renderer_h;
SDL_GetWindowSize(screen->window, &window_w, &window_h);
SDL_GetRendererOutputSize(screen->renderer, &renderer_w, &renderer_h);
screen->expected_hidpi_w_factor = renderer_w * 1000 / window_w;
screen->expected_hidpi_h_factor = renderer_h * 1000 / window_h;
#endif
screen->texture = create_texture(screen->renderer, screen->frame_size);
if (!screen->texture) {
LOGC("Could not create texture: %s", SDL_GetError());
@ -214,6 +225,19 @@ screen_init_rendering(struct screen *screen, const char *window_title,
return screen_init_renderer_and_texture(screen);
}
#ifdef HIDPI_SUPPORT
bool
screen_test_correct_hidpi_ratio(struct screen *screen) {
int window_w, window_h, renderer_w, renderer_h;
SDL_GetWindowSize(screen->window, &window_w, &window_h);
SDL_GetRendererOutputSize(screen->renderer, &renderer_w, &renderer_h);
int current_hidpi_w_factor = renderer_w * 1000 / window_w;
int current_hidpi_h_factor = renderer_h * 1000 / window_h;
return current_hidpi_w_factor == screen->expected_hidpi_w_factor &&
current_hidpi_h_factor == screen->expected_hidpi_h_factor;
}
#endif
void
screen_show_window(struct screen *screen) {
SDL_ShowWindow(screen->window);

View file

@ -20,6 +20,15 @@ struct screen {
bool has_frame;
bool fullscreen;
bool no_window;
#ifdef HIDPI_SUPPORT
// these values store the ratio between renderer pixel size and window size
// in most configurations these ratios would be 1.0 (1000), but on MacOS with
// a Retina/HIDPI monitor connected they are 2.0 (2000) because that's how
// Apple chose to maintain compatibility with legacy apps, by pretending that
// that the screen has half of its real resolution.
int expected_hidpi_w_factor; // multiplied by 1000 to avoid float
int expected_hidpi_h_factor; // multiplied by 1000 to avoid float
#endif
};
#define SCREEN_INITIALIZER { \
@ -48,6 +57,15 @@ bool
screen_init_rendering(struct screen *screen, const char *window_title,
struct size frame_size, bool always_on_top);
#ifdef HIDPI_SUPPORT
// test if the expected renderer to window ratio is correct
// used to work around SDL bugs
// returns true if correct.
// If it returns false the renderer state needs to be fixed
bool
screen_test_correct_hidpi_ratio(struct screen *screen);
#endif
// reinitialize the renderer (only used in some configurations
// if necessary to workaround SDL bugs)
bool