1
0
Fork 0
forked from wry/wry

render: simplify buffer coordinates

This commit is contained in:
Julian Orth 2024-02-27 23:44:05 +01:00
parent 85c11448fb
commit 7d3b8b6278
10 changed files with 337 additions and 419 deletions

View file

@ -16,14 +16,10 @@ use {
client::{Client, ClientError, RequestParser},
drm_feedback::DrmFeedback,
fixed::Fixed,
gfx_api::{BufferPoint, BufferPoints},
gfx_api::SampleRect,
ifs::{
wl_buffer::WlBuffer,
wl_callback::WlCallback,
wl_output::{
TF_180, TF_270, TF_90, TF_FLIPPED, TF_FLIPPED_180, TF_FLIPPED_270, TF_FLIPPED_90,
TF_NORMAL,
},
wl_seat::{
wl_pointer::PendingScroll, zwp_pointer_constraints_v1::SeatConstraint, Dnd,
NodeSeatState, SeatId, WlSeatGlobal,
@ -54,6 +50,7 @@ use {
linkedlist::LinkedList,
numcell::NumCell,
smallmap::SmallMap,
transform_ext::TransformExt,
},
wire::{
wl_surface::*, WlOutputId, WlSurfaceId, ZwpIdleInhibitorV1Id,
@ -63,6 +60,7 @@ use {
xwayland::XWaylandEvent,
},
ahash::AHashMap,
jay_config::video::Transform,
std::{
cell::{Cell, RefCell},
fmt::{Debug, Formatter},
@ -84,110 +82,6 @@ const INVALID_SIZE: u32 = 2;
const OFFSET_SINCE: u32 = 5;
const BUFFER_SCALE_SINCE: u32 = 6;
#[derive(Copy, Clone, Debug, PartialEq)]
enum Transform {
Normal,
Rotate90,
Rotate180,
Rotate270,
Flipped,
Flipped90,
Flipped180,
Flipped270,
}
impl Transform {
fn swaps_dimensions(self) -> bool {
match self {
Transform::Normal => false,
Transform::Rotate90 => true,
Transform::Rotate180 => false,
Transform::Rotate270 => true,
Transform::Flipped => false,
Transform::Flipped90 => true,
Transform::Flipped180 => false,
Transform::Flipped270 => true,
}
}
}
impl Transform {
fn apply_inv_sized(self, x1: f32, y1: f32, width: f32, height: f32) -> BufferPoints {
let x2 = x1 + width;
let y2 = y1 + height;
self.apply_inv(x1, y1, x2, y2)
}
fn apply_inv(self, x1: f32, y1: f32, x2: f32, y2: f32) -> BufferPoints {
macro_rules! bp {
(
$tl_x:expr, $tl_y:expr,
$tr_x:expr, $tr_y:expr,
$br_x:expr, $br_y:expr,
$bl_x:expr, $bl_y:expr,
) => {
BufferPoints {
top_left: BufferPoint { x: $tl_x, y: $tl_y },
top_right: BufferPoint { x: $tr_x, y: $tr_y },
bottom_right: BufferPoint { x: $br_x, y: $br_y },
bottom_left: BufferPoint { x: $bl_x, y: $bl_y },
}
};
}
use Transform::*;
match self {
Normal => bp! {
x1, y1,
x2, y1,
x2, y2,
x1, y2,
},
Rotate90 => bp! {
y1, x2,
y1, x1,
y2, x1,
y2, x2,
},
Rotate180 => bp! {
x2, y2,
x1, y2,
x1, y1,
x2, y1,
},
Rotate270 => bp! {
y2, x1,
y2, x2,
y1, x2,
y1, x1,
},
Flipped => bp! {
x2, y1,
x1, y1,
x1, y2,
x2, y2,
},
Flipped90 => bp! {
y1, x1,
y1, x2,
y2, x2,
y2, x1,
},
Flipped180 => bp! {
x1, y2,
x2, y2,
x2, y1,
x1, y1,
},
Flipped270 => bp! {
y2, x2,
y2, x1,
y1, x1,
y1, x2,
},
}
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum SurfaceRole {
None,
@ -233,7 +127,7 @@ pub struct WlSurface {
input_region: Cell<Option<Rc<Region>>>,
opaque_region: Cell<Option<Rc<Region>>>,
buffer_points: RefCell<BufferPoints>,
pub buffer_points_norm: RefCell<BufferPoints>,
pub buffer_points_norm: RefCell<SampleRect>,
buffer_transform: Cell<Transform>,
buffer_scale: Cell<i32>,
src_rect: Cell<Option<[Fixed; 4]>>,
@ -273,6 +167,14 @@ impl Debug for WlSurface {
}
}
#[derive(Default)]
struct BufferPoints {
x1: f32,
x2: f32,
y1: f32,
y2: f32,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
enum CommitContext {
RootCommit,
@ -387,7 +289,7 @@ impl WlSurface {
opaque_region: Default::default(),
buffer_points: Default::default(),
buffer_points_norm: Default::default(),
buffer_transform: Cell::new(Transform::Normal),
buffer_transform: Cell::new(Transform::None),
buffer_scale: Cell::new(1),
src_rect: Cell::new(None),
dst_size: Cell::new(None),
@ -823,10 +725,12 @@ impl WlSurface {
width *= scale;
height *= scale;
}
*buffer_points = self
.buffer_transform
.get()
.apply_inv_sized(x1, y1, width, height);
*buffer_points = BufferPoints {
x1,
y1,
x2: x1 + width,
y2: y1 + height,
};
}
let size = match self.dst_size.get() {
Some(ds) => ds,
@ -838,10 +742,8 @@ impl WlSurface {
}
if let Some(buffer) = self.buffer.get() {
if new_size.is_none() {
let (mut width, mut height) = buffer.rect.size();
if self.buffer_transform.get().swaps_dimensions() {
mem::swap(&mut width, &mut height);
}
let (mut width, mut height) =
self.buffer_transform.get().maybe_swap(buffer.rect.size());
let scale = self.buffer_scale.get();
if scale != 1 {
width = (width + scale - 1) / scale;
@ -850,19 +752,29 @@ impl WlSurface {
new_size = Some((width, height));
}
if transform_changed || Some(buffer.rect) != old_raw_size {
if self.src_rect.get().is_none() {
*buffer_points = self
.buffer_transform
.get()
.apply_inv_sized(0.0, 0.0, 1.0, 1.0);
*buffer_points_norm = *buffer_points;
let (x1, y1, x2, y2) = if self.src_rect.get().is_none() {
(0.0, 0.0, 1.0, 1.0)
} else {
*buffer_points_norm = buffer_points
.norm(buffer.rect.width() as f32, buffer.rect.height() as f32);
if !buffer_points_norm.is_leq_1() {
let (width, height) =
self.buffer_transform.get().maybe_swap(buffer.rect.size());
let width = width as f32;
let height = height as f32;
let x1 = buffer_points.x1 / width;
let x2 = buffer_points.x2 / width;
let y1 = buffer_points.y1 / height;
let y2 = buffer_points.y2 / height;
if x1 > 1.0 || x2 > 1.0 || y1 > 1.0 || y2 > 1.0 {
return Err(WlSurfaceError::ViewportOutsideBuffer);
}
}
(x1, y1, x2, y2)
};
*buffer_points_norm = SampleRect {
x1,
y1,
x2,
y2,
buffer_transform: self.buffer_transform.get(),
};
}
}
let (width, height) = new_size.unwrap_or_default();
@ -932,17 +844,8 @@ impl WlSurface {
fn set_buffer_transform(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSurfaceError> {
let req: SetBufferTransform = self.parse(parser)?;
use Transform::*;
let tf = match req.transform {
TF_NORMAL => Normal,
TF_90 => Rotate90,
TF_180 => Rotate180,
TF_270 => Rotate270,
TF_FLIPPED => Flipped,
TF_FLIPPED_90 => Flipped90,
TF_FLIPPED_180 => Flipped180,
TF_FLIPPED_270 => Flipped270,
_ => return Err(WlSurfaceError::UnknownBufferTransform(req.transform)),
let Some(tf) = Transform::from_wl(req.transform) else {
return Err(WlSurfaceError::UnknownBufferTransform(req.transform));
};
self.pending.transform.set(Some(tf));
Ok(())