output-schedule: refactor change tracking
This commit is contained in:
parent
7e40e90c4d
commit
435b0a49da
1 changed files with 36 additions and 21 deletions
|
|
@ -15,6 +15,17 @@ use {
|
||||||
std::{cell::Cell, rc::Rc},
|
std::{cell::Cell, rc::Rc},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
|
enum Change {
|
||||||
|
/// The backend has applied the latest changes.
|
||||||
|
None,
|
||||||
|
/// There are changes that the backend is not yet aware of.
|
||||||
|
Scheduled,
|
||||||
|
/// The backend is aware that there are changes and will apply them as part of the
|
||||||
|
/// next latch event.
|
||||||
|
AwaitingLatch,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct OutputSchedule {
|
pub struct OutputSchedule {
|
||||||
changed: AsyncEvent,
|
changed: AsyncEvent,
|
||||||
run: Cell<bool>,
|
run: Cell<bool>,
|
||||||
|
|
@ -32,9 +43,8 @@ pub struct OutputSchedule {
|
||||||
|
|
||||||
vrr_enabled: Cell<bool>,
|
vrr_enabled: Cell<bool>,
|
||||||
|
|
||||||
present_scheduled: Cell<bool>,
|
hardware_cursor_change: Cell<Change>,
|
||||||
needs_hardware_cursor_commit: Cell<bool>,
|
software_cursor_change: Cell<Change>,
|
||||||
needs_software_cursor_damage: Cell<bool>,
|
|
||||||
|
|
||||||
iteration: NumCell<u64>,
|
iteration: NumCell<u64>,
|
||||||
}
|
}
|
||||||
|
|
@ -53,9 +63,8 @@ impl OutputSchedule {
|
||||||
ring: ring.clone(),
|
ring: ring.clone(),
|
||||||
eng: eng.clone(),
|
eng: eng.clone(),
|
||||||
vrr_enabled: Default::default(),
|
vrr_enabled: Default::default(),
|
||||||
present_scheduled: Cell::new(true),
|
hardware_cursor_change: Cell::new(Change::None),
|
||||||
needs_hardware_cursor_commit: Default::default(),
|
software_cursor_change: Cell::new(Change::None),
|
||||||
needs_software_cursor_damage: Default::default(),
|
|
||||||
hardware_cursor: Default::default(),
|
hardware_cursor: Default::default(),
|
||||||
persistent: persistent.clone(),
|
persistent: persistent.clone(),
|
||||||
last_present_nsec: Default::default(),
|
last_present_nsec: Default::default(),
|
||||||
|
|
@ -79,9 +88,9 @@ impl OutputSchedule {
|
||||||
|
|
||||||
fn trigger(&self) {
|
fn trigger(&self) {
|
||||||
let trigger = self.vrr_enabled.get()
|
let trigger = self.vrr_enabled.get()
|
||||||
&& !self.present_scheduled.get()
|
|
||||||
&& self.cursor_delta_nsec.is_some()
|
&& self.cursor_delta_nsec.is_some()
|
||||||
&& (self.needs_software_cursor_damage.get() || self.needs_hardware_cursor_commit.get());
|
&& (self.software_cursor_change.get() == Change::Scheduled
|
||||||
|
|| self.hardware_cursor_change.get() == Change::Scheduled);
|
||||||
if trigger {
|
if trigger {
|
||||||
self.run.set(true);
|
self.run.set(true);
|
||||||
self.changed.trigger();
|
self.changed.trigger();
|
||||||
|
|
@ -90,7 +99,12 @@ impl OutputSchedule {
|
||||||
|
|
||||||
pub fn latched(&self) {
|
pub fn latched(&self) {
|
||||||
self.last_present_nsec.set(self.eng.now().nsec());
|
self.last_present_nsec.set(self.eng.now().nsec());
|
||||||
self.present_scheduled.set(false);
|
if self.software_cursor_change.get() == Change::AwaitingLatch {
|
||||||
|
self.software_cursor_change.set(Change::None);
|
||||||
|
}
|
||||||
|
if self.hardware_cursor_change.get() == Change::AwaitingLatch {
|
||||||
|
self.hardware_cursor_change.set(Change::None);
|
||||||
|
}
|
||||||
self.iteration.fetch_add(1);
|
self.iteration.fetch_add(1);
|
||||||
self.trigger();
|
self.trigger();
|
||||||
}
|
}
|
||||||
|
|
@ -126,25 +140,26 @@ impl OutputSchedule {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hardware_cursor_changed(&self) {
|
pub fn hardware_cursor_changed(&self) {
|
||||||
if !self.needs_hardware_cursor_commit.replace(true) {
|
if self.hardware_cursor_change.get() == Change::None {
|
||||||
|
self.hardware_cursor_change.set(Change::Scheduled);
|
||||||
self.trigger();
|
self.trigger();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn software_cursor_changed(&self) {
|
pub fn software_cursor_changed(&self) {
|
||||||
if !self.needs_software_cursor_damage.replace(true) {
|
if self.software_cursor_change.get() == Change::None {
|
||||||
|
self.software_cursor_change.set(Change::Scheduled);
|
||||||
self.trigger();
|
self.trigger();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_once(&self) {
|
async fn run_once(&self) {
|
||||||
if self.present_scheduled.get() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if !self.needs_hardware_cursor_commit.get() && !self.needs_software_cursor_damage.get() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
loop {
|
loop {
|
||||||
|
if self.hardware_cursor_change.get() != Change::Scheduled
|
||||||
|
&& self.software_cursor_change.get() != Change::Scheduled
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
if !self.vrr_enabled.get() {
|
if !self.vrr_enabled.get() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -169,15 +184,15 @@ impl OutputSchedule {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn commit_cursor(&self) {
|
pub fn commit_cursor(&self) {
|
||||||
if self.needs_hardware_cursor_commit.take() {
|
if self.hardware_cursor_change.get() == Change::Scheduled {
|
||||||
if let Some(hc) = self.hardware_cursor.get() {
|
if let Some(hc) = self.hardware_cursor.get() {
|
||||||
hc.damage();
|
hc.damage();
|
||||||
self.present_scheduled.set(true);
|
|
||||||
}
|
}
|
||||||
|
self.hardware_cursor_change.set(Change::AwaitingLatch);
|
||||||
}
|
}
|
||||||
if self.needs_software_cursor_damage.take() {
|
if self.software_cursor_change.get() == Change::Scheduled {
|
||||||
self.connector.damage();
|
self.connector.damage();
|
||||||
self.present_scheduled.set(true);
|
self.software_cursor_change.set(Change::AwaitingLatch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue