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::{
components::render_panel::messages::{MonitorInputMsg, MonitorOutputMsg},
data::Npz,
dynamic_col::DynamicCol,
render::{predefined::color_mapper::BoundaryNorm, Layer, Render},
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 crate::render::CMS;
use super::sidebar::{sidebar::SideBarModel, Msg, SideBarOutputMsg};
use adw::prelude::*;
@ -100,7 +98,24 @@ impl AsyncComponent for MonitorModel {
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
match msg {
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
.output_sender()
.send(MonitorOutputMsg::LayerAdded(0))

View File

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

View File

@ -1,5 +1,8 @@
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::sync::{Mutex, RwLock};
use std::{cell::RefCell, sync::Arc};
@ -9,7 +12,7 @@ pub struct OffscreenRenderer {
context: Arc<RwLock<Context>>,
device: Device,
// renderer: Arc<Mutex<femtovg::renderer::OpenGl>>,
canvas: Arc<RwLock<Canvas<OpenGl>>>,
canvas: Arc<Mutex<CanvasWrapper>>,
}
impl OffscreenRenderer {
@ -58,11 +61,11 @@ impl OffscreenRenderer {
Ok(Self {
context: Arc::new(RwLock::new(context)),
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()
}
}
@ -75,5 +78,37 @@ impl Drop for OffscreenRenderer {
}
}
unsafe impl Send 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::{coords::Range, render::Render};
use femtovg::Paint;
use femtovg::{renderer::OpenGl, Canvas, ImageId};
use ndarray::AssignElem;
use std::{
cell::{Ref, RefCell},
fmt::Debug,
@ -13,24 +12,26 @@ use std::{
type PrepareFunc = Box<
dyn FnOnce(
Box<dyn LayerImpl>,
&mut Canvas<OpenGl>,
LayerImplSync,
// Box<dyn LayerImpl + Send + Sync>,
Arc<Mutex<CanvasWrapper>>,
CMS,
) -> Pin<Box<dyn Future<Output = Target>>>
) -> Pin<Box<dyn Future<Output = Target> + Send + Sync>>
+ Sync
+ Send,
>;
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)]
pub struct Layer {
pub visiable: bool,
pub name: String,
snapshot: Option<gtk::gdk::Texture>,
target: RefCell<Option<Target>>,
prepare: Arc<Option<PrepareFunc>>,
imp: RefCell<Option<Arc<LayerImplSync>>>,
target: Arc<Mutex<Option<Target>>>,
// prepare: Arc<Option<PrepareFunc>>,
prepare:Option<Arc<PrepareFunc>>,
imp: Arc<Mutex<Option<LayerImplSync>>>,
draw: Arc<DrawFunc>,
}
@ -52,7 +53,10 @@ impl Layer {
pub fn new<
FU: Future<Output = Target> + Send + Sync + 'static,
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,
>(
visiable: bool,
@ -63,21 +67,27 @@ impl Layer {
) -> Self {
Layer {
visiable,
target: RefCell::new(None),
target: Arc::new(Mutex::new(None)),
name: layer_name,
snapshot: None,
// prepare: Arc::new(prepare),
prepare: Arc::new(prepare.map(|p| {
Box::new(
move |layer: Arc<Layer>, render: Render| -> Pin<Box<dyn Future<Output = ()>>> {
Box::pin(p(layer, render))
prepare: prepare.map(|p| {
Arc::new(Box::new(
move |a: LayerImplSync,
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)),
imp: RefCell::new(
imp.map(|x| Arc::new(Box::new(x) as Box<dyn LayerImpl + Send + Sync>)),
),
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<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> {
self.prepare.as_ref().as_ref()
pub fn get_prepare(&self) -> Option<Arc<PrepareFunc>> {
let c= self.prepare.clone();
c
}
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> {
self.target.borrow().clone()
self.target.lock().unwrap().clone()
// self.target.borrow().clone()
}
pub fn get_imp(&self) -> Ref<Option<Arc<LayerImplSync>>> {
let im = self.imp.borrow();
im
pub fn get_imp(&self) -> Arc<Mutex<Option<LayerImplSync>>> {
self.imp.clone()
}
}

View File

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

View File

@ -9,44 +9,44 @@ use femtovg::{Canvas, Paint};
use geo_types::LineString;
use geojson::GeoJson;
impl Layer {
pub fn map_layer_with_geojson_by_path(path: impl AsRef<Path>) -> Self {
let geojson = std::fs::read_to_string(path).unwrap();
let json = geojson.parse::<GeoJson>().unwrap();
Self::map_layer_with_geojson(json)
}
// impl Layer {
// pub fn map_layer_with_geojson_by_path(path: impl AsRef<Path>) -> Self {
// let geojson = std::fs::read_to_string(path).unwrap();
// let json = geojson.parse::<GeoJson>().unwrap();
// Self::map_layer_with_geojson(json)
// }
pub fn map_layer_with_geojson(json: GeoJson) -> Self {
let mut layer = Layer::new(
true,
|s, render, _| {
if let Some(renderer) = s.get_imp().as_ref() {
renderer.draw(render.clone());
}
},
"Map".into(),
Some(|_, _| async {}),
Some(GeoJsonMapImpl::new(json)),
);
layer
}
// pub fn map_layer_with_geojson(json: GeoJson) -> Self {
// let mut layer = Layer::new(
// true,
// |s, render, _| {
// if let Some(renderer) = s.get_imp().as_ref() {
// renderer.draw(render.clone());
// }
// },
// "Map".into(),
// Some(|_, _| async {}),
// Some(GeoJsonMapImpl::new(json)),
// );
// layer
// }
pub fn meshgrid_layer() -> Self {
let mut layer = Layer::new(
true,
|s, render, _| {
if let Some(renderer) = s.get_imp().as_ref() {
renderer.draw(render.clone());
}
},
"MeshGrid".into(),
Some(|_, _| async {}),
Some(MeshGridImpl),
);
// pub fn meshgrid_layer() -> Self {
// let mut layer = Layer::new(
// true,
// |s, render, _| {
// if let Some(renderer) = s.get_imp().as_ref() {
// renderer.draw(render.clone());
// }
// },
// "MeshGrid".into(),
// Some(|_, _| async {}),
// Some(MeshGridImpl),
// );
layer
}
}
// layer
// }
// }
#[derive(Debug)]
struct GeoJsonMapImpl {
@ -59,101 +59,101 @@ impl GeoJsonMapImpl {
}
}
impl LayerImpl for GeoJsonMapImpl {
fn draw(&self, render: Render) -> Option<crate::render::Target> {
let paint = Paint::color(femtovg::Color::rgb(255, 255, 255));
let geojson = &self.geojson;
// impl LayerImpl for GeoJsonMapImpl {
// fn draw(&self, render: Render) -> Option<crate::render::Target> {
// let paint = Paint::color(femtovg::Color::rgb(255, 255, 255));
// let geojson = &self.geojson;
let mut canvas = render.get_canvas();
let canvas = canvas.as_mut().unwrap();
// let mut canvas = render.get_canvas();
// let canvas = canvas.as_mut().unwrap();
if let GeoJson::FeatureCollection(ref feature_collection) = geojson {
for feature in &feature_collection.features {
feature
.geometry
.as_ref()
.iter()
.for_each(|geometry| match geometry.value {
geojson::Value::Polygon(ref polygon) => {
let mut path = femtovg::Path::new();
let polygon = &polygon[0];
for (i, point) in polygon.iter().enumerate() {
let _point = (point[0], point[1]);
if render.point_in_bound(_point) {
let (x, y) = render.map(_point).unwrap();
if i == 0 {
path.move_to(x, y);
} else {
path.line_to(x, y);
}
}
}
}
geojson::Value::MultiPolygon(ref multi_polygon) => {
let mut path = femtovg::Path::new();
for polygon in multi_polygon {
let out_ring = &polygon[0];
let out_ring_line: LineString = out_ring
.iter()
.map(|x| (x[0], x[1]))
.collect::<Vec<_>>()
.into();
let out_ring = render.ring_map(&out_ring_line).unwrap();
// if let GeoJson::FeatureCollection(ref feature_collection) = geojson {
// for feature in &feature_collection.features {
// feature
// .geometry
// .as_ref()
// .iter()
// .for_each(|geometry| match geometry.value {
// geojson::Value::Polygon(ref polygon) => {
// let mut path = femtovg::Path::new();
// let polygon = &polygon[0];
// for (i, point) in polygon.iter().enumerate() {
// let _point = (point[0], point[1]);
// if render.point_in_bound(_point) {
// let (x, y) = render.map(_point).unwrap();
// if i == 0 {
// path.move_to(x, y);
// } else {
// path.line_to(x, y);
// }
// }
// }
// }
// geojson::Value::MultiPolygon(ref multi_polygon) => {
// let mut path = femtovg::Path::new();
// for polygon in multi_polygon {
// let out_ring = &polygon[0];
// let out_ring_line: LineString = out_ring
// .iter()
// .map(|x| (x[0], x[1]))
// .collect::<Vec<_>>()
// .into();
// let out_ring = render.ring_map(&out_ring_line).unwrap();
for (i, point) in out_ring.points().enumerate() {
let (x, y) = (point.x(), point.y());
if i == 0 {
path.move_to(x, y);
} else {
path.line_to(x, y);
}
}
}
canvas.stroke_path(&mut path, &paint);
}
_ => println!("Unknown geometry type: {:?}", geometry.value),
});
}
}
None
}
}
// for (i, point) in out_ring.points().enumerate() {
// let (x, y) = (point.x(), point.y());
// if i == 0 {
// path.move_to(x, y);
// } else {
// path.line_to(x, y);
// }
// }
// }
// canvas.stroke_path(&mut path, &paint);
// }
// _ => println!("Unknown geometry type: {:?}", geometry.value),
// });
// }
// }
// None
// }
// }
#[derive(Debug)]
struct MeshGridImpl;
impl LayerImpl for MeshGridImpl {
fn draw(&self, render: Render) -> Option<crate::render::Target> {
let mut canvas = render.get_canvas();
let canvas = canvas.as_mut().unwrap();
// impl LayerImpl for MeshGridImpl {
// fn draw(&self, render: Render) -> Option<crate::render::Target> {
// let mut canvas = render.get_canvas();
// let canvas = canvas.as_mut().unwrap();
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) = render.render_range();
// let (lon_range, lat_range): (Range, Range) = (lon_range.into(), lat_range.into());
let lon_keypoints = lon_range.key_points(10);
let lat_keypoints = lat_range.key_points(5);
// let lon_keypoints = lon_range.key_points(10);
// let lat_keypoints = lat_range.key_points(5);
for lon in lon_keypoints.iter() {
let mut path = femtovg::Path::new();
render
.map((*lon, lat_range.0))
.map(|(x, y)| path.move_to(x, y));
render
.map((*lon, lat_range.1))
.map(|(x, y)| path.line_to(x, y));
canvas.stroke_path(&mut path, &Paint::color(femtovg::Color::rgb(255, 255, 255)));
}
for lat in lat_keypoints.iter() {
let mut path = femtovg::Path::new();
render
.map((lon_range.0, *lat))
.map(|(x, y)| path.move_to(x, y));
render
.map((lon_range.1, *lat))
.map(|(x, y)| path.line_to(x, y));
canvas.stroke_path(&mut path, &Paint::color(femtovg::Color::rgb(255, 255, 255)));
}
// for lon in lon_keypoints.iter() {
// let mut path = femtovg::Path::new();
// render
// .map((*lon, lat_range.0))
// .map(|(x, y)| path.move_to(x, y));
// render
// .map((*lon, lat_range.1))
// .map(|(x, y)| path.line_to(x, y));
// canvas.stroke_path(&mut path, &Paint::color(femtovg::Color::rgb(255, 255, 255)));
// }
// for lat in lat_keypoints.iter() {
// let mut path = femtovg::Path::new();
// render
// .map((lon_range.0, *lat))
// .map(|(x, y)| path.move_to(x, y));
// render
// .map((lon_range.1, *lat))
// .map(|(x, y)| path.line_to(x, y));
// 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),
) -> Target {
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 {
// 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);
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 num_traits::{Num, NumOps};
use std::path::Path;
use std::sync::Arc;
use std::thread::spawn;
use std::{os::unix::thread, path::Path};
use std::sync::Mutex;
use crate::pipeline::offscreen_renderer::CanvasWrapper;
use crate::render::cms::CMS;
use crate::render::{LayerImpl, Target};
use crate::OFFSCREEN;
use crate::{
data::{AsyncDataLoader, DataLoader, Radar2d},
render::{Layer, Render},
@ -41,20 +41,13 @@ impl Layer {
},
layer_name,
Some(
|s_imp: Box<dyn LayerImpl>, c: &mut Canvas<OpenGl>, cms: CMS| async move {
if let Some(renderer) = s.as_ref() {
let img = renderer.draw(render.clone()).unwrap();
if let Ok(_) = c.image_size(img.target) {
let (x, y) = img.size(&render);
let (ox, oy) = img.origin(&render);
println!("{} {} {} {}", x, y, ox, oy);
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);
}
}
|renderer: Arc<Mutex<dyn LayerImpl + Send + Sync>>,
c: Arc<Mutex<CanvasWrapper>>,
cms: CMS| async move {
let mut canvas = c.lock().unwrap();
let c = &mut *canvas;
let img = renderer.lock().unwrap().draw(c, &cms).unwrap();
img
},
),
Some(GridLayerImpl::new(GridFieldRenderer::new(color_map), data)),