@@ -19,18 +19,14 @@ use openscreen_compositor::compositor::Compositor;
1919use openscreen_compositor:: config:: Cfg ;
2020use openscreen_compositor:: cursor:: CursorTrack ;
2121use openscreen_compositor:: d3d:: Gpu ;
22- use openscreen_compositor:: ffi:: AVFrame ;
2322use openscreen_compositor:: frame_geometry:: {
2423 live_params_from_scene, plan_cursor, plan_frame, CursorPlacement , CursorPlanInput ,
2524 FrameGeometryInput ,
2625} ;
2726use openscreen_compositor:: scene:: Scene ;
28- use windows:: core:: Interface ;
29- use windows:: Win32 :: Graphics :: Direct3D11 :: {
30- ID3D11Texture2D , D3D11_BIND_SHADER_RESOURCE , D3D11_CPU_ACCESS_WRITE ,
31- D3D11_MAPPED_SUBRESOURCE , D3D11_MAP_WRITE_DISCARD , D3D11_TEXTURE2D_DESC , D3D11_USAGE_DYNAMIC ,
32- } ;
33- use windows:: Win32 :: Graphics :: Dxgi :: Common :: { DXGI_FORMAT_NV12 , DXGI_SAMPLE_DESC } ;
27+
28+ mod common;
29+ use common:: { gpu, Nv12Frame } ;
3430
3531const SRC : ( u32 , u32 ) = ( 640 , 360 ) ;
3632/// Instant rendu : en plein palier de la région de zoom (0..10 s).
@@ -67,16 +63,6 @@ fn is_centred(key: &str) -> bool {
6763 matches ! ( key, "text" | "resize-ew" | "not-allowed" )
6864}
6965
70- fn gpu ( ) -> Option < Gpu > {
71- match Gpu :: create ( false ) {
72- Ok ( g) => Some ( g) ,
73- Err ( e) => {
74- eprintln ! ( "pas de device D3D11 matériel ({e:#}) — test saute" ) ;
75- None
76- }
77- }
78- }
79-
8066/// Deux teintes de contenu : un pixel identique sur les deux est du modèle opaque, un pixel qui
8167/// change est le contenu, son ombre ou une frange antialiasée.
8268#[ derive( Clone , Copy ) ]
@@ -89,63 +75,20 @@ enum Tint {
8975/// D3D11VA (le seul contrat que `Compositor::nv12_srvs` lit). Une teinte moyenne striée de barres
9076/// plus sombres : rien d'aussi clair ni d'aussi sombre que le curseur, et surtout rien de NEUTRE,
9177/// si bien qu'un pixel gris est le curseur et un pixel teinté assombri, son ombre.
92- struct FakeFrame {
93- frame : Box < AVFrame > ,
94- _tex : ID3D11Texture2D ,
95- }
96-
97- impl FakeFrame {
98- fn new ( gpu : & Gpu , tint : Tint ) -> FakeFrame {
99- let ( w, h) = SRC ;
100- let ( u, v) = match tint {
101- Tint :: Blue => ( 150 , 120 ) ,
102- Tint :: Orange => ( 100 , 170 ) ,
103- } ;
104- let desc = D3D11_TEXTURE2D_DESC {
105- Width : w,
106- Height : h,
107- MipLevels : 1 ,
108- ArraySize : 1 ,
109- Format : DXGI_FORMAT_NV12 ,
110- SampleDesc : DXGI_SAMPLE_DESC { Count : 1 , Quality : 0 } ,
111- Usage : D3D11_USAGE_DYNAMIC ,
112- BindFlags : D3D11_BIND_SHADER_RESOURCE . 0 as u32 ,
113- CPUAccessFlags : D3D11_CPU_ACCESS_WRITE . 0 as u32 ,
114- MiscFlags : 0 ,
115- } ;
116- unsafe {
117- let mut tex: Option < ID3D11Texture2D > = None ;
118- gpu. device . CreateTexture2D ( & desc, None , Some ( & mut tex) ) . expect ( "texture NV12" ) ;
119- let tex = tex. expect ( "texture NV12" ) ;
120- let mut m = D3D11_MAPPED_SUBRESOURCE :: default ( ) ;
121- gpu. context . Map ( & tex, 0 , D3D11_MAP_WRITE_DISCARD , 0 , Some ( & mut m) ) . expect ( "Map" ) ;
122- let pitch = m. RowPitch as usize ;
123- let dst = m. pData as * mut u8 ;
124- for row in 0 ..h as usize {
125- for col in 0 ..w as usize {
126- let bar = row % 24 >= 8 && row % 24 < 12 && ( col / 40 ) % 3 != 2 ;
127- * dst. add ( row * pitch + col) = if bar { 90 } else { 150 } ;
128- }
129- }
130- for row in 0 ..( h / 2 ) as usize {
131- for col in 0 ..w as usize {
132- let uv = ( h as usize + row) * pitch + col;
133- * dst. add ( uv) = if col % 2 == 0 { u } else { v } ;
134- }
135- }
136- gpu. context . Unmap ( & tex, 0 ) ;
137- let mut frame: Box < AVFrame > = Box :: new ( std:: mem:: zeroed ( ) ) ;
138- frame. data [ 0 ] = tex. as_raw ( ) as * mut u8 ;
139- frame. data [ 1 ] = std:: ptr:: null_mut ( ) ;
140- frame. width = w as i32 ;
141- frame. height = h as i32 ;
142- FakeFrame { frame, _tex : tex }
143- }
144- }
145-
146- fn as_ptr ( & self ) -> * const AVFrame {
147- & * self . frame as * const AVFrame
148- }
78+ fn fake_frame ( gpu : & Gpu , tint : Tint ) -> Nv12Frame {
79+ let [ u, v] = match tint {
80+ Tint :: Blue => [ 150 , 120 ] ,
81+ Tint :: Orange => [ 100 , 170 ] ,
82+ } ;
83+ Nv12Frame :: new (
84+ gpu,
85+ SRC ,
86+ |col, row| {
87+ let bar = row % 24 >= 8 && row % 24 < 12 && ( col / 40 ) % 3 != 2 ;
88+ if bar { 90 } else { 150 }
89+ } ,
90+ |_, _| [ u, v] ,
91+ )
14992}
15093
15194/// Les seize sprites livrés, au format `cursorSprites` de la scène.
@@ -287,15 +230,15 @@ struct Probe {
287230 unit : f32 ,
288231}
289232
290- fn render ( comp : & Compositor , screen : & FakeFrame , json : & str , track : & CursorTrack ) -> ( Vec < u8 > , Probe ) {
233+ fn render ( comp : & Compositor , screen : & Nv12Frame , json : & str , track : & CursorTrack ) -> ( Vec < u8 > , Probe ) {
291234 let ( rgba, probe) = render_any ( comp, screen, json, track) ;
292235 ( rgba, probe. expect ( "un curseur à dessiner" ) )
293236}
294237
295238/// `render`, sans exiger de curseur (scène au curseur masqué).
296239fn render_any (
297240 comp : & Compositor ,
298- screen : & FakeFrame ,
241+ screen : & Nv12Frame ,
299242 json : & str ,
300243 track : & CursorTrack ,
301244) -> ( Vec < u8 > , Option < Probe > ) {
@@ -517,7 +460,7 @@ fn save(name: &str, rgba: &[u8]) {
517460fn the_modelled_arrow_stands_on_the_screen_and_casts_its_shadow ( ) {
518461 let Some ( gpu) = gpu ( ) else { return } ;
519462 let comp = Compositor :: new_sized ( & gpu, 1280 , 720 ) . expect ( "compositor" ) ;
520- let screen = FakeFrame :: new ( & gpu, Tint :: Blue ) ;
463+ let screen = fake_frame ( & gpu, Tint :: Blue ) ;
521464 let still = resting ( "still" , false ) ;
522465 let clicked = resting ( "clicked" , true ) ;
523466
@@ -580,7 +523,7 @@ fn the_modelled_arrow_stands_on_the_screen_and_casts_its_shadow() {
580523fn every_state_keeps_its_art_and_its_footprint ( ) {
581524 let Some ( gpu) = gpu ( ) else { return } ;
582525 let comp = Compositor :: new_sized ( & gpu, 1280 , 720 ) . expect ( "compositor" ) ;
583- let ( blue, orange) = ( FakeFrame :: new ( & gpu, Tint :: Blue ) , FakeFrame :: new ( & gpu, Tint :: Orange ) ) ;
526+ let ( blue, orange) = ( fake_frame ( & gpu, Tint :: Blue ) , fake_frame ( & gpu, Tint :: Orange ) ) ;
584527 const SIZE : f32 = 5.0 ;
585528 let bare = render_any ( & comp, & blue, & hidden_json ( "null" ) , & resting ( "bare" , false ) ) . 0 ;
586529 let mut failures = Vec :: new ( ) ;
@@ -647,7 +590,7 @@ fn every_state_keeps_its_art_and_its_footprint() {
647590fn the_tilt_turns_every_state_with_the_screen ( ) {
648591 let Some ( gpu) = gpu ( ) else { return } ;
649592 let comp = Compositor :: new_sized ( & gpu, 1280 , 720 ) . expect ( "compositor" ) ;
650- let screen = FakeFrame :: new ( & gpu, Tint :: Blue ) ;
593+ let screen = fake_frame ( & gpu, Tint :: Blue ) ;
651594 for key in TESTED {
652595 let mask = |rotation : & str , x : f32 , y : f32 | -> ( Vec < bool > , Probe ) {
653596 let still = track_as ( & format ! ( "tilt-{key}" ) , Some ( key) , & [ ( 0.0 , x, y, false ) , ( 9.0 , x, y, false ) ] ) ;
@@ -686,7 +629,7 @@ fn the_tilt_turns_every_state_with_the_screen() {
686629fn without_the_model_the_cursor_renders_the_flat_sprite ( ) {
687630 let Some ( gpu) = gpu ( ) else { return } ;
688631 let comp = Compositor :: new_sized ( & gpu, 1280 , 720 ) . expect ( "compositor" ) ;
689- let screen = FakeFrame :: new ( & gpu, Tint :: Blue ) ;
632+ let screen = fake_frame ( & gpu, Tint :: Blue ) ;
690633 let still = resting ( "flat-sprite" , false ) ;
691634 let clicked = resting ( "flat-sprite-clicked" , true ) ;
692635 let text = resting_as ( "flat-sprite-text" , Some ( "text" ) , false ) ;
@@ -727,7 +670,7 @@ fn without_the_model_the_cursor_renders_the_flat_sprite() {
727670fn a_moving_pointer_turns_towards_its_motion_and_a_centred_cursor_does_not ( ) {
728671 let Some ( gpu) = gpu ( ) else { return } ;
729672 let comp = Compositor :: new_sized ( & gpu, 1280 , 720 ) . expect ( "compositor" ) ;
730- let screen = FakeFrame :: new ( & gpu, Tint :: Blue ) ;
673+ let screen = fake_frame ( & gpu, Tint :: Blue ) ;
731674 let json = scene_json ( r#""iso""# , Some ( true ) , "default" , 0.0 , 3.0 ) ;
732675 // En T, la piste mobile passe en x = 0,2 + 0,6 × T / (T + 1) = 0,6 : la piste immobile y est.
733676 let moving_as = |key : Option < & str > | {
@@ -771,7 +714,7 @@ fn a_moving_pointer_turns_towards_its_motion_and_a_centred_cursor_does_not() {
771714fn the_motion_blur_trail_draws_modelled_copies ( ) {
772715 let Some ( gpu) = gpu ( ) else { return } ;
773716 let comp = Compositor :: new_sized ( & gpu, 1280 , 720 ) . expect ( "compositor" ) ;
774- let screen = FakeFrame :: new ( & gpu, Tint :: Blue ) ;
717+ let screen = fake_frame ( & gpu, Tint :: Blue ) ;
775718 let moving = track ( "trail" , & [ ( 0.0 , 0.2 , 0.45 , false ) , ( T + 1.0 , 0.8 , 0.45 , false ) ] ) ;
776719 let ( rgba, _) = render ( & comp, & screen, & scene_json ( "null" , Some ( true ) , "default" , 1.0 , 3.0 ) , & moving) ;
777720 let ( flat, _) = render ( & comp, & screen, & scene_json ( "null" , Some ( false ) , "default" , 1.0 , 3.0 ) , & moving) ;
@@ -788,7 +731,7 @@ fn the_motion_blur_trail_draws_modelled_copies() {
788731fn the_sculpted_cursors_stand_at_the_hotspot ( ) {
789732 let Some ( gpu) = gpu ( ) else { return } ;
790733 let comp = Compositor :: new_sized ( & gpu, 1280 , 720 ) . expect ( "compositor" ) ;
791- let ( blue, orange) = ( FakeFrame :: new ( & gpu, Tint :: Blue ) , FakeFrame :: new ( & gpu, Tint :: Orange ) ) ;
734+ let ( blue, orange) = ( fake_frame ( & gpu, Tint :: Blue ) , fake_frame ( & gpu, Tint :: Orange ) ) ;
792735 let bare = render_any ( & comp, & blue, & hidden_json ( "null" ) , & resting ( "sculpt-bare" , false ) ) . 0 ;
793736 let bare_orange = render_any ( & comp, & orange, & hidden_json ( "null" ) , & resting ( "sculpt-bare" , false ) ) . 0 ;
794737 let mut failures = Vec :: new ( ) ;
@@ -860,7 +803,7 @@ fn contact_sheets() {
860803 } ;
861804 let Some ( gpu) = gpu ( ) else { return } ;
862805 let comp = Compositor :: new_sized ( & gpu, 1280 , 720 ) . expect ( "compositor" ) ;
863- let screen = FakeFrame :: new ( & gpu, Tint :: Blue ) ;
806+ let screen = fake_frame ( & gpu, Tint :: Blue ) ;
864807 const CELL : u32 = 300 ;
865808 let crop = |rgba : & [ u8 ] , p : Probe | {
866809 let img = image:: RgbaImage :: from_raw ( 1280 , 720 , rgba. to_vec ( ) ) . expect ( "readback" ) ;
@@ -928,7 +871,7 @@ fn bench_the_modelled_cursor_at_1080p() {
928871 gpu
929872 } ;
930873 let comp = Compositor :: new_sized ( & gpu, 1920 , 1080 ) . expect ( "compositor" ) ;
931- let screen = FakeFrame :: new ( & gpu, Tint :: Blue ) ;
874+ let screen = fake_frame ( & gpu, Tint :: Blue ) ;
932875 let still = resting ( "bench" , false ) ;
933876 let text = resting_as ( "bench-text" , Some ( "text" ) , false ) ;
934877 // Un geste rapide : la traînée prend ses 16 copies.
0 commit comments