Skip to content

[linux] Add an Impeller Vulkan backend for the GTK embedder#189584

Draft
sero583 wants to merge 1 commit into
flutter:masterfrom
sero583:impeller-vulkan-linux
Draft

[linux] Add an Impeller Vulkan backend for the GTK embedder#189584
sero583 wants to merge 1 commit into
flutter:masterfrom
sero583:impeller-vulkan-linux

Conversation

@sero583

@sero583 sero583 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Adds an opt-in Vulkan rendering path to the Linux GTK embedder: Impeller renders with its existing Vulkan backend through a KHR swapchain, presented into a synchronized wl_subsurface on Wayland or the toplevel window on X11. This is the Linux half of the desktop Impeller Vulkan effort (#181711); the Windows half is presented through DirectComposition in a separate PR because knopp's review of #183382 asked Windows off the KHR-swapchain path, while KHR presentation remains the right fit on Linux where the Mesa/driver WSI is the native presentation mechanism.

Activation uses the engine switch mechanism, matching the Windows backend and in line with the review guidance to gate the backend behind flags rather than public API: --enable-impeller together with --impeller-backend=vulkan. Without the switches, or when no capable Vulkan device exists, nothing changes: OpenGL remains the default and the fallback, and the existing software renderer stays opt-in through the FLUTTER_LINUX_RENDERER environment variable. When Vulkan is active, EGL is not initialized at all.

How it works

  • FlVulkanManager owns the VkInstance, VkDevice, VkQueue, and the presentation surface. On Wayland it creates a child wl_surface, makes it a subsurface of the toplevel positioned at the content area (below the header bar), sets an empty input region so events pass through to GTK, and marks it opaque. On X11 it presents to the toplevel window directly.
  • Impeller manages the KHR swapchain end to end (SurfaceContextVK); the engine renders into the acquired swapchain images and presents through the Vulkan queue.
  • FlEngine selects the renderer from the engine switches and skips EGL / OpenGL manager creation when Vulkan is chosen, so a Vulkan-only session does not load libepoxy.
  • FlViewRendererVulkan is a new FlViewRenderer subclass alongside FlViewRendererOpenGL and FlViewRendererSoftware. FlView instantiates it for the Vulkan renderer type. Unlike the OpenGL/software renderers it does not composite layers (Impeller owns presentation through the swapchain); it creates the FlVulkanManager on realize, keeps the subsurface positioned, and drives parent-surface commits (see below).

Synchronized subsurface (Wayland)

The Vulkan subsurface runs in synchronized mode (wl_subsurface_set_sync) so its buffer is applied atomically with the parent surface's commit. This keeps the Vulkan content and the window geometry in lockstep during resizes, avoiding the tearing a desynchronized subsurface produces when the parent resizes before the child presents its new-size buffer. Because a synchronized subsurface only becomes visible when the parent commits, and GTK does not redraw the toplevel on its own while only the Vulkan content changes, FlViewRendererVulkan keeps a frame-clock tick callback registered; it queues a draw each frame, and the renderer's draw handler paints the background (committing the parent), which flushes the subsurface's latest frame. The tick callback is removed on dispose.

Embedder plumbing

The Vulkan renderer config gains an optional surface field (FlutterVulkanSurfaceHandle). When the embedder supplies a surface, Impeller drives the swapchain and the get_next_image / present_image callbacks are optional; when it does not, the existing embedder-managed image callbacks are used unchanged. The field is struct_size compatible, so existing embedders are unaffected. The legacy vulkan/ support library gains the Xlib and Wayland surface procs and the Linux native surface wrapper.

Not in this PR

Testing

New unit tests in flutter_linux_unittests (hardware-dependent cases skip cleanly without Vulkan):

  • FlVulkanManagerTest (6): availability, create-or-null without a window, shutdown/wait-idle, deferred-deletion null safety, memory properties, surface release.
  • VulkanNativeSurfaceLinuxTest (7): X11 and Wayland surface validity and extension-name checks, zero/negative dimension rejection.
  • FlEngineTest.RendererTypeVulkan plus the existing software/OpenGL/default/unknown selection tests: the Vulkan backend is selected only through the switches and otherwise falls back to OpenGL. RendererTypeVulkanEnvVarFallsBackToOpenGL covers the migration path: FLUTTER_LINUX_RENDERER=vulkan is not a selector, warns with a pointer to the switches, and falls back to OpenGL.

Manual verification on AMD Radeon RX 6750 XT: the backend was exercised on a real Wayland compositor (WSLg, which exposes VK_KHR_wayland_surface over both the D3D12 translation layer and llvmpipe). The switch selection picks Vulkan, the KHR swapchain initializes on the subsurface, and the app renders continuously; the synchronized-subsurface tick driver was confirmed to keep the parent committing every frame.

Part of #181711. This PR has no build-time dependency on the Impeller hardening PR (#189580) and can be reviewed in parallel; landing the hardening PR first is recommended because its KHR swapchain robustness fixes (fence re-signal on failed acquire, zero-extent minimized-window guard) directly improve the runtime behavior of the swapchain path this PR enables. Design doc: https://flutter.dev/go/impeller-backend-desktop

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

Selects the Vulkan backend via engine switches, presents through a KHR
swapchain into a synchronized wl_subsurface (Wayland) or the toplevel
window (X11), and integrates with the FlViewRenderer architecture via a
new FlViewRendererVulkan. Removes the public rendering-backend getter.
@github-actions github-actions Bot added engine flutter/engine related. See also e: labels. platform-linux Building on or for Linux specifically a: desktop Running on desktop team-linux Owned by the Linux platform team labels Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: desktop Running on desktop engine flutter/engine related. See also e: labels. platform-linux Building on or for Linux specifically team-linux Owned by the Linux platform team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant