all: implement output transforms
This commit is contained in:
parent
79df8d69f4
commit
b7d2964e19
20 changed files with 254 additions and 71 deletions
|
|
@ -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));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue