Skip to content

[HIGH] [SDL #8070] First frame of metal renderer shows garbage #153

Description

@Chevalier12

Tracking upstream SDL issue libsdl-org#8070

  • Priority: HIGH — provisional triage from SDL-OPEN-ISSUES-PRIORITIES.md, NOT an official SDL severity.
  • Source: First frame of metal renderer shows garbage libsdl-org/SDL#8070
  • Original title: First frame of metal renderer shows garbage
  • Reported by: slouken
  • Upstream state at capture: open; state reason:
  • Created: 2023-08-02T14:57:18.0000000Z; updated: 2024-12-04T17:04:50.0000000Z
  • Snapshot captured: 2026-09-07T17:43:49.9274526Z
  • Upstream labels:
  • Upstream milestone (not affected versions): 3.x (https://github.com/libsdl-org/SDL/milestone/6)
  • Upstream assignees: icculus
  • Upstream comments included: 5
  • Locked: False; lock reason:
  • Triage rationale: Input absent sau rezultate de randare greșite raportate; verificați regresia și scenariul activ.

This is an attributed tracking copy, not a locally reproduced or confirmed Graphix defect. Applicability, affected versions and ownership still require validation. No automatic synchronization or resolution is implied. Original descriptions and comments are preserved literally in Markdown code blocks to avoid notifying mentioned users or resolving SDL references against Graphix. Attachments, logs, patches and other linked resources remain at their original URLs; external resource contents and edit/event histories are not copied.

Graphix validation checklist

  • Read the current upstream issue and discussion.
  • Establish affected versions/platforms and whether Graphix is affected.
  • Reproduce the reported behavior and identify the invariant owner.
  • Implement an ownership-correct fix or document an upstream/external resolution.
  • Verify regression coverage and applicable platform/runtime gates.

Original description

This is an SDL3 bug, and does not happen in SDL2.

Repro steps:
Run SDL_image showimage ../test/sample.xcf, see that the first frame is garbage and the image shows up correctly on the second frame.

With SDL2, the image shows up correctly on the first frame.

I don't see anything obviously wrong in the renderer...

Original discussion (chronological)

Original comment by icculus

Source: libsdl-org#8070 (comment)
Created: 2023-09-09T17:41:42.0000000Z; updated: 2023-09-09T17:41:42.0000000Z; association: COLLABORATOR

This reproduces here, I'm digging in.

Original comment by icculus

Source: libsdl-org#8070 (comment)
Created: 2023-09-09T19:09:13.0000000Z; updated: 2023-09-09T19:09:13.0000000Z; association: COLLABORATOR

Bisecting this is hard, since there's a big block of commits between definitely-works and definitely-broken that fails to create the window correctly, as this moved from SDL2 to SDL3.

Original comment by icculus

Source: libsdl-org#8070 (comment)
Created: 2023-09-09T20:25:19.0000000Z; updated: 2023-09-09T20:25:19.0000000Z; association: COLLABORATOR

I don't have a fix yet, but it appears to be the window resizing causing problems here.

showimage.c does this at startup:

```c
    if (SDL_CreateWindowAndRenderer(0, 0, flags, &window, &renderer) < 0) {
```

...and sets the window size once it loads the image file.

sample.xcf is 23x42 pixels.

So if I force the window size to 100x100 in the create call, it shrinks the window once it knows the image size, and renders correctly:

![image](https://github.com/libsdl-org/SDL/assets/673562/34826d77-b983-46d2-9324-e1c16bc1d3bd)

If I force it to zero, it's all corrupt:

![image](https://github.com/libsdl-org/SDL/assets/673562/79ad3012-9d16-49ca-b179-1d91fd0640ae)

BUT...if I force it to something in the middle, like 20x30...

![image](https://github.com/libsdl-org/SDL/assets/673562/d1595324-2ba1-4688-891b-39e45d4c00ae)

...then the part of the window that already exists is okay, the new surface area is hosed.

My guess is that this is rendering correctly to the original window dimensions, and _then_ the OS's resize work is happening after the RenderPresent call (even though the resize is requested before we render, but since the window and app are still coming up, there could be async issues, I don't know), and there's nothing to be done at that point, which is why the second rendered frame fixes it.  I'm not sure why this works in SDL2, but lots of small pieces have moved around between then and SDL3 that might affect it.

CC'ing @slime73 in case there's something obvious and easy to fix here, but I'm not sure this is actually a bug so much as something that happened to work by accident in SDL2.

Original comment by slime73

Source: libsdl-org#8070 (comment)
Created: 2023-09-09T21:11:00.0000000Z; updated: 2023-09-09T21:11:00.0000000Z; association: CONTRIBUTOR

I haven't debugged this myself yet, but just taking a quick look at the metal renderer and layer/view code, maybe it has something to do with the order of SDL resize events relative to everything else, in SDL2 versus SDL3? In particular I wonder if seeing when exactly SDL_cocoametalview's `updateDrawableSize` method gets called would reveal any useful info, since that's hooked into an event watcher for `SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED` in SDL3.

Original comment by slime73

Source: libsdl-org#8070 (comment)
Created: 2023-09-09T21:30:56.0000000Z; updated: 2023-09-09T21:30:56.0000000Z; association: CONTRIBUTOR

Another possibility to me is it could be related to the dimensions used by the viewport / clip rect code in the Metal renderer. `showimage.c` never clears the screen so it's relying on `draw_background` to replace any garbage pixels on the screen with something valid, which means if something's causing the scissor rectangle in the Metal renderer to be smaller than the screen/drawable's dimensions, the parts outside of that scissor area will be garbage.

(I'm still just guessing from looking at code, so this might not be too helpful, sorry.)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions