Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wireframe mode toggle to debug menu #11880

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
desktop,render/wgpu: Add wireframe mode toggle to debug menu
  • Loading branch information
torokati44 committed Nov 30, 2023
commit d205489f55d8493f125cfa07d9babdc4951d8383
1 change: 1 addition & 0 deletions desktop/assets/texts/en-US/main_menu.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ debug-menu-open-stage = View Stage Info
debug-menu-open-movie = View Movie
debug-menu-open-movie-list = Show Known Movies
debug-menu-search-display-objects = Search Display Objects...
debug-menu-wireframe-mode = Wireframe Mode

24 changes: 24 additions & 0 deletions desktop/src/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod open_dialog;

pub use controller::GuiController;
pub use movie::MovieView;
use ruffle_render_wgpu::backend::WgpuRenderBackend;
use std::borrow::Cow;
use url::Url;

Expand Down Expand Up @@ -301,6 +302,29 @@ impl RuffleGui {
player.debug_ui().queue_message(DebugMessage::SearchForDisplayObject);
}
}

// The rest is for the backend-specific "Wireframe Mode" toggle.
let mut renderer: Option<&mut WgpuRenderBackend<MovieView>> =
player
.map(|p| p.renderer_mut().downcast_mut()
.expect("The renderer should be a WgpuRenderBackend<MovieView>"));

if let Some(ref mut renderer) = renderer {
let wireframe_available = renderer.is_wireframe_available();

let mut wireframe_enabled = renderer.get_wireframe();
if ui.add_enabled(wireframe_available, Checkbox::new(&mut wireframe_enabled, text(&self.locale, "debug-menu-wireframe-mode")))
.on_disabled_hover_text("Not supported by graphics device")
.changed()
{
ui.close_menu();
renderer.set_wireframe(wireframe_enabled);
}
}
else {
let mut wireframe_enabled: bool = false;
ui.add_enabled(false, Checkbox::new(&mut wireframe_enabled, text(&self.locale, "debug-menu-wireframe-mode")));
}
});
});
menu::menu_button(ui, text(&self.locale, "help-menu"), |ui| {
Expand Down
2 changes: 1 addition & 1 deletion desktop/src/gui/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ impl GuiController {
full_output.platform_output.cursor_icon = player
.ui()
.downcast_ref::<DesktopUiBackend>()
.unwrap_or_else(|| panic!("UI Backend should be DesktopUiBackend"))
.expect("UI Backend should be DesktopUiBackend")
.cursor();
}
}
Expand Down
34 changes: 34 additions & 0 deletions render/wgpu/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,27 @@ pub struct WgpuRenderBackend<T: RenderTarget> {
// This is currently unused - we just store it to report in
// `get_viewport_dimensions`
viewport_scale_factor: f64,
wireframe_available: bool,
wireframe: bool,
texture_pool: TexturePool,
offscreen_texture_pool: TexturePool,
pub(crate) offscreen_buffer_pool: Arc<BufferPool<wgpu::Buffer, BufferDimensions>>,
}

impl<T: RenderTarget> WgpuRenderBackend<T> {
pub fn is_wireframe_available(&self) -> bool {
self.wireframe_available
}

pub fn get_wireframe(&self) -> bool {
self.wireframe
}

pub fn set_wireframe(&mut self, enabled: bool) {
self.wireframe = enabled;
}
}

impl WgpuRenderBackend<SwapChainTarget> {
#[cfg(target_family = "wasm")]
pub async fn for_canvas(canvas: web_sys::HtmlCanvasElement) -> Result<Self, Error> {
Expand Down Expand Up @@ -189,6 +205,11 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
.into());
}

let wireframe_available = descriptors
.adapter
.features()
.contains(wgpu::Features::POLYGON_MODE_LINE);

let surface = Surface::new(
&descriptors,
StageQuality::Low,
Expand Down Expand Up @@ -221,6 +242,8 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
target,
surface,
meshes: Vec::new(),
wireframe_available,
wireframe: false,
shape_tessellator: ShapeTessellator::new(),
viewport_scale_factor: 1.0,
texture_pool: TexturePool::new(),
Expand Down Expand Up @@ -552,6 +575,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
a: f64::from(entry.clear.a) / 255.0,
},
),
self.wireframe,
&self.descriptors,
&self.meshes,
entry.commands,
Expand All @@ -577,6 +601,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
a: f64::from(entry.clear.a) / 255.0,
},
),
self.wireframe,
&self.descriptors,
&self.meshes,
entry.commands,
Expand Down Expand Up @@ -619,6 +644,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
b: f64::from(clear.b) / 255.0,
a: f64::from(clear.a) / 255.0,
}),
self.wireframe,
&self.descriptors,
&mut uniform_buffer,
&mut color_buffer,
Expand Down Expand Up @@ -800,6 +826,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
surface.draw_commands_and_copy_to(
frame_output.view(),
RenderTargetMode::FreshWithTexture(target.get_texture()),
self.wireframe,
&self.descriptors,
&mut uniform_buffer,
&mut color_buffer,
Expand Down Expand Up @@ -1109,6 +1136,13 @@ async fn request_device(
}
}

if adapter
.features()
.contains(wgpu::Features::POLYGON_MODE_LINE)
{
features |= wgpu::Features::POLYGON_MODE_LINE;
}

adapter
.request_device(
&wgpu::DeviceDescriptor {
Expand Down
12 changes: 9 additions & 3 deletions render/wgpu/src/descriptors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct Descriptors {
copy_pipeline: Mutex<FnvHashMap<(u32, wgpu::TextureFormat), Arc<wgpu::RenderPipeline>>>,
copy_srgb_pipeline: Mutex<FnvHashMap<(u32, wgpu::TextureFormat), Arc<wgpu::RenderPipeline>>>,
pub shaders: Shaders,
pipelines: Mutex<FnvHashMap<(u32, wgpu::TextureFormat), Arc<Pipelines>>>,
pipelines: Mutex<FnvHashMap<(u32, wgpu::PolygonMode, wgpu::TextureFormat), Arc<Pipelines>>>,
pub default_color_bind_group: wgpu::BindGroup,
pub filters: Filters,
}
Expand Down Expand Up @@ -238,19 +238,25 @@ impl Descriptors {
.clone()
}

pub fn pipelines(&self, msaa_sample_count: u32, format: wgpu::TextureFormat) -> Arc<Pipelines> {
pub fn pipelines(
&self,
msaa_sample_count: u32,
polygon_mode: wgpu::PolygonMode,
format: wgpu::TextureFormat,
) -> Arc<Pipelines> {
let mut pipelines = self
.pipelines
.lock()
.expect("Pipelines should not be already locked");
pipelines
.entry((msaa_sample_count, format))
.entry((msaa_sample_count, polygon_mode, format))
.or_insert_with(|| {
Arc::new(Pipelines::new(
&self.device,
&self.shaders,
format,
msaa_sample_count,
polygon_mode,
&self.bind_layouts,
))
})
Expand Down
13 changes: 12 additions & 1 deletion render/wgpu/src/pipelines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ impl Pipelines {
shaders: &Shaders,
format: wgpu::TextureFormat,
msaa_sample_count: u32,
polygon_mode: wgpu::PolygonMode,
bind_layouts: &BindLayouts,
) -> Self {
let colort_bindings = if device.limits().max_push_constant_size > 0 {
Expand Down Expand Up @@ -121,6 +122,7 @@ impl Pipelines {
format,
&shaders.color_shader,
msaa_sample_count,
polygon_mode,
&VERTEX_BUFFERS_DESCRIPTION_COLOR,
&colort_bindings,
wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING,
Expand All @@ -144,6 +146,7 @@ impl Pipelines {
format,
&shaders.gradient_shader,
msaa_sample_count,
polygon_mode,
&VERTEX_BUFFERS_DESCRIPTION_POS,
&gradient_bindings,
wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING,
Expand All @@ -167,6 +170,7 @@ impl Pipelines {
format,
&shaders.blend_shaders[blend],
msaa_sample_count,
polygon_mode,
&VERTEX_BUFFERS_DESCRIPTION_POS,
&complex_blend_bindings,
wgpu::BlendState::REPLACE,
Expand Down Expand Up @@ -195,6 +199,7 @@ impl Pipelines {
format,
&shaders.bitmap_shader,
msaa_sample_count,
polygon_mode,
&VERTEX_BUFFERS_DESCRIPTION_POS,
&bitmap_blend_bindings,
blend.blend_state(),
Expand Down Expand Up @@ -227,6 +232,7 @@ impl Pipelines {
})],
&VERTEX_BUFFERS_DESCRIPTION_POS,
msaa_sample_count,
polygon_mode,
));

let bitmap_opaque_dummy_depth = device.create_render_pipeline(&create_pipeline_descriptor(
Expand All @@ -253,6 +259,7 @@ impl Pipelines {
})],
&VERTEX_BUFFERS_DESCRIPTION_POS,
msaa_sample_count,
polygon_mode,
));

Self {
Expand All @@ -276,6 +283,7 @@ fn create_pipeline_descriptor<'a>(
color_target_state: &'a [Option<wgpu::ColorTargetState>],
vertex_buffer_layout: &'a [wgpu::VertexBufferLayout<'a>],
msaa_sample_count: u32,
polygon_mode: wgpu::PolygonMode,
) -> wgpu::RenderPipelineDescriptor<'a> {
wgpu::RenderPipelineDescriptor {
label,
Expand All @@ -295,7 +303,7 @@ fn create_pipeline_descriptor<'a>(
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: None,
polygon_mode: wgpu::PolygonMode::default(),
polygon_mode,
unclipped_depth: false,
conservative: false,
},
Expand All @@ -316,6 +324,7 @@ fn create_shape_pipeline(
format: wgpu::TextureFormat,
shader: &wgpu::ShaderModule,
msaa_sample_count: u32,
polygon_mode: wgpu::PolygonMode,
vertex_buffers_layout: &[wgpu::VertexBufferLayout<'_>],
bind_group_layouts: &[&wgpu::BindGroupLayout],
blend: wgpu::BlendState,
Expand Down Expand Up @@ -353,6 +362,7 @@ fn create_shape_pipeline(
})],
vertex_buffers_layout,
msaa_sample_count,
polygon_mode,
))
};

Expand All @@ -370,6 +380,7 @@ fn create_shape_pipeline(
})],
vertex_buffers_layout,
msaa_sample_count,
polygon_mode,
)),
|mask_state| match mask_state {
MaskState::NoMask => mask_render_state(
Expand Down
36 changes: 28 additions & 8 deletions render/wgpu/src/surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub struct Surface {
quality: StageQuality,
sample_count: u32,
pipelines: Arc<Pipelines>,
wf_pipelines: Option<Arc<Pipelines>>,
format: wgpu::TextureFormat,
actual_surface_format: wgpu::TextureFormat,
}
Expand All @@ -50,12 +51,15 @@ impl Surface {

let sample_count =
supported_sample_count(&descriptors.adapter, quality, frame_buffer_format);
let pipelines = descriptors.pipelines(sample_count, frame_buffer_format);
let pipelines =
descriptors.pipelines(sample_count, wgpu::PolygonMode::Fill, frame_buffer_format);

Self {
size,
quality,
sample_count,
pipelines,
wf_pipelines: None,
format: frame_buffer_format,
actual_surface_format: surface_format,
}
Expand All @@ -67,6 +71,7 @@ impl Surface {
&mut self,
frame_view: &wgpu::TextureView,
render_target_mode: RenderTargetMode,
as_wireframe: bool,
descriptors: &'global Descriptors,
uniform_buffers: &'frame mut UniformBuffer<'global, Transforms>,
color_buffers: &'frame mut UniformBuffer<'global, ColorAdjustments>,
Expand All @@ -79,6 +84,7 @@ impl Surface {
) {
let target = self.draw_commands(
render_target_mode,
as_wireframe,
descriptors,
meshes,
commands,
Expand Down Expand Up @@ -109,6 +115,7 @@ impl Surface {
pub fn draw_commands<'frame, 'global: 'frame>(
&mut self,
render_target_mode: RenderTargetMode,
as_wireframe: bool,
descriptors: &'global Descriptors,
meshes: &'global Vec<Mesh>,
commands: CommandList,
Expand All @@ -133,6 +140,7 @@ impl Surface {
let mut mask_state = MaskState::NoMask;
let chunks = chunk_blends(
commands.commands,
as_wireframe,
descriptors,
uniform_buffers,
color_buffers,
Expand All @@ -149,6 +157,20 @@ impl Surface {
texture_pool,
);

let pl: Arc<Pipelines> = if as_wireframe {
if let Some(ref wfpl) = self.wf_pipelines {
wfpl.clone()
} else {
let wf_pipelines =
descriptors.pipelines(self.sample_count, wgpu::PolygonMode::Line, self.format);

self.wf_pipelines = Some(wf_pipelines.clone());
wf_pipelines
}
} else {
self.pipelines.clone()
};

for chunk in chunks {
match chunk {
Chunk::Draw(chunk, needs_stencil) => {
Expand All @@ -172,7 +194,7 @@ impl Surface {
});
render_pass.set_bind_group(0, target.globals().bind_group(), &[]);
let mut renderer = CommandRenderer::new(
&self.pipelines,
&pl,
descriptors,
uniform_buffers,
color_buffers,
Expand Down Expand Up @@ -314,13 +336,11 @@ impl Surface {
render_pass.set_stencil_reference(num_masks);
}
}
render_pass.set_pipeline(
self.pipelines.complex_blends[blend_mode].pipeline_for(mask_state),
);
render_pass
.set_pipeline(pl.complex_blends[blend_mode].pipeline_for(mask_state));
} else {
render_pass.set_pipeline(
self.pipelines.complex_blends[blend_mode].stencilless_pipeline(),
);
render_pass
.set_pipeline(pl.complex_blends[blend_mode].stencilless_pipeline());
}

if descriptors.limits.max_push_constant_size > 0 {
Expand Down
Loading