From 04776b4f459b739292fc1c7c9b9ed77333a0597e Mon Sep 17 00:00:00 2001 From: Tsuki Date: Sun, 21 Jan 2024 10:40:40 +0800 Subject: [PATCH] surfman offscreen --- .../render_panel/monitor/_monitor.rs | 171 ++++++++++++++++++ .../render_panel/monitor/monitor.rs | 145 +++++++++------ .../render_panel/monitor/sidebar/sidebar.rs | 4 +- src/components/render_panel/render_panel.rs | 11 +- src/main.rs | 2 +- src/pipeline/offscreen_renderer.rs | 67 ++++--- src/render/cms.rs | 12 ++ src/render/interior/layers.rs | 92 +++++----- src/render/interior/mod.rs | 2 +- src/render/mod.rs | 2 +- src/render/predefined/grid_field_renderer.rs | 39 ++-- src/render/predefined/layers.rs | 11 +- src/render/renders.rs | 2 +- 13 files changed, 400 insertions(+), 160 deletions(-) create mode 100644 src/components/render_panel/monitor/_monitor.rs diff --git a/src/components/render_panel/monitor/_monitor.rs b/src/components/render_panel/monitor/_monitor.rs new file mode 100644 index 0000000..5e80533 --- /dev/null +++ b/src/components/render_panel/monitor/_monitor.rs @@ -0,0 +1,171 @@ +use crate::render::{Target, CMS}; +use crate::{ + components::render_panel::messages::{MonitorInputMsg, MonitorOutputMsg}, + coords::{proj::Mercator, Mapper}, + data::Npz, + dynamic_col::DynamicCol, + render::{predefined::color_mapper::BoundaryNorm, Layer, Render}, + OFFSCREEN, RUNTIME, +}; +use glib::clone; +use std::sync::Arc; + +use super::sidebar::{sidebar::SideBarModel, Msg, SideBarOutputMsg}; +use adw::prelude::*; +use gtk::prelude::StyleContextExt; +use gtk::subclass::root; +use relm4::{ + component::{AsyncComponent, AsyncComponentParts}, + loading_widgets::LoadingWidgets, + *, +}; +pub struct MonitorModel { + sidebar_open: bool, + sidebar_width: i32, + layers: Vec, + sidebar: Controller, +} + +pub struct MonitorWidgets { + paned: gtk::Paned, +} + +#[relm4::component(async, pub)] +impl AsyncComponent for MonitorModel { + type Init = (); + type Output = MonitorOutputMsg; + type Input = MonitorInputMsg; + type CommandOutput = (); + + view! { + adw::BreakpointBin { + set_hexpand: true, + set_vexpand: true, + set_height_request: 500, + set_width_request: 700, + #[wrap(Some)] + #[name="test"] + set_child = &DynamicCol{ + set_end_width: 300, + set_hexpand: true, + set_vexpand: true, + #[wrap(Some)] + #[name="paned"] + set_child_paned=>k::Paned{ + #[wrap(Some)] + #[name="render"] + set_start_child=>k::Frame{ + add_css_class: "rb", + set_margin_all: 5, + Render{ + add_css_class: "rb", + #[watch] + set_interior_layers: model.layers.clone(), + } + }, + #[wrap(Some)] + set_end_child=model.sidebar.widget(), + } + }, + + } + } + + async fn init( + init: Self::Init, + root: Self::Root, + sender: relm4::AsyncComponentSender, + ) -> AsyncComponentParts { + let sidebar: Controller = + SideBarModel::builder() + .launch(()) + .forward(sender.input_sender(), |msg| match msg { + SideBarOutputMsg::NewLayer(layer) => MonitorInputMsg::AddLayer(layer), + _ => MonitorInputMsg::None, + }); + let model = MonitorModel { + sidebar_open: true, + sidebar_width: 400, + layers: vec![], + sidebar, + }; + + let widgets = view_output! {}; + AsyncComponentParts { model, widgets } + } + + async fn update( + &mut self, + msg: Self::Input, + _sender: AsyncComponentSender, + _root: &Self::Root, + ) { + tokio::time::sleep(std::time::Duration::from_millis(100)).await; + match msg { + MonitorInputMsg::AddLayer(layer) => { + let f = { + let p = layer.get_prepare(); + let mut _p = p.lock().unwrap(); + _p.take() + }; + println!("hi"); + let target = if let Some(f) = f { + let imp = layer.get_imp().unwrap(); + + let map: Mapper = Mercator::default().into(); + let cms = CMS::new(map, (500.0, 500.0)); + let canvas = OFFSCREEN.canvas(); + let c = f(imp, canvas, cms).await; + Some(c) + } else { + None + }; + + // RUNTIME.spawn_blocking(|| async move { + // let f = { + // let p = layer.get_prepare(); + // let mut _p = p.lock().unwrap(); + // _p.take() + // }; + // println!("hi"); + // if let Some(f) = f { + // let imp = layer.get_imp().unwrap(); + + // let map: Mapper = Mercator::default().into(); + // let cms = CMS::new(map, (500.0, 500.0)); + // let canvas = OFFSCREEN.canvas(); + // let c = f(imp, canvas, cms).await; + // Some(c) + // } else { + // None + // } + // }); + // self.layers.push(layer); + + _sender + .output_sender() + .send(MonitorOutputMsg::LayerAdded(0)) + .unwrap(); + + self.sidebar + .sender() + .send(Msg::RefreshList(self.layers.clone())); + } + MonitorInputMsg::RemoveLayer(index) => { + self.layers.remove(index); + _sender + .output_sender() + .send(MonitorOutputMsg::LayerRemoved(0)) + .unwrap(); + } + MonitorInputMsg::UpdateLayer((idx, f)) => { + f(&mut self.layers[idx]); + _sender + .output_sender() + .send(MonitorOutputMsg::LayerUpdated(0)) + .unwrap(); + } + MonitorInputMsg::None => {} + } + } +} diff --git a/src/components/render_panel/monitor/monitor.rs b/src/components/render_panel/monitor/monitor.rs index e01d3a9..8b1f1e3 100644 --- a/src/components/render_panel/monitor/monitor.rs +++ b/src/components/render_panel/monitor/monitor.rs @@ -1,19 +1,31 @@ +use crate::pipeline::offscreen_renderer::OffscreenRenderer; +use crate::render::{Target, CMS}; use crate::{ - components::render_panel::messages::{MonitorInputMsg, MonitorOutputMsg}, coords::{proj::Mercator, Mapper}, data::Npz, dynamic_col::DynamicCol, render::{predefined::color_mapper::BoundaryNorm, Layer, Render}, OFFSCREEN, RUNTIME + components::render_panel::messages::{MonitorInputMsg, MonitorOutputMsg}, + coords::{proj::Mercator, Mapper}, + data::Npz, + dynamic_col::DynamicCol, + render::{predefined::color_mapper::BoundaryNorm, Layer, Render}, + RUNTIME, }; use glib::clone; -use std::sync::Arc; -use crate::render::CMS; +use std::sync::{Arc, Mutex}; use super::sidebar::{sidebar::SideBarModel, Msg, SideBarOutputMsg}; use adw::prelude::*; use gtk::prelude::StyleContextExt; use gtk::subclass::root; use relm4::{ - component::{AsyncComponent, AsyncComponentParts}, + component::{AsyncComponent, AsyncComponentParts, Component}, loading_widgets::LoadingWidgets, *, }; + +#[derive(Debug)] +pub enum MonitorCommand { + NewLayer(Layer), + None, +} pub struct MonitorModel { sidebar_open: bool, sidebar_width: i32, @@ -25,14 +37,15 @@ pub struct MonitorWidgets { paned: gtk::Paned, } -#[relm4::component(async, pub)] -impl AsyncComponent for MonitorModel { +#[relm4::component(pub)] +impl Component for MonitorModel { + type CommandOutput = MonitorCommand; + type Input = MonitorInputMsg; type Init = (); type Output = MonitorOutputMsg; - type Input = MonitorInputMsg; - type CommandOutput = (); view! { + #[root] adw::BreakpointBin { set_hexpand: true, set_vexpand: true, @@ -66,11 +79,68 @@ impl AsyncComponent for MonitorModel { } } - async fn init( + fn update(&mut self, message: Self::Input, sender: ComponentSender, root: &Self::Root) { + match message { + MonitorInputMsg::AddLayer(layer) => { + sender.oneshot_command(async move { + let new_canvas = OffscreenRenderer::new().unwrap(); + let f = { + let p = layer.get_prepare(); + let mut _p = p.lock().unwrap(); + _p.take() + }; + let target = if let Some(f) = f { + let imp = layer.get_imp().unwrap(); + + let map: Mapper = Mercator::default().into(); + let cms = CMS::new(map, (3000.0, 3000.0)); + let canvas = new_canvas.create_canvas(); + let canvas = Arc::new(Mutex::new(canvas)); + let c = f(imp, canvas, cms).await; + Some(c) + // None + } else { + None + }; + + if let Some(target) = target { + layer.set_render_target(target); + } + MonitorCommand::NewLayer(layer) + }); + + sender + .output_sender() + .send(MonitorOutputMsg::LayerAdded(0)) + .unwrap(); + + self.sidebar + .sender() + .send(Msg::RefreshList(self.layers.clone())); + } + MonitorInputMsg::RemoveLayer(index) => { + self.layers.remove(index); + sender + .output_sender() + .send(MonitorOutputMsg::LayerRemoved(0)) + .unwrap(); + } + MonitorInputMsg::UpdateLayer((idx, f)) => { + f(&mut self.layers[idx]); + sender + .output_sender() + .send(MonitorOutputMsg::LayerUpdated(0)) + .unwrap(); + } + MonitorInputMsg::None => {} + } + } + + fn init( init: Self::Init, - root: Self::Root, - sender: relm4::AsyncComponentSender, - ) -> AsyncComponentParts { + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { let sidebar: Controller = SideBarModel::builder() .launch(()) @@ -86,60 +156,23 @@ impl AsyncComponent for MonitorModel { }; let widgets = view_output! {}; - AsyncComponentParts { model, widgets } + ComponentParts { model, widgets } } - async fn update( + fn update_cmd( &mut self, - msg: Self::Input, - _sender: AsyncComponentSender, + msg: Self::CommandOutput, + _sender: ComponentSender, _root: &Self::Root, ) { - tokio::time::sleep(std::time::Duration::from_millis(100)).await; match msg { - MonitorInputMsg::AddLayer(layer) => { - RUNTIME.spawn_blocking(|| async move { - - - if let Some(f) = layer.get_prepare() { - let imp = layer.get_imp(); - - let map: Mapper = Mercator::default().into(); - let cms = CMS::new(map, (500.0,500.0)); - - let imp = &imp.lock().unwrap(); - - let i = imp.unwrap(); - let c = (f)(i.clone(), OFFSCREEN.canvas(),cms).await; - Some(c) - - } else {None} }); - // self.layers.push(layer); - - _sender - .output_sender() - .send(MonitorOutputMsg::LayerAdded(0)) - .unwrap(); - + MonitorCommand::NewLayer(layer) => { + self.layers.push(layer); self.sidebar .sender() .send(Msg::RefreshList(self.layers.clone())); } - MonitorInputMsg::RemoveLayer(index) => { - self.layers.remove(index); - _sender - .output_sender() - .send(MonitorOutputMsg::LayerRemoved(0)) - .unwrap(); - } - MonitorInputMsg::UpdateLayer((idx, f)) => { - f(&mut self.layers[idx]); - _sender - .output_sender() - .send(MonitorOutputMsg::LayerUpdated(0)) - .unwrap(); - } - MonitorInputMsg::None => {} + _ => {} } } } diff --git a/src/components/render_panel/monitor/sidebar/sidebar.rs b/src/components/render_panel/monitor/sidebar/sidebar.rs index 0b3f0c2..174b8ce 100644 --- a/src/components/render_panel/monitor/sidebar/sidebar.rs +++ b/src/components/render_panel/monitor/sidebar/sidebar.rs @@ -25,7 +25,7 @@ pub struct SideBarModel { #[derive(Debug)] pub enum Msg { RefreshList(Vec), - None + None, } #[derive(Debug)] @@ -65,6 +65,7 @@ impl SimpleComponent for SideBarModel { gtk::Button { set_label: "Add Layer", connect_clicked[sender] => move |_| { + println!("hello"); sender.output( SideBarOutputMsg::NewLayer( Layer::grid_render_layer_with_path( @@ -111,7 +112,6 @@ impl SimpleComponent for SideBarModel { let mut bottom_bar_vec = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender()); - { let mut bottom_bar_vec_guard = bottom_bar_vec.guard(); bottom_bar_vec_guard.push_back(BottomBarModel::new("add-filled".to_string())); diff --git a/src/components/render_panel/render_panel.rs b/src/components/render_panel/render_panel.rs index b06fedf..f1d852e 100644 --- a/src/components/render_panel/render_panel.rs +++ b/src/components/render_panel/render_panel.rs @@ -8,8 +8,8 @@ use relm4::{ }; pub struct RenderPanelModel { - // monitor: Controller, - monitor: AsyncController, + monitor: Controller, + // monitor: AsyncController, } #[relm4::component(pub)] @@ -32,10 +32,13 @@ impl SimpleComponent for RenderPanelModel { root: &Self::Root, sender: relm4::ComponentSender, ) -> relm4::ComponentParts { + // let monitor: AsyncController = MonitorModel::builder() + // .launch(()) + // .forward(sender.input_sender(), |msg| {}); - let monitor: AsyncController = MonitorModel::builder() + let monitor: Controller = MonitorModel::builder() .launch(()) - .forward(sender.input_sender(), |msg| {}); + .forward(sender.input_sender(), |_| {}); let model = RenderPanelModel { monitor }; let widgets = view_output!(); diff --git a/src/main.rs b/src/main.rs index 77ade78..d17d5f5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,7 @@ const APP_ID: &str = "org.gtk_rs.HelloWorld2"; static RUNTIME: Lazy = Lazy::new(|| Runtime::new().expect("Setting up tokio runtime needs to succeed.")); -static OFFSCREEN: Lazy = Lazy::new(|| OffscreenRenderer::new().expect("Can't create offscreen renderer.")); +// static OFFSCREEN: Lazy = Lazy::new(|| OffscreenRenderer::new().expect("Can't create offscreen renderer.")); fn main() { // Load GL pointers from epoxy (GL context management library used by GTK). diff --git a/src/pipeline/offscreen_renderer.rs b/src/pipeline/offscreen_renderer.rs index c67b272..96239a7 100644 --- a/src/pipeline/offscreen_renderer.rs +++ b/src/pipeline/offscreen_renderer.rs @@ -1,39 +1,42 @@ use euclid::Size2D; -use std::ops::{Deref, DerefMut}; use femtovg::{renderer::OpenGl, Canvas}; use lazy_static::__Deref; use std::borrow::BorrowMut; use std::num::NonZeroU32; +use std::ops::{Deref, DerefMut}; use std::sync::{Mutex, RwLock}; use std::{cell::RefCell, sync::Arc}; -use surfman::{device, Adapter, Connection, Context, Device, Error}; +use surfman::platform::system::connection; +use surfman::{ + device, Adapter, Connection, Context, ContextAttributeFlags, Device, Error, GLApi, + NativeConnection, NativeDevice, +}; pub struct OffscreenRenderer { context: Arc>, device: Device, - // renderer: Arc>, - canvas: Arc>, + fbo: NonZeroU32, + // canvas: Arc>, } impl OffscreenRenderer { pub fn new() -> Result { let connection = Connection::new()?; - let adapter = connection.create_adapter()?; + let adapter = connection.create_hardware_adapter()?; let mut device = connection.create_device(&adapter)?; - - let api = device.gl_api(); + let api = connection.gl_api(); let descriptor = device.create_context_descriptor(&surfman::ContextAttributes { version: surfman::GLVersion::new(3, 3), - flags: surfman::ContextAttributeFlags::empty(), + flags: ContextAttributeFlags::DEPTH.union(ContextAttributeFlags::STENCIL), })?; let mut context = device.create_context(&descriptor, None)?; - let mut surface = device.create_surface( + let surface = device.create_surface( &context, - surfman::SurfaceAccess::GPUOnly, + surfman::SurfaceAccess::GPUCPU, surfman::SurfaceType::Generic { - size: euclid::Size2D::new(500, 500), + size: euclid::Size2D::new(3000, 3000), }, )?; @@ -41,32 +44,39 @@ impl OffscreenRenderer { device .bind_surface_to_context(&mut context, surface) .expect("Failed to bind surface to context"); + device.make_context_current(&context).unwrap(); + Ok(Self { + context: Arc::new(RwLock::new(context)), + device, + fbo: NonZeroU32::new(surface_info.framebuffer_object).unwrap(), + }) + } + + pub fn create_canvas(&self) -> CanvasWrapper { + use glow::HasContext; static LOAD_FN: fn(&str) -> *const std::ffi::c_void = |s| epoxy::get_proc_addr(s) as *const _; let (mut renderer, fbo) = unsafe { let renderer = OpenGl::new_from_function(LOAD_FN).expect("Cannot create renderer"); - let fbo = - glow::NativeFramebuffer(NonZeroU32::new(surface_info.framebuffer_object).unwrap()); + let ctx = glow::Context::from_loader_function(LOAD_FN); + + let fbo = ctx.create_framebuffer().expect("can't create framebuffer"); + let cbo = ctx.create_buffer().expect("can't create color buffer"); + + // let id = NonZeroU32::new(ctx.get_parameter_i32(glow::DRAW_FRAMEBUFFER_BINDING) as u32) + // .expect("No GTK provided framebuffer binding"); + ctx.bind_framebuffer(glow::FRAMEBUFFER, None); + // let fbo = glow::NativeFramebuffer(id); (renderer, fbo) }; - renderer.set_screen_target(Some(fbo)); - let mut canvas = Canvas::new(renderer).expect("Cannot create canvas"); - canvas.set_size(500, 500, 1.0); + canvas.set_size(3000, 3000, 1.0); - Ok(Self { - context: Arc::new(RwLock::new(context)), - device, - canvas: Arc::new(Mutex::new(CanvasWrapper::new(canvas))), - }) - } - - pub fn canvas(&self) -> Arc>{ - self.canvas.clone() + CanvasWrapper::new(canvas) } } @@ -78,12 +88,8 @@ impl Drop for OffscreenRenderer { } } - - unsafe impl Send for OffscreenRenderer {} unsafe impl Sync for OffscreenRenderer {} - - pub struct CanvasWrapper(femtovg::Canvas); impl CanvasWrapper { @@ -106,9 +112,10 @@ impl DerefMut for CanvasWrapper { } unsafe impl Send for CanvasWrapper {} +unsafe impl Sync for CanvasWrapper {} impl Drop for CanvasWrapper { fn drop(&mut self) { let _ = self; } -} \ No newline at end of file +} diff --git a/src/render/cms.rs b/src/render/cms.rs index eba7282..6ed5896 100644 --- a/src/render/cms.rs +++ b/src/render/cms.rs @@ -1,3 +1,5 @@ +use std::ops::Range; + use geo_types::LineString; use crate::coords::Mapper; @@ -21,6 +23,16 @@ impl CMS { } } + pub fn set_lat_range(&mut self, lat_range: Range) { + self.mapper.set_lat_range(lat_range); + self.bounds = self.mapper.get_bounds() + } + + pub fn set_lon_range(&mut self, lon_range: Range) { + self.mapper.set_lon_range(lon_range); + self.bounds = self.mapper.get_bounds(); + } + pub fn map(&self, loc: (f64, f64)) -> Option<(f32, f32)> { self.mapper.map(loc).ok().map(|(x, y)| { // println!("x: {}, y: {}", x, y); diff --git a/src/render/interior/layers.rs b/src/render/interior/layers.rs index ab09c54..a33dcb0 100644 --- a/src/render/interior/layers.rs +++ b/src/render/interior/layers.rs @@ -10,29 +10,35 @@ use std::{ sync::{Arc, Mutex}, }; -type PrepareFunc = Box< - dyn FnOnce( - LayerImplSync, - // Box, - Arc>, - CMS, - ) -> Pin + Send + Sync>> - + Sync - + Send, +type PrepareFunc = Arc< + Mutex< + Option< + Box< + dyn FnOnce( + LayerImplSync, + // Box, + Arc>, + CMS, + ) + -> Pin + Send + Sync>> + + Sync + + Send, + >, + >, + >, >; -type DrawFunc = Box; +type DrawFunc = Arc; // type LayerImplSync = Box; -type LayerImplSync = Arc; +pub type LayerImplSync = Arc>>; #[derive(Clone)] pub struct Layer { pub visiable: bool, pub name: String, target: Arc>>, - // prepare: Arc>, - prepare:Option>, - imp: Arc>>, - draw: Arc, + prepare: PrepareFunc, + imp: Option>>>, + draw: DrawFunc, } impl Debug for Layer { @@ -46,17 +52,14 @@ impl Debug for Layer { } pub trait LayerImpl: Debug { - fn draw(&self, canvas: &mut Canvas, cms: &CMS) -> Option; + fn draw(&self, canvas: &mut Canvas, cms: CMS) -> Option; } impl Layer { pub fn new< FU: Future + Send + Sync + 'static, F: 'static + Fn(&Self, Render, (f32, f32)) + Send + Sync, - PREPARE: FnOnce(LayerImplSync, Arc>, CMS) -> FU - + Send - + Sync - + 'static, + PREPARE: FnOnce(LayerImplSync, Arc>, CMS) -> FU + Send + Sync + 'static, IMP: LayerImpl + Sync + Send + 'static, >( visiable: bool, @@ -69,25 +72,28 @@ impl Layer { visiable, target: Arc::new(Mutex::new(None)), name: layer_name, - // prepare: Arc::new(prepare), - prepare: prepare.map(|p| { - Arc::new(Box::new( - move |a: LayerImplSync, - b: Arc>, - c: CMS| - -> Pin + Send + Sync>> { - Box::pin(p(a, b, c)) - }, - ) as PrepareFunc) - }), + prepare: Arc::new(Mutex::new(prepare.map(|p| { + Box::new(move |a, b, c| { + Box::pin(p(a, b, c)) + as Pin + Send + Sync + 'static>> + }) + as Box< + dyn FnOnce( + LayerImplSync, + Arc>, + CMS, + ) + -> Pin + Send + Sync>> + + Sync + + Send, + > + }))), draw: Arc::new(Box::new(draw)), - imp: Arc::new(Mutex::new( - imp.map(|x| Arc::new(Mutex::new(x)) as LayerImplSync), - )), - // imp: Arc::new(Mutex::new(imp.map(|x| Box::new(x) as Box))), - // imp: RefCell::new( - // imp.map(|x| Arc::new(Box::new(x) as Box)), - // ), + imp: imp.map(|i| { + Arc::new(Mutex::new( + Box::new(i) as Box + )) + }), } } @@ -98,22 +104,20 @@ impl Layer { } } - pub fn get_prepare(&self) -> Option> { - let c= self.prepare.clone(); - c + pub fn get_prepare(&self) -> PrepareFunc { + self.prepare.clone() } pub fn set_render_target(&self, target: Target) { self.target.lock().unwrap().replace(target); - // *self.target.borrow_mut() = Some(target); } pub fn render_target(&self) -> Option { self.target.lock().unwrap().clone() - // self.target.borrow().clone() } - pub fn get_imp(&self) -> Arc>> { + pub fn get_imp(&self) -> Option>>> { + // self.imp.map(|p| p.clone()) self.imp.clone() } } diff --git a/src/render/interior/mod.rs b/src/render/interior/mod.rs index aa496a7..32f4347 100644 --- a/src/render/interior/mod.rs +++ b/src/render/interior/mod.rs @@ -2,7 +2,7 @@ mod imp; mod layers; use crate::render::Render; use femtovg::{renderer::OpenGl, Canvas}; -pub use layers::{Layer, LayerImpl, Target}; +pub use layers::{Layer, LayerImpl, LayerImplSync, Target}; use std::cell::Ref; use crate::render::imp::{RenderConfig, RenderStatus}; diff --git a/src/render/mod.rs b/src/render/mod.rs index 78da0f4..7b1e664 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -14,7 +14,7 @@ use glib::clone; pub use glib::subclass::prelude::*; use gtk::traits::WidgetExt; use gtk::{EventControllerScrollFlags, Inhibit}; -pub use interior::{Layer, LayerImpl, Target}; +pub use interior::{Layer, LayerImpl, LayerImplSync, Target}; use relm4::once_cell::sync::Lazy; use std::cell::{Ref, RefCell, RefMut}; use std::sync::{Arc, Mutex}; diff --git a/src/render/predefined/grid_field_renderer.rs b/src/render/predefined/grid_field_renderer.rs index 00b6aac..30746b2 100644 --- a/src/render/predefined/grid_field_renderer.rs +++ b/src/render/predefined/grid_field_renderer.rs @@ -100,7 +100,7 @@ where fn render( &self, canvas: &mut Canvas, - cms: &CMS, + mut cms: CMS, data: &Self::Data, size: (f32, f32), ) -> Target { @@ -109,18 +109,32 @@ where .create_image_empty(w as usize, h as usize, Rgba8, ImageFlags::empty()) .expect("Can't Create Image"); + canvas.image_size(new_img).unwrap(); + canvas.set_render_target(RenderTarget::Image(new_img)); + let _data = data.data.view(); let (_dim1, _dim2) = meshgrid(data.dim1.view(), data.dim2.view()); + let lat_start = data.dim2.view().first().unwrap().clone(); + let lat_end = data.dim2.view().last().unwrap().clone(); + + let lon_start = data.dim1.view().first().unwrap().clone(); + let lon_end = data.dim1.view().last().unwrap().clone(); + + cms.set_lat_range(lat_start..lat_end); + cms.set_lon_range(lon_start..lon_end); + self.draw_2d( canvas, - cms, + &cms, _data, (_dim1.view(), _dim2.view()), (w, h), data.fill_value, ); + canvas.set_render_target(RenderTarget::Screen); + let d1_start = (data.dim1.view()).first().unwrap().clone(); let d1_end = (data.dim1.view()).last().unwrap().clone(); @@ -170,19 +184,14 @@ where fn draw( &self, canvas: &mut femtovg::Canvas, - cms: &crate::render::cms::CMS, + cms: crate::render::cms::CMS, ) -> Option { - let new_img = canvas - .create_image_empty(3000, 3000, Rgba8, ImageFlags::empty()) - .expect("Can't Create Image"); - - if let Ok(_) = canvas.image_size(new_img) { - canvas.reset(); - canvas.set_render_target(RenderTarget::Image(new_img)); - } - - canvas.set_render_target(RenderTarget::Screen); - - Some(self.renderer.render(canvas,cms, &self.data, (3000.0, 3000.0))) + canvas.save(); + canvas.reset(); + let result = self + .renderer + .render(canvas, cms, &self.data, (3000.0, 3000.0)); + canvas.restore(); + return Some(result); } } diff --git a/src/render/predefined/layers.rs b/src/render/predefined/layers.rs index 8367e9c..673b65b 100644 --- a/src/render/predefined/layers.rs +++ b/src/render/predefined/layers.rs @@ -1,3 +1,5 @@ +use femtovg::ImageFlags; +use femtovg::PixelFormat::Rgba8; use femtovg::{renderer::OpenGl, Canvas, Paint}; use num_traits::{Num, NumOps}; use std::path::Path; @@ -6,6 +8,7 @@ use std::sync::Mutex; use crate::pipeline::offscreen_renderer::CanvasWrapper; use crate::render::cms::CMS; +use crate::render::LayerImplSync; use crate::render::{LayerImpl, Target}; use crate::{ data::{AsyncDataLoader, DataLoader, Radar2d}, @@ -41,12 +44,10 @@ impl Layer { }, layer_name, Some( - |renderer: Arc>, - c: Arc>, - cms: CMS| async move { + |renderer: LayerImplSync, c: Arc>, cms: CMS| async move { let mut canvas = c.lock().unwrap(); - let c = &mut *canvas; - let img = renderer.lock().unwrap().draw(c, &cms).unwrap(); + let renderer = renderer.lock().unwrap(); + let img = renderer.draw(&mut canvas, cms).unwrap(); img }, ), diff --git a/src/render/renders.rs b/src/render/renders.rs index 455be2f..1826950 100644 --- a/src/render/renders.rs +++ b/src/render/renders.rs @@ -8,7 +8,7 @@ pub trait DataRenderer { fn render( &self, canvas: &mut Canvas, - cms: &CMS, + cms: CMS, data: &Self::Data, size: (f32, f32), ) -> Target;