[linux] Add an Impeller Vulkan backend for the GTK embedder#189584
Draft
sero583 wants to merge 1 commit into
Draft
[linux] Add an Impeller Vulkan backend for the GTK embedder#189584sero583 wants to merge 1 commit into
sero583 wants to merge 1 commit into
Conversation
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.
This was referenced Jul 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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_subsurfaceon 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-impellertogether 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 theFLUTTER_LINUX_RENDERERenvironment variable. When Vulkan is active, EGL is not initialized at all.How it works
FlVulkanManagerowns theVkInstance,VkDevice,VkQueue, and the presentation surface. On Wayland it creates a childwl_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.SurfaceContextVK); the engine renders into the acquired swapchain images and presents through the Vulkan queue.FlEngineselects 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.FlViewRendererVulkanis a newFlViewRenderersubclass alongsideFlViewRendererOpenGLandFlViewRendererSoftware.FlViewinstantiates it for the Vulkan renderer type. Unlike the OpenGL/software renderers it does not composite layers (Impeller owns presentation through the swapchain); it creates theFlVulkanManageron 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,FlViewRendererVulkankeeps 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
surfacefield (FlutterVulkanSurfaceHandle). When the embedder supplies a surface, Impeller drives the swapchain and theget_next_image/present_imagecallbacks are optional; when it does not, the existing embedder-managed image callbacks are used unchanged. The field isstruct_sizecompatible, so existing embedders are unaffected. The legacyvulkan/support library gains the Xlib and Wayland surface procs and the Linux native surface wrapper.Not in this PR
FlRendererType,fl_engine_get_rendering_backend); those are removed per the review guidance, and selection is internal via switches only.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.RendererTypeVulkanplus the existing software/OpenGL/default/unknown selection tests: the Vulkan backend is selected only through the switches and otherwise falls back to OpenGL.RendererTypeVulkanEnvVarFallsBackToOpenGLcovers the migration path:FLUTTER_LINUX_RENDERER=vulkanis 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_surfaceover 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-assistbot 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.