This commit is contained in:
sleptworld 2024-01-19 01:02:37 +08:00
parent 99c3bf35d7
commit 33afd78b9b
8 changed files with 265 additions and 200 deletions

View File

@ -1,11 +1,9 @@
use crate::{ use crate::{
components::render_panel::messages::{MonitorInputMsg, MonitorOutputMsg}, components::render_panel::messages::{MonitorInputMsg, MonitorOutputMsg}, coords::{proj::Mercator, Mapper}, data::Npz, dynamic_col::DynamicCol, render::{predefined::color_mapper::BoundaryNorm, Layer, Render}, OFFSCREEN, RUNTIME
data::Npz,
dynamic_col::DynamicCol,
render::{predefined::color_mapper::BoundaryNorm, Layer, Render},
}; };
use glib::clone; use glib::clone;
use std::sync::Arc; use std::sync::Arc;
use crate::render::CMS;
use super::sidebar::{sidebar::SideBarModel, Msg, SideBarOutputMsg}; use super::sidebar::{sidebar::SideBarModel, Msg, SideBarOutputMsg};
use adw::prelude::*; use adw::prelude::*;
@ -100,7 +98,24 @@ impl AsyncComponent for MonitorModel {
tokio::time::sleep(std::time::Duration::from_millis(100)).await; tokio::time::sleep(std::time::Duration::from_millis(100)).await;
match msg { match msg {
MonitorInputMsg::AddLayer(layer) => { MonitorInputMsg::AddLayer(layer) => {
self.layers.push(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 _sender
.output_sender() .output_sender()
.send(MonitorOutputMsg::LayerAdded(0)) .send(MonitorOutputMsg::LayerAdded(0))

View File

@ -11,6 +11,10 @@ pub struct Mapper {
bounds: (f64, f64, f64, f64), bounds: (f64, f64, f64, f64),
} }
unsafe impl Send for Mapper {}
unsafe impl Sync for Mapper {}
impl Clone for Mapper { impl Clone for Mapper {
fn clone(&self) -> Self { fn clone(&self) -> Self {
let c = self.proj.proj_info(); let c = self.proj.proj_info();

View File

@ -1,5 +1,8 @@
use euclid::Size2D; use euclid::Size2D;
use std::ops::{Deref, DerefMut};
use femtovg::{renderer::OpenGl, Canvas}; use femtovg::{renderer::OpenGl, Canvas};
use lazy_static::__Deref;
use std::borrow::BorrowMut;
use std::num::NonZeroU32; use std::num::NonZeroU32;
use std::sync::{Mutex, RwLock}; use std::sync::{Mutex, RwLock};
use std::{cell::RefCell, sync::Arc}; use std::{cell::RefCell, sync::Arc};
@ -9,7 +12,7 @@ pub struct OffscreenRenderer {
context: Arc<RwLock<Context>>, context: Arc<RwLock<Context>>,
device: Device, device: Device,
// renderer: Arc<Mutex<femtovg::renderer::OpenGl>>, // renderer: Arc<Mutex<femtovg::renderer::OpenGl>>,
canvas: Arc<RwLock<Canvas<OpenGl>>>, canvas: Arc<Mutex<CanvasWrapper>>,
} }
impl OffscreenRenderer { impl OffscreenRenderer {
@ -58,11 +61,11 @@ impl OffscreenRenderer {
Ok(Self { Ok(Self {
context: Arc::new(RwLock::new(context)), context: Arc::new(RwLock::new(context)),
device, device,
canvas: Arc::new(RwLock::new(canvas)), canvas: Arc::new(Mutex::new(CanvasWrapper::new(canvas))),
}) })
} }
pub fn canvas(&self) -> Arc<RwLock<Canvas<OpenGl>>> { pub fn canvas(&self) -> Arc<Mutex<CanvasWrapper>>{
self.canvas.clone() self.canvas.clone()
} }
} }
@ -75,5 +78,37 @@ impl Drop for OffscreenRenderer {
} }
} }
unsafe impl Send for OffscreenRenderer {} unsafe impl Send for OffscreenRenderer {}
unsafe impl Sync for OffscreenRenderer {} unsafe impl Sync for OffscreenRenderer {}
pub struct CanvasWrapper(femtovg::Canvas<OpenGl>);
impl CanvasWrapper {
fn new(canvas: femtovg::Canvas<OpenGl>) -> Self {
Self(canvas)
}
}
impl Deref for CanvasWrapper {
type Target = femtovg::Canvas<OpenGl>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for CanvasWrapper {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
unsafe impl Send for CanvasWrapper {}
impl Drop for CanvasWrapper {
fn drop(&mut self) {
let _ = self;
}
}

View File

@ -1,8 +1,7 @@
use crate::pipeline::offscreen_renderer::CanvasWrapper;
use crate::render::cms::CMS; use crate::render::cms::CMS;
use crate::{coords::Range, render::Render}; use crate::{coords::Range, render::Render};
use femtovg::Paint;
use femtovg::{renderer::OpenGl, Canvas, ImageId}; use femtovg::{renderer::OpenGl, Canvas, ImageId};
use ndarray::AssignElem;
use std::{ use std::{
cell::{Ref, RefCell}, cell::{Ref, RefCell},
fmt::Debug, fmt::Debug,
@ -13,24 +12,26 @@ use std::{
type PrepareFunc = Box< type PrepareFunc = Box<
dyn FnOnce( dyn FnOnce(
Box<dyn LayerImpl>, LayerImplSync,
&mut Canvas<OpenGl>, // Box<dyn LayerImpl + Send + Sync>,
Arc<Mutex<CanvasWrapper>>,
CMS, CMS,
) -> Pin<Box<dyn Future<Output = Target>>> ) -> Pin<Box<dyn Future<Output = Target> + Send + Sync>>
+ Sync + Sync
+ Send, + Send,
>; >;
type DrawFunc = Box<dyn Fn(&Layer, Render, (f32, f32)) + Send + Sync>; type DrawFunc = Box<dyn Fn(&Layer, Render, (f32, f32)) + Send + Sync>;
type LayerImplSync = Box<dyn LayerImpl + Send + Sync>; // type LayerImplSync = Box<dyn LayerImpl + Send + Sync>;
type LayerImplSync = Arc<dyn LayerImpl + Send + Sync>;
#[derive(Clone)] #[derive(Clone)]
pub struct Layer { pub struct Layer {
pub visiable: bool, pub visiable: bool,
pub name: String, pub name: String,
snapshot: Option<gtk::gdk::Texture>, target: Arc<Mutex<Option<Target>>>,
target: RefCell<Option<Target>>, // prepare: Arc<Option<PrepareFunc>>,
prepare: Arc<Option<PrepareFunc>>, prepare:Option<Arc<PrepareFunc>>,
imp: RefCell<Option<Arc<LayerImplSync>>>, imp: Arc<Mutex<Option<LayerImplSync>>>,
draw: Arc<DrawFunc>, draw: Arc<DrawFunc>,
} }
@ -52,7 +53,10 @@ impl Layer {
pub fn new< pub fn new<
FU: Future<Output = Target> + Send + Sync + 'static, FU: Future<Output = Target> + Send + Sync + 'static,
F: 'static + Fn(&Self, Render, (f32, f32)) + Send + Sync, F: 'static + Fn(&Self, Render, (f32, f32)) + Send + Sync,
PREPARE: FnOnce(Box<dyn LayerImpl>, &mut Canvas<OpenGl>, CMS) -> FU + Send + Sync + 'static, PREPARE: FnOnce(LayerImplSync, Arc<Mutex<CanvasWrapper>>, CMS) -> FU
+ Send
+ Sync
+ 'static,
IMP: LayerImpl + Sync + Send + 'static, IMP: LayerImpl + Sync + Send + 'static,
>( >(
visiable: bool, visiable: bool,
@ -63,21 +67,27 @@ impl Layer {
) -> Self { ) -> Self {
Layer { Layer {
visiable, visiable,
target: RefCell::new(None), target: Arc::new(Mutex::new(None)),
name: layer_name, name: layer_name,
snapshot: None,
// prepare: Arc::new(prepare), // prepare: Arc::new(prepare),
prepare: Arc::new(prepare.map(|p| { prepare: prepare.map(|p| {
Box::new( Arc::new(Box::new(
move |layer: Arc<Layer>, render: Render| -> Pin<Box<dyn Future<Output = ()>>> { move |a: LayerImplSync,
Box::pin(p(layer, render)) b: Arc<Mutex<CanvasWrapper>>,
c: CMS|
-> Pin<Box<dyn Future<Output = Target> + Send + Sync>> {
Box::pin(p(a, b, c))
}, },
) as PrepareFunc ) as PrepareFunc)
})), }),
draw: Arc::new(Box::new(draw)), draw: Arc::new(Box::new(draw)),
imp: RefCell::new( imp: Arc::new(Mutex::new(
imp.map(|x| Arc::new(Box::new(x) as Box<dyn LayerImpl + Send + Sync>)), imp.map(|x| Arc::new(Mutex::new(x)) as LayerImplSync),
), )),
// imp: Arc::new(Mutex::new(imp.map(|x| Box::new(x) as Box<dyn LayerImpl + Send + Sync>))),
// imp: RefCell::new(
// imp.map(|x| Arc::new(Box::new(x) as Box<dyn LayerImpl + Send + Sync>)),
// ),
} }
} }
@ -88,21 +98,23 @@ impl Layer {
} }
} }
pub fn get_prepare(&self) -> Option<&PrepareFunc> { pub fn get_prepare(&self) -> Option<Arc<PrepareFunc>> {
self.prepare.as_ref().as_ref() let c= self.prepare.clone();
c
} }
pub fn set_render_target(&self, target: Target) { pub fn set_render_target(&self, target: Target) {
*self.target.borrow_mut() = Some(target); self.target.lock().unwrap().replace(target);
// *self.target.borrow_mut() = Some(target);
} }
pub fn render_target(&self) -> Option<Target> { pub fn render_target(&self) -> Option<Target> {
self.target.borrow().clone() self.target.lock().unwrap().clone()
// self.target.borrow().clone()
} }
pub fn get_imp(&self) -> Ref<Option<Arc<LayerImplSync>>> { pub fn get_imp(&self) -> Arc<Mutex<Option<LayerImplSync>>> {
let im = self.imp.borrow(); self.imp.clone()
im
} }
} }

View File

@ -4,7 +4,7 @@ mod imp;
mod interior; mod interior;
pub mod predefined; pub mod predefined;
mod renders; mod renders;
use self::cms::CMS; pub use self::cms::CMS;
pub use self::imp::{RenderConfig, RenderMotion, RenderStatus}; pub use self::imp::{RenderConfig, RenderMotion, RenderStatus};
use crate::coords::Mapper; use crate::coords::Mapper;
use crate::RUNTIME; use crate::RUNTIME;

View File

@ -9,44 +9,44 @@ use femtovg::{Canvas, Paint};
use geo_types::LineString; use geo_types::LineString;
use geojson::GeoJson; use geojson::GeoJson;
impl Layer { // impl Layer {
pub fn map_layer_with_geojson_by_path(path: impl AsRef<Path>) -> Self { // pub fn map_layer_with_geojson_by_path(path: impl AsRef<Path>) -> Self {
let geojson = std::fs::read_to_string(path).unwrap(); // let geojson = std::fs::read_to_string(path).unwrap();
let json = geojson.parse::<GeoJson>().unwrap(); // let json = geojson.parse::<GeoJson>().unwrap();
Self::map_layer_with_geojson(json) // Self::map_layer_with_geojson(json)
} // }
pub fn map_layer_with_geojson(json: GeoJson) -> Self { // pub fn map_layer_with_geojson(json: GeoJson) -> Self {
let mut layer = Layer::new( // let mut layer = Layer::new(
true, // true,
|s, render, _| { // |s, render, _| {
if let Some(renderer) = s.get_imp().as_ref() { // if let Some(renderer) = s.get_imp().as_ref() {
renderer.draw(render.clone()); // renderer.draw(render.clone());
} // }
}, // },
"Map".into(), // "Map".into(),
Some(|_, _| async {}), // Some(|_, _| async {}),
Some(GeoJsonMapImpl::new(json)), // Some(GeoJsonMapImpl::new(json)),
); // );
layer // layer
} // }
pub fn meshgrid_layer() -> Self { // pub fn meshgrid_layer() -> Self {
let mut layer = Layer::new( // let mut layer = Layer::new(
true, // true,
|s, render, _| { // |s, render, _| {
if let Some(renderer) = s.get_imp().as_ref() { // if let Some(renderer) = s.get_imp().as_ref() {
renderer.draw(render.clone()); // renderer.draw(render.clone());
} // }
}, // },
"MeshGrid".into(), // "MeshGrid".into(),
Some(|_, _| async {}), // Some(|_, _| async {}),
Some(MeshGridImpl), // Some(MeshGridImpl),
); // );
layer // layer
} // }
} // }
#[derive(Debug)] #[derive(Debug)]
struct GeoJsonMapImpl { struct GeoJsonMapImpl {
@ -59,101 +59,101 @@ impl GeoJsonMapImpl {
} }
} }
impl LayerImpl for GeoJsonMapImpl { // impl LayerImpl for GeoJsonMapImpl {
fn draw(&self, render: Render) -> Option<crate::render::Target> { // fn draw(&self, render: Render) -> Option<crate::render::Target> {
let paint = Paint::color(femtovg::Color::rgb(255, 255, 255)); // let paint = Paint::color(femtovg::Color::rgb(255, 255, 255));
let geojson = &self.geojson; // let geojson = &self.geojson;
let mut canvas = render.get_canvas(); // let mut canvas = render.get_canvas();
let canvas = canvas.as_mut().unwrap(); // let canvas = canvas.as_mut().unwrap();
if let GeoJson::FeatureCollection(ref feature_collection) = geojson { // if let GeoJson::FeatureCollection(ref feature_collection) = geojson {
for feature in &feature_collection.features { // for feature in &feature_collection.features {
feature // feature
.geometry // .geometry
.as_ref() // .as_ref()
.iter() // .iter()
.for_each(|geometry| match geometry.value { // .for_each(|geometry| match geometry.value {
geojson::Value::Polygon(ref polygon) => { // geojson::Value::Polygon(ref polygon) => {
let mut path = femtovg::Path::new(); // let mut path = femtovg::Path::new();
let polygon = &polygon[0]; // let polygon = &polygon[0];
for (i, point) in polygon.iter().enumerate() { // for (i, point) in polygon.iter().enumerate() {
let _point = (point[0], point[1]); // let _point = (point[0], point[1]);
if render.point_in_bound(_point) { // if render.point_in_bound(_point) {
let (x, y) = render.map(_point).unwrap(); // let (x, y) = render.map(_point).unwrap();
if i == 0 { // if i == 0 {
path.move_to(x, y); // path.move_to(x, y);
} else { // } else {
path.line_to(x, y); // path.line_to(x, y);
} // }
} // }
} // }
} // }
geojson::Value::MultiPolygon(ref multi_polygon) => { // geojson::Value::MultiPolygon(ref multi_polygon) => {
let mut path = femtovg::Path::new(); // let mut path = femtovg::Path::new();
for polygon in multi_polygon { // for polygon in multi_polygon {
let out_ring = &polygon[0]; // let out_ring = &polygon[0];
let out_ring_line: LineString = out_ring // let out_ring_line: LineString = out_ring
.iter() // .iter()
.map(|x| (x[0], x[1])) // .map(|x| (x[0], x[1]))
.collect::<Vec<_>>() // .collect::<Vec<_>>()
.into(); // .into();
let out_ring = render.ring_map(&out_ring_line).unwrap(); // let out_ring = render.ring_map(&out_ring_line).unwrap();
for (i, point) in out_ring.points().enumerate() { // for (i, point) in out_ring.points().enumerate() {
let (x, y) = (point.x(), point.y()); // let (x, y) = (point.x(), point.y());
if i == 0 { // if i == 0 {
path.move_to(x, y); // path.move_to(x, y);
} else { // } else {
path.line_to(x, y); // path.line_to(x, y);
} // }
} // }
} // }
canvas.stroke_path(&mut path, &paint); // canvas.stroke_path(&mut path, &paint);
} // }
_ => println!("Unknown geometry type: {:?}", geometry.value), // _ => println!("Unknown geometry type: {:?}", geometry.value),
}); // });
} // }
} // }
None // None
} // }
} // }
#[derive(Debug)] #[derive(Debug)]
struct MeshGridImpl; struct MeshGridImpl;
impl LayerImpl for MeshGridImpl { // impl LayerImpl for MeshGridImpl {
fn draw(&self, render: Render) -> Option<crate::render::Target> { // fn draw(&self, render: Render) -> Option<crate::render::Target> {
let mut canvas = render.get_canvas(); // let mut canvas = render.get_canvas();
let canvas = canvas.as_mut().unwrap(); // let canvas = canvas.as_mut().unwrap();
let (lon_range, lat_range) = render.render_range(); // let (lon_range, lat_range) = render.render_range();
let (lon_range, lat_range): (Range, Range) = (lon_range.into(), lat_range.into()); // let (lon_range, lat_range): (Range, Range) = (lon_range.into(), lat_range.into());
let lon_keypoints = lon_range.key_points(10); // let lon_keypoints = lon_range.key_points(10);
let lat_keypoints = lat_range.key_points(5); // let lat_keypoints = lat_range.key_points(5);
for lon in lon_keypoints.iter() { // for lon in lon_keypoints.iter() {
let mut path = femtovg::Path::new(); // let mut path = femtovg::Path::new();
render // render
.map((*lon, lat_range.0)) // .map((*lon, lat_range.0))
.map(|(x, y)| path.move_to(x, y)); // .map(|(x, y)| path.move_to(x, y));
render // render
.map((*lon, lat_range.1)) // .map((*lon, lat_range.1))
.map(|(x, y)| path.line_to(x, y)); // .map(|(x, y)| path.line_to(x, y));
canvas.stroke_path(&mut path, &Paint::color(femtovg::Color::rgb(255, 255, 255))); // canvas.stroke_path(&mut path, &Paint::color(femtovg::Color::rgb(255, 255, 255)));
} // }
for lat in lat_keypoints.iter() { // for lat in lat_keypoints.iter() {
let mut path = femtovg::Path::new(); // let mut path = femtovg::Path::new();
render // render
.map((lon_range.0, *lat)) // .map((lon_range.0, *lat))
.map(|(x, y)| path.move_to(x, y)); // .map(|(x, y)| path.move_to(x, y));
render // render
.map((lon_range.1, *lat)) // .map((lon_range.1, *lat))
.map(|(x, y)| path.line_to(x, y)); // .map(|(x, y)| path.line_to(x, y));
canvas.stroke_path(&mut path, &Paint::color(femtovg::Color::rgb(255, 255, 255))); // canvas.stroke_path(&mut path, &Paint::color(femtovg::Color::rgb(255, 255, 255)));
} // }
None // None
} // }
} // }

View File

@ -105,32 +105,38 @@ where
size: (f32, f32), size: (f32, f32),
) -> Target { ) -> Target {
let (w, h) = size; let (w, h) = size;
let new_img = canvas
.create_image_empty(w as usize, h as usize, Rgba8, ImageFlags::empty())
.expect("Can't Create Image");
let _data = data.data.view();
let (_dim1, _dim2) = meshgrid(data.dim1.view(), data.dim2.view());
self.draw_2d(
canvas,
cms,
_data,
(_dim1.view(), _dim2.view()),
(w, h),
data.fill_value,
);
let d1_start = (data.dim1.view()).first().unwrap().clone();
let d1_end = (data.dim1.view()).last().unwrap().clone();
let d2_start = data.dim2.view().first().unwrap().clone();
let d2_end = data.dim2.view().last().unwrap().clone();
Target::new(
new_img,
w,
h,
((d1_start, d1_end).into(), (d2_start, d2_end).into()),
)
} }
// fn render(&self, canvas: &mut Canvas<OpenGl>, cms: &CMS, data: &Self::Data) -> Target { // fn render(&self, canvas: &mut Canvas<OpenGl>, cms: &CMS, data: &Self::Data) -> Target {
// let _data = data.data.view();
// let (_dim1, _dim2) = meshgrid(data.dim1.view(), data.dim2.view());
// self.draw_2d(
// canvas,
// cms,
// _data,
// (_dim1.view(), _dim2.view()),
// (3000.0, 3000.0),
// data.fill_value,
// );
// let d1_start = (data.dim1.view()).first().unwrap().clone();
// let d1_end = (data.dim1.view()).last().unwrap().clone();
// let d2_start = data.dim2.view().first().unwrap().clone();
// let d2_end = data.dim2.view().last().unwrap().clone();
// Target::new(
// new_img,
// 3000f32,
// 3000f32,
// ((d1_start, d1_end).into(), (d2_start, d2_end).into()),
// )
// } // }
} }
@ -177,6 +183,6 @@ where
canvas.set_render_target(RenderTarget::Screen); canvas.set_render_target(RenderTarget::Screen);
Some(self.renderer.render(Render::new(canvas, cms), &self.data)) Some(self.renderer.render(canvas,cms, &self.data, (3000.0, 3000.0)))
} }
} }

View File

@ -1,12 +1,12 @@
use femtovg::{renderer::OpenGl, Canvas, Paint}; use femtovg::{renderer::OpenGl, Canvas, Paint};
use num_traits::{Num, NumOps}; use num_traits::{Num, NumOps};
use std::path::Path;
use std::sync::Arc; use std::sync::Arc;
use std::thread::spawn; use std::sync::Mutex;
use std::{os::unix::thread, path::Path};
use crate::pipeline::offscreen_renderer::CanvasWrapper;
use crate::render::cms::CMS; use crate::render::cms::CMS;
use crate::render::{LayerImpl, Target}; use crate::render::{LayerImpl, Target};
use crate::OFFSCREEN;
use crate::{ use crate::{
data::{AsyncDataLoader, DataLoader, Radar2d}, data::{AsyncDataLoader, DataLoader, Radar2d},
render::{Layer, Render}, render::{Layer, Render},
@ -41,20 +41,13 @@ impl Layer {
}, },
layer_name, layer_name,
Some( Some(
|s_imp: Box<dyn LayerImpl>, c: &mut Canvas<OpenGl>, cms: CMS| async move { |renderer: Arc<Mutex<dyn LayerImpl + Send + Sync>>,
if let Some(renderer) = s.as_ref() { c: Arc<Mutex<CanvasWrapper>>,
let img = renderer.draw(render.clone()).unwrap(); cms: CMS| async move {
if let Ok(_) = c.image_size(img.target) { let mut canvas = c.lock().unwrap();
let (x, y) = img.size(&render); let c = &mut *canvas;
let (ox, oy) = img.origin(&render); let img = renderer.lock().unwrap().draw(c, &cms).unwrap();
println!("{} {} {} {}", x, y, ox, oy); img
let painter = Paint::image(img.target, ox, oy, x, y, 0.0, 1.0);
let mut path = femtovg::Path::new();
path.rect(ox, oy, x, y);
s.set_render_target(img);
c.fill_path(&path, &painter);
}
}
}, },
), ),
Some(GridLayerImpl::new(GridFieldRenderer::new(color_map), data)), Some(GridLayerImpl::new(GridFieldRenderer::new(color_map), data)),