wgpu: Make WgpuRenderBackend::build_descriptors async

This will be necessary for using wgpu on web, where the whole
renderer creation will need to be async.
This commit is contained in:
Mike Welsh 2021-09-08 16:40:51 -07:00
parent 9067dd3668
commit df270c55af
6 changed files with 47 additions and 32 deletions

1
Cargo.lock generated
View File

@ -3538,6 +3538,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"approx", "approx",
"env_logger", "env_logger",
"futures",
"image", "image",
"pretty_assertions", "pretty_assertions",
"ruffle_core", "ruffle_core",

View File

@ -384,13 +384,14 @@ fn trace_path(_opt: &Opt) -> Option<&Path> {
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
let opt: Opt = Opt::parse(); let opt: Opt = Opt::parse();
let instance = wgpu::Instance::new(opt.graphics.into()); let instance = wgpu::Instance::new(opt.graphics.into());
let descriptors = WgpuRenderBackend::<TextureTarget>::build_descriptors( let descriptors =
futures::executor::block_on(WgpuRenderBackend::<TextureTarget>::build_descriptors(
opt.graphics.into(), opt.graphics.into(),
instance, instance,
None, None,
opt.power.into(), opt.power.into(),
trace_path(&opt), trace_path(&opt),
)?; ))?;
if opt.swf.is_file() { if opt.swf.is_file() {
capture_single_swf(descriptors, &opt)?; capture_single_swf(descriptors, &opt)?;

View File

@ -291,13 +291,13 @@ impl WgpuRenderBackend<SwapChainTarget> {
} }
let instance = wgpu::Instance::new(backend); let instance = wgpu::Instance::new(backend);
let surface = unsafe { instance.create_surface(window) }; let surface = unsafe { instance.create_surface(window) };
let descriptors = Self::build_descriptors( let descriptors = block_on(Self::build_descriptors(
backend, backend,
instance, instance,
Some(&surface), Some(&surface),
power_preference, power_preference,
trace_path, trace_path,
)?; ))?;
let target = SwapChainTarget::new( let target = SwapChainTarget::new(
surface, surface,
descriptors.surface_format, descriptors.surface_format,
@ -322,8 +322,13 @@ impl WgpuRenderBackend<TextureTarget> {
); );
} }
let instance = wgpu::Instance::new(backend); let instance = wgpu::Instance::new(backend);
let descriptors = let descriptors = block_on(Self::build_descriptors(
Self::build_descriptors(backend, instance, None, power_preference, trace_path)?; backend,
instance,
None,
power_preference,
trace_path,
))?;
let target = TextureTarget::new(&descriptors.device, size); let target = TextureTarget::new(&descriptors.device, size);
Self::new(descriptors, target) Self::new(descriptors, target)
} }
@ -388,18 +393,18 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
}) })
} }
pub fn build_descriptors( pub async fn build_descriptors(
backend: wgpu::Backends, backend: wgpu::Backends,
instance: wgpu::Instance, instance: wgpu::Instance,
surface: Option<&wgpu::Surface>, surface: Option<&wgpu::Surface>,
power_preference: wgpu::PowerPreference, power_preference: wgpu::PowerPreference,
trace_path: Option<&Path>, trace_path: Option<&Path>,
) -> Result<Descriptors, Error> { ) -> Result<Descriptors, Error> {
let adapter = block_on(instance.request_adapter(&wgpu::RequestAdapterOptions { let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions {
power_preference, power_preference,
compatible_surface: surface, compatible_surface: surface,
force_fallback_adapter: false, force_fallback_adapter: false,
})) }).await
.ok_or_else(|| { .ok_or_else(|| {
let names = get_backend_names(backend); let names = get_backend_names(backend);
if names.is_empty() { if names.is_empty() {
@ -409,14 +414,16 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
} }
})?; })?;
let (device, queue) = block_on(adapter.request_device( let (device, queue) = adapter
.request_device(
&wgpu::DeviceDescriptor { &wgpu::DeviceDescriptor {
label: None, label: None,
features: wgpu::Features::empty(), features: wgpu::Features::empty(),
..Default::default() ..Default::default()
}, },
trace_path, trace_path,
))?; )
.await?;
let info = adapter.get_info(); let info = adapter.get_info();
// Prefer a linear surface format, when available. // Prefer a linear surface format, when available.
let surface_format = if info.backend == wgpu::Backend::Gl { let surface_format = if info.backend == wgpu::Backend::Gl {

View File

@ -7,6 +7,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
futures = "0.3.17"
ruffle_core = { path = "../core" } ruffle_core = { path = "../core" }
ruffle_render_wgpu = { path = "../render/wgpu" } ruffle_render_wgpu = { path = "../render/wgpu" }
image = "0.23.14" image = "0.23.14"

View File

@ -1028,12 +1028,14 @@ fn run_swf(
if check_img { if check_img {
let instance = wgpu::Instance::new(backend_bit); let instance = wgpu::Instance::new(backend_bit);
let descriptors = WgpuRenderBackend::<TextureTarget>::build_descriptors( let descriptors = futures::executor::block_on(
WgpuRenderBackend::<TextureTarget>::build_descriptors(
backend_bit, backend_bit,
instance, instance,
None, None,
Default::default(), Default::default(),
None, None,
),
)?; )?;
platform_id = Some(get_img_platform_suffix(&descriptors.info)); platform_id = Some(get_img_platform_suffix(&descriptors.info));

View File

@ -411,7 +411,11 @@ export class RufflePlayer extends HTMLElement {
throw e; throw e;
}); });
this.instance = new ruffleConstructor(this.container, this, config); this.instance = await new ruffleConstructor(
this.container,
this,
config
);
console.log("New Ruffle instance created."); console.log("New Ruffle instance created.");
// In Firefox, AudioContext.state is always "suspended" when the object has just been created. // In Firefox, AudioContext.state is always "suspended" when the object has just been created.
@ -1226,8 +1230,7 @@ export class RufflePlayer extends HTMLElement {
} }
protected debugPlayerInfo(): string { protected debugPlayerInfo(): string {
return `Allows script access: ${ return `Allows script access: ${this.options?.allowScriptAccess ?? false
this.options?.allowScriptAccess ?? false
}\n`; }\n`;
} }