Skip to content

[linux] Startup fixes for the Vulkan GTK backend - #1

Merged
sero583 merged 4 commits into
sero583:impeller-vulkan-linuxfrom
ales-drnz:vulkan-gtk-startup-fixes
Aug 18, 2026
Merged

sero583 merged 4 commits into
sero583:impeller-vulkan-linuxfrom
ales-drnz:vulkan-gtk-startup-fixes

Conversation

@ales-drnz

Copy link
Copy Markdown

Fixes 1, 2, 4 and 5 from the discussion on flutter/flutter#189584, as requested on top of d45d937be61:

  • Fix SIGSEGV on realize with the Vulkan renderer — guard the fl_opengl_manager_clear_current call in realize_cb; there is no FlOpenGLManager when the renderer is Vulkan.
  • Announce the Vulkan first frame from the next-frame callback — FlutterEngineSetNextFrameCallback fires once the first frame is in the swapchain, regardless of window visibility, which breaks the show-window cycle. Routed through a new FlRenderable.notify_first_frame.
  • Commit the parent surface to apply the subsurface position — set_position is double-buffered state of the parent, so committing the child was a no-op.
  • Size the Vulkan subsurface with wp_viewport — declares the widget allocation as the viewport destination, from both size_allocate and realize (GTK allocates before it realizes, so the initial size_allocate runs before the manager exists). Includes the hand-written pre-1.20 viewporter client header discussed in the thread; happy to adjust its licensing treatment however you prefer.
  • Drop stray executable bit from vulkan_native_surface_linux — mode change only; the engine's pre-push formatting hook trips on it.

Thank you!

@sero583

sero583 commented Aug 18, 2026

Copy link
Copy Markdown
Owner

Reviewed properly, the code holds up:

  • Threading in the first frame callback is handled correctly.
  • The optional vfunc keeps the other renderables untouched.
  • A missing viewporter degrades with a warning instead of crashing, and the viewport is destroyed on teardown.
  • Committing the parent instead of the child removes a cross thread commit that was there before, so that one is a straight improvement.
  • I also checked whether wl_surface_set_buffer_scale could have avoided the vendoring, since an integer scale would have saved us the whole licensing question. It cannot. On Wayland VkSurfaceCapabilitiesKHR.currentExtent is {0xFFFFFFFF, 0xFFFFFFFF}, so the swapchain starts at a fallback size rather than at allocation * scale (my own code doing that), and no integer buffer scale maps an 800x600 buffer onto a 1280x720 widget. wp_viewport_set_destination does exactly that, so viewporter is the right mechanism.

One thing is in the way. viewporter-protocol.c is generated and correctly carries the Collabora MIT notice, but it sits in a first party directory and sky/packages/sky_engine/LICENSE has no entry for it. The licenses CI builder checks exactly that, so the branch goes red as it stands.

There is no wayland third party dir in the engine at all, so I do not think either of us should guess where these files belong. Two ways out:

  1. You regenerate the license golden with the files where they are, and we let upstream tell us if they want them moved.
  2. We drop the viewporter commit from this PR, land the other three, and do the scaling fix separately once a maintainer has said where protocol files should live.

I lean towards 2, so the startup fixes are not held hostage to the licensing question. Your work, your call.

A few smaller things:

  • The commits carry a Co-Authored-By trailer for an assistant. I would drop it before this goes upstream. There is no commit in flutter/flutter that has one, for any tool, and the CLA is checked per author, so it is the kind of detail that stalls a PR on the bot instead of on review. If you want the assistance on the record, the way it has gone through there is a short note in the PR description instead, like this merged one.
  • A test for the first frame callback would be nice to have. It is the only one of the four fixes that is cheaply testable today, and it does not need a realized widget.
  • You will get asked to sign the CLA once your commits land on flutter/flutter.

I would rather merge this when everything is right than merge early and patch afterwards, so take the time you need. Once it is clean I will rebase onto the branch so your commits keep their authorship.

Thanks for putting real hardware behind this. Without your testing the backend would have gone into review crashing on startup and never showing a window.

realize_cb calls the OpenGL manager unconditionally, but fl_engine only
creates it when the renderer is not Vulkan, so selecting the Vulkan
backend dereferenced a null FlOpenGLManager on every launch:

  #0  fl_opengl_manager_clear_current
  flutter#1  realize_cb
  flutter#7  gtk_widget_realize
The runner shows the window on the "first-frame" signal, which the
Vulkan renderer only emitted from its draw handler - and the draw
handler cannot run before the window is shown, so the window never
appeared.

Announce it from FlutterEngineSetNextFrameCallback instead: it fires on
the raster thread once the first frame is actually in the swapchain,
regardless of window visibility. Routed to the view through a new
FlRenderable.notify_first_frame so backends that present outside the
GTK draw cycle can signal it. Tested on an unrealized view, matching
how the runner receives it.
wl_subsurface.set_position is double-buffered state of the parent
surface - "the scheduled coordinates will take effect whenever the
state of the parent surface is applied" - so committing the child was a
no-op for it. The position only applied when the tick-callback redraw
happened to commit the parent.
Mode change only; the engine's pre-push formatting hook trips on it.
@ales-drnz
ales-drnz force-pushed the vulkan-gtk-startup-fixes branch from 02c60a6 to a53607e Compare August 18, 2026 08:49
@ales-drnz

Copy link
Copy Markdown
Author

Done, at the end I went with the second one. I really appreciate all the work on this and I'm happy to help any time =)

@sero583

sero583 commented Aug 18, 2026

Copy link
Copy Markdown
Owner

@ales-drnz LGTM, thanks again! :)

@sero583
sero583 merged commit a53607e into sero583:impeller-vulkan-linux Aug 18, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants