damage: move transform matrix into workspace crate
This commit is contained in:
parent
db94c9167f
commit
54aefd8c41
5 changed files with 140 additions and 113 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
|
@ -730,6 +730,7 @@ dependencies = [
|
||||||
"jay-config",
|
"jay-config",
|
||||||
"jay-cpu-worker",
|
"jay-cpu-worker",
|
||||||
"jay-criteria",
|
"jay-criteria",
|
||||||
|
"jay-damage",
|
||||||
"jay-dbus-core",
|
"jay-dbus-core",
|
||||||
"jay-drm-feedback",
|
"jay-drm-feedback",
|
||||||
"jay-edid",
|
"jay-edid",
|
||||||
|
|
@ -830,6 +831,15 @@ dependencies = [
|
||||||
"regex",
|
"regex",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jay-damage"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"jay-geometry",
|
||||||
|
"jay-tree-types",
|
||||||
|
"jay-units",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jay-dbus-core"
|
name = "jay-dbus-core"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ members = [
|
||||||
"output-schedule",
|
"output-schedule",
|
||||||
"drm-feedback",
|
"drm-feedback",
|
||||||
"udmabuf",
|
"udmabuf",
|
||||||
|
"damage",
|
||||||
"pango",
|
"pango",
|
||||||
"libinput",
|
"libinput",
|
||||||
"toml-config",
|
"toml-config",
|
||||||
|
|
@ -103,6 +104,7 @@ jay-allocator = { version = "0.1.0", path = "allocator" }
|
||||||
jay-output-schedule = { version = "0.1.0", path = "output-schedule" }
|
jay-output-schedule = { version = "0.1.0", path = "output-schedule" }
|
||||||
jay-drm-feedback = { version = "0.1.0", path = "drm-feedback" }
|
jay-drm-feedback = { version = "0.1.0", path = "drm-feedback" }
|
||||||
jay-udmabuf = { version = "0.1.0", path = "udmabuf" }
|
jay-udmabuf = { version = "0.1.0", path = "udmabuf" }
|
||||||
|
jay-damage = { version = "0.1.0", path = "damage" }
|
||||||
jay-pango = { version = "0.1.0", path = "pango" }
|
jay-pango = { version = "0.1.0", path = "pango" }
|
||||||
jay-libinput = { version = "0.1.0", path = "libinput" }
|
jay-libinput = { version = "0.1.0", path = "libinput" }
|
||||||
|
|
||||||
|
|
|
||||||
10
damage/Cargo.toml
Normal file
10
damage/Cargo.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "jay-damage"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
license = "GPL-3.0-only"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
jay-geometry = { version = "0.1.0", path = "../geometry" }
|
||||||
|
jay-tree-types = { version = "0.1.0", path = "../tree-types" }
|
||||||
|
jay-units = { version = "0.1.0", path = "../units" }
|
||||||
116
damage/src/lib.rs
Normal file
116
damage/src/lib.rs
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
use {
|
||||||
|
jay_geometry::Rect,
|
||||||
|
jay_tree_types::Transform,
|
||||||
|
jay_units::fixed::Fixed,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct DamageMatrix {
|
||||||
|
transform: Transform,
|
||||||
|
mx: f64,
|
||||||
|
my: f64,
|
||||||
|
dx: f64,
|
||||||
|
dy: f64,
|
||||||
|
smear: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for DamageMatrix {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
transform: Default::default(),
|
||||||
|
mx: 1.0,
|
||||||
|
my: 1.0,
|
||||||
|
dx: 0.0,
|
||||||
|
dy: 0.0,
|
||||||
|
smear: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DamageMatrix {
|
||||||
|
pub fn apply(&self, dx: i32, dy: i32, rect: Rect) -> Rect {
|
||||||
|
let x1 = rect.x1() - self.smear;
|
||||||
|
let x2 = rect.x2() + self.smear;
|
||||||
|
let y1 = rect.y1() - self.smear;
|
||||||
|
let y2 = rect.y2() + self.smear;
|
||||||
|
let [x1, y1, x2, y2] = match self.transform {
|
||||||
|
Transform::None => [x1, y1, x2, y2],
|
||||||
|
Transform::Rotate90 => [-y2, x1, -y1, x2],
|
||||||
|
Transform::Rotate180 => [-x2, -y2, -x1, -y1],
|
||||||
|
Transform::Rotate270 => [y1, -x2, y2, -x1],
|
||||||
|
Transform::Flip => [-x2, y1, -x1, y2],
|
||||||
|
Transform::FlipRotate90 => [y1, x1, y2, x2],
|
||||||
|
Transform::FlipRotate180 => [x1, -y2, x2, -y1],
|
||||||
|
Transform::FlipRotate270 => [-y2, -x2, -y1, -x1],
|
||||||
|
};
|
||||||
|
let x1 = (x1 as f64 * self.mx + self.dx).floor() as i32 + dx;
|
||||||
|
let y1 = (y1 as f64 * self.my + self.dy).floor() as i32 + dy;
|
||||||
|
let x2 = (x2 as f64 * self.mx + self.dx).ceil() as i32 + dx;
|
||||||
|
let y2 = (y2 as f64 * self.my + self.dy).ceil() as i32 + dy;
|
||||||
|
Rect::new_saturating(x1, y1, x2, y2)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(
|
||||||
|
transform: Transform,
|
||||||
|
legacy_scale: i32,
|
||||||
|
buffer_width: i32,
|
||||||
|
buffer_height: i32,
|
||||||
|
viewport: Option<[Fixed; 4]>,
|
||||||
|
dst_width: i32,
|
||||||
|
dst_height: i32,
|
||||||
|
) -> DamageMatrix {
|
||||||
|
let mut buffer_width = buffer_width as f64;
|
||||||
|
let mut buffer_height = buffer_height as f64;
|
||||||
|
let dst_width = dst_width as f64;
|
||||||
|
let dst_height = dst_height as f64;
|
||||||
|
|
||||||
|
let mut mx = 1.0;
|
||||||
|
let mut my = 1.0;
|
||||||
|
if legacy_scale != 1 {
|
||||||
|
let scale_inv = 1.0 / (legacy_scale as f64);
|
||||||
|
mx = scale_inv;
|
||||||
|
my = scale_inv;
|
||||||
|
buffer_width *= scale_inv;
|
||||||
|
buffer_height *= scale_inv;
|
||||||
|
}
|
||||||
|
let (mut buffer_width, mut buffer_height) =
|
||||||
|
transform.maybe_swap((buffer_width, buffer_height));
|
||||||
|
let (mut dx, mut dy) = match transform {
|
||||||
|
Transform::None => (0.0, 0.0),
|
||||||
|
Transform::Rotate90 => (buffer_width, 0.0),
|
||||||
|
Transform::Rotate180 => (buffer_width, buffer_height),
|
||||||
|
Transform::Rotate270 => (0.0, buffer_height),
|
||||||
|
Transform::Flip => (buffer_width, 0.0),
|
||||||
|
Transform::FlipRotate90 => (0.0, 0.0),
|
||||||
|
Transform::FlipRotate180 => (0.0, buffer_height),
|
||||||
|
Transform::FlipRotate270 => (buffer_width, buffer_height),
|
||||||
|
};
|
||||||
|
if let Some([x, y, w, h]) = viewport {
|
||||||
|
dx -= x.to_f64();
|
||||||
|
dy -= y.to_f64();
|
||||||
|
buffer_width = w.to_f64();
|
||||||
|
buffer_height = h.to_f64();
|
||||||
|
}
|
||||||
|
let mut smear = false;
|
||||||
|
if dst_width != buffer_width {
|
||||||
|
let scale = dst_width / buffer_width;
|
||||||
|
mx *= scale;
|
||||||
|
dx *= scale;
|
||||||
|
smear |= dst_width > buffer_width;
|
||||||
|
}
|
||||||
|
if dst_height != buffer_height {
|
||||||
|
let scale = dst_height / buffer_height;
|
||||||
|
my *= scale;
|
||||||
|
dy *= scale;
|
||||||
|
smear |= dst_height > buffer_height;
|
||||||
|
}
|
||||||
|
DamageMatrix {
|
||||||
|
transform,
|
||||||
|
mx,
|
||||||
|
my,
|
||||||
|
dx,
|
||||||
|
dy,
|
||||||
|
smear: smear as _,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
115
src/damage.rs
115
src/damage.rs
|
|
@ -2,14 +2,12 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
async_engine::AsyncEngine,
|
async_engine::AsyncEngine,
|
||||||
cmm::{cmm_manager::ColorManager, cmm_render_intent::RenderIntent},
|
cmm::{cmm_manager::ColorManager, cmm_render_intent::RenderIntent},
|
||||||
fixed::Fixed,
|
|
||||||
ifs::wl_output::WlOutputGlobal,
|
ifs::wl_output::WlOutputGlobal,
|
||||||
rect::{Rect, Region},
|
rect::{Rect, Region},
|
||||||
renderer::renderer_base::RendererBase,
|
renderer::renderer_base::RendererBase,
|
||||||
state::State,
|
state::State,
|
||||||
theme::Color,
|
theme::Color,
|
||||||
time::Time,
|
time::Time,
|
||||||
tree::Transform,
|
|
||||||
utils::{asyncevent::AsyncEvent, errorfmt::ErrorFmt, timer::TimerFd},
|
utils::{asyncevent::AsyncEvent, errorfmt::ErrorFmt, timer::TimerFd},
|
||||||
},
|
},
|
||||||
isnt::std_1::primitive::IsntSliceExt,
|
isnt::std_1::primitive::IsntSliceExt,
|
||||||
|
|
@ -22,6 +20,8 @@ use {
|
||||||
uapi::c::CLOCK_MONOTONIC,
|
uapi::c::CLOCK_MONOTONIC,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub use jay_damage::*;
|
||||||
|
|
||||||
pub async fn visualize_damage(state: Rc<State>) {
|
pub async fn visualize_damage(state: Rc<State>) {
|
||||||
let timer = match TimerFd::new(CLOCK_MONOTONIC) {
|
let timer = match TimerFd::new(CLOCK_MONOTONIC) {
|
||||||
Ok(t) => t,
|
Ok(t) => t,
|
||||||
|
|
@ -196,114 +196,3 @@ impl DamageVisualizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
pub struct DamageMatrix {
|
|
||||||
transform: Transform,
|
|
||||||
mx: f64,
|
|
||||||
my: f64,
|
|
||||||
dx: f64,
|
|
||||||
dy: f64,
|
|
||||||
smear: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for DamageMatrix {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
transform: Default::default(),
|
|
||||||
mx: 1.0,
|
|
||||||
my: 1.0,
|
|
||||||
dx: 0.0,
|
|
||||||
dy: 0.0,
|
|
||||||
smear: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DamageMatrix {
|
|
||||||
pub fn apply(&self, dx: i32, dy: i32, rect: Rect) -> Rect {
|
|
||||||
let x1 = rect.x1() - self.smear;
|
|
||||||
let x2 = rect.x2() + self.smear;
|
|
||||||
let y1 = rect.y1() - self.smear;
|
|
||||||
let y2 = rect.y2() + self.smear;
|
|
||||||
let [x1, y1, x2, y2] = match self.transform {
|
|
||||||
Transform::None => [x1, y1, x2, y2],
|
|
||||||
Transform::Rotate90 => [-y2, x1, -y1, x2],
|
|
||||||
Transform::Rotate180 => [-x2, -y2, -x1, -y1],
|
|
||||||
Transform::Rotate270 => [y1, -x2, y2, -x1],
|
|
||||||
Transform::Flip => [-x2, y1, -x1, y2],
|
|
||||||
Transform::FlipRotate90 => [y1, x1, y2, x2],
|
|
||||||
Transform::FlipRotate180 => [x1, -y2, x2, -y1],
|
|
||||||
Transform::FlipRotate270 => [-y2, -x2, -y1, -x1],
|
|
||||||
};
|
|
||||||
let x1 = (x1 as f64 * self.mx + self.dx).floor() as i32 + dx;
|
|
||||||
let y1 = (y1 as f64 * self.my + self.dy).floor() as i32 + dy;
|
|
||||||
let x2 = (x2 as f64 * self.mx + self.dx).ceil() as i32 + dx;
|
|
||||||
let y2 = (y2 as f64 * self.my + self.dy).ceil() as i32 + dy;
|
|
||||||
Rect::new_saturating(x1, y1, x2, y2)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(
|
|
||||||
transform: Transform,
|
|
||||||
legacy_scale: i32,
|
|
||||||
buffer_width: i32,
|
|
||||||
buffer_height: i32,
|
|
||||||
viewport: Option<[Fixed; 4]>,
|
|
||||||
dst_width: i32,
|
|
||||||
dst_height: i32,
|
|
||||||
) -> DamageMatrix {
|
|
||||||
let mut buffer_width = buffer_width as f64;
|
|
||||||
let mut buffer_height = buffer_height as f64;
|
|
||||||
let dst_width = dst_width as f64;
|
|
||||||
let dst_height = dst_height as f64;
|
|
||||||
|
|
||||||
let mut mx = 1.0;
|
|
||||||
let mut my = 1.0;
|
|
||||||
if legacy_scale != 1 {
|
|
||||||
let scale_inv = 1.0 / (legacy_scale as f64);
|
|
||||||
mx = scale_inv;
|
|
||||||
my = scale_inv;
|
|
||||||
buffer_width *= scale_inv;
|
|
||||||
buffer_height *= scale_inv;
|
|
||||||
}
|
|
||||||
let (mut buffer_width, mut buffer_height) =
|
|
||||||
transform.maybe_swap((buffer_width, buffer_height));
|
|
||||||
let (mut dx, mut dy) = match transform {
|
|
||||||
Transform::None => (0.0, 0.0),
|
|
||||||
Transform::Rotate90 => (buffer_width, 0.0),
|
|
||||||
Transform::Rotate180 => (buffer_width, buffer_height),
|
|
||||||
Transform::Rotate270 => (0.0, buffer_height),
|
|
||||||
Transform::Flip => (buffer_width, 0.0),
|
|
||||||
Transform::FlipRotate90 => (0.0, 0.0),
|
|
||||||
Transform::FlipRotate180 => (0.0, buffer_height),
|
|
||||||
Transform::FlipRotate270 => (buffer_width, buffer_height),
|
|
||||||
};
|
|
||||||
if let Some([x, y, w, h]) = viewport {
|
|
||||||
dx -= x.to_f64();
|
|
||||||
dy -= y.to_f64();
|
|
||||||
buffer_width = w.to_f64();
|
|
||||||
buffer_height = h.to_f64();
|
|
||||||
}
|
|
||||||
let mut smear = false;
|
|
||||||
if dst_width != buffer_width {
|
|
||||||
let scale = dst_width / buffer_width;
|
|
||||||
mx *= scale;
|
|
||||||
dx *= scale;
|
|
||||||
smear |= dst_width > buffer_width;
|
|
||||||
}
|
|
||||||
if dst_height != buffer_height {
|
|
||||||
let scale = dst_height / buffer_height;
|
|
||||||
my *= scale;
|
|
||||||
dy *= scale;
|
|
||||||
smear |= dst_height > buffer_height;
|
|
||||||
}
|
|
||||||
DamageMatrix {
|
|
||||||
transform,
|
|
||||||
mx,
|
|
||||||
my,
|
|
||||||
dx,
|
|
||||||
dy,
|
|
||||||
smear: smear as _,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue