use std::sync::Arc;
use iced::{Color, Size};
use iced_wgpu::wgpu;
use truce_params::Params;
use crate::editor::{IcedPlugin, IcedProgram};
use crate::param_cache::ParamCache;
use crate::param_message::Message;
use truce_core::editor::for_test_params;
#[allow(clippy::needless_pass_by_value)]
pub(crate) fn render_to_pixels<P, M>(
params: Arc<P>,
plugin: M,
size: (u32, u32),
scale: f64,
font: Option<&'static [u8]>,
) -> Option<(Vec<u8>, u32, u32)>
where
P: Params + 'static,
M: IcedPlugin<P>,
{
let w = truce_gui::to_physical_px(size.0, scale);
let h = truce_gui::to_physical_px(size.1, scale);
let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor {
backends: crate::editor::editor_backends(),
..Default::default()
});
let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::HighPerformance,
compatible_surface: None,
force_fallback_adapter: false,
}))
.ok()?;
let (device, queue) = pollster::block_on(adapter.request_device(&wgpu::DeviceDescriptor {
label: Some("truce-iced-screenshot"),
required_features: wgpu::Features::empty(),
required_limits: adapter.limits(),
experimental_features: wgpu::ExperimentalFeatures::default(),
memory_hints: wgpu::MemoryHints::default(),
trace: wgpu::Trace::Off,
}))
.ok()?;
let format = wgpu::TextureFormat::Bgra8UnormSrgb;
let engine = iced_wgpu::Engine::new(
&adapter,
device,
queue,
format,
Some(iced_graphics::Antialiasing::MSAAx4),
iced_graphics::Shell::headless(),
);
let default_font = if let Some(data) = font {
crate::font::apply_font(data)
} else {
iced::Font::DEFAULT
};
let mut renderer = iced_wgpu::Renderer::new(engine, default_font, iced::Pixels(14.0));
let mut param_cache = ParamCache::new(params.clone());
param_cache.set_font(default_font);
let context = for_test_params(params.clone() as Arc<dyn Params>).with_params(params.clone());
let mut program = IcedProgram {
plugin,
param_cache,
context,
meter_ids: Vec::new(),
};
#[allow(clippy::cast_possible_truncation)] let scale_f32 = scale as f32;
let viewport = iced_graphics::Viewport::with_physical_size(Size::new(w, h), scale_f32);
let theme = program.plugin.theme();
program.dispatch(Message::Tick);
let style = iced_runtime::core::renderer::Style {
text_color: Color::from_rgb(0.90, 0.90, 0.92),
};
let cursor = iced::mouse::Cursor::Available(iced::Point::new(-1.0, -1.0));
let mut messages: Vec<Message<M::Message>> = Vec::new();
let view_element = program.view();
let mut user_interface = iced_runtime::UserInterface::build(
view_element,
viewport.logical_size(),
iced_runtime::user_interface::Cache::new(),
&mut renderer,
);
let _ = user_interface.update(
&[],
cursor,
&mut renderer,
&mut iced_runtime::core::clipboard::Null,
&mut messages,
);
user_interface.draw(&mut renderer, &theme, &style, cursor);
let bg = crate::theme::truce_dark_theme().palette().background;
let rgba = renderer.screenshot(&viewport, bg);
Some((rgba, w, h))
}