Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance improvements, and (fractional) DPI scaling #53

Merged
merged 7 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
667 changes: 462 additions & 205 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ cosmic-bg-config = { path = "./config" }
cosmic-config = { workspace=true }
dirs = "5.0.1"
eyre = "0.6.11"
fast_image_resize = { version = "4.2.1", features = ["image"] }
image = { version = "0.25", features = ["hdr", "jpeg", "png", "rayon", "webp"], default-features = false }
notify = "6.1.1"
rand = "0.8"
ron = { workspace = true }
sctk = { package = "smithay-client-toolkit", git = "https://github.com/smithay/client-toolkit", rev = "2e9bf9f" }
sctk = { package = "smithay-client-toolkit", version = "0.19.2" }
slab = "0.4.9"
tracing = { workspace=true }
tracing-subscriber = "0.3.18"
Expand All @@ -30,6 +31,8 @@ tracing = "0.1.40"

[workspace.dependencies.cosmic-config]
git = "https://github.com/pop-os/libcosmic"
# TODO: Remove when sctk is updated to latest calloop, like cosmic-config
rev = "8c6f2c9ebc5c2c04fe168c2d941f8c5a416b33bb"
features = ["calloop"]

[profile.release]
Expand Down
1 change: 0 additions & 1 deletion rust-toolchain

This file was deleted.

2 changes: 2 additions & 0 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "1.80"
5 changes: 3 additions & 2 deletions src/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ pub fn layer_surface(
queue_handle: &QueueHandle<CosmicBg>,
buffer: &Buffer,
) {
let width = layer.width;
let height = layer.height;
let (width, height) = layer.size.unwrap();

let wl_surface = layer.layer.wl_surface();

Expand All @@ -65,6 +64,8 @@ pub fn layer_surface(
tracing::error!(?why, "buffer attachment failed");
}

layer.viewport.set_destination(width as i32, height as i32);

wl_surface.commit();
}

Expand Down
112 changes: 88 additions & 24 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,29 @@ use sctk::{
calloop,
calloop_wayland_source::WaylandSource,
client::{
delegate_noop,
globals::registry_queue_init,
protocol::{
wl_output::{self, WlOutput},
wl_surface,
},
Connection, QueueHandle,
Connection, Dispatch, Proxy, QueueHandle, Weak,
},
protocols::wp::{
fractional_scale::v1::client::{
wp_fractional_scale_manager_v1, wp_fractional_scale_v1,
},
viewporter::client::{wp_viewport, wp_viewporter},
},
},
registry::{ProvidesRegistryState, RegistryState},
registry_handlers,
shell::wlr_layer::{
Anchor, KeyboardInteractivity, Layer, LayerShell, LayerShellHandler, LayerSurface,
LayerSurfaceConfigure,
shell::{
wlr_layer::{
Anchor, KeyboardInteractivity, Layer, LayerShell, LayerShellHandler, LayerSurface,
LayerSurfaceConfigure,
},
WaylandSurface,
},
shm::{slot::SlotPool, Shm, ShmHandler},
};
Expand All @@ -45,12 +55,13 @@ extern "C" {
#[derive(Debug)]
pub struct CosmicBgLayer {
layer: LayerSurface,
viewport: wp_viewport::WpViewport,
wl_output: WlOutput,
output_info: OutputInfo,
pool: Option<SlotPool>,
first_configure: bool,
width: u32,
height: u32,
needs_redraw: bool,
size: Option<(u32, u32)>,
fractional_scale: Option<u32>,
}

#[allow(clippy::too_many_lines)]
Expand All @@ -75,6 +86,7 @@ fn main() -> color_eyre::Result<()> {

WaylandSource::new(conn, event_queue)
.insert(event_loop.handle())
.map_err(|err| err.error)
.wrap_err("failed to insert main EventLoop into WaylandSource")?;

let config_context = cosmic_bg_config::context();
Expand Down Expand Up @@ -200,6 +212,8 @@ fn main() -> color_eyre::Result<()> {
compositor_state: CompositorState::bind(&globals, &qh).unwrap(),
shm_state: Shm::bind(&globals, &qh).unwrap(),
layer_state: LayerShell::bind(&globals, &qh).unwrap(),
viewporter: globals.bind(&qh, 1..=1, ()).unwrap(),
fractional_scale_manager: globals.bind(&qh, 1..=1, ()).unwrap(),
qh,
source_tx,
loop_handle: event_loop.handle(),
Expand Down Expand Up @@ -227,6 +241,8 @@ pub struct CosmicBg {
compositor_state: CompositorState,
shm_state: Shm,
layer_state: LayerShell,
viewporter: wp_viewporter::WpViewporter,
fractional_scale_manager: wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1,
qh: QueueHandle<CosmicBg>,
source_tx: calloop::channel::SyncSender<(String, notify::Event)>,
loop_handle: calloop::LoopHandle<'static, CosmicBg>,
Expand Down Expand Up @@ -286,10 +302,6 @@ impl CosmicBg {

#[must_use]
pub fn new_layer(&self, output: WlOutput, output_info: OutputInfo) -> CosmicBgLayer {
let (width, height) = output_info
.logical_size
.map_or((0, 0), |(w, h)| (w as u32, h as u32));

let surface = self.compositor_state.create_surface(&self.qh);

let layer = self.layer_state.create_layer_surface(
Expand All @@ -303,16 +315,21 @@ impl CosmicBg {
layer.set_anchor(Anchor::all());
layer.set_exclusive_zone(-1);
layer.set_keyboard_interactivity(KeyboardInteractivity::None);
layer.set_size(width, height);
surface.commit();

let viewport = self.viewporter.get_viewport(&surface, &self.qh, ());

self.fractional_scale_manager
.get_fractional_scale(&surface, &self.qh, surface.downgrade());

CosmicBgLayer {
layer,
viewport,
wl_output: output,
output_info,
width,
height,
first_configure: false,
size: None,
fractional_scale: None,
needs_redraw: false,
pool: None,
}
}
Expand Down Expand Up @@ -347,6 +364,24 @@ impl CompositorHandler for CosmicBg {
) {
// TODO
}

fn surface_enter(
&mut self,
_: &Connection,
_: &QueueHandle<Self>,
_: &wl_surface::WlSurface,
_: &WlOutput,
) {
}

fn surface_leave(
&mut self,
_: &Connection,
_: &QueueHandle<Self>,
_: &wl_surface::WlSurface,
_: &WlOutput,
) {
}
}

impl OutputHandler for CosmicBg {
Expand Down Expand Up @@ -466,8 +501,8 @@ impl LayerShellHandler for CosmicBg {
for wallpaper in &mut self.wallpapers {
let (w, h) = configure.new_size;
if let Some(w_layer) = wallpaper.layers.iter_mut().find(|l| &l.layer == layer) {
w_layer.width = w;
w_layer.height = h;
w_layer.size = Some((w, h));
w_layer.needs_redraw = true;

if let Some(pool) = w_layer.pool.as_mut() {
if let Err(why) = pool.resize(w as usize * h as usize * 4) {
Expand All @@ -487,13 +522,7 @@ impl LayerShellHandler for CosmicBg {
}
}

if w_layer.first_configure {
w_layer.first_configure = false;
}

if wallpaper.layers.iter().all(|l| !l.first_configure) {
wallpaper.draw();
}
wallpaper.draw();

break;
}
Expand All @@ -512,6 +541,41 @@ delegate_output!(CosmicBg);
delegate_shm!(CosmicBg);
delegate_layer!(CosmicBg);
delegate_registry!(CosmicBg);
delegate_noop!(CosmicBg: wp_viewporter::WpViewporter);
delegate_noop!(CosmicBg: wp_viewport::WpViewport);
delegate_noop!(CosmicBg: wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1);

impl Dispatch<wp_fractional_scale_v1::WpFractionalScaleV1, Weak<wl_surface::WlSurface>>
for CosmicBg
{
fn event(
state: &mut CosmicBg,
_: &wp_fractional_scale_v1::WpFractionalScaleV1,
event: wp_fractional_scale_v1::Event,
surface: &Weak<wl_surface::WlSurface>,
_: &Connection,
_: &QueueHandle<CosmicBg>,
) {
match event {
wp_fractional_scale_v1::Event::PreferredScale { scale } => {
if let Ok(surface) = surface.upgrade() {
for wallpaper in &mut state.wallpapers {
if let Some(layer) = wallpaper
.layers
.iter_mut()
.find(|layer| layer.layer.wl_surface() == &surface)
{
layer.fractional_scale = Some(scale);
wallpaper.draw();
break;
}
}
}
}
_ => unreachable!(),
}
}
}

impl ProvidesRegistryState for CosmicBg {
fn registry(&mut self) -> &mut RegistryState {
Expand Down
23 changes: 20 additions & 3 deletions src/scaler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub fn fit(
(h as f64 * ratio).round() as u32,
);

let resized_image = img.resize(new_width, new_height, FilterType::Lanczos3);
let resized_image = resize(img, new_width, new_height);

image::imageops::replace(
&mut filled_image,
Expand All @@ -41,7 +41,7 @@ pub fn stretch(
layer_width: u32,
layer_height: u32,
) -> image::DynamicImage {
img.resize_exact(layer_width, layer_height, FilterType::Lanczos3)
resize(img, layer_width, layer_height)
}

pub fn zoom(img: &image::DynamicImage, layer_width: u32, layer_height: u32) -> image::DynamicImage {
Expand All @@ -54,7 +54,7 @@ pub fn zoom(img: &image::DynamicImage, layer_width: u32, layer_height: u32) -> i
(h as f64 * ratio).round() as u32,
);

let mut new_image = image::imageops::resize(img, new_width, new_height, FilterType::Lanczos3);
let mut new_image = resize(img, new_width, new_height);

image::imageops::crop(
&mut new_image,
Expand All @@ -66,3 +66,20 @@ pub fn zoom(img: &image::DynamicImage, layer_width: u32, layer_height: u32) -> i
.to_image()
.into()
}

fn resize(img: &image::DynamicImage, new_width: u32, new_height: u32) -> image::DynamicImage {
let mut resizer = fast_image_resize::Resizer::new();
let options = fast_image_resize::ResizeOptions {
algorithm: fast_image_resize::ResizeAlg::Convolution(
fast_image_resize::FilterType::Lanczos3,
),
..Default::default()
};
let mut new_image = image::DynamicImage::new(new_width, new_height, img.color());
if let Err(err) = resizer.resize(img, &mut new_image, &options) {
tracing::warn!(?err, "Failed to use `fast_image_resize`. Falling back.");
new_image =
image::imageops::resize(img, new_width, new_height, FilterType::Lanczos3).into();
}
new_image
}
Loading
Loading