pygame-community / pygame-ce

🐍🎮 pygame - Community Edition is a FOSS Python library for multimedia applications (like games). Built on top of the excellent SDL library.
https://pyga.me
777 stars 123 forks source link

Calling `pygame.display.set_mode` a second time crashes with `SCALED` flag if it hasn't been called with it the first time. #2737

Closed u8slvn closed 1 week ago

u8slvn commented 4 months ago

Environment:

Current behavior:

When the method pygame.display.set_mode is called a second time with SCALED flag and hasn't been called the first time with SCALED flag, pygame crash with the following error:

pygame.error: failed to create renderer

The error happens only when set_mode is called with SCALED flag and if it hasn't been set with it before.

Expected behavior:

This seems to happen only since 2.4.0, I tested it with 2.3.2 and it works properly.

Steps to reproduce:

  1. Call set_mode without SCALED flag.
  2. Call set_mode a second time with SCALED flag makes pygame crash.

Or:

  1. Call set_mode with SCALED flag.
  2. Call set_mode a second time without it, this will work as intended.
  3. Call set_mode a third time with SCALED flag, then it crashes.

Test code

Just press SPACE key to switch mode.

import pygame

pygame.init()

screen = pygame.display.set_mode((500, 500), pygame.RESIZABLE)

running = True
fullscreen = False

while running:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                fullscreen = not fullscreen
                if fullscreen is True:
                    screen = pygame.display.set_mode((500, 500), pygame.FULLSCREEN | pygame.SCALED)
                else:
                    screen = pygame.display.set_mode((500, 500), pygame.RESIZABLE)

        if event.type == pygame.QUIT:
            running = False

    screen.fill((255, 255, 255))
    pygame.draw.circle(screen, (0, 255, 0), (250, 250), 75)
    pygame.display.flip()

pygame.quit()
ankith26 commented 4 months ago

Thanks for the bug report.

I cannot seem to reproduce this on Ubuntu, perhaps this is a windows only issue

Starbuck5 commented 4 months ago

This seems like the same problem as #2571 and #2376

Starbuck5 commented 4 months ago

If you're trying to run code that switches between SCALED and not-scaled, I think it would work to quit and re-initialize the video system while doing it. pygame.display.quit() and pygame.display.init(). Haven't tested though.

I cannot seem to reproduce this on Ubuntu, perhaps this is a windows only issue

This is in a whole stream of renderer semantics issues, and all the earliest reports were on Linux, so that's surprising. Are you using an old system SDL? It's an SDL version thing.

u8slvn commented 4 months ago

I think it would work to quit and re-initialize the video system while doing it. pygame.display.quit() and pygame.display.init().

I just tested it and it does the trick! Thks!

ankith26 commented 4 months ago

This is in a whole stream of renderer semantics issues, and all the earliest reports were on Linux, so that's surprising. Are you using an old system SDL? It's an SDL version thing.

No, I'm using pip installed pygame-ce 2.4.1 (SDL 2.28.5, Python 3.11.6)

MyreMylar commented 1 month ago

simplest repro:

import pygame

pygame.init()

pygame.display.set_mode([800, 600])
pygame.display.set_mode([800, 600], flags=pygame.SCALED)