diff --git a/render/canvas/src/lib.rs b/render/canvas/src/lib.rs index 9ec4c3720..ababdac5b 100644 --- a/render/canvas/src/lib.rs +++ b/render/canvas/src/lib.rs @@ -11,6 +11,7 @@ use ruffle_render::matrix::Matrix; use ruffle_render::shape_utils::{DistilledShape, DrawCommand, LineScaleMode, LineScales}; use ruffle_render::transform::Transform; use ruffle_web_common::{JsError, JsResult}; +use std::borrow::Cow; use std::sync::Arc; use swf::{BlendMode, Color}; use wasm_bindgen::{Clamped, JsCast, JsValue}; @@ -498,6 +499,10 @@ impl RenderBackend for WebCanvasRenderBackend { ) -> Result<(), Error> { Err(Error::Unimplemented) } + + fn debug_info(&self) -> Cow<'static, str> { + Cow::Borrowed("Renderer: Canvas") + } } impl CommandHandler for WebCanvasRenderBackend { diff --git a/render/src/backend.rs b/render/src/backend.rs index 4abda4212..987f4b6a3 100644 --- a/render/src/backend.rs +++ b/render/src/backend.rs @@ -6,6 +6,7 @@ use crate::error::Error; use crate::shape_utils::DistilledShape; use downcast_rs::{impl_downcast, Downcast}; use gc_arena::{Collect, GcCell, MutationContext}; +use std::borrow::Cow; use std::rc::Rc; use swf; @@ -62,6 +63,8 @@ pub trait RenderBackend: Downcast { commands: Vec>, mc: MutationContext<'gc, '_>, ) -> Result<(), Error>; + + fn debug_info(&self) -> Cow<'static, str>; } impl_downcast!(RenderBackend); diff --git a/render/src/backend/null.rs b/render/src/backend/null.rs index 378adb1e8..56873e7ad 100644 --- a/render/src/backend/null.rs +++ b/render/src/backend/null.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::sync::Arc; use crate::backend::{RenderBackend, ShapeHandle, ViewportDimensions}; @@ -96,4 +97,8 @@ impl RenderBackend for NullRenderer { ) -> Result<(), Error> { Err(Error::Unimplemented) } + + fn debug_info(&self) -> Cow<'static, str> { + Cow::Borrowed("Renderer: Null") + } } diff --git a/render/webgl/src/lib.rs b/render/webgl/src/lib.rs index 7a6f3f23d..31f27997d 100644 --- a/render/webgl/src/lib.rs +++ b/render/webgl/src/lib.rs @@ -1,6 +1,7 @@ #![allow(clippy::bool_to_int_with_if)] use bytemuck::{Pod, Zeroable}; +use std::borrow::Cow; use gc_arena::MutationContext; use ruffle_render::backend::null::NullBitmapSource; @@ -1088,6 +1089,14 @@ impl RenderBackend for WebGlRenderBackend { ) -> Result<(), BitmapError> { Err(BitmapError::Unimplemented) } + + fn debug_info(&self) -> Cow<'static, str> { + if self.gl2.is_some() { + Cow::Borrowed("Renderer: WebGL 2.0") + } else { + Cow::Borrowed("Renderer: WebGL 1.0") + } + } } impl CommandHandler for WebGlRenderBackend { diff --git a/render/wgpu/src/backend.rs b/render/wgpu/src/backend.rs index 41074ae60..f873d90fc 100644 --- a/render/wgpu/src/backend.rs +++ b/render/wgpu/src/backend.rs @@ -18,6 +18,7 @@ use ruffle_render::commands::CommandList; use ruffle_render::error::Error as BitmapError; use ruffle_render::shape_utils::DistilledShape; use ruffle_render::tessellator::ShapeTessellator; +use std::borrow::Cow; use std::num::NonZeroU32; use std::path::Path; use std::sync::Arc; @@ -310,6 +311,32 @@ impl RenderBackend for WgpuRenderBackend { Ok(()) } + fn debug_info(&self) -> Cow<'static, str> { + let mut result = vec![]; + result.push("Renderer: wgpu".to_string()); + + let info = self.descriptors.adapter.get_info(); + result.push(format!("Adapter Backend: {:?}", info.backend)); + result.push(format!("Adapter Name: {:?}", info.name)); + result.push(format!("Adapter Device Type: {:?}", info.device_type)); + result.push(format!("Adapter Driver Name: {:?}", info.driver)); + result.push(format!("Adapter Driver Info: {:?}", info.driver_info)); + + let enabled_features = self.descriptors.device.features(); + let available_features = self.descriptors.adapter.features() - enabled_features; + let current_limits = &self.descriptors.limits; + let available_limits = &self.descriptors.limits; + + result.push(format!("Enabled features: {enabled_features:?}")); + result.push(format!("Available features: {available_features:?}")); + result.push(format!("Current limits: {current_limits:?}")); + result.push(format!("Available limits: {available_limits:?}")); + result.push(format!("Surface samples: {}", self.surface.sample_count())); + result.push(format!("Surface size: {:?}", self.surface.size())); + + Cow::Owned(result.join("\n")) + } + fn viewport_dimensions(&self) -> ViewportDimensions { ViewportDimensions { width: self.target.width(), diff --git a/render/wgpu/src/surface.rs b/render/wgpu/src/surface.rs index e61ce1a3a..f954809d1 100644 --- a/render/wgpu/src/surface.rs +++ b/render/wgpu/src/surface.rs @@ -351,4 +351,12 @@ impl Surface { target } + + pub fn sample_count(&self) -> u32 { + self.sample_count + } + + pub fn size(&self) -> wgpu::Extent3d { + self.size + } } diff --git a/web/packages/core/src/ruffle-player.ts b/web/packages/core/src/ruffle-player.ts index 3e89fc35c..8707737c3 100644 --- a/web/packages/core/src/ruffle-player.ts +++ b/web/packages/core/src/ruffle-player.ts @@ -1537,7 +1537,7 @@ export class RufflePlayer extends HTMLElement { protected debugPlayerInfo(): string { let result = `Allows script access: ${this.loadedConfig.allowScriptAccess}\n`; if (this.instance) { - result += `Renderer: ${this.instance.renderer_name()}\n`; + result += `${this.instance.renderer_debug_info()}\n`; } return result; } diff --git a/web/src/lib.rs b/web/src/lib.rs index c881e2140..1bb8e954a 100644 --- a/web/src/lib.rs +++ b/web/src/lib.rs @@ -6,7 +6,7 @@ mod storage; mod ui; use generational_arena::{Arena, Index}; -use js_sys::{Array, Function, JsString, Object, Promise, Uint8Array}; +use js_sys::{Array, Function, Object, Promise, Uint8Array}; use ruffle_core::config::Letterbox; use ruffle_core::context::UpdateContext; use ruffle_core::events::{KeyCode, MouseButton, MouseWheelDelta}; @@ -66,7 +66,6 @@ struct RuffleInstance { unload_callback: Option>, has_focus: bool, trace_observer: Arc>, - renderer_name: &'static str, } #[wasm_bindgen] @@ -260,10 +259,9 @@ impl Ruffle { let _ = self.with_core_mut(|core| core.set_volume(value)); } - pub fn renderer_name(&self) -> JsString { - self.with_instance(|instance| instance.renderer_name) - .unwrap_or("Unknown") - .into() + pub fn renderer_debug_info(&self) -> JsValue { + self.with_core(|core| JsValue::from_str(&core.renderer().debug_info())) + .unwrap_or(JsValue::NULL) } // after the context menu is closed, remember to call `clear_custom_menu_items`! @@ -462,7 +460,7 @@ impl Ruffle { let window = web_sys::window().ok_or("Expected window")?; let document = window.document().ok_or("Expected document")?; - let (mut builder, canvas, renderer_name) = + let (mut builder, canvas) = create_renderer(PlayerBuilder::new(), &document, &config).await?; parent @@ -542,7 +540,6 @@ impl Ruffle { timestamp: None, has_focus: false, trace_observer, - renderer_name, }; // Prevent touch-scrolling on canvas. @@ -1213,7 +1210,7 @@ async fn create_renderer( builder: PlayerBuilder, document: &web_sys::Document, config: &Config, -) -> Result<(PlayerBuilder, HtmlCanvasElement, &'static str), Box> { +) -> Result<(PlayerBuilder, HtmlCanvasElement), Box> { #[cfg(not(any(feature = "canvas", feature = "webgpu", feature = "wgpu-webgl")))] std::compile_error!("You must enable one of the render backend features (e.g., webgl)."); @@ -1248,7 +1245,7 @@ async fn create_renderer( .await { Ok(renderer) => { - return Ok((builder.with_renderer(renderer), canvas, "WebGPU")); + return Ok((builder.with_renderer(renderer), canvas)); } Err(error) => log::error!("Error creating wgpu webgpu renderer: {}", error), } @@ -1274,11 +1271,7 @@ async fn create_renderer( .await { Ok(renderer) => { - return Ok(( - builder.with_renderer(renderer), - canvas, - "WebGL through wgpu", - )); + return Ok((builder.with_renderer(renderer), canvas)); } Err(error) => log::error!("Error creating wgpu webgl renderer: {}", error), } @@ -1297,7 +1290,7 @@ async fn create_renderer( .map_err(|_| "Expected HtmlCanvasElement")?; match ruffle_render_webgl::WebGlRenderBackend::new(&canvas, _is_transparent) { Ok(renderer) => { - return Ok((builder.with_renderer(renderer), canvas, "WebGL")); + return Ok((builder.with_renderer(renderer), canvas)); } Err(error) => log::error!("Error creating WebGL renderer: {}", error), } @@ -1313,7 +1306,7 @@ async fn create_renderer( .map_err(|_| "Expected HtmlCanvasElement")?; match ruffle_render_canvas::WebCanvasRenderBackend::new(&canvas, _is_transparent) { Ok(renderer) => { - return Ok((builder.with_renderer(renderer), canvas, "Canvas")); + return Ok((builder.with_renderer(renderer), canvas)); } Err(error) => log::error!("Error creating canvas renderer: {}", error), }