Skip to content

Port display.c to SDL3 #3428

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Aug 17, 2025
Merged

Port display.c to SDL3 #3428

merged 11 commits into from
Aug 17, 2025

Conversation

ankith26
Copy link
Member

@ankith26 ankith26 commented May 12, 2025

WIP to port display.c to SDL3

Summary by CodeRabbit

  • New Features

    • SDL3 compatibility for display and window management.
    • Updated display enumeration, mode queries, and refresh rate reporting.
    • Unified integer scaling behavior across SDL2 and SDL3.
    • Improved window/WM info retrieval and fullscreen handling.
  • Bug Fixes

    • More reliable fullscreen transitions and state detection across platforms.
    • Safer pixel format handling.
  • Refactor

    • Broad internal updates to support dual SDL2/SDL3 code paths without changing public APIs.
  • Chores

    • Display module is now always built.

@ankith26 ankith26 requested a review from a team as a code owner May 12, 2025 16:56
@ankith26 ankith26 marked this pull request as draft May 12, 2025 16:59
@damusss damusss added display pygame.display sdl3 labels May 13, 2025
@ankith26 ankith26 force-pushed the ankith26-display-sdl3 branch 4 times, most recently from 7006314 to 6b66f16 Compare May 18, 2025 18:12
@ankith26 ankith26 marked this pull request as ready for review May 18, 2025 18:15
@ankith26
Copy link
Member Author

This PR should be done from my side.

Given that this is a kinda big PR to review, I have already organized everything into commits that take up stuff one at a time and focus on it fully. So, if it helps reviewing I can split this up into multiple PRs each with subsets of commits from here.

@@ -331,6 +331,10 @@ pg_window_set_fullscreen(SDL_Window *window, int desktop)
goto end;
}
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this doing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically while working on fullscreen changes in display I saw that SDL_SetWindowFullscreenMode in SDL3 has effect only if the window is already in fullscreen mode according to the docs. So I added a call here as well that does that first.

@ankith26 ankith26 force-pushed the ankith26-display-sdl3 branch from 6b66f16 to efb4dd4 Compare May 31, 2025 19:25
@ankith26 ankith26 force-pushed the ankith26-display-sdl3 branch from efb4dd4 to 1ab8b97 Compare July 13, 2025 19:34
Comment on lines -2808 to -2814
// could also take the size of the old display surface
SDL_GetWindowSize(win, &window_w, &window_h);
window_display = SDL_GetWindowDisplayIndex(win);
if (SDL_GetDesktopDisplayMode(window_display, &display_mode) != 0) {
return RAISE(pgExc_SDLError, SDL_GetError());
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was just unused?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it was just unused in this function. Just a relic of copy pasting stuff IG

Copy link
Member

@Starbuck5 Starbuck5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Ankith! I looked through the changes and it seems good.

This did take a significant amount of time to read through, maybe if some of the smaller commits were split into their own PRs they could be reviewed more quickly by others? Not sure the best move.

When I combine with my surface branch I'm unable to open a window, but this PR is for compiling and not necessarily for getting everything to run.

>>> screen = pygame.display.set_mode((500, 500))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
pygame.error: Invalid display

@ankith26 ankith26 force-pushed the ankith26-display-sdl3 branch from 1ab8b97 to e495f2c Compare August 3, 2025 14:34
@ankith26
Copy link
Member Author

ankith26 commented Aug 3, 2025

I rebased this PR on main to get the latest surface compilation changes (hence the force push). While I was at it I also fixed a super minor return code related issue in an SDL3 specific part of this PR, and as a result set_mode now works on SDL3! *

*: set_mode on SDL3 only works when called after pygame.init() as of now. This can be fixed but needs a bit more code restructuring that would also affect SDL2 paths, hence I am keeping that out of this PR.

With this PR we have some examples in a somewhat usable/runnable state on SDL3

@ankith26
Copy link
Member Author

@coderabbitai full review

Copy link

coderabbitai bot commented Aug 13, 2025

✅ Actions performed

Full review triggered.

Copy link

coderabbitai bot commented Aug 13, 2025

Walkthrough

Adds SDL3 compatibility across display/window management alongside existing SDL2 paths, guarded by SDL version checks. Updates pixel format types under PG_SDL3, un-gates building the display module, and adjusts fullscreen logic to pre-enable fullscreen before setting mode. Gamma ramp APIs now error under SDL3. Public API signatures unchanged.

Changes

Cohort / File(s) Summary
SDL3 compatibility in display subsystem
src_c/display.c
Introduces SDL3 code paths for window creation, display enumeration, mode queries, fullscreen handling, WM info, integer scaling, and erroring gamma APIs; retains SDL2 branches; adds helpers (PG_CreateWindowCompat, PG_SetWindowFullscreen, PG_RenderSetIntegerScale); updates memory and env handling for SDL3.
Public struct pixel format adjustments (SDL-versioned)
src_c/include/_pygame.h
In pg_VideoInfo, conditionally switches vfmt/vfmt_data types to SDL_PixelFormatDetails* and SDL_PixelFormatDetails under PG_SDL3; preserves SDL2 types otherwise; wrapped in #if PG_SDL3.
Build system: enable display module for SDL3
src_c/meson.build
Removes conditional gate; builds display extension unconditionally; deletes obsolete TODO and endif.
Fullscreen flow tweak
src_c/window.c
In pg_window_set_fullscreen, calls SDL_SetWindowFullscreen(window, 1) before SDL_SetWindowFullscreenMode; aborts if the first call fails; no API changes.

Sequence Diagram(s)

sequenceDiagram
  participant App
  participant Display as Display module
  participant SDL as SDL2/SDL3

  App->>Display: set_mode()/resize/init
  alt SDL3
    Display->>SDL: SDL_GetDisplays / SDL_CreateWindowWithProperties
    Display->>SDL: SDL_GetDesktopDisplayMode (const ptr)
    Display->>SDL: SDL_SetRenderLogicalPresentation / flags
  else SDL2
    Display->>SDL: SDL_GetNumVideoDisplays / SDL_CreateWindow
    Display->>SDL: SDL_GetDesktopDisplayMode (by value)
    Display->>SDL: SDL_RenderSetIntegerScale
  end
  Display-->>App: window/display state
Loading
sequenceDiagram
  participant Caller
  participant Window as pg_window_set_fullscreen
  participant SDL

  Caller->>Window: request fullscreen (desktop/non-desktop)
  Window->>SDL: SDL_SetWindowFullscreen(window, 1)
  alt success
    Window->>SDL: SDL_SetWindowFullscreenMode(window, mode)
    Window-->>Caller: result
  else failure
    Window-->>Caller: error
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

A twitch of whiskers, screens aligned,
I hop between the twos and threes combined.
Fullscreen first—then modes in queue,
Pixels whisper: “Details new!”
Build burrows open, flags set free—
Carrots for compatibility. 🥕✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ankith26-display-sdl3

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src_c/window.c (1)

334-337: Verify error handling for fullscreen mode transition

The function now calls SDL_SetWindowFullscreen(window, 1) before SDL_SetWindowFullscreenMode. While the logic aligns with SDL3's requirements, the error handling could be improved for clarity.

Apply this diff to improve error messaging:

-    if (!SDL_SetWindowFullscreen(window, 1)) {
-        goto end;
-    }
+    if (!SDL_SetWindowFullscreen(window, 1)) {
+        SDL_SetError("Failed to enable fullscreen state before setting mode");
+        goto end;
+    }
src_c/display.c (1)

2977-3032: Creative solution for SDL3 window manager type detection

The get_syswm_type() function provides a workaround for the absence of SDL_SysWMinfo in SDL3 by detecting the video driver string. While functional, this approach is somewhat fragile.

Consider adding a comment explaining why this approach is necessary and potentially logging a warning if an unknown driver is detected:

 static SDL_SYSWM_TYPE
 get_syswm_type()
 {
+    /* SDL3 removed SDL_SysWMinfo, so we detect the window system
+     * by checking the video driver name. This is less reliable but
+     * currently the only available method. */
     const char *driver = SDL_GetCurrentVideoDriver();
     if (!driver) {
         return SDL_SYSWM_UNKNOWN;
     }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b7f0c25 and e495f2c.

📒 Files selected for processing (4)
  • src_c/display.c (71 hunks)
  • src_c/include/_pygame.h (1 hunks)
  • src_c/meson.build (0 hunks)
  • src_c/window.c (1 hunks)
💤 Files with no reviewable changes (1)
  • src_c/meson.build
🧰 Additional context used
🧬 Code Graph Analysis (1)
src_c/display.c (2)
src_c/base.c (1)
  • pg_GetDefaultWindow (2170-2174)
src_c/_pygame.h (3)
  • PG_GetSurfaceFormat (128-132)
  • PG_GetSurfaceFormat (235-239)
  • PG_GetSurfacePalette (241-245)
🔇 Additional comments (17)
src_c/include/_pygame.h (1)

287-294: LGTM! Clean SDL3 compatibility for pg_VideoInfo struct

The conditional compilation for SDL3 correctly updates the pixel format types from SDL_PixelFormat* to SDL_PixelFormatDetails*, aligning with SDL3's new API.

src_c/display.c (16)

34-36: LGTM! Proper SDL3 conditional exclusion of SDL_syswm.h

The header is correctly excluded for SDL3 builds since SDL_SysWMinfo is no longer available in SDL3.


867-883: LGTM! Well-designed integer scaling compatibility layer

The PG_RenderSetIntegerScale function provides a clean abstraction over the differences between SDL2 and SDL3's rendering APIs. The SDL3 path correctly uses SDL_SetRenderLogicalPresentation with appropriate presentation modes.


1052-1081: LGTM! Proper SDL3 display enumeration with memory management

The SDL3 path correctly:

  1. Uses SDL_GetDisplays instead of SDL_GetNumVideoDisplays
  2. Properly frees the allocated display array with SDL_free
  3. Uses SDL_DisplayID correctly for display identification

1122-1159: Well-structured fullscreen mode handling for SDL3

The PG_SetWindowFullscreen function properly implements SDL3's two-step fullscreen process:

  1. First calls SDL_SetWindowFullscreen to toggle fullscreen state
  2. Then calls SDL_SetWindowFullscreenMode with appropriate display mode
  3. Properly handles memory cleanup with SDL_free(modes)

1787-1790: LGTM! Correct SDL3 surface color mapping

The SDL3 path correctly uses SDL_MapSurfaceRGB instead of SDL_MapRGB, properly adapting to SDL3's API changes.


2460-2477: SDL3 gamma ramp removal handled appropriately

The functions correctly return an error for SDL3 builds since gamma ramp functionality has been removed from SDL3. The error messages are clear and informative.


2385-2385: LGTM! Correct palette access using compatibility macro

Uses PG_GetSurfacePalette macro which provides proper abstraction for SDL2/SDL3 differences.


535-563: LGTM! Comprehensive SDL3 window properties access

The Windows platform code correctly uses SDL3's new property system with SDL_GetPointerProperty to access window handles, device contexts, and instance pointers.


244-248: Proper SDL3 setenv handling for Windows compatibility

Uses SDL_setenv_unsafe in SDL3 which is the appropriate replacement for SDL_setenv.


1642-1644: Verify SDL_CreateRenderer call for SDL3

The SDL3 path correctly uses the simplified SDL_CreateRenderer(win, NULL) API. The vsync is properly set afterwards with SDL_SetRenderVSync.


2714-2727: LGTM! Renderer info retrieval adapted for SDL3

The function correctly handles the differences between SDL2's SDL_RendererInfo struct and SDL3's simpler API that only provides the renderer name.


2809-2813: LGTM! Correct window flags handling for fullscreen detection

The SDL3 path correctly uses SDL_WINDOW_FULLSCREEN flag alone, as SDL3 simplified the fullscreen flag system.


2864-2874: LGTM! Proper vsync detection for SDL3 OpenGL contexts

The SDL3 path correctly uses SDL_GL_GetSwapInterval with an output parameter instead of a return value.


3664-3668: SDL3 message box button ID field name updated

Correctly uses buttonID instead of buttonid for SDL3 compatibility.


1086-1118: LGTM! Clean window creation compatibility wrapper

The PG_CreateWindowCompat function provides a good abstraction over SDL2's SDL_CreateWindow and SDL3's SDL_CreateWindowWithProperties, properly handling the property-based API in SDL3.


1283-1295: Const pointer usage in SDL3 display mode is consistent
All instances of SDL_GetDesktopDisplayMode in SDL3 code paths declare a const SDL_DisplayMode*; the pattern is applied uniformly across the file. No changes required.

@ankith26 ankith26 merged commit bf90331 into main Aug 17, 2025
26 checks passed
@ankith26 ankith26 deleted the ankith26-display-sdl3 branch August 17, 2025 08:26
@ankith26 ankith26 added this to the 2.5.6 milestone Aug 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
display pygame.display sdl3
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants