11use std:: {
2- f32:: consts:: PI ,
32 os:: fd:: AsRawFd ,
43 sync:: { Arc , OnceLock } ,
54} ;
65
7- use glam:: { Affine3A , Vec3 } ;
6+ use glam:: Affine3A ;
87use smallvec:: { SmallVec , smallvec} ;
98use vulkano:: {
109 buffer:: { BufferUsage , Subbuffer } ,
@@ -55,6 +54,7 @@ pub struct ScreenPipeline {
5554 pipeline : Arc < WGfxPipeline < Vert2Uv > > ,
5655 extentf : [ f32 ; 2 ] ,
5756 offsetf : [ f32 ; 2 ] ,
57+ transform : wlx_frame:: Transform ,
5858 stereo : StereoMode ,
5959}
6060
@@ -64,6 +64,7 @@ impl ScreenPipeline {
6464 app : & mut AppState ,
6565 stereo : StereoMode ,
6666 offsetf : [ f32 ; 2 ] ,
67+ transform : wlx_frame:: Transform ,
6768 ) -> anyhow:: Result < Self > {
6869 let extentf = [ meta. extent [ 0 ] as f32 , meta. extent [ 1 ] as f32 ] ;
6970
@@ -81,6 +82,7 @@ impl ScreenPipeline {
8182 pipeline,
8283 extentf,
8384 offsetf,
85+ transform,
8486 stereo,
8587 } ;
8688 me. ensure_stereo ( stereo) ;
@@ -96,6 +98,10 @@ impl ScreenPipeline {
9698 self . pass . clear ( ) ; // ensure_depth will repopulate
9799 }
98100
101+ pub const fn transform ( & self ) -> wlx_frame:: Transform {
102+ self . transform
103+ }
104+
99105 fn ensure_depth ( & mut self , app : & mut AppState , depth : usize ) -> anyhow:: Result < ( ) > {
100106 while self . pass . len ( ) < depth {
101107 self . pass . push ( Self :: create_pass (
@@ -111,20 +117,22 @@ impl ScreenPipeline {
111117 }
112118
113119 for ( eye, current) in self . pass . iter_mut ( ) . enumerate ( ) {
114- let verts = stereo_mode_to_verts ( self . stereo , eye) ;
120+ let verts = stereo_mode_to_verts ( self . stereo , eye, self . transform ) ;
115121 current. buf_vert . write ( ) ?. copy_from_slice ( & verts) ;
116122 }
117123 Ok ( ( ) )
118124 }
119125
120- pub fn set_extent (
126+ pub fn set_layout (
121127 & mut self ,
122128 app : & mut AppState ,
123129 extentf : [ f32 ; 2 ] ,
124130 offsetf : [ f32 ; 2 ] ,
131+ transform : wlx_frame:: Transform ,
125132 ) -> anyhow:: Result < ( ) > {
126133 self . extentf = extentf;
127134 self . offsetf = offsetf;
135+ self . transform = transform;
128136 self . pass . clear ( ) ;
129137
130138 self . mouse = Self :: create_mouse_pass ( app, self . pipeline . clone ( ) , extentf, offsetf) ?;
@@ -241,13 +249,31 @@ impl ScreenPipeline {
241249 }
242250}
243251
244- fn stereo_mode_to_verts ( stereo : StereoMode , array_index : usize ) -> [ Vert2Uv ; 4 ] {
252+ fn transform_uv ( uv : [ f32 ; 2 ] , transform : wlx_frame:: Transform ) -> [ f32 ; 2 ] {
253+ let [ u, v] = uv;
254+ match transform {
255+ wlx_frame:: Transform :: Normal | wlx_frame:: Transform :: Undefined => [ u, v] ,
256+ wlx_frame:: Transform :: Rotated90 => [ v, 1.0 - u] ,
257+ wlx_frame:: Transform :: Rotated180 => [ 1.0 - u, 1.0 - v] ,
258+ wlx_frame:: Transform :: Rotated270 => [ 1.0 - v, u] ,
259+ wlx_frame:: Transform :: Flipped => [ 1.0 - u, v] ,
260+ wlx_frame:: Transform :: Flipped90 => [ v, u] ,
261+ wlx_frame:: Transform :: Flipped180 => [ u, 1.0 - v] ,
262+ wlx_frame:: Transform :: Flipped270 => [ 1.0 - v, 1.0 - u] ,
263+ }
264+ }
265+
266+ fn stereo_mode_to_verts (
267+ stereo : StereoMode ,
268+ array_index : usize ,
269+ transform : wlx_frame:: Transform ,
270+ ) -> [ Vert2Uv ; 4 ] {
245271 let eye = match stereo {
246272 StereoMode :: RightLeft | StereoMode :: BottomTop => ( 1 - array_index) as f32 ,
247273 _ => array_index as f32 ,
248274 } ;
249275
250- match stereo {
276+ let mut verts = match stereo {
251277 StereoMode :: None => [
252278 Vert2Uv {
253279 in_pos : [ 0. , 0. ] ,
@@ -302,7 +328,13 @@ fn stereo_mode_to_verts(stereo: StereoMode, array_index: usize) -> [Vert2Uv; 4]
302328 in_uv : [ 1. , 0.5 + eye * 0.5 ] ,
303329 } ,
304330 ] ,
331+ } ;
332+
333+ for vert in & mut verts {
334+ vert. in_uv = transform_uv ( vert. in_uv , transform) ;
305335 }
336+
337+ verts
306338}
307339
308340static DMA_ALLOCATOR : OnceLock < Arc < dyn MemoryAllocator > > = OnceLock :: new ( ) ;
@@ -460,7 +492,7 @@ impl WlxCaptureOut {
460492 FrameMeta {
461493 clear : WGfxClearMode :: DontCare ,
462494 extent : extent_from_format ( self . format , config) ,
463- transform : affine_from_format ( & self . format ) ,
495+ transform : Affine3A :: IDENTITY ,
464496 format : self . image . format ( ) ,
465497 stereo,
466498 }
@@ -585,13 +617,14 @@ pub(super) fn receive_callback(me: &WlxCaptureIn, frame: WlxFrame) -> Option<Wlx
585617 mouse : frame. mouse ,
586618 } )
587619 }
588- WlxFrame :: Implicit => {
620+ WlxFrame :: Implicit ( transform ) => {
589621 log:: trace!( "{}: New Implicit frame" , me. name) ;
590622
591- let Some ( ( image, format) ) = me. dma_exporter . as_ref ( ) . unwrap ( ) . get_current ( ) else {
623+ let Some ( ( image, mut format) ) = me. dma_exporter . as_ref ( ) . unwrap ( ) . get_current ( ) else {
592624 log:: error!( "{}: Implicit frame is missing!" , me. name) ;
593625 return None ;
594626 } ;
627+ format. transform = transform;
595628
596629 Some ( WlxCaptureOut {
597630 image,
@@ -676,43 +709,26 @@ const fn receive_callback_dummy(_: &DummyDrmExporter, frame: WlxFrame) -> Option
676709}
677710
678711fn extent_from_format ( fmt : FrameFormat , config : & GeneralConfig ) -> [ u32 ; 2 ] {
712+ let ( width, height) = match fmt. transform {
713+ wlx_frame:: Transform :: Rotated90
714+ | wlx_frame:: Transform :: Rotated270
715+ | wlx_frame:: Transform :: Flipped90
716+ | wlx_frame:: Transform :: Flipped270 => ( fmt. height , fmt. width ) ,
717+ _ => ( fmt. width , fmt. height ) ,
718+ } ;
719+
679720 // screens above a certain resolution will have severe aliasing
680721 let height_limit = if config. screen_render_down {
681722 u32:: from ( config. screen_max_height . min ( 2560 ) )
682723 } else {
683724 2560
684725 } ;
685726
686- let h = fmt . height . min ( height_limit) ;
687- let w = ( fmt . width as f32 / fmt . height as f32 * h as f32 ) as u32 ;
727+ let h = height. min ( height_limit) ;
728+ let w = ( width as f32 / height as f32 * h as f32 ) as u32 ;
688729 [ w, h]
689730}
690731
691- fn affine_from_format ( format : & FrameFormat ) -> Affine3A {
692- const FLIP_X : Vec3 = Vec3 {
693- x : -1.0 ,
694- y : 1.0 ,
695- z : 1.0 ,
696- } ;
697-
698- match format. transform {
699- wlx_frame:: Transform :: Rotated90 => Affine3A :: from_rotation_z ( -PI / 2.0 ) ,
700- wlx_frame:: Transform :: Rotated180 => Affine3A :: from_rotation_z ( PI ) ,
701- wlx_frame:: Transform :: Rotated270 => Affine3A :: from_rotation_z ( PI / 2.0 ) ,
702- wlx_frame:: Transform :: Flipped => Affine3A :: from_scale ( FLIP_X ) ,
703- wlx_frame:: Transform :: Flipped90 => {
704- Affine3A :: from_scale ( FLIP_X ) * Affine3A :: from_rotation_z ( -PI / 2.0 )
705- }
706- wlx_frame:: Transform :: Flipped180 => {
707- Affine3A :: from_scale ( FLIP_X ) * Affine3A :: from_rotation_z ( PI )
708- }
709- wlx_frame:: Transform :: Flipped270 => {
710- Affine3A :: from_scale ( FLIP_X ) * Affine3A :: from_rotation_z ( PI / 2.0 )
711- }
712- _ => Affine3A :: IDENTITY ,
713- }
714- }
715-
716732macro_rules! new_wlx_capture {
717733 ( $capture_queue: expr, $capture: expr) => {
718734 if $capture_queue. is_none( ) {
0 commit comments