1
0
Fork 0
forked from wry/wry

all: implement output transforms

This commit is contained in:
Julian Orth 2024-02-27 23:32:40 +01:00
parent 79df8d69f4
commit b7d2964e19
20 changed files with 254 additions and 71 deletions

View file

@ -9,7 +9,7 @@ use {
state::State,
theme::Color,
tree::{Node, OutputNode},
utils::numcell::NumCell,
utils::{numcell::NumCell, transform_ext::TransformExt},
video::{dmabuf::DmaBuf, gbm::GbmDevice, Modifier},
},
ahash::AHashMap,
@ -86,24 +86,44 @@ pub struct FramebufferRect {
pub x2: f32,
pub y1: f32,
pub y2: f32,
pub output_transform: Transform,
}
impl FramebufferRect {
pub fn new(x1: f32, y1: f32, x2: f32, y2: f32, width: f32, height: f32) -> Self {
pub fn new(
x1: f32,
y1: f32,
x2: f32,
y2: f32,
transform: Transform,
width: f32,
height: f32,
) -> Self {
Self {
x1: 2.0 * x1 / width - 1.0,
x2: 2.0 * x2 / width - 1.0,
y1: 2.0 * y1 / height - 1.0,
y2: 2.0 * y2 / height - 1.0,
output_transform: transform,
}
}
pub fn to_points(&self) -> [[f32; 2]; 4] {
use Transform::*;
let x1 = self.x1;
let x2 = self.x2;
let y1 = self.y1;
let y2 = self.y2;
[[x2, y1], [x1, y1], [x2, y2], [x1, y2]]
match self.output_transform {
None => [[x2, y1], [x1, y1], [x2, y2], [x1, y2]],
Rotate90 => [[y1, -x2], [y1, -x1], [y2, -x2], [y2, -x1]],
Rotate180 => [[-x2, -y1], [-x1, -y1], [-x2, -y2], [-x1, -y2]],
Rotate270 => [[-y1, x2], [-y1, x1], [-y2, x2], [-y2, x1]],
Flip => [[-x2, y1], [-x1, y1], [-x2, y2], [-x1, y2]],
FlipRotate90 => [[y1, x2], [y1, x1], [y2, x2], [y2, x1]],
FlipRotate180 => [[x2, -y1], [x1, -y1], [x2, -y2], [x1, -y2]],
FlipRotate270 => [[-y1, -x2], [-y1, -x1], [-y2, -x2], [-y2, -x1]],
}
}
pub fn is_covering(&self) -> bool {
@ -136,7 +156,7 @@ pub trait GfxFramebuffer: Debug {
fn take_render_ops(&self) -> Vec<GfxApiOpt>;
fn size(&self) -> (i32, i32);
fn physical_size(&self) -> (i32, i32);
fn render(&self, ops: Vec<GfxApiOpt>, clear: Option<&Color>);
@ -164,13 +184,23 @@ impl dyn GfxFramebuffer {
self.render(ops, Some(&Color { r, g, b, a }));
}
pub fn renderer_base<'a>(&self, ops: &'a mut Vec<GfxApiOpt>, scale: Scale) -> RendererBase<'a> {
let (width, height) = self.size();
pub fn logical_size(&self, transform: Transform) -> (i32, i32) {
transform.maybe_swap(self.physical_size())
}
pub fn renderer_base<'a>(
&self,
ops: &'a mut Vec<GfxApiOpt>,
scale: Scale,
transform: Transform,
) -> RendererBase<'a> {
let (width, height) = self.logical_size(transform);
RendererBase {
ops,
scaled: scale != 1,
scale,
scalef: scale.to_f64(),
transform,
fb_width: width as _,
fb_height: height as _,
}
@ -179,7 +209,7 @@ impl dyn GfxFramebuffer {
pub fn copy_texture(&self, texture: &Rc<dyn GfxTexture>, x: i32, y: i32) {
let mut ops = self.take_render_ops();
let scale = Scale::from_int(1);
let mut renderer = self.renderer_base(&mut ops, scale);
let mut renderer = self.renderer_base(&mut ops, scale, Transform::None);
renderer.render_texture(texture, x, y, None, None, scale, None);
let clear = self.format().has_alpha.then_some(&Color::TRANSPARENT);
self.render(ops, clear);
@ -192,7 +222,7 @@ impl dyn GfxFramebuffer {
f: &mut dyn FnMut(&mut RendererBase),
) {
let mut ops = self.take_render_ops();
let mut renderer = self.renderer_base(&mut ops, scale);
let mut renderer = self.renderer_base(&mut ops, scale, Transform::None);
f(&mut renderer);
self.render(ops, clear);
}
@ -206,15 +236,18 @@ impl dyn GfxFramebuffer {
scale: Scale,
render_hardware_cursor: bool,
black_background: bool,
transform: Transform,
) -> GfxRenderPass {
let mut ops = self.take_render_ops();
let (width, height) = self.size();
let mut renderer = Renderer {
base: self.renderer_base(&mut ops, scale),
base: self.renderer_base(&mut ops, scale, transform),
state,
result,
logical_extents: node.node_absolute_position().at_point(0, 0),
physical_extents: Rect::new(0, 0, width, height).unwrap(),
pixel_extents: {
let (width, height) = self.logical_size(transform);
Rect::new(0, 0, width, height).unwrap()
},
};
node.node_render(&mut renderer, 0, 0, None);
if let Some(rect) = cursor_rect {
@ -272,6 +305,7 @@ impl dyn GfxFramebuffer {
scale,
render_hardware_cursor,
node.has_fullscreen(),
node.global.transform.get(),
)
}
@ -284,6 +318,7 @@ impl dyn GfxFramebuffer {
scale: Scale,
render_hardware_cursor: bool,
black_background: bool,
transform: Transform,
) {
let pass = self.create_render_pass(
node,
@ -293,19 +328,28 @@ impl dyn GfxFramebuffer {
scale,
render_hardware_cursor,
black_background,
transform,
);
self.perform_render_pass(pass);
}
pub fn render_hardware_cursor(&self, cursor: &dyn Cursor, state: &State, scale: Scale) {
pub fn render_hardware_cursor(
&self,
cursor: &dyn Cursor,
state: &State,
scale: Scale,
transform: Transform,
) {
let mut ops = self.take_render_ops();
let (width, height) = self.size();
let mut renderer = Renderer {
base: self.renderer_base(&mut ops, scale),
base: self.renderer_base(&mut ops, scale, transform),
state,
result: None,
logical_extents: Rect::new_empty(0, 0),
physical_extents: Rect::new(0, 0, width, height).unwrap(),
pixel_extents: {
let (width, height) = self.logical_size(transform);
Rect::new(0, 0, width, height).unwrap()
},
};
cursor.render_hardware_cursor(&mut renderer);
self.render(ops, Some(&Color::TRANSPARENT));