Skip to content

Commit

Permalink
support webgl2
Browse files Browse the repository at this point in the history
  • Loading branch information
mockersf committed May 18, 2024
1 parent 62c6733 commit 9051b31
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 13 deletions.
24 changes: 16 additions & 8 deletions crates/bevy_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ use bevy_utils::prelude::default;
pub use extract_param::Extract;

use bevy_hierarchy::ValidParentCheckPlugin;
use bevy_window::{PrimaryWindow, RawHandleWrapper};
use bevy_window::{PrimaryWindow, RawHandleWrapperHolder};
use extract_resource::ExtractResourcePlugin;
use globals::GlobalsPlugin;
use render_asset::RenderAssetBytesPerFrame;
Expand Down Expand Up @@ -268,10 +268,9 @@ impl Plugin for RenderPlugin {
));

let mut system_state: SystemState<
Query<&RawHandleWrapper, With<PrimaryWindow>>,
Query<&RawHandleWrapperHolder, With<PrimaryWindow>>,
> = SystemState::new(app.world_mut());
let primary_window = system_state.get(app.world()).get_single().ok().cloned();

let settings = render_creation.clone();
let async_renderer = async move {
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
Expand All @@ -282,11 +281,20 @@ impl Plugin for RenderPlugin {
});

// SAFETY: Plugins should be set up on the main thread.
let surface = primary_window.map(|wrapper| unsafe {
let handle = wrapper.get_handle();
instance
.create_surface(handle)
.expect("Failed to create wgpu surface")
let surface = primary_window.and_then(|wrapper| unsafe {
let maybe_handle = wrapper.0.lock().expect(
"Couldn't get the window handle in time for renderer initialization",
);
if let Some(wrapper) = maybe_handle.as_ref() {
let handle = wrapper.get_handle();
Some(
instance
.create_surface(handle)
.expect("Failed to create wgpu surface"),
)
} else {
None
}
});

let request_adapter_options = wgpu::RequestAdapterOptions {
Expand Down
7 changes: 6 additions & 1 deletion crates/bevy_window/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
//! The [`WindowPlugin`] sets up some global window-related parameters and
//! is part of the [`DefaultPlugins`](https://docs.rs/bevy/latest/bevy/struct.DefaultPlugins.html).

use std::sync::{Arc, Mutex};

use bevy_a11y::Focus;

mod cursor;
Expand Down Expand Up @@ -112,7 +114,10 @@ impl Plugin for WindowPlugin {
let initial_focus = app
.world_mut()
.spawn(primary_window.clone())
.insert(PrimaryWindow)
.insert((
PrimaryWindow,
RawHandleWrapperHolder(Arc::new(Mutex::new(None))),
))
.id();
if let Some(mut focus) = app.world_mut().get_resource_mut::<Focus>() {
**focus = Some(initial_focus);
Expand Down
11 changes: 10 additions & 1 deletion crates/bevy_window/src/raw_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ use raw_window_handle::{
DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, RawDisplayHandle,
RawWindowHandle, WindowHandle,
};
use std::{any::Any, marker::PhantomData, ops::Deref, sync::Arc};
use std::{
any::Any,
marker::PhantomData,
ops::Deref,
sync::{Arc, Mutex},
};

/// A wrapper over a window.
///
Expand Down Expand Up @@ -116,3 +121,7 @@ impl HasDisplayHandle for ThreadLockedRawWindowHandleWrapper {
Ok(unsafe { DisplayHandle::borrow_raw(self.0.display_handle) })
}
}

/// Holder of the [`RawHandleWrapper`] with wrappers, to allow use in asynchronous context
#[derive(Debug, Clone, Component)]
pub struct RawHandleWrapperHolder(pub Arc<Mutex<Option<RawHandleWrapper>>>);
12 changes: 11 additions & 1 deletion crates/bevy_winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//! The app's [runner](bevy_app::App::runner) is set by `WinitPlugin` and handles the `winit` [`EventLoop`].
//! See `winit_runner` for details.

use bevy_window::RawHandleWrapperHolder;
use std::marker::PhantomData;
use winit::event_loop::EventLoop;
#[cfg(target_os = "android")]
Expand Down Expand Up @@ -158,7 +159,16 @@ impl AppSendEvent for Vec<WinitEvent> {
/// The parameters of the [`create_windows`] system.
pub type CreateWindowParams<'w, 's, F = ()> = (
Commands<'w, 's>,
Query<'w, 's, (Entity, &'static mut Window), F>,
Query<
'w,
's,
(
Entity,
&'static mut Window,
Option<&'static RawHandleWrapperHolder>,
),
F,
>,
EventWriter<'w, WindowCreated>,
NonSendMut<'w, WinitWindows>,
NonSendMut<'w, AccessKitAdapters>,
Expand Down
8 changes: 6 additions & 2 deletions crates/bevy_winit/src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub fn create_windows<F: QueryFilter + 'static>(
accessibility_requested,
): SystemParamItem<CreateWindowParams<F>>,
) {
for (entity, mut window) in &mut created_windows {
for (entity, mut window, handle_holder) in &mut created_windows {
if winit_windows.get_window(entity).is_some() {
continue;
}
Expand Down Expand Up @@ -78,7 +78,11 @@ pub fn create_windows<F: QueryFilter + 'static>(
});

if let Ok(handle_wrapper) = RawHandleWrapper::new(winit_window) {
commands.entity(entity).insert(handle_wrapper);
let mut entity = commands.entity(entity);
entity.insert(handle_wrapper.clone());
if let Some(handle_holder) = handle_holder {
*handle_holder.0.lock().unwrap() = Some(handle_wrapper);
}
}

#[cfg(target_arch = "wasm32")]
Expand Down

0 comments on commit 9051b31

Please sign in to comment.