Skip to content

Commit

Permalink
Fix renderer creation for HW display engine (OpenRCT2#22445)
Browse files Browse the repository at this point in the history
SDL requires a renderer to be created in an empty window, i.e. one
without any other renderer nor surface. Leaving the window with earlier
surface from another engine (e.g. when switching from SW to SW+HWD)
caused no renderer to be created (_sdlRenderer set to nullptr) and
setting up a bomb to explode next time we try to render a frame.

I think this can also get triggered when resizing/switching the focus of
a window.

While SDL already has internal checks for window surface presence in
`SDL_DestroyWindowSurface` _in the SDL version I checked_, I have no
certainty if this is correct for all of them. I added check for window
surface presence to better express the code intent as well.

`SDL_DestroyWindowSurface` was introduced in SDL 2.28

This should take care of most of the `BlitPixel`, `DrawRLESpriteMinify`
issues reported by backtrace.
  • Loading branch information
janisozaur authored Aug 1, 2024
1 parent b0fbd5e commit b1e14c6
Showing 2 changed files with 10 additions and 0 deletions.
1 change: 1 addition & 0 deletions distribution/changelog.txt
Original file line number Diff line number Diff line change
@@ -35,6 +35,7 @@
- Fix: [#22339] Printing ui.tool.cursor in console crashes the game.
- Fix: [#22348] Progress bar screen doesn’t handle window resizing.
- Fix: [#22389] Alpine coaster has wrong tunnel entrance type.
- Fix: [#22445] Crash due to incorrect renderer state.

0.4.12 (2024-07-07)
------------------------------------------------------------------------
Original file line number Diff line number Diff line change
@@ -67,7 +67,16 @@ class HardwareDisplayDrawingEngine final : public X8DrawingEngine

void Initialise() override
{
#if SDL_VERSION_ATLEAST(2, 28, 0)
// Before creating a new renderer, destroy any possible leftover state, as it will prevent the renderer from being
// created.
if (SDL_GetWindowSurface(_window) != nullptr)
{
SDL_DestroyWindowSurface(_window);
}
#endif
_sdlRenderer = SDL_CreateRenderer(_window, -1, SDL_RENDERER_ACCELERATED | (_useVsync ? SDL_RENDERER_PRESENTVSYNC : 0));
Guard::Assert(_sdlRenderer != nullptr, "Failed to create renderer: %s", SDL_GetError());
}

void SetVSync(bool vsync) override

0 comments on commit b1e14c6

Please sign in to comment.