From 1ea04f081519dcbc2887c6b6b474109996fa5377 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Fri, 3 Jun 2022 20:28:57 +0100 Subject: [PATCH] bevy_render: Avoid creating multiple surfaces on Android When looking for an adapter Bevy currently creates a one-shot surface that can be used to find a compatible adapter instead of referencing the surface that's associated with the primary window for rendering. This results in creating multiple render surfaces for a single window which may not be portable and may also result in large, redundant allocations (e.g. for a full swap chain) On Android VkAndroidSurfaceCreateInfoKHR (which is used by wgpu to create a surface) will throw a `VK_ERROR_NATIVE_WINDOW_IN_USE_KHR` error if we try to create multiple surfaces for a single window. As a workaround for now we don't request an adapter based on a surface on Android. --- crates/bevy_render/src/lib.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index 60d6bb1ddfb36..0ca4ea5a27c54 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -135,14 +135,26 @@ impl Plugin for RenderPlugin { }; let instance = wgpu::Instance::new(backends); - let surface = { + + // FIXME: instead of creating a new surface here we should be aiming to + // reference the surface that's created for the primary window to avoid + // creating multiple render surfaces. (Or the surface created here should + // somehow become the surface for the primary window.) + // + // This is especially important on Android where VkAndroidSurfaceCreateInfoKHR + // (which is used by wgpu to reate a surface) will throw a + // `VK_ERROR_NATIVE_WINDOW_IN_USE_KHR` error if we try to create multiple + // surfaces for a single window. As a workaround for now we don't + // request an adapter based on a surface on Android. + let surface = if cfg!(not(target_os = "android")) { let windows = app.world.resource_mut::(); let raw_handle = windows.get_primary().map(|window| unsafe { let handle = window.raw_window_handle().get_handle(); instance.create_surface(&handle) }); raw_handle - }; + } else { None }; + let request_adapter_options = wgpu::RequestAdapterOptions { power_preference: options.power_preference, compatible_surface: surface.as_ref(),