web: Move create_renderer to builder
This commit is contained in:
parent
a6ab799e1f
commit
77a65be5a2
|
@ -5,8 +5,11 @@ use ruffle_core::backend::ui::FontDefinition;
|
|||
use ruffle_core::compatibility_rules::CompatibilityRules;
|
||||
use ruffle_core::config::{Letterbox, NetworkingAccessMode};
|
||||
use ruffle_core::{swf, Color, DefaultFont, Player, PlayerRuntime, StageAlign, StageScaleMode};
|
||||
use ruffle_render::backend::RenderBackend;
|
||||
use ruffle_render::quality::StageQuality;
|
||||
use ruffle_web_common::JsResult;
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
@ -14,7 +17,7 @@ use tracing_subscriber::layer::{Layered, SubscriberExt};
|
|||
use tracing_subscriber::Registry;
|
||||
use tracing_wasm::{WASMLayer, WASMLayerConfigBuilder};
|
||||
use wasm_bindgen::prelude::*;
|
||||
use web_sys::HtmlElement;
|
||||
use web_sys::{HtmlCanvasElement, HtmlElement};
|
||||
|
||||
#[wasm_bindgen(inspectable)]
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -379,4 +382,134 @@ impl RuffleInstanceBuilder {
|
|||
);
|
||||
Arc::new(tracing_subscriber::registry().with(layer))
|
||||
}
|
||||
|
||||
pub async fn create_renderer(
|
||||
&self,
|
||||
) -> Result<(Box<dyn RenderBackend>, HtmlCanvasElement), Box<dyn Error>> {
|
||||
let window = web_sys::window().ok_or("Expected window")?;
|
||||
let document = window.document().ok_or("Expected document")?;
|
||||
#[cfg(not(any(
|
||||
feature = "canvas",
|
||||
feature = "webgl",
|
||||
feature = "webgpu",
|
||||
feature = "wgpu-webgl"
|
||||
)))]
|
||||
std::compile_error!("You must enable one of the render backend features (e.g., webgl).");
|
||||
|
||||
let _is_transparent = self.wmode.as_deref() == Some("transparent");
|
||||
|
||||
let mut renderer_list = vec!["wgpu-webgl", "webgpu", "webgl", "canvas"];
|
||||
if let Some(preferred_renderer) = &self.preferred_renderer {
|
||||
if let Some(pos) = renderer_list.iter().position(|&r| r == preferred_renderer) {
|
||||
renderer_list.remove(pos);
|
||||
renderer_list.insert(0, preferred_renderer.as_str());
|
||||
} else {
|
||||
tracing::error!("Unrecognized renderer name: {}", preferred_renderer);
|
||||
}
|
||||
}
|
||||
|
||||
// Try to create a backend, falling through to the next backend on failure.
|
||||
// We must recreate the canvas each attempt, as only a single context may be created per canvas
|
||||
// with `getContext`.
|
||||
for renderer in renderer_list {
|
||||
match renderer {
|
||||
#[cfg(all(feature = "webgpu", target_family = "wasm"))]
|
||||
"webgpu" => {
|
||||
// Check that we have access to WebGPU (navigator.gpu should exist).
|
||||
if web_sys::window()
|
||||
.ok_or(JsValue::FALSE)
|
||||
.and_then(|window| {
|
||||
js_sys::Reflect::has(&window.navigator(), &JsValue::from_str("gpu"))
|
||||
})
|
||||
.unwrap_or_default()
|
||||
{
|
||||
tracing::info!("Creating wgpu webgpu renderer...");
|
||||
let canvas: HtmlCanvasElement = document
|
||||
.create_element("canvas")
|
||||
.into_js_result()?
|
||||
.dyn_into()
|
||||
.map_err(|_| "Expected HtmlCanvasElement")?;
|
||||
|
||||
match ruffle_render_wgpu::backend::WgpuRenderBackend::for_canvas(
|
||||
canvas.clone(),
|
||||
true,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(renderer) => {
|
||||
return Ok((Box::new(renderer), canvas));
|
||||
}
|
||||
Err(error) => {
|
||||
tracing::error!("Error creating wgpu webgpu renderer: {}", error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(all(feature = "wgpu-webgl", target_family = "wasm"))]
|
||||
"wgpu-webgl" => {
|
||||
tracing::info!("Creating wgpu webgl renderer...");
|
||||
let canvas: HtmlCanvasElement = document
|
||||
.create_element("canvas")
|
||||
.into_js_result()?
|
||||
.dyn_into()
|
||||
.map_err(|_| "Expected HtmlCanvasElement")?;
|
||||
|
||||
match ruffle_render_wgpu::backend::WgpuRenderBackend::for_canvas(
|
||||
canvas.clone(),
|
||||
false,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(renderer) => {
|
||||
return Ok((Box::new(renderer), canvas));
|
||||
}
|
||||
Err(error) => {
|
||||
tracing::error!("Error creating wgpu webgl renderer: {}", error)
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "webgl")]
|
||||
"webgl" => {
|
||||
tracing::info!("Creating WebGL renderer...");
|
||||
let canvas: HtmlCanvasElement = document
|
||||
.create_element("canvas")
|
||||
.into_js_result()?
|
||||
.dyn_into()
|
||||
.map_err(|_| "Expected HtmlCanvasElement")?;
|
||||
match ruffle_render_webgl::WebGlRenderBackend::new(
|
||||
&canvas,
|
||||
_is_transparent,
|
||||
self.quality,
|
||||
) {
|
||||
Ok(renderer) => {
|
||||
return Ok((Box::new(renderer), canvas));
|
||||
}
|
||||
Err(error) => {
|
||||
tracing::error!("Error creating WebGL renderer: {}", error)
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "canvas")]
|
||||
"canvas" => {
|
||||
tracing::info!("Creating Canvas renderer...");
|
||||
let canvas: HtmlCanvasElement = document
|
||||
.create_element("canvas")
|
||||
.into_js_result()?
|
||||
.dyn_into()
|
||||
.map_err(|_| "Expected HtmlCanvasElement")?;
|
||||
match ruffle_render_canvas::WebCanvasRenderBackend::new(
|
||||
&canvas,
|
||||
_is_transparent,
|
||||
) {
|
||||
Ok(renderer) => {
|
||||
return Ok((Box::new(renderer), canvas));
|
||||
}
|
||||
Err(error) => tracing::error!("Error creating canvas renderer: {}", error),
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Err("Unable to create renderer".into())
|
||||
}
|
||||
}
|
||||
|
|
132
web/src/lib.rs
132
web/src/lib.rs
|
@ -389,10 +389,9 @@ impl RuffleHandle {
|
|||
let allow_networking = config.allow_networking;
|
||||
|
||||
let window = web_sys::window().ok_or("Expected window")?;
|
||||
let document = window.document().ok_or("Expected document")?;
|
||||
|
||||
let (mut builder, canvas) =
|
||||
create_renderer(PlayerBuilder::new(), &document, &config).await?;
|
||||
let (renderer, canvas) = config.create_renderer().await?;
|
||||
let mut builder = PlayerBuilder::new().with_boxed_renderer(renderer);
|
||||
|
||||
parent
|
||||
.append_child(&canvas.clone().into())
|
||||
|
@ -1077,133 +1076,6 @@ pub enum RuffleInstanceError {
|
|||
InstanceNotFound,
|
||||
}
|
||||
|
||||
async fn create_renderer(
|
||||
builder: PlayerBuilder,
|
||||
document: &web_sys::Document,
|
||||
config: &RuffleInstanceBuilder,
|
||||
) -> Result<(PlayerBuilder, HtmlCanvasElement), Box<dyn Error>> {
|
||||
#[cfg(not(any(
|
||||
feature = "canvas",
|
||||
feature = "webgl",
|
||||
feature = "webgpu",
|
||||
feature = "wgpu-webgl"
|
||||
)))]
|
||||
std::compile_error!("You must enable one of the render backend features (e.g., webgl).");
|
||||
|
||||
let _is_transparent = config.wmode.as_deref() == Some("transparent");
|
||||
|
||||
let mut renderer_list = vec!["wgpu-webgl", "webgpu", "webgl", "canvas"];
|
||||
if let Some(preferred_renderer) = &config.preferred_renderer {
|
||||
if let Some(pos) = renderer_list.iter().position(|&r| r == preferred_renderer) {
|
||||
renderer_list.remove(pos);
|
||||
renderer_list.insert(0, preferred_renderer.as_str());
|
||||
} else {
|
||||
tracing::error!("Unrecognized renderer name: {}", preferred_renderer);
|
||||
}
|
||||
}
|
||||
|
||||
// Try to create a backend, falling through to the next backend on failure.
|
||||
// We must recreate the canvas each attempt, as only a single context may be created per canvas
|
||||
// with `getContext`.
|
||||
for renderer in renderer_list {
|
||||
match renderer {
|
||||
#[cfg(all(feature = "webgpu", target_family = "wasm"))]
|
||||
"webgpu" => {
|
||||
// Check that we have access to WebGPU (navigator.gpu should exist).
|
||||
if web_sys::window()
|
||||
.ok_or(JsValue::FALSE)
|
||||
.and_then(|window| {
|
||||
js_sys::Reflect::has(&window.navigator(), &JsValue::from_str("gpu"))
|
||||
})
|
||||
.unwrap_or_default()
|
||||
{
|
||||
tracing::info!("Creating wgpu webgpu renderer...");
|
||||
let canvas: HtmlCanvasElement = document
|
||||
.create_element("canvas")
|
||||
.into_js_result()?
|
||||
.dyn_into()
|
||||
.map_err(|_| "Expected HtmlCanvasElement")?;
|
||||
|
||||
match ruffle_render_wgpu::backend::WgpuRenderBackend::for_canvas(
|
||||
canvas.clone(),
|
||||
true,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(renderer) => {
|
||||
return Ok((builder.with_renderer(renderer), canvas));
|
||||
}
|
||||
Err(error) => {
|
||||
tracing::error!("Error creating wgpu webgpu renderer: {}", error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(all(feature = "wgpu-webgl", target_family = "wasm"))]
|
||||
"wgpu-webgl" => {
|
||||
tracing::info!("Creating wgpu webgl renderer...");
|
||||
let canvas: HtmlCanvasElement = document
|
||||
.create_element("canvas")
|
||||
.into_js_result()?
|
||||
.dyn_into()
|
||||
.map_err(|_| "Expected HtmlCanvasElement")?;
|
||||
|
||||
match ruffle_render_wgpu::backend::WgpuRenderBackend::for_canvas(
|
||||
canvas.clone(),
|
||||
false,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(renderer) => {
|
||||
return Ok((builder.with_renderer(renderer), canvas));
|
||||
}
|
||||
Err(error) => {
|
||||
tracing::error!("Error creating wgpu webgl renderer: {}", error)
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "webgl")]
|
||||
"webgl" => {
|
||||
tracing::info!("Creating WebGL renderer...");
|
||||
let canvas: HtmlCanvasElement = document
|
||||
.create_element("canvas")
|
||||
.into_js_result()?
|
||||
.dyn_into()
|
||||
.map_err(|_| "Expected HtmlCanvasElement")?;
|
||||
match ruffle_render_webgl::WebGlRenderBackend::new(
|
||||
&canvas,
|
||||
_is_transparent,
|
||||
config.quality,
|
||||
) {
|
||||
Ok(renderer) => {
|
||||
return Ok((builder.with_renderer(renderer), canvas));
|
||||
}
|
||||
Err(error) => {
|
||||
tracing::error!("Error creating WebGL renderer: {}", error)
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "canvas")]
|
||||
"canvas" => {
|
||||
tracing::info!("Creating Canvas renderer...");
|
||||
let canvas: HtmlCanvasElement = document
|
||||
.create_element("canvas")
|
||||
.into_js_result()?
|
||||
.dyn_into()
|
||||
.map_err(|_| "Expected HtmlCanvasElement")?;
|
||||
match ruffle_render_canvas::WebCanvasRenderBackend::new(&canvas, _is_transparent) {
|
||||
Ok(renderer) => {
|
||||
return Ok((builder.with_renderer(renderer), canvas));
|
||||
}
|
||||
Err(error) => tracing::error!("Error creating canvas renderer: {}", error),
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Err("Unable to create renderer".into())
|
||||
}
|
||||
|
||||
fn parse_movie_parameters(input: &JsValue) -> Vec<(String, String)> {
|
||||
let mut params = Vec::new();
|
||||
if let Ok(keys) = js_sys::Reflect::own_keys(input) {
|
||||
|
|
Loading…
Reference in New Issue