Opened 11 months ago

Last modified 11 months ago

#14530 new defect

BACKENDS: SDL2: Regression with software mode

Reported by: raziel- Owned by:
Priority: normal Component: GUI
Version: Keywords: window/fullscreen switch, launcher, SDL2, regression
Cc: Game:

Description

Latest ScummVM sources

SDL driver set to Software
ScummVM's GFXMode set to SDLSurface

Using SDL 2.26.5 one can switch the launcher between window and fullscreen

Using SDL 2.28.0 one gets this instead

WARNING: SearchSet::add: archive 'gui-icons.dat' already present!
WARNING: SDL_SetVideoMode: SDL_CreateRenderer() failed with VSYNC option, retrying without it...!
WARNING: SDL_SetVideoMode: SDL_CreateRenderer() failed with VSYNC option, retrying without it...!
WARNING: SDL_SetVideoMode says we can't switch to that mode (Surface already associated with window)!

AmigaOS4 - PPC - BigEndian

Can anyone test/confirm, please

Thank you

Attachments (1)

sdl_repro.c (1011 bytes ) - added by PushmePullyu 11 months ago.

Download all attachments as: .zip

Change History (6)

comment:1 by raziel-, 11 months ago

Further tests show that renaming SDL2.26.5.so to SDL2.28.0.so fixes the issue.

So, it *does* seem like something in SDL2 itself introduced this regression.

comment:3 by lotharsm, 11 months ago

I think this is upstream related.

I checked the changelog and stumbled across this entry:

Added SDL_HasWindowSurface() and SDL_DestroyWindowSurface() to switch between the window surface and rendering APIs

And since the commit you picked works on exactly that part of the code, I think this is the culprit.

Could you try to revert this commit in SDL and rebuild?

comment:4 by PushmePullyu, 11 months ago

I think the problem is that with software rendering SDL_CreateRenderer() creates a surface for the window, but SDL_DestroyRenderer() will not destroy this surface.
The check introduced in commit https://github.com/libsdl-org/SDL/commit/36033e3832633506a01c9da3d08a0c0844761965 will then prevent creating a new renderer for this window.

One could manually destroy the surface with the new DestroyWindowSurface(), but since it was created by SDL itself, this should probably be done by SDL_DestroyRenderer(). This would then be a SDL bug.

Take all this with a grain of salt though, as I am not very familiar with SDL.

Here is some code to test (it should fail to recreate the renderer with SDL 2.28.0 and software rendering):

#include <stdio.h>

#define SDL_MAIN_HANDLED
#include "SDL.h"

// gcc -o sdl_repro sdl_repro.c $(sdl2-config --cflags) $(sdl2-config --libs)
// = gcc -o sdl_repro sdl_repro.c -I/usr/include/SDL2 -D_REENTRANT -lSDL2
// SDL_RENDER_DRIVER="software" ./sdl_repro

void fail() {
	printf("error: %s\n", SDL_GetError());
	exit(1);
}

int main() {
	SDL_Init(SDL_INIT_EVERYTHING);

	SDL_Window *window = NULL;
	SDL_Renderer *renderer = NULL;

	// Create window
	window = SDL_CreateWindow("myWindow", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 320, 240, 0);
	if (!window)
		fail();

	// Create renderer
	printf("Creating renderer\n");
	renderer = SDL_CreateRenderer(window, -1, 0);
	if (!renderer)
		fail();

	// Destroy renderer
	printf("Destroying renderer\n");
	SDL_DestroyRenderer(renderer);
	if (SDL_GetRenderer(window))
		fail();

	// Recreate renderer
	printf("Recreating  renderer\n");
	renderer = SDL_CreateRenderer(window, -1, 0);
	if (!renderer)
		fail();

	printf("Quitting\n");
	SDL_Quit();
	return 0;
}

by PushmePullyu, 11 months ago

Attachment: sdl_repro.c added

comment:5 by raziel-, 11 months ago

@PushmePullyu

Confirmed

sdl_repro

Creating renderer
Destroying renderer
Recreating renderer
error: Surface already associated with window

SDL Renderer set to Software, SDL 2.28.0

Works fine with anything else than Software

...

Thank you for the test program

Note: See TracTickets for help on using tickets.