Skip to content

Commit

Permalink
FractionalScaleManager and PollTime structs
Browse files Browse the repository at this point in the history
Improve readability.
  • Loading branch information
LGFae committed Aug 9, 2024
1 parent 0ae168e commit 810960d
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 36 deletions.
60 changes: 42 additions & 18 deletions daemon/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustix::{

use wallpaper::Wallpaper;
use wayland::{
globals::{self, Initializer},
globals::{self, FractionalScaleManager, Initializer},
ObjectId,
};

Expand All @@ -30,20 +30,19 @@ use std::{
time::Duration,
};

use animations::{ImageAnimator, TransitionAnimator};
use common::ipc::{Answer, BgInfo, ImageReq, IpcSocket, RequestRecv, RequestSend, Scale, Server};
use common::mmap::MmappedStr;

use animations::{ImageAnimator, TransitionAnimator};

// We need this because this might be set by signals, so we can't keep it in the daemon
static EXIT: AtomicBool = AtomicBool::new(false);

fn exit_daemon() {
EXIT.store(true, Ordering::Release);
EXIT.store(true, Ordering::Relaxed);
}

fn should_daemon_exit() -> bool {
EXIT.load(Ordering::Acquire)
EXIT.load(Ordering::Relaxed)
}

extern "C" fn signal_handler(_s: libc::c_int) {
Expand All @@ -55,8 +54,8 @@ struct Daemon {
transition_animators: Vec<TransitionAnimator>,
image_animators: Vec<ImageAnimator>,
use_cache: bool,
fractional_scale_manager: Option<(ObjectId, NonZeroU32)>,
poll_time: i32,
fractional_scale_manager: Option<FractionalScaleManager>,
poll_time: PollTime,
}

impl Daemon {
Expand All @@ -75,7 +74,7 @@ impl Daemon {
image_animators: Vec::new(),
use_cache: !no_cache,
fractional_scale_manager,
poll_time: -1,
poll_time: PollTime::Never,
}
}

Expand Down Expand Up @@ -106,10 +105,14 @@ impl Daemon {
let viewport = globals::object_create(wayland::WlDynObj::Viewport);
wp_viewporter::req::get_viewport(viewport, surface).unwrap();

let wp_fractional = if let Some((id, _)) = self.fractional_scale_manager.as_ref() {
let wp_fractional = if let Some(fract_man) = self.fractional_scale_manager.as_ref() {
let fractional = globals::object_create(wayland::WlDynObj::FractionalScale);
wp_fractional_scale_manager_v1::req::get_fractional_scale(*id, fractional, surface)
.unwrap();
wp_fractional_scale_manager_v1::req::get_fractional_scale(
fract_man.id(),
fractional,
surface,
)
.unwrap();
Some(fractional)
} else {
None
Expand Down Expand Up @@ -181,8 +184,8 @@ impl Daemon {
transition.frame();
self.transition_animators.push(transition);
}
self.poll_time = 0;
}
self.poll_time = PollTime::Instant;
Answer::Ok
}
};
Expand Down Expand Up @@ -211,7 +214,7 @@ impl Daemon {
}

fn draw(&mut self) {
self.poll_time = -1;
self.poll_time = PollTime::Never;

let mut i = 0;
while i < self.transition_animators.len() {
Expand All @@ -223,7 +226,7 @@ impl Daemon {
{
let time = animator.time_to_draw();
if time > Duration::from_micros(1200) {
self.poll_time = 1;
self.poll_time = PollTime::Short;
i += 1;
continue;
}
Expand Down Expand Up @@ -255,7 +258,7 @@ impl Daemon {
{
let time = animator.time_to_draw();
if time > Duration::from_micros(1200) {
self.poll_time = 1;
self.poll_time = PollTime::Short;
continue;
}

Expand Down Expand Up @@ -298,6 +301,7 @@ impl wayland::interfaces::wl_display::EvHandler for Daemon {
}
}
}

impl wayland::interfaces::wl_registry::EvHandler for Daemon {
fn global(&mut self, name: u32, interface: &str, version: u32) {
if interface == "wl_output" {
Expand Down Expand Up @@ -410,6 +414,7 @@ impl wayland::interfaces::wl_output::EvHandler for Daemon {
}
}
}

impl wayland::interfaces::wl_surface::EvHandler for Daemon {
fn enter(&mut self, _sender_id: ObjectId, output: ObjectId) {
debug!("Output {}: Surface Enter", output.get());
Expand Down Expand Up @@ -539,7 +544,7 @@ fn main() -> Result<(), String> {
while !should_daemon_exit() {
use wayland::{interfaces::*, wire, WlDynObj};

if let Err(e) = poll(&mut fds, daemon.poll_time) {
if let Err(e) = poll(&mut fds, daemon.poll_time.into()) {
match e {
rustix::io::Errno::INTR => continue,
_ => return Err(format!("failed to poll file descriptors: {e:?}")),
Expand Down Expand Up @@ -584,14 +589,13 @@ fn main() -> Result<(), String> {

if !fds[1].revents().is_empty() {
match rustix::net::accept(&listener.0) {
// TODO: abstract away explicit socket creation
Ok(stream) => daemon.recv_socket_msg(IpcSocket::new(stream)),
Err(rustix::io::Errno::INTR | rustix::io::Errno::WOULDBLOCK) => continue,
Err(e) => return Err(format!("failed to accept incoming connection: {e}")),
}
}

if daemon.poll_time > -1 {
if !matches!(daemon.poll_time, PollTime::Never) {
daemon.draw();
}
}
Expand Down Expand Up @@ -678,6 +682,26 @@ impl Drop for SocketWrapper {
}
}

#[repr(i32)]
#[derive(Clone, Copy)]
/// We use PollTime as a way of making sure we draw at the right time
/// when we call `Daemon::draw` before the frame callback returned, we need to *not* draw and
/// instead wait for the next callback, which we do with a short poll time.
///
/// The instant poll time is for when we receive an img request, after we set up the requested
/// transitions
enum PollTime {
Never = -1,
Instant = 0,
Short = 1,
}

impl From<PollTime> for i32 {
fn from(value: PollTime) -> Self {
value as i32
}
}

struct Logger {
level_filter: LevelFilter,
start: std::time::Instant,
Expand Down
51 changes: 33 additions & 18 deletions daemon/src/wayland/globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use common::ipc::PixelFormat;
use log::{debug, error, info};

use super::{ObjectId, ObjectManager, WlDynObj};
use std::{cell::RefCell, num::NonZeroU32, path::PathBuf, sync::atomic::AtomicBool};
use std::{num::NonZeroU32, path::PathBuf, sync::atomic::AtomicBool};

// all of these objects must always exist for `swww-daemon` to work correctly, so we turn them into
// global constants
Expand All @@ -48,7 +48,7 @@ const VERSIONS: [u32; 4] = [4, 1, 1, 3];
static mut WAYLAND_FD: OwnedFd = unsafe { std::mem::zeroed() };
static mut FRACTIONAL_SCALE_SUPPORT: bool = false;
static mut PIXEL_FORMAT: PixelFormat = PixelFormat::Xrgb;
static mut OBJECT_MANAGER: RefCell<ObjectManager> = RefCell::new(ObjectManager::new());
static mut OBJECT_MANAGER: ObjectManager = ObjectManager::new();

static INITIALIZED: AtomicBool = AtomicBool::new(false);

Expand All @@ -64,20 +64,23 @@ pub fn fractional_scale_support() -> bool {
}

#[must_use]
/// Safe because this is a single threaded application, so no race conditions can occur
pub fn object_type_get(object_id: ObjectId) -> Option<WlDynObj> {
debug_assert!(INITIALIZED.load(std::sync::atomic::Ordering::Relaxed));
unsafe { OBJECT_MANAGER.borrow() }.get(object_id)
unsafe { OBJECT_MANAGER.get(object_id) }
}

#[must_use]
/// Safe because this is a single threaded application, so no race conditions can occur
pub fn object_create(object_type: WlDynObj) -> ObjectId {
debug_assert!(INITIALIZED.load(std::sync::atomic::Ordering::Relaxed));
unsafe { OBJECT_MANAGER.borrow_mut() }.create(object_type)
unsafe { OBJECT_MANAGER.create(object_type) }
}

/// Safe because this is a single threaded application, so no race conditions can occur
pub fn object_remove(object_id: ObjectId) {
debug_assert!(INITIALIZED.load(std::sync::atomic::Ordering::Relaxed));
unsafe { OBJECT_MANAGER.borrow_mut() }.remove(object_id)
unsafe { OBJECT_MANAGER.remove(object_id) }
}

#[must_use]
Expand All @@ -99,12 +102,12 @@ pub fn wl_shm_format() -> u32 {

/// Note that this function assumes the logger has already been set up
pub fn init(pixel_format: Option<PixelFormat>) -> Initializer {
// if we have initialized already, return imediatelly with an empty Initializer
let mut initializer = Initializer::new(pixel_format);
if INITIALIZED.load(std::sync::atomic::Ordering::SeqCst) {
return initializer;
if INITIALIZED.load(std::sync::atomic::Ordering::Relaxed) {
panic!("trying to run initialization code twice");
}

let mut initializer = Initializer::new(pixel_format);

// initialize the two most important globals:
// * the wayland file descriptor; and
// * the object manager
Expand Down Expand Up @@ -161,11 +164,11 @@ pub fn init(pixel_format: Option<PixelFormat>) -> Initializer {
}

// bind fractional scale, if it is supported
if let Some((id, name)) = initializer.fractional_scale.as_ref() {
if let Some(fractional_scale_manager) = initializer.fractional_scale.as_ref() {
unsafe { FRACTIONAL_SCALE_SUPPORT = true };
super::interfaces::wl_registry::req::bind(
name.get(),
*id,
fractional_scale_manager.name.get(),
fractional_scale_manager.id,
"wp_fractional_scale_manager_v1",
1,
)
Expand Down Expand Up @@ -244,11 +247,23 @@ fn connect() -> OwnedFd {
}
}

#[derive(Clone)]
pub struct FractionalScaleManager {
id: ObjectId,
name: NonZeroU32,
}

impl FractionalScaleManager {
pub fn id(&self) -> ObjectId {
self.id
}
}

/// Helper struct to do all the initialization in this file
pub struct Initializer {
global_names: [u32; REQUIRED_GLOBALS.len()],
output_names: Vec<u32>,
fractional_scale: Option<(ObjectId, NonZeroU32)>,
fractional_scale: Option<FractionalScaleManager>,
forced_shm_format: bool,
should_exit: bool,
}
Expand Down Expand Up @@ -276,7 +291,7 @@ impl Initializer {
&self.output_names
}

pub fn fractional_scale(&self) -> Option<&(ObjectId, NonZeroU32)> {
pub fn fractional_scale(&self) -> Option<&FractionalScaleManager> {
self.fractional_scale.as_ref()
}
}
Expand Down Expand Up @@ -311,10 +326,10 @@ impl super::interfaces::wl_registry::EvHandler for Initializer {
fn global(&mut self, name: u32, interface: &str, version: u32) {
match interface {
"wp_fractional_scale_manager_v1" => {
self.fractional_scale = Some((
ObjectId(unsafe { NonZeroU32::new_unchecked(7) }),
name.try_into().unwrap(),
));
self.fractional_scale = Some(FractionalScaleManager {
id: ObjectId(unsafe { NonZeroU32::new_unchecked(7) }),
name: name.try_into().unwrap(),
});
}
"wl_output" => {
if version < 4 {
Expand Down

0 comments on commit 810960d

Please sign in to comment.