mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2025-02-25 18:55:26 -06:00
feat: wip plotters-gtk4
This commit is contained in:
parent
0894f9ae9d
commit
4f1074526e
38
Cargo.lock
generated
38
Cargo.lock
generated
@ -1283,6 +1283,7 @@ version = "0.7.1"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"divan",
|
"divan",
|
||||||
|
"gtk4",
|
||||||
"lact-cli",
|
"lact-cli",
|
||||||
"lact-daemon",
|
"lact-daemon",
|
||||||
"lact-gui",
|
"lact-gui",
|
||||||
@ -1366,7 +1367,7 @@ dependencies = [
|
|||||||
"lact-schema",
|
"lact-schema",
|
||||||
"libadwaita",
|
"libadwaita",
|
||||||
"plotters",
|
"plotters",
|
||||||
"plotters-cairo",
|
"plotters-gtk4",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
"relm4",
|
"relm4",
|
||||||
"relm4-components",
|
"relm4-components",
|
||||||
@ -1776,6 +1777,32 @@ dependencies = [
|
|||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pangocairo"
|
||||||
|
version = "0.20.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4690509a2fea2a6552a0ef8aa3e5f790c1365365ee0712afa1aedb39af3997b6"
|
||||||
|
dependencies = [
|
||||||
|
"cairo-rs",
|
||||||
|
"glib",
|
||||||
|
"libc",
|
||||||
|
"pango",
|
||||||
|
"pangocairo-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pangocairo-sys"
|
||||||
|
version = "0.20.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5be6ac24147911a6a46783922fc288cf02f67570bc0d360e563b5b26aead6767"
|
||||||
|
dependencies = [
|
||||||
|
"cairo-sys-rs",
|
||||||
|
"glib-sys",
|
||||||
|
"libc",
|
||||||
|
"pango-sys",
|
||||||
|
"system-deps",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking"
|
name = "parking"
|
||||||
version = "2.2.1"
|
version = "2.2.1"
|
||||||
@ -1857,12 +1884,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a"
|
checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "plotters-cairo"
|
name = "plotters-gtk4"
|
||||||
version = "0.7.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5e7a3a2567b691ed2f0670ea3cc39988add29c968228b474ec5fe8261b1ff2a5"
|
checksum = "2f18ee173b0c8e6d8cb01c1e32a9b41bf41d74b277a69f22277bab05870e13d7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cairo-rs",
|
"gtk4",
|
||||||
|
"pangocairo",
|
||||||
"plotters-backend",
|
"plotters-backend",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -32,13 +32,14 @@ plotters = { version = "0.3.5", default-features = false, features = [
|
|||||||
"line_series",
|
"line_series",
|
||||||
"full_palette",
|
"full_palette",
|
||||||
] }
|
] }
|
||||||
plotters-cairo = "0.7.0"
|
# plotters-cairo = "0.7.0"
|
||||||
cairo-rs = { version = "0.20", default-features = false }
|
cairo-rs = { version = "0.20", default-features = false }
|
||||||
itertools = "0.13.0"
|
itertools = "0.13.0"
|
||||||
|
|
||||||
thread-priority = "1.1.0"
|
thread-priority = "1.1.0"
|
||||||
|
|
||||||
divan = { workspace = true, optional = true }
|
divan = { workspace = true, optional = true }
|
||||||
|
plotters-gtk4 = "0.5.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = "1.4.0"
|
pretty_assertions = "1.4.0"
|
||||||
|
@ -2,6 +2,7 @@ use chrono::NaiveDateTime;
|
|||||||
use glib::Properties;
|
use glib::Properties;
|
||||||
|
|
||||||
use gtk::{glib, prelude::*, subclass::prelude::*};
|
use gtk::{glib, prelude::*, subclass::prelude::*};
|
||||||
|
use plotters_gtk4::SnapshotBackend;
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
@ -24,7 +25,7 @@ pub struct Plot {
|
|||||||
secondary_y_label_area_relative_size: Cell<f64>,
|
secondary_y_label_area_relative_size: Cell<f64>,
|
||||||
pub(super) data: RefCell<PlotData>,
|
pub(super) data: RefCell<PlotData>,
|
||||||
pub(super) dirty: Cell<bool>,
|
pub(super) dirty: Cell<bool>,
|
||||||
render_thread: RenderThread,
|
// render_thread: RenderThread,
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
time_period_seconds: Cell<i64>,
|
time_period_seconds: Cell<i64>,
|
||||||
}
|
}
|
||||||
@ -50,42 +51,58 @@ impl ObjectImpl for Plot {
|
|||||||
|
|
||||||
impl WidgetImpl for Plot {
|
impl WidgetImpl for Plot {
|
||||||
fn snapshot(&self, snapshot: >k::Snapshot) {
|
fn snapshot(&self, snapshot: >k::Snapshot) {
|
||||||
|
snapshot.scale(0.25, 0.25);
|
||||||
|
|
||||||
let width = self.obj().width() as u32;
|
let width = self.obj().width() as u32;
|
||||||
let height = self.obj().height() as u32;
|
let height = self.obj().height() as u32;
|
||||||
|
|
||||||
if width == 0 || height == 0 {
|
if width == 0 || height == 0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let request = RenderRequest {
|
||||||
|
data: self.data.borrow().clone(),
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
title: self.title.borrow().clone(),
|
||||||
|
value_suffix: self.value_suffix.borrow().clone(),
|
||||||
|
secondary_value_suffix: self.secondary_value_suffix.borrow().clone(),
|
||||||
|
y_label_area_relative_size: self.y_label_area_relative_size.get(),
|
||||||
|
secondary_y_label_relative_area_size: self.secondary_y_label_area_relative_size.get(),
|
||||||
|
supersample_factor: 4,
|
||||||
|
time_period_seconds: self.time_period_seconds.get(),
|
||||||
|
};
|
||||||
|
let backend = SnapshotBackend::new(snapshot, (width * 4, height * 4));
|
||||||
|
request.draw(backend).unwrap();
|
||||||
|
|
||||||
let last_texture = self.render_thread.get_last_texture();
|
// let last_texture = self.render_thread.get_last_texture();
|
||||||
let size_changed = last_texture
|
// let size_changed = last_texture
|
||||||
.as_ref()
|
// .as_ref()
|
||||||
.map(|texture| (texture.width() as u32, texture.height() as u32) != (width, height))
|
// .map(|texture| (texture.width() as u32, texture.height() as u32) != (width, height))
|
||||||
.unwrap_or(true);
|
// .unwrap_or(true);
|
||||||
|
|
||||||
if self.dirty.replace(false) || size_changed {
|
// if self.dirty.replace(false) || size_changed {
|
||||||
self.render_thread.replace_render_request(RenderRequest {
|
// self.render_thread.replace_render_request(RenderRequest {
|
||||||
data: self.data.borrow().clone(),
|
// data: self.data.borrow().clone(),
|
||||||
width,
|
// width,
|
||||||
height,
|
// height,
|
||||||
title: self.title.borrow().clone(),
|
// title: self.title.borrow().clone(),
|
||||||
value_suffix: self.value_suffix.borrow().clone(),
|
// value_suffix: self.value_suffix.borrow().clone(),
|
||||||
secondary_value_suffix: self.secondary_value_suffix.borrow().clone(),
|
// secondary_value_suffix: self.secondary_value_suffix.borrow().clone(),
|
||||||
y_label_area_relative_size: self.y_label_area_relative_size.get(),
|
// y_label_area_relative_size: self.y_label_area_relative_size.get(),
|
||||||
secondary_y_label_relative_area_size: self
|
// secondary_y_label_relative_area_size: self
|
||||||
.secondary_y_label_area_relative_size
|
// .secondary_y_label_area_relative_size
|
||||||
.get(),
|
// .get(),
|
||||||
supersample_factor: 4,
|
// supersample_factor: 4,
|
||||||
time_period_seconds: self.time_period_seconds.get(),
|
// time_period_seconds: self.time_period_seconds.get(),
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Rendering is always behind by at least one frame, but it's not an issue
|
// // Rendering is always behind by at least one frame, but it's not an issue
|
||||||
if let Some(texture) = last_texture {
|
// if let Some(texture) = last_texture {
|
||||||
let bounds = gtk::graphene::Rect::new(0.0, 0.0, width as f32, height as f32);
|
// let bounds = gtk::graphene::Rect::new(0.0, 0.0, width as f32, height as f32);
|
||||||
// Uses by default Trillinear texture filtering, which is quite good at 4x supersampling
|
// // Uses by default Trillinear texture filtering, which is quite good at 4x supersampling
|
||||||
snapshot.append_texture(&texture, &bounds);
|
// snapshot.append_texture(&texture, &bounds);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ use itertools::Itertools;
|
|||||||
use plotters::prelude::*;
|
use plotters::prelude::*;
|
||||||
use plotters::style::colors::full_palette::DEEPORANGE_100;
|
use plotters::style::colors::full_palette::DEEPORANGE_100;
|
||||||
use plotters::style::RelativeSize;
|
use plotters::style::RelativeSize;
|
||||||
use plotters_cairo::CairoBackend;
|
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
@ -131,7 +130,7 @@ impl RenderThread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn process_request(render_request: RenderRequest, last_texture: &Mutex<Option<MemoryTexture>>) {
|
fn process_request(render_request: RenderRequest, last_texture: &Mutex<Option<MemoryTexture>>) {
|
||||||
// Create a new ImageSurface for Cairo rendering.
|
/*// Create a new ImageSurface for Cairo rendering.
|
||||||
let mut surface = ImageSurface::create(
|
let mut surface = ImageSurface::create(
|
||||||
cairo::Format::ARgb32,
|
cairo::Format::ARgb32,
|
||||||
(render_request.width * render_request.supersample_factor) as i32,
|
(render_request.width * render_request.supersample_factor) as i32,
|
||||||
@ -178,7 +177,7 @@ fn process_request(render_request: RenderRequest, last_texture: &Mutex<Option<Me
|
|||||||
(result, last_texture) => {
|
(result, last_texture) => {
|
||||||
*last_texture = result;
|
*last_texture = result;
|
||||||
}
|
}
|
||||||
};
|
};*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implement the default constructor for RenderThread using the `new` method.
|
// Implement the default constructor for RenderThread using the `new` method.
|
||||||
@ -400,11 +399,13 @@ mod benches {
|
|||||||
use crate::app::graphs_window::plot::PlotData;
|
use crate::app::graphs_window::plot::PlotData;
|
||||||
use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
|
use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
|
||||||
use divan::{counter::ItemsCount, Bencher};
|
use divan::{counter::ItemsCount, Bencher};
|
||||||
|
use gtk::prelude::SnapshotExt;
|
||||||
|
use plotters_gtk4::SnapshotBackend;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
#[divan::bench]
|
#[divan::bench]
|
||||||
fn render_plot(bencher: Bencher) {
|
fn render_plot(bencher: Bencher) {
|
||||||
let last_texture = &Mutex::new(None);
|
// let last_texture = &Mutex::new(None);
|
||||||
|
|
||||||
bencher
|
bencher
|
||||||
.with_inputs(sample_plot_data)
|
.with_inputs(sample_plot_data)
|
||||||
@ -423,7 +424,20 @@ mod benches {
|
|||||||
time_period_seconds: 60,
|
time_period_seconds: 60,
|
||||||
};
|
};
|
||||||
|
|
||||||
process_request(request, last_texture)
|
let snapshot = gtk::Snapshot::new();
|
||||||
|
snapshot.scale(
|
||||||
|
1.0 / request.supersample_factor as f32,
|
||||||
|
1.0 / request.supersample_factor as f32,
|
||||||
|
);
|
||||||
|
let backend = SnapshotBackend::new(
|
||||||
|
&snapshot,
|
||||||
|
(
|
||||||
|
request.width * request.supersample_factor,
|
||||||
|
request.height * request.supersample_factor,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
request.draw(backend).unwrap();
|
||||||
|
// process_request(request, last_texture)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ anyhow = { workspace = true }
|
|||||||
divan = { workspace = true }
|
divan = { workspace = true }
|
||||||
lact-daemon = { path = "../lact-daemon", features = ["bench"] }
|
lact-daemon = { path = "../lact-daemon", features = ["bench"] }
|
||||||
lact-gui = { path = "../lact-gui", features = ["bench"] }
|
lact-gui = { path = "../lact-gui", features = ["bench"] }
|
||||||
|
gtk = { version = "0.9", package = "gtk4" }
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "bench"
|
name = "bench"
|
||||||
|
@ -3,5 +3,7 @@ fn main() {
|
|||||||
let _ = lact_daemon::run;
|
let _ = lact_daemon::run;
|
||||||
let _ = lact_gui::run;
|
let _ = lact_gui::run;
|
||||||
|
|
||||||
|
let _ = gtk::init();
|
||||||
|
|
||||||
divan::main();
|
divan::main();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user