@@ -801,15 +801,14 @@ impl<'render, 'target, R: GraphicsApi, T: GraphicsApi> MultiRenderer<'render, 't
801801}
802802
803803/// A Framebuffer of a [`MultiRenderer`].
804- pub struct MultiFramebuffer < ' buffer , R : GraphicsApi , T : GraphicsApi > ( MultiFramebufferInternal < ' buffer , R , T > ) ;
805- enum MultiFramebufferInternal < ' buffer , R : GraphicsApi , T : GraphicsApi > {
806- Render ( <<R :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' buffer > ) ,
804+ pub struct MultiFramebuffer < ' buffer , T : GraphicsApi > ( MultiFramebufferInternal < ' buffer , T > ) ;
805+ enum MultiFramebufferInternal < ' buffer , T : GraphicsApi > {
806+ Render ( <<T :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' buffer > ) ,
807807 Target ( <<T :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' buffer > ) ,
808808}
809809
810- impl < ' buffer , R : GraphicsApi , T : GraphicsApi > fmt:: Debug for MultiFramebuffer < ' buffer , R , T >
810+ impl < ' buffer , T : GraphicsApi > fmt:: Debug for MultiFramebuffer < ' buffer , T >
811811where
812- <<R :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' buffer > : fmt:: Debug ,
813812 <<T :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' buffer > : fmt:: Debug ,
814813{
815814 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
@@ -820,7 +819,7 @@ where
820819 }
821820}
822821
823- impl < R : GraphicsApi , T : GraphicsApi > Texture for MultiFramebuffer < ' _ , R , T > {
822+ impl < T : GraphicsApi > Texture for MultiFramebuffer < ' _ , T > {
824823 fn size ( & self ) -> Size < i32 , BufferCoords > {
825824 match & self . 0 {
826825 MultiFramebufferInternal :: Render ( framebuffer) => framebuffer. size ( ) ,
@@ -850,6 +849,28 @@ impl<R: GraphicsApi, T: GraphicsApi> Texture for MultiFramebuffer<'_, R, T> {
850849 }
851850}
852851
852+ impl < ' a , T : GraphicsApi > AsRef < <<T :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' a > >
853+ for MultiFramebuffer < ' a , T >
854+ {
855+ fn as_ref ( & self ) -> & <<T :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' a > {
856+ match & self . 0 {
857+ MultiFramebufferInternal :: Render ( fb) => fb,
858+ MultiFramebufferInternal :: Target ( fb) => fb,
859+ }
860+ }
861+ }
862+
863+ impl < ' a , T : GraphicsApi > AsMut < <<T :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' a > >
864+ for MultiFramebuffer < ' a , T >
865+ {
866+ fn as_mut ( & mut self ) -> & mut <<T :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' a > {
867+ match & mut self . 0 {
868+ MultiFramebufferInternal :: Render ( fb) => fb,
869+ MultiFramebufferInternal :: Target ( fb) => fb,
870+ }
871+ }
872+ }
873+
853874/// [`Frame`] implementation of a [`MultiRenderer`].
854875///
855876/// Leaking the frame will potentially keep it from doing necessary copies
@@ -993,10 +1014,8 @@ where
9931014impl < R : GraphicsApi , T : GraphicsApi , Target > Offscreen < Target > for MultiRenderer < ' _ , ' _ , R , T >
9941015where
9951016 <T :: Device as ApiDevice >:: Renderer : Offscreen < Target > ,
996- <R :: Device as ApiDevice >:: Renderer : Offscreen < Target > ,
9971017 // We need these because the Bind-impl does and Offscreen requires Bind
9981018 <T :: Device as ApiDevice >:: Renderer : Bind < Target > ,
999- <R :: Device as ApiDevice >:: Renderer : Bind < Target > ,
10001019 // We need these because the Renderer-impl does and Offscreen requires Bind, which requires Unbind, which requires Renderer
10011020 R : ' static ,
10021021 R :: Error : ' static ,
@@ -1021,18 +1040,21 @@ where
10211040 . create_buffer ( format, size)
10221041 . map_err ( Error :: Target )
10231042 } else {
1024- self . render
1025- . renderer_mut ( )
1026- . create_buffer ( format, size)
1027- . map_err ( Error :: Render )
1043+ // SAFETY: We know this is safe, because `self.target` can only be `None` if R == T.
1044+ let renderer = unsafe {
1045+ std:: mem:: transmute :: <
1046+ & mut <R :: Device as ApiDevice >:: Renderer ,
1047+ & mut <T :: Device as ApiDevice >:: Renderer ,
1048+ > ( self . render . renderer_mut ( ) )
1049+ } ;
1050+ renderer. create_buffer ( format, size) . map_err ( Error :: Target )
10281051 }
10291052 }
10301053}
10311054
10321055impl < R : GraphicsApi , T : GraphicsApi , Target > Bind < Target > for MultiRenderer < ' _ , ' _ , R , T >
10331056where
10341057 <T :: Device as ApiDevice >:: Renderer : Bind < Target > ,
1035- <R :: Device as ApiDevice >:: Renderer : Bind < Target > ,
10361058 // We need this because the Renderer-impl does and Bind requires Unbind, which requires Renderer
10371059 R : ' static ,
10381060 R :: Error : ' static ,
@@ -1058,20 +1080,32 @@ where
10581080 . map ( MultiFramebuffer )
10591081 . map_err ( Error :: Target )
10601082 } else {
1061- self . render
1062- . renderer_mut ( )
1083+ // SAFETY: We know this is safe, because `self.target` can only be `None` if R == T.
1084+ let renderer = unsafe {
1085+ std:: mem:: transmute :: <
1086+ & mut <R :: Device as ApiDevice >:: Renderer ,
1087+ & mut <T :: Device as ApiDevice >:: Renderer ,
1088+ > ( self . render . renderer_mut ( ) )
1089+ } ;
1090+ renderer
10631091 . bind ( bind)
10641092 . map ( MultiFramebufferInternal :: Render )
10651093 . map ( MultiFramebuffer )
1066- . map_err ( Error :: Render )
1094+ . map_err ( Error :: Target )
10671095 }
10681096 }
10691097
10701098 fn supported_formats ( & self ) -> Option < FormatSet > {
10711099 if let Some ( target) = self . target . as_ref ( ) {
10721100 Bind :: < Target > :: supported_formats ( target. device . renderer ( ) )
10731101 } else {
1074- Bind :: < Target > :: supported_formats ( self . render . renderer ( ) )
1102+ // SAFETY: We know this is safe, because `self.target` can only be `None` if R == T.
1103+ let renderer = unsafe {
1104+ std:: mem:: transmute :: < & <R :: Device as ApiDevice >:: Renderer , & <T :: Device as ApiDevice >:: Renderer > (
1105+ self . render . renderer ( ) ,
1106+ )
1107+ } ;
1108+ Bind :: < Target > :: supported_formats ( renderer)
10751109 }
10761110 }
10771111}
@@ -1091,7 +1125,7 @@ where
10911125{
10921126 type Error = Error < R , T > ;
10931127 type TextureId = MultiTexture ;
1094- type Framebuffer < ' buffer > = MultiFramebuffer < ' buffer , R , T > ;
1128+ type Framebuffer < ' buffer > = MultiFramebuffer < ' buffer , T > ;
10951129 type Frame < ' frame , ' buffer >
10961130 = MultiFrame < ' render , ' target , ' frame , ' buffer , R , T >
10971131 where
@@ -1228,11 +1262,19 @@ where
12281262 let mut target = None ;
12291263 let mut new_framebuffer = None ;
12301264 let frame = match & mut framebuffer. 0 {
1231- MultiFramebufferInternal :: Render ( framebuffer) => self
1232- . render
1233- . renderer_mut ( )
1234- . render ( framebuffer, size, dst_transform)
1235- . map_err ( Error :: Render ) ?,
1265+ MultiFramebufferInternal :: Render ( framebuffer) => {
1266+ // SAFETY: We know this is fine, because target can only be `None` (and thus this framebuffer be of variant `Render`), if R == T.
1267+ let framebuffer = unsafe {
1268+ std:: mem:: transmute :: <
1269+ & mut <<T :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' buffer > ,
1270+ & mut <<R :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' buffer > ,
1271+ > ( framebuffer)
1272+ } ;
1273+ self . render
1274+ . renderer_mut ( )
1275+ . render ( framebuffer, size, dst_transform)
1276+ . map_err ( Error :: Render ) ?
1277+ }
12361278 MultiFramebufferInternal :: Target ( target_framebuffer) => {
12371279 let ( target_device, render_framebuffer, texture, format) = target_state. unwrap ( ) ;
12381280 target = Some ( TargetFrameData {
@@ -2792,7 +2834,7 @@ where
27922834 #[ profiling:: function]
27932835 fn copy_framebuffer (
27942836 & mut self ,
2795- framebuffer : & MultiFramebuffer < ' _ , R , T > ,
2837+ framebuffer : & MultiFramebuffer < ' _ , T > ,
27962838 region : Rectangle < i32 , BufferCoords > ,
27972839 format : Fourcc ,
27982840 ) -> Result < Self :: TextureMapping , <Self as RendererSuper >:: Error > {
@@ -2806,12 +2848,20 @@ where
28062848 . map ( |mapping| MultiTextureMapping ( TextureMappingInternal :: Either ( mapping) ) )
28072849 . map_err ( Error :: Target )
28082850 }
2809- MultiFramebufferInternal :: Render ( fb) => self
2810- . render
2811- . renderer_mut ( )
2812- . copy_framebuffer ( fb, region, format)
2813- . map ( |mapping| MultiTextureMapping ( TextureMappingInternal :: Or ( mapping) ) )
2814- . map_err ( Error :: Render ) ,
2851+ MultiFramebufferInternal :: Render ( fb) => {
2852+ // SAFETY: We know this is fine, because target can only be `None` (and thus this framebuffer be of variant `Render`), if R == T.
2853+ let fb = unsafe {
2854+ std:: mem:: transmute :: <
2855+ & <<T :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' _ > ,
2856+ & <<R :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' _ > ,
2857+ > ( fb)
2858+ } ;
2859+ self . render
2860+ . renderer_mut ( )
2861+ . copy_framebuffer ( fb, region, format)
2862+ . map ( |mapping| MultiTextureMapping ( TextureMappingInternal :: Or ( mapping) ) )
2863+ . map_err ( Error :: Render )
2864+ }
28152865 }
28162866 }
28172867
@@ -2867,7 +2917,7 @@ where
28672917 }
28682918}
28692919
2870- impl < ' frame , ' buffer , R : GraphicsApi , T : GraphicsApi > BlitFrame < MultiFramebuffer < ' buffer , R , T > >
2920+ impl < ' frame , ' buffer , R : GraphicsApi , T : GraphicsApi > BlitFrame < MultiFramebuffer < ' buffer , T > >
28712921 for MultiFrame < ' _ , ' _ , ' frame , ' buffer , R , T >
28722922where
28732923 <<R :: Device as ApiDevice >:: Renderer as RendererSuper >:: Frame < ' frame , ' buffer > :
@@ -2886,7 +2936,7 @@ where
28862936 #[ profiling:: function]
28872937 fn blit_to (
28882938 & mut self ,
2889- to : & mut MultiFramebuffer < ' buffer , R , T > ,
2939+ to : & mut MultiFramebuffer < ' buffer , T > ,
28902940 src : Rectangle < i32 , Physical > ,
28912941 dst : Rectangle < i32 , Physical > ,
28922942 filter : TextureFilter ,
@@ -2907,6 +2957,13 @@ where
29072957 let MultiFramebufferInternal :: Render ( ref mut to_fb) = & mut to. 0 else {
29082958 unreachable ! ( )
29092959 } ;
2960+ // SAFETY: We know this is fine, because target can only be `None` (and thus this framebuffer be of variant `Render`), if R == T.
2961+ let to_fb = unsafe {
2962+ std:: mem:: transmute :: <
2963+ & mut <<T :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' _ > ,
2964+ & mut <<R :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' _ > ,
2965+ > ( to_fb)
2966+ } ;
29102967 self . frame
29112968 . as_mut ( )
29122969 . unwrap ( )
@@ -2919,7 +2976,7 @@ where
29192976 #[ profiling:: function]
29202977 fn blit_from (
29212978 & mut self ,
2922- from : & MultiFramebuffer < ' buffer , R , T > ,
2979+ from : & MultiFramebuffer < ' buffer , T > ,
29232980 src : Rectangle < i32 , Physical > ,
29242981 dst : Rectangle < i32 , Physical > ,
29252982 filter : TextureFilter ,
@@ -2940,6 +2997,13 @@ where
29402997 let MultiFramebufferInternal :: Render ( ref from_fb) = & from. 0 else {
29412998 unreachable ! ( )
29422999 } ;
3000+ // SAFETY: We know this is fine, because target can only be `None` (and thus this framebuffer be of variant `Render`), if R == T.
3001+ let from_fb = unsafe {
3002+ std:: mem:: transmute :: <
3003+ & <<T :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' _ > ,
3004+ & <<R :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' _ > ,
3005+ > ( from_fb)
3006+ } ;
29433007 self . frame
29443008 . as_mut ( )
29453009 . unwrap ( )
@@ -2967,8 +3031,8 @@ where
29673031 #[ profiling:: function]
29683032 fn blit (
29693033 & mut self ,
2970- from : & MultiFramebuffer < ' _ , R , T > ,
2971- to : & mut MultiFramebuffer < ' _ , R , T > ,
3034+ from : & MultiFramebuffer < ' _ , T > ,
3035+ to : & mut MultiFramebuffer < ' _ , T > ,
29723036 src : Rectangle < i32 , Physical > ,
29733037 dst : Rectangle < i32 , Physical > ,
29743038 filter : TextureFilter ,
@@ -2992,6 +3056,20 @@ where
29923056 let MultiFramebufferInternal :: Render ( ref mut to_fb) = & mut to. 0 else {
29933057 unreachable ! ( )
29943058 } ;
3059+ // SAFETY: We know this is fine, because target can only be `None` (and thus this framebuffer be of variant `Render`), if R == T.
3060+ let from_fb = unsafe {
3061+ std:: mem:: transmute :: <
3062+ & <<T :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' _ > ,
3063+ & <<R :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' _ > ,
3064+ > ( from_fb)
3065+ } ;
3066+ // SAFETY: We know this is fine, because target can only be `None` (and thus this framebuffer be of variant `Render`), if R == T.
3067+ let to_fb = unsafe {
3068+ std:: mem:: transmute :: <
3069+ & mut <<T :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' _ > ,
3070+ & mut <<R :: Device as ApiDevice >:: Renderer as RendererSuper >:: Framebuffer < ' _ > ,
3071+ > ( to_fb)
3072+ } ;
29953073 self . render
29963074 . renderer_mut ( )
29973075 . blit ( from_fb, to_fb, src, dst, filter)
0 commit comments