webgl: Fall back to canvas if not using hardware acceleration

Display WebGL driver info, detect whether hardware acceleration
is enabled, and fall back to the canvas backend in this case.
This commit is contained in:
Mike Welsh 2020-09-23 14:41:27 -07:00
parent b908b027a9
commit 313b02d24f
3 changed files with 23 additions and 8 deletions

View File

@ -25,6 +25,6 @@ default-features = false
[dependencies.web-sys]
version = "0.3.45"
features = ["HtmlCanvasElement", "HtmlElement", "Node", "OesVertexArrayObject", "WebGlBuffer", "WebGlFramebuffer", "WebGlProgram",
"WebGlRenderbuffer", "WebGlRenderingContext", "WebGl2RenderingContext", "WebGlShader", "WebGlTexture", "WebGlUniformLocation",
"WebGlVertexArrayObject"]
features = ["HtmlCanvasElement", "HtmlElement", "Node", "OesVertexArrayObject", "WebGlBuffer", "WebglDebugRendererInfo",
"WebGlFramebuffer", "WebGlProgram", "WebGlRenderbuffer", "WebGlRenderingContext", "WebGl2RenderingContext",
"WebGlShader", "WebGlTexture", "WebGlUniformLocation", "WebGlVertexArrayObject"]

View File

@ -11,7 +11,7 @@ use wasm_bindgen::{JsCast, JsValue};
use web_sys::{
HtmlCanvasElement, OesVertexArrayObject, WebGl2RenderingContext as Gl2, WebGlBuffer,
WebGlFramebuffer, WebGlProgram, WebGlRenderbuffer, WebGlRenderingContext as Gl, WebGlShader,
WebGlTexture, WebGlUniformLocation, WebGlVertexArrayObject,
WebGlTexture, WebGlUniformLocation, WebGlVertexArrayObject, WebglDebugRendererInfo,
};
type Error = Box<dyn std::error::Error>;
@ -76,6 +76,7 @@ impl WebGlRenderBackend {
("alpha", JsValue::FALSE),
("antialias", JsValue::FALSE),
("depth", JsValue::FALSE),
("failIfMajorPerformanceCaveat", JsValue::TRUE), // fail if no GPU available
];
let context_options = js_sys::Object::new();
for (name, value) in options.iter() {
@ -141,6 +142,18 @@ impl WebGlRenderBackend {
}
};
// Get WebGL driver info.
let driver_info = if gl.get_extension("WEBGL_debug_renderer_info").is_ok() {
gl.get_parameter(WebglDebugRendererInfo::UNMASKED_RENDERER_WEBGL)
.ok()
.and_then(|val| val.as_string())
.unwrap_or_else(|| "<unknown>".to_string())
} else {
"<unknown>".to_string()
};
log::info!("WebGL graphics driver: {}", driver_info);
let color_vertex = Self::compile_shader(&gl, Gl::VERTEX_SHADER, COLOR_VERTEX_GLSL)?;
let texture_vertex = Self::compile_shader(&gl, Gl::VERTEX_SHADER, TEXTURE_VERTEX_GLSL)?;
let color_fragment = Self::compile_shader(&gl, Gl::FRAGMENT_SHADER, COLOR_FRAGMENT_GLSL)?;

View File

@ -835,8 +835,9 @@ fn create_renderer(
.into_js_result()?
.dyn_into()
.map_err(|_| "Expected HtmlCanvasElement")?;
if let Ok(renderer) = ruffle_render_webgl::WebGlRenderBackend::new(&canvas) {
return Ok((canvas, Box::new(renderer)));
match ruffle_render_webgl::WebGlRenderBackend::new(&canvas) {
Ok(renderer) => return Ok((canvas, Box::new(renderer))),
Err(error) => log::error!("Error creating WebGL renderer: {}", error),
}
}
@ -848,8 +849,9 @@ fn create_renderer(
.into_js_result()?
.dyn_into()
.map_err(|_| "Expected HtmlCanvasElement")?;
if let Ok(renderer) = ruffle_render_canvas::WebCanvasRenderBackend::new(&canvas) {
return Ok((canvas, Box::new(renderer)));
match ruffle_render_canvas::WebCanvasRenderBackend::new(&canvas) {
Ok(renderer) => return Ok((canvas, Box::new(renderer))),
Err(error) => log::error!("Error creating canvas renderer: {}", error),
}
}