diff --git a/Cargo.lock b/Cargo.lock index bc33d4ec..e9d30900 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1467,7 +1467,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2934,9 +2934,9 @@ dependencies = [ [[package]] name = "libseat" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a0adf8d8607a73a5b74cbe4132f57cb349e4bf860103cd089461bbcbc9907e" +checksum = "c23a245bbd5790c690791c4fe6eefafe4c75851226288a71cb657601135aa00c" dependencies = [ "errno", "libseat-sys", @@ -2945,9 +2945,9 @@ dependencies = [ [[package]] name = "libseat-sys" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3671cb5e03871f1d6bf0b3b5daa9275549e348fa6359e0f9adb910ca163d4c34" +checksum = "134621e50557e8698a96ccff3eadbc6f4b449d5d12f8aa48fcef8d40b4b02725" dependencies = [ "pkg-config", ] @@ -4386,7 +4386,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4671,9 +4671,10 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "smithay" -version = "0.4.0" -source = "git+https://github.com/smithay/smithay.git?rev=f93476c#f93476cebab3d47f6729354805b3e184f6878ef2" +version = "0.5.0" +source = "git+https://github.com/smithay/smithay?rev=a503d98#a503d981d1be9a54b286ab5e160e4b9edddb500f" dependencies = [ + "aliasable", "appendlist", "ash", "bitflags 2.8.0", @@ -4760,7 +4761,7 @@ dependencies = [ [[package]] name = "smithay-egui" version = "0.1.0" -source = "git+https://github.com/Smithay/smithay-egui.git?rev=e9411da#e9411da9932316d6770661788c348f4b5a9be184" +source = "git+https://github.com/Smithay/smithay-egui.git?rev=e720136#e7201366b88e4fb20d0c6618a6cac9acc6299e07" dependencies = [ "cgmath", "egui", @@ -4986,7 +4987,7 @@ dependencies = [ "getrandom", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -5691,9 +5692,9 @@ dependencies = [ [[package]] name = "wayland-cursor" -version = "0.31.7" +version = "0.31.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b08bc3aafdb0035e7fe0fdf17ba0c09c268732707dca4ae098f60cb28c9e4c" +checksum = "a93029cbb6650748881a00e4922b076092a6a08c11e7fbdb923f064b23968c5d" dependencies = [ "rustix", "wayland-client", @@ -5702,9 +5703,9 @@ dependencies = [ [[package]] name = "wayland-egl" -version = "0.32.4" +version = "0.32.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3cb8b84ff95310fe59ce6c61f1fa344ec22f4c240c369a2b20f15caebfede4" +checksum = "504838241a10e271f48ffd429ac4033e0ac468b399fe7c2e2840f5c3a82d9902" dependencies = [ "wayland-backend", "wayland-sys", @@ -5725,9 +5726,9 @@ dependencies = [ [[package]] name = "wayland-protocols-misc" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2e42969764e469a115d4bb1c16e9588ef8b75b127ba7a2c9ddf1e140b25ca7" +checksum = "feb7ee1810026d1bb15d47086d03a7e5c68651c707e305ba1e8cc796fcbf5a54" dependencies = [ "bitflags 2.8.0", "wayland-backend", @@ -5751,9 +5752,9 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "782e12f6cd923c3c316130d56205ebab53f55d6666b7faddfad36cecaeeb4022" +checksum = "248a02e6f595aad796561fa82d25601bd2c8c3b145b1c7453fc8f94c1a58f8b2" dependencies = [ "bitflags 2.8.0", "wayland-backend", @@ -5959,7 +5960,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 6c292c23..cb22d7db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,13 +84,14 @@ features = [ "wayland_frontend", "xwayland", ] -version = "0.4" +git = "https://github.com/smithay/smithay" +rev = "a503d98" [dependencies.smithay-egui] features = ["svg"] git = "https://github.com/Smithay/smithay-egui.git" optional = true -rev = "e9411da" +rev = "e720136" [features] debug = ["egui", "egui_plot", "smithay-egui", "anyhow/backtrace"] @@ -114,9 +115,6 @@ inherits = "release" [profile.release] lto = "fat" -[patch.crates-io] -smithay = { git = "https://github.com/smithay/smithay.git", rev = "f93476c" } - [patch."https://github.com/pop-os/cosmic-protocols"] cosmic-protocols = { git = "https://github.com/pop-os//cosmic-protocols", rev = "e706814" } cosmic-client-toolkit = { git = "https://github.com/pop-os//cosmic-protocols", rev = "e706814" } diff --git a/src/backend/kms/render/gles.rs b/src/backend/kms/render/gles.rs index c4629137..b5c8f8c5 100644 --- a/src/backend/kms/render/gles.rs +++ b/src/backend/kms/render/gles.rs @@ -11,7 +11,7 @@ use smithay::backend::{ gles::GlesError, glow::GlowRenderer, multigpu::{ApiDevice, Error as MultiError, GraphicsApi}, - Renderer, + RendererSuper, }, SwapBuffersError, }; @@ -182,7 +182,7 @@ impl ApiDevice for GbmGlowDevice { impl FromGlesError for MultiError, T> where T::Error: 'static, - <::Renderer as Renderer>::Error: 'static, + <::Renderer as RendererSuper>::Error: 'static, { #[inline] fn from_gles_error(err: GlesError) -> MultiError, T> { diff --git a/src/backend/kms/surface/mod.rs b/src/backend/kms/surface/mod.rs index fe51eadf..2705150a 100644 --- a/src/backend/kms/surface/mod.rs +++ b/src/backend/kms/surface/mod.rs @@ -45,7 +45,7 @@ use smithay::{ multigpu::{Error as MultiError, GpuManager}, sync::SyncPoint, utils::with_renderer_surface_state, - Bind, ImportDma, Offscreen, Renderer, Texture, + Bind, ImportDma, Offscreen, Renderer, RendererSuper, Texture, }, }, desktop::utils::OutputPresentationFeedback, @@ -93,13 +93,6 @@ use super::{drm_helpers, render::gles::GbmGlowBackend}; #[cfg(feature = "debug")] use smithay_egui::EguiState; -#[cfg(feature = "debug")] -static INTEL_LOGO: &'static [u8] = include_bytes!("../../../../resources/icons/intel.svg"); -#[cfg(feature = "debug")] -static AMD_LOGO: &'static [u8] = include_bytes!("../../../../resources/icons/amd.svg"); -#[cfg(feature = "debug")] -static NVIDIA_LOGO: &'static [u8] = include_bytes!("../../../../resources/icons/nvidia.svg"); - #[derive(Debug)] pub struct Surface { pub(crate) connector: connector::Handle, @@ -740,19 +733,6 @@ impl SurfaceThreadState { unsafe { GlowRenderer::new(egl) }.context("Failed to create renderer")?; init_shaders(renderer.borrow_mut()).context("Failed to initialize shaders")?; - #[cfg(feature = "debug")] - { - self.egui - .load_svg(&mut renderer, String::from("intel"), INTEL_LOGO) - .unwrap(); - self.egui - .load_svg(&mut renderer, String::from("amd"), AMD_LOGO) - .unwrap(); - self.egui - .load_svg(&mut renderer, String::from("nvidia"), NVIDIA_LOGO) - .unwrap(); - } - self.api.as_mut().add_node(node, gbm, renderer); /* } else { @@ -1107,10 +1087,11 @@ impl SurfaceThreadState { mirroring_state .texture .render() - .draw::<_, ::Error>(|tex| { - let res = match mirroring_state.damage_tracker.render_output_with( + .draw::<_, ::Error>(|tex| { + let mut fb = renderer.bind(tex)?; + let res = match mirroring_state.damage_tracker.render_output( &mut renderer, - tex.clone(), + &mut fb, 1, &elements, CLEAR_COLOR, @@ -1119,8 +1100,8 @@ impl SurfaceThreadState { Err(RenderError::Rendering(err)) => return Err(err), Err(RenderError::OutputNoMode(_)) => unreachable!(), }; - renderer.wait(&res.sync)?; + std::mem::drop(fb); let transform = mirrored_output.current_transform(); let area = tex.size().to_logical(1, transform); @@ -1235,34 +1216,39 @@ impl SurfaceThreadState { let mut sync = SyncPoint::default(); - if let Some(ref damage) = damage { - let buffer = frame.buffer(); - if let Ok(dmabuf) = get_dmabuf(&buffer) { - renderer - .bind(dmabuf.clone()) - .map_err(RenderError::<::Error>::Rendering)?; - } else { - let size = buffer_dimensions(&buffer).ok_or(RenderError::< - ::Error, - >::Rendering( - MultiError::ImportFailed, - ))?; - let format = - with_buffer_contents(&buffer, |_, _, data| shm_format_to_fourcc(data.format)) - .map_err(|_| OutputNoMode)? // eh, we have to do some error - .expect("We should be able to convert all hardcoded shm screencopy formats"); - let render_buffer = - Offscreen::::create_buffer( - &mut renderer, - format, - size, - ) - .map_err(RenderError::<::Error>::Rendering)?; - renderer - .bind(render_buffer) - .map_err(RenderError::<::Error>::Rendering)?; - } + let mut dmabuf_clone; + let mut render_buffer; + let buffer = frame.buffer(); + let mut shm_buffer = false; + let mut fb = if let Ok(dmabuf) = get_dmabuf(&buffer) { + dmabuf_clone = dmabuf.clone(); + renderer + .bind(&mut dmabuf_clone) + .map_err(RenderError::<::Error>::Rendering)? + } else { + shm_buffer = true; + let size = buffer_dimensions(&buffer).ok_or(RenderError::< + ::Error, + >::Rendering( + MultiError::ImportFailed, + ))?; + let format = + with_buffer_contents(&buffer, |_, _, data| shm_format_to_fourcc(data.format)) + .map_err(|_| OutputNoMode)? // eh, we have to do some error + .expect("We should be able to convert all hardcoded shm screencopy formats"); + render_buffer = + Offscreen::::create_buffer( + &mut renderer, + format, + size, + ) + .map_err(RenderError::<::Error>::Rendering)?; + renderer + .bind(&mut render_buffer) + .map_err(RenderError::<::Error>::Rendering)? + }; + if let Some(ref damage) = damage { let (output_size, output_scale, output_transform) = ( self.output.current_mode().ok_or(OutputNoMode)?.size, self.output.current_scale().fractional_scale(), @@ -1292,23 +1278,25 @@ impl SurfaceThreadState { .to_physical(1); d }); + match frame_result .blit_frame_result( output_size, output_transform, output_scale, &mut renderer, + &mut fb, adjusted, filter, ) .map_err(|err| match err { BlitFrameResultError::Rendering(err) => RenderError::< - ::Error, + ::Error, >::Rendering( err ), BlitFrameResultError::Export(_) => RenderError::< - ::Error, + ::Error, >::Rendering( MultiError::DeviceMissing, ), @@ -1329,13 +1317,14 @@ impl SurfaceThreadState { continue; } }; - } + }; let transform = self.output.current_transform(); match submit_buffer( frame, &mut renderer, + shm_buffer.then_some(&mut fb), transform, damage.as_deref(), sync, diff --git a/src/backend/render/cursor.rs b/src/backend/render/cursor.rs index ca673f15..c1452df1 100644 --- a/src/backend/render/cursor.rs +++ b/src/backend/render/cursor.rs @@ -131,7 +131,7 @@ pub fn draw_surface_cursor( ) -> Vec<(CursorRenderElement, Point)> where R: Renderer + ImportAll, - ::TextureId: Clone + 'static, + R::TextureId: Clone + 'static, { let position = location.into(); let scale = scale.into(); @@ -172,7 +172,7 @@ pub fn draw_dnd_icon( ) -> Vec> where R: Renderer + ImportAll, - ::TextureId: Clone + 'static, + R::TextureId: Clone + 'static, { if get_role(&surface) != Some("dnd_icon") { warn!( @@ -262,7 +262,7 @@ pub fn draw_cursor( ) -> Vec<(CursorRenderElement, Point)> where R: Renderer + ImportMem + ImportAll, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, { // draw the cursor as relevant // reset the cursor if the surface is no longer alive diff --git a/src/backend/render/element.rs b/src/backend/render/element.rs index 2c4449af..c4b31521 100644 --- a/src/backend/render/element.rs +++ b/src/backend/render/element.rs @@ -22,7 +22,7 @@ use super::{cursor::CursorRenderElement, GlMultiRenderer}; pub enum CosmicElement where R: AsGlowRenderer + Renderer + ImportAll + ImportMem, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { Workspace( @@ -45,7 +45,7 @@ where impl Element for CosmicElement where R: AsGlowRenderer + Renderer + ImportAll + ImportMem, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { fn id(&self) -> &Id { @@ -196,13 +196,13 @@ where impl RenderElement for CosmicElement where R: AsGlowRenderer + Renderer + ImportAll + ImportMem, - ::TextureId: 'static, - ::Error: FromGlesError, + R::TextureId: 'static, + R::Error: FromGlesError, CosmicMappedRenderElement: RenderElement, { fn draw( &self, - frame: &mut R::Frame<'_>, + frame: &mut R::Frame<'_, '_>, src: Rectangle, dst: Rectangle, damage: &[Rectangle], @@ -286,7 +286,7 @@ impl From>>> for CosmicElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { fn from(elem: CropRenderElement>>) -> Self { @@ -301,7 +301,7 @@ where impl From for CosmicElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { fn from(elem: DamageElement) -> Self { @@ -312,7 +312,7 @@ where impl From> for CosmicElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { fn from(value: MemoryRenderBufferRenderElement) -> Self { @@ -324,7 +324,7 @@ where impl From> for CosmicElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { fn from(elem: TextureRenderElement) -> Self { @@ -338,8 +338,12 @@ where { fn glow_renderer(&self) -> &GlowRenderer; fn glow_renderer_mut(&mut self) -> &mut GlowRenderer; - fn glow_frame<'a, 'frame>(frame: &'a Self::Frame<'frame>) -> &'a GlowFrame<'frame>; - fn glow_frame_mut<'a, 'frame>(frame: &'a mut Self::Frame<'frame>) -> &'a mut GlowFrame<'frame>; + fn glow_frame<'a, 'frame, 'buffer>( + frame: &'a Self::Frame<'frame, 'buffer>, + ) -> &'a GlowFrame<'frame, 'buffer>; + fn glow_frame_mut<'a, 'frame, 'buffer>( + frame: &'a mut Self::Frame<'frame, 'buffer>, + ) -> &'a mut GlowFrame<'frame, 'buffer>; } impl AsGlowRenderer for GlowRenderer { @@ -349,10 +353,14 @@ impl AsGlowRenderer for GlowRenderer { fn glow_renderer_mut(&mut self) -> &mut GlowRenderer { self } - fn glow_frame<'a, 'frame>(frame: &'a Self::Frame<'frame>) -> &'a GlowFrame<'frame> { + fn glow_frame<'a, 'frame, 'buffer>( + frame: &'a Self::Frame<'frame, 'buffer>, + ) -> &'a GlowFrame<'frame, 'buffer> { frame } - fn glow_frame_mut<'a, 'frame>(frame: &'a mut Self::Frame<'frame>) -> &'a mut GlowFrame<'frame> { + fn glow_frame_mut<'a, 'frame, 'buffer>( + frame: &'a mut Self::Frame<'frame, 'buffer>, + ) -> &'a mut GlowFrame<'frame, 'buffer> { frame } } @@ -364,10 +372,14 @@ impl<'a> AsGlowRenderer for GlMultiRenderer<'a> { fn glow_renderer_mut(&mut self) -> &mut GlowRenderer { self.as_mut() } - fn glow_frame<'b, 'frame>(frame: &'b Self::Frame<'frame>) -> &'b GlowFrame<'frame> { + fn glow_frame<'b, 'frame, 'buffer>( + frame: &'b Self::Frame<'frame, 'buffer>, + ) -> &'b GlowFrame<'frame, 'buffer> { frame.as_ref() } - fn glow_frame_mut<'b, 'frame>(frame: &'b mut Self::Frame<'frame>) -> &'b mut GlowFrame<'frame> { + fn glow_frame_mut<'b, 'frame, 'buffer>( + frame: &'b mut Self::Frame<'frame, 'buffer>, + ) -> &'b mut GlowFrame<'frame, 'buffer> { frame.as_mut() } } @@ -415,12 +427,12 @@ impl Element for DamageElement { impl RenderElement for DamageElement { fn draw( &self, - _frame: &mut ::Frame<'_>, + _frame: &mut R::Frame<'_, '_>, _src: Rectangle, _dst: Rectangle, _damage: &[Rectangle], _opaque_regions: &[Rectangle], - ) -> Result<(), ::Error> { + ) -> Result<(), R::Error> { Ok(()) } } diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index 040774b2..c781ed16 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -39,7 +39,6 @@ use smithay::{ allocator::dmabuf::Dmabuf, drm::{DrmDeviceFd, DrmNode}, renderer::{ - buffer_dimensions, damage::{Error as RenderError, OutputDamageTracker, RenderOutputResult}, element::{ surface::{render_elements_from_surface_tree, WaylandSurfaceRenderElement}, @@ -60,11 +59,7 @@ use smithay::{ input::Seat, output::{Output, OutputNoMode}, utils::{IsAlive, Logical, Monotonic, Point, Rectangle, Scale, Time, Transform}, - wayland::{ - dmabuf::get_dmabuf, - session_lock::LockSurface, - shm::{shm_format_to_fourcc, with_buffer_contents}, - }, + wayland::{dmabuf::get_dmabuf, session_lock::LockSurface}, }; #[cfg(feature = "debug")] @@ -80,8 +75,8 @@ use super::kms::Timings; pub type GlMultiRenderer<'a> = MultiRenderer<'a, 'a, GbmGlowBackend, GbmGlowBackend>; -pub type GlMultiFrame<'a, 'frame> = - MultiFrame<'a, 'a, 'frame, GbmGlowBackend, GbmGlowBackend>; +pub type GlMultiFrame<'a, 'frame, 'buffer> = + MultiFrame<'a, 'a, 'frame, 'buffer, GbmGlowBackend, GbmGlowBackend>; pub type GlMultiError = MultiError, GbmGlowBackend>; pub enum RendererRef<'a> { @@ -414,7 +409,7 @@ pub fn cursor_elements<'a, 'frame, R>( ) -> Vec> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, CosmicMappedRenderElement: RenderElement, { let scale = output.current_scale().fractional_scale(); @@ -556,8 +551,8 @@ pub fn output_elements( ) -> Result>, RenderError> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, - ::Error: FromGlesError, + R::TextureId: Send + Clone + 'static, + R::Error: FromGlesError, CosmicMappedRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, { @@ -647,11 +642,11 @@ pub fn workspace_elements( current: (WorkspaceHandle, usize), cursor_mode: CursorMode, element_filter: ElementFilter, -) -> Result>, RenderError<::Error>> +) -> Result>, RenderError> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, - ::Error: FromGlesError, + R::TextureId: Send + Clone + 'static, + R::Error: FromGlesError, CosmicMappedRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, { @@ -970,7 +965,7 @@ fn session_lock_elements( ) -> Vec> where R: Renderer + ImportAll, - ::TextureId: Clone + 'static, + R::TextureId: Clone + 'static, { if let Some(surface) = lock_surface { let scale = Scale::from(output.current_scale().fractional_scale()); @@ -988,33 +983,31 @@ where } #[profiling::function] -pub fn render_output<'d, R, Target, OffTarget>( +pub fn render_output<'d, R, OffTarget>( gpu: Option<&DrmNode>, renderer: &mut R, - target: Target, + target: &mut R::Framebuffer<'_>, damage_tracker: &'d mut OutputDamageTracker, age: usize, shell: &Arc>, now: Time, output: &Output, cursor_mode: CursorMode, -) -> Result, RenderError<::Error>> +) -> Result, RenderError> where R: Renderer + ImportAll + ImportMem + ExportMem + Bind - + Bind + Offscreen - + Blit + + Blit + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, - ::Error: FromGlesError, + R::TextureId: Send + Clone + 'static, + R::Error: FromGlesError, CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, - Target: Clone, { let shell_ref = shell.read().unwrap(); let (previous_workspace, workspace) = shell_ref @@ -1038,7 +1031,7 @@ where let result = render_workspace( gpu, renderer, - target.clone(), + target, damage_tracker, age, None, @@ -1055,12 +1048,12 @@ where match result { Ok((res, mut elements)) => { for (session, frame) in output.take_pending_frames() { - if let Some((frame, damage)) = render_session( + if let Some((frame, damage)) = render_session::<_, _, OffTarget>( renderer, &session.user_data().get::().unwrap(), frame, output.current_transform(), - |buffer, renderer, dt, age, additional_damage| { + |buffer, renderer, offscreen, dt, age, additional_damage| { let old_len = if !additional_damage.is_empty() { let area = output .current_mode() @@ -1104,29 +1097,23 @@ where if let (Some(ref damage), _) = &res { if let Ok(dmabuf) = get_dmabuf(buffer) { - renderer - .bind(dmabuf.clone()) + let mut dmabuf_clone = dmabuf.clone(); + let mut fb = renderer + .bind(&mut dmabuf_clone) .map_err(RenderError::Rendering)?; + for rect in damage.iter() { + renderer + .blit(target, &mut fb, *rect, *rect, TextureFilter::Nearest) + .map_err(RenderError::Rendering)?; + } } else { - let size = buffer_dimensions(buffer).unwrap(); - let format = with_buffer_contents(buffer, |_, _, data| { - shm_format_to_fourcc(data.format) - }) - .map_err(|_| OutputNoMode)? // eh, we have to do some error - .expect( - "We should be able to convert all hardcoded shm screencopy formats", - ); - let render_buffer = renderer - .create_buffer(format, size) - .map_err(RenderError::Rendering)?; - renderer - .bind(render_buffer) - .map_err(RenderError::Rendering)?; - } - for rect in damage.iter() { - renderer - .blit_from(target.clone(), *rect, *rect, TextureFilter::Nearest) - .map_err(RenderError::Rendering)?; + let fb = + offscreen.expect("shm buffers should have offscreen target"); + for rect in damage.iter() { + renderer + .blit(target, fb, *rect, *rect, TextureFilter::Nearest) + .map_err(RenderError::Rendering)?; + } } } @@ -1148,10 +1135,10 @@ where } #[profiling::function] -pub fn render_workspace<'d, R, Target, OffTarget>( +pub fn render_workspace<'d, R>( gpu: Option<&DrmNode>, renderer: &mut R, - target: Target, + target: &mut R::Framebuffer<'_>, damage_tracker: &'d mut OutputDamageTracker, age: usize, additional_damage: Option>>, @@ -1163,18 +1150,11 @@ pub fn render_workspace<'d, R, Target, OffTarget>( current: (WorkspaceHandle, usize), cursor_mode: CursorMode, element_filter: ElementFilter, -) -> Result<(RenderOutputResult<'d>, Vec>), RenderError<::Error>> +) -> Result<(RenderOutputResult<'d>, Vec>), RenderError> where - R: Renderer - + ImportAll - + ImportMem - + ExportMem - + Bind - + Bind - + Offscreen - + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, - ::Error: FromGlesError, + R: Renderer + ImportAll + ImportMem + ExportMem + Bind + AsGlowRenderer, + R::TextureId: Send + Clone + 'static, + R::Error: FromGlesError, CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, @@ -1203,9 +1183,9 @@ where ); } - renderer.bind(target).map_err(RenderError::Rendering)?; let res = damage_tracker.render_output( renderer, + target, age, &elements, CLEAR_COLOR, // TODO use a theme neutral color diff --git a/src/backend/winit.rs b/src/backend/winit.rs index f293341c..e56c3385 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -47,16 +47,15 @@ pub struct WinitState { impl WinitState { #[profiling::function] pub fn render_output(&mut self, state: &mut Common) -> Result<()> { - self.backend + let age = self.backend.buffer_age().unwrap_or(0); + let (renderer, mut fb) = self + .backend .bind() .with_context(|| "Failed to bind buffer")?; - let age = self.backend.buffer_age().unwrap_or(0); - - let surface = self.backend.egl_surface(); - match render::render_output::<_, _, GlesRenderbuffer>( + match render::render_output::<_, GlesRenderbuffer>( None, - self.backend.renderer(), - surface.clone(), + renderer, + &mut fb, &mut self.damage_tracker, age, &state.shell, @@ -65,9 +64,7 @@ impl WinitState { CursorMode::NotDefault, ) { Ok(RenderOutputResult { damage, states, .. }) => { - self.backend - .bind() - .with_context(|| "Failed to bind display")?; + std::mem::drop(fb); self.backend .submit(damage.map(|x| x.as_slice())) .with_context(|| "Failed to submit buffer for display")?; diff --git a/src/backend/x11.rs b/src/backend/x11.rs index a18bcaf5..6db09b4c 100644 --- a/src/backend/x11.rs +++ b/src/backend/x11.rs @@ -202,14 +202,17 @@ pub struct Surface { impl Surface { pub fn render_output(&mut self, renderer: &mut GlowRenderer, state: &mut Common) -> Result<()> { - let (buffer, age) = self + let (mut buffer, age) = self .surface .buffer() .with_context(|| "Failed to allocate buffer")?; - match render::render_output::<_, _, GlesRenderbuffer>( + let mut fb = renderer + .bind(&mut buffer) + .with_context(|| "Failed to bind dmabuf")?; + match render::render_output::<_, GlesRenderbuffer>( None, renderer, - buffer.clone(), + &mut fb, &mut self.damage_tracker, age as usize, &state.shell, diff --git a/src/debug.rs b/src/debug.rs index dd88f211..98577da6 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -1,13 +1,11 @@ // SPDX-License-Identifier: GPL-3.0-only -use std::collections::HashMap; - use crate::{ backend::kms::Timings, shell::focus::target::{KeyboardFocusTarget, PointerFocusTarget, PointerFocusToplevel}, State, }; -use egui::{load::SizedTexture, Color32, Vec2}; +use egui::Color32; use smithay::{ backend::{ drm::DrmNode, @@ -97,33 +95,6 @@ pub fn fps_ui<'a>( }) .unzip(); - let vendors = HashMap::from([ - ( - "0x10de", - state - .with_image(renderer, "nvidia", |image, ctx| { - (image.texture_id(ctx), image.size_vec2()) - }) - .expect("Logo images not loaded?"), - ), - ( - "0x1002", - state - .with_image(renderer, "amd", |image, ctx| { - (image.texture_id(ctx), image.size_vec2()) - }) - .expect("Logo images not loaded?"), - ), - ( - "0x8086", - state - .with_image(renderer, "intel", |image, ctx| { - (image.texture_id(ctx), image.size_vec2()) - }) - .expect("Logo images not loaded?"), - ), - ]); - state.render( |ctx| { egui::Area::new("main".into()) @@ -152,11 +123,21 @@ pub fn fps_ui<'a>( "/sys/class/drm/renderD{}/device/vendor", gpu.minor() )) { - if let Some((texture_id, mut size)) = vendors.get(vendor.trim()) - { - let factor = resp.rect.height() / size.y; - size = Vec2::from([size.x * factor, resp.rect.height()]); - ui.image(SizedTexture::new(*texture_id, size)); + if let Some(img) = match vendor.trim() { + "0x10de" => Some(egui::include_image!( + "../resources/icons/nvidia.svg" + )), + "0x1002" => { + Some(egui::include_image!("../resources/icons/amd.svg")) + } + "0x8086" => Some(egui::include_image!( + "../resources/icons/intel.svg" + )), + _ => None, + } { + ui.add( + egui::Image::new(img).max_height(resp.rect.height()), + ); } } }); diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 383b0b54..ff79a147 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -625,7 +625,7 @@ impl CosmicMapped { ) -> Vec where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, CosmicMappedRenderElement: RenderElement, C: From>, { @@ -654,7 +654,7 @@ impl CosmicMapped { ) -> Vec where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, CosmicMappedRenderElement: RenderElement, C: From>, { @@ -1046,7 +1046,7 @@ impl From for CosmicMapped { pub enum CosmicMappedRenderElement where R: Renderer + ImportAll + ImportMem, - ::TextureId: 'static, + R::TextureId: 'static, { Stack(self::stack::CosmicStackRenderElement), Window(self::window::CosmicWindowRenderElement), @@ -1081,7 +1081,7 @@ where impl Element for CosmicMappedRenderElement where R: Renderer + ImportAll + ImportMem, - ::TextureId: 'static, + R::TextureId: 'static, { fn id(&self) -> &smithay::backend::renderer::element::Id { match self { @@ -1264,12 +1264,12 @@ where impl RenderElement for CosmicMappedRenderElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, - ::Error: FromGlesError, + R::TextureId: 'static, + R::Error: FromGlesError, { fn draw( &self, - frame: &mut R::Frame<'_>, + frame: &mut R::Frame<'_, '_>, src: Rectangle, dst: Rectangle, damage: &[Rectangle], @@ -1385,7 +1385,7 @@ where impl From> for CosmicMappedRenderElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { fn from(elem: stack::CosmicStackRenderElement) -> Self { @@ -1395,7 +1395,7 @@ where impl From> for CosmicMappedRenderElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { fn from(elem: window::CosmicWindowRenderElement) -> Self { @@ -1406,7 +1406,7 @@ where impl From for CosmicMappedRenderElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { fn from(elem: PixelShaderElement) -> Self { @@ -1417,7 +1417,7 @@ where impl From> for CosmicMappedRenderElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { fn from(elem: MemoryRenderBufferRenderElement) -> Self { @@ -1429,7 +1429,7 @@ where impl From> for CosmicMappedRenderElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { fn from(elem: TextureRenderElement) -> Self { diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index 6275135f..6872d36e 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -618,7 +618,7 @@ impl CosmicStack { ) -> Vec where R: Renderer + ImportAll + ImportMem, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, C: From>, { let window_loc = location + Point::from((0, (TAB_HEIGHT as f64 * scale.y) as i32)); @@ -645,7 +645,7 @@ impl CosmicStack { ) -> Vec where R: Renderer + ImportAll + ImportMem, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, C: From>, { let offset = self diff --git a/src/shell/element/surface.rs b/src/shell/element/surface.rs index 05b1da45..e8968e1e 100644 --- a/src/shell/element/surface.rs +++ b/src/shell/element/surface.rs @@ -660,7 +660,7 @@ impl CosmicSurface { ) -> Vec where R: Renderer + ImportAll, - ::TextureId: Clone + 'static, + R::TextureId: Clone + 'static, C: From>, { match self.0.underlying_surface() { @@ -695,7 +695,7 @@ impl CosmicSurface { ) -> Vec where R: Renderer + ImportAll, - ::TextureId: Clone + 'static, + R::TextureId: Clone + 'static, C: From>, { match self.0.underlying_surface() { @@ -848,7 +848,7 @@ impl X11Relatable for CosmicSurface { impl AsRenderElements for CosmicSurface where R: Renderer + ImportAll, - ::TextureId: Clone + 'static, + R::TextureId: Clone + 'static, { type RenderElement = WaylandSurfaceRenderElement; diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 3937e1cd..fe1ad3c4 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -312,7 +312,7 @@ impl CosmicWindow { ) -> Vec where R: Renderer + ImportAll + ImportMem, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, C: From>, { let has_ssd = self.0.with_program(|p| p.has_ssd(false)); @@ -343,7 +343,7 @@ impl CosmicWindow { ) -> Vec where R: Renderer + ImportAll + ImportMem, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, C: From>, { let has_ssd = self.0.with_program(|p| p.has_ssd(false)); diff --git a/src/shell/grabs/menu/mod.rs b/src/shell/grabs/menu/mod.rs index 071090bd..733031c6 100644 --- a/src/shell/grabs/menu/mod.rs +++ b/src/shell/grabs/menu/mod.rs @@ -68,7 +68,7 @@ impl MenuGrabState { pub fn render(&self, renderer: &mut R, output: &Output) -> Vec where R: Renderer + ImportMem, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, I: From>, { let scale = output.current_scale().fractional_scale(); diff --git a/src/shell/grabs/moving.rs b/src/shell/grabs/moving.rs index 36724911..1b73e26b 100644 --- a/src/shell/grabs/moving.rs +++ b/src/shell/grabs/moving.rs @@ -71,7 +71,7 @@ impl MoveGrabState { pub fn render(&self, renderer: &mut R, output: &Output, theme: &CosmicTheme) -> Vec where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, CosmicMappedRenderElement: RenderElement, I: From>, { diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index d3625291..b2f6f1ce 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -1390,7 +1390,7 @@ impl FloatingLayout { ) -> Vec> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, CosmicStackRenderElement: RenderElement, @@ -1441,7 +1441,7 @@ impl FloatingLayout { ) -> Vec> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, CosmicStackRenderElement: RenderElement, diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index f0fc552b..526cf38f 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -3565,7 +3565,7 @@ impl TilingLayout { let third_width = (last_geometry.size.w as f64 / 3.0).round() as i32; let third_height = (last_geometry.size.h as f64 / 3.0).round() as i32; - let stack_region = Rectangle::from_extemities( + let stack_region = Rectangle::from_extremities( ( last_geometry.loc.x + third_width, last_geometry.loc.y + third_height, @@ -3942,7 +3942,7 @@ impl TilingLayout { ) -> Result>, OutputNotMapped> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, CosmicStackRenderElement: RenderElement, @@ -4102,7 +4102,7 @@ impl TilingLayout { ) -> Result>, OutputNotMapped> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, CosmicStackRenderElement: RenderElement, @@ -4276,7 +4276,7 @@ fn geometries_for_groupview<'a, R>( ) where R: Renderer + ImportAll + ImportMem + AsGlowRenderer + 'a, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, { @@ -4906,7 +4906,7 @@ fn render_old_tree_popups( ) -> Vec> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, CosmicStackRenderElement: RenderElement, @@ -4949,7 +4949,7 @@ fn render_old_tree_windows( ) -> Vec> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, CosmicStackRenderElement: RenderElement, @@ -5115,7 +5115,7 @@ fn render_new_tree_popups( ) -> Vec> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, CosmicStackRenderElement: RenderElement, @@ -5181,7 +5181,7 @@ fn render_new_tree_windows( ) -> Vec> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, CosmicStackRenderElement: RenderElement, diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 784a4e52..1d63fbff 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -1160,7 +1160,7 @@ impl Workspace { ) -> Result>, OutputNotMapped> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, CosmicStackRenderElement: RenderElement, @@ -1363,7 +1363,7 @@ impl Workspace { ) -> Result>, OutputNotMapped> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, CosmicStackRenderElement: RenderElement, @@ -1521,7 +1521,7 @@ pub struct OutputNotMapped; pub enum WorkspaceRenderElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, + R::TextureId: 'static, { OverrideRedirect(WaylandSurfaceRenderElement), Fullscreen(RescaleRenderElement>), @@ -1533,7 +1533,7 @@ where impl Element for WorkspaceRenderElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, + R::TextureId: 'static, { fn id(&self) -> &smithay::backend::renderer::element::Id { match self { @@ -1633,12 +1633,12 @@ where impl RenderElement for WorkspaceRenderElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, - ::Error: FromGlesError, + R::TextureId: 'static, + R::Error: FromGlesError, { fn draw( &self, - frame: &mut R::Frame<'_>, + frame: &mut R::Frame<'_, '_>, src: Rectangle, dst: Rectangle, damage: &[Rectangle], @@ -1688,7 +1688,7 @@ where impl From>> for WorkspaceRenderElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { fn from(elem: RescaleRenderElement>) -> Self { @@ -1699,7 +1699,7 @@ where impl From> for WorkspaceRenderElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { fn from(elem: CosmicWindowRenderElement) -> Self { @@ -1710,7 +1710,7 @@ where impl From> for WorkspaceRenderElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { fn from(elem: WaylandSurfaceRenderElement) -> Self { @@ -1721,7 +1721,7 @@ where impl From> for WorkspaceRenderElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { fn from(elem: CosmicMappedRenderElement) -> Self { @@ -1732,7 +1732,7 @@ where impl From> for WorkspaceRenderElement where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, + R::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { fn from(elem: TextureRenderElement) -> Self { diff --git a/src/shell/zoom.rs b/src/shell/zoom.rs index 606d5728..5dfaf7ad 100644 --- a/src/shell/zoom.rs +++ b/src/shell/zoom.rs @@ -170,7 +170,7 @@ impl OutputZoomState { where C: From< as AsRenderElements>::RenderElement>, R: Renderer + ImportMem, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, { let size = self.element.current_size().to_f64(); let output_geo = output.geometry().to_f64(); @@ -372,7 +372,7 @@ impl ZoomState { where C: From< as AsRenderElements>::RenderElement>, R: Renderer + ImportMem, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, { let output_state = output.user_data().get::>().unwrap(); output_state.lock().unwrap().render(renderer, output) diff --git a/src/utils/iced.rs b/src/utils/iced.rs index 8ced31d7..7c34d45b 100644 --- a/src/utils/iced.rs +++ b/src/utils/iced.rs @@ -903,7 +903,7 @@ impl AsRenderElements for IcedElement

where P: Program + Send + 'static, R: Renderer + ImportMem, - ::TextureId: Send + Clone + 'static, + R::TextureId: Send + Clone + 'static, { type RenderElement = MemoryRenderBufferRenderElement; diff --git a/src/utils/screenshot.rs b/src/utils/screenshot.rs index 500efeaf..6c063e8d 100644 --- a/src/utils/screenshot.rs +++ b/src/utils/screenshot.rs @@ -29,8 +29,8 @@ pub fn screenshot_window(state: &mut State, surface: &CosmicSurface) { ) -> anyhow::Result<()> where R: Renderer + ImportAll + Offscreen + ExportMem, - ::TextureId: Clone + 'static, - ::Error: Send + Sync + 'static, + R::TextureId: Clone + 'static, + R::Error: Send + Sync + 'static, { let bbox = bbox_from_surface_tree(&window.wl_surface().unwrap(), (0, 0)); let elements = AsRenderElements::::render_elements::>( @@ -43,22 +43,25 @@ pub fn screenshot_window(state: &mut State, surface: &CosmicSurface) { // TODO: 10-bit let format = Fourcc::Abgr8888; - let render_buffer = Offscreen::::create_buffer( + let mut render_buffer = Offscreen::::create_buffer( renderer, format, bbox.size.to_buffer(1, Transform::Normal), )?; - renderer.bind(render_buffer)?; + let mut fb = renderer.bind(&mut render_buffer)?; let mut output_damage_tracker = OutputDamageTracker::new(bbox.size.to_physical(1), 1.0, Transform::Normal); output_damage_tracker - .render_output(renderer, 0, &elements, [0.0, 0.0, 0.0, 0.0]) + .render_output(renderer, &mut fb, 0, &elements, [0.0, 0.0, 0.0, 0.0]) .map_err(|err| match err { smithay::backend::renderer::damage::Error::Rendering(err) => err, smithay::backend::renderer::damage::Error::OutputNoMode(_) => unreachable!(), })?; - let mapping = - renderer.copy_framebuffer(bbox.to_buffer(1, Transform::Normal, &bbox.size), format)?; + let mapping = renderer.copy_framebuffer( + &mut fb, + bbox.to_buffer(1, Transform::Normal, &bbox.size), + format, + )?; let gl_data = renderer.map_texture(&mapping)?; if let Ok(Some(path)) = xdg_user::pictures() { diff --git a/src/wayland/handlers/screencopy/render.rs b/src/wayland/handlers/screencopy/render.rs index 3ee7628e..933d0338 100644 --- a/src/wayland/handlers/screencopy/render.rs +++ b/src/wayland/handlers/screencopy/render.rs @@ -57,13 +57,14 @@ use super::super::data_device::get_dnd_icon; pub fn submit_buffer( frame: Frame, renderer: &mut R, + offscreen: Option<&mut R::Framebuffer<'_>>, transform: Transform, damage: Option<&[Rectangle]>, sync: SyncPoint, -) -> Result>)>, ::Error> +) -> Result>)>, R::Error> where R: ExportMem, - ::Error: FromGlesError, + R::Error: FromGlesError, { let Some(damage) = damage else { frame.success( @@ -77,7 +78,8 @@ where }; let buffer = frame.buffer(); - if matches!(buffer_type(&buffer), Some(BufferType::Shm)) { + if let Some(fb) = offscreen { + assert!(matches!(buffer_type(&buffer), Some(BufferType::Shm))); let buffer_size = buffer_dimensions(&buffer).unwrap(); if let Err(err) = with_buffer_contents_mut(&buffer, |ptr, len, data| { let offset = data.offset; @@ -98,7 +100,8 @@ where renderer.wait(&sync)?; let format = get_transparent(format).unwrap_or(format); - let mapping = renderer.copy_framebuffer(Rectangle::from_size(buffer_size), format)?; + let mapping = + renderer.copy_framebuffer(fb, Rectangle::from_size(buffer_size), format)?; let gl_data = renderer.map_texture(&mapping)?; assert!((width * height * pixelsize) as usize <= gl_data.len()); @@ -113,7 +116,7 @@ where } Ok(()) }) - .map_err(|err| ::Error::from_gles_error(GlesError::BufferAccessError(err))) + .map_err(|err| R::Error::from_gles_error(GlesError::BufferAccessError(err))) .and_then(|x| x) { frame.fail(FailureReason::Unknown); @@ -133,31 +136,51 @@ where ))) } -pub fn render_session( +pub fn render_session( renderer: &mut R, session: &SessionData, frame: Frame, transform: Transform, render_fn: F, -) -> Result>)>, DTError<::Error>> +) -> Result>)>, DTError> where - R: ExportMem, - ::Error: FromGlesError, - F: for<'d> FnOnce( + R: ExportMem + Offscreen, + R::Error: FromGlesError, + F: for<'d, 'f> FnOnce( &WlBuffer, &mut R, + Option<&mut R::Framebuffer<'f>>, &'d mut OutputDamageTracker, usize, Vec>, - ) -> Result, DTError<::Error>>, + ) -> Result, DTError>, { let mut session_damage_tracking = session.lock().unwrap(); let buffer = frame.buffer(); + let mut offscreen = matches!(buffer_type(&buffer), Some(BufferType::Shm)) + .then(|| { + let size = buffer_dimensions(&buffer).ok_or(DTError::OutputNoMode(OutputNoMode))?; + let format = with_buffer_contents(&buffer, |_, _, data| { + shm_format_to_fourcc(data.format) + .expect("We should be able to convert all hardcoded shm screencopy formats") + }) + .map_err(|_| DTError::OutputNoMode(OutputNoMode))?; + renderer + .create_buffer(format, size) + .map_err(DTError::Rendering) + }) + .transpose()?; + let age = session_damage_tracking.age_for_buffer(&buffer); + let mut fb = offscreen + .as_mut() + .map(|tex| renderer.bind(tex).map_err(DTError::Rendering)) + .transpose()?; let res = render_fn( &frame.buffer(), renderer, + fb.as_mut(), &mut session_damage_tracking.dt, age, frame.damage(), @@ -167,6 +190,7 @@ where Ok(result) => submit_buffer( frame, renderer, + fb.as_mut(), transform, result.damage.map(|x| x.as_slice()), result.sync, @@ -217,6 +241,7 @@ pub fn render_workspace_to_buffer( fn render_fn<'d, R>( buffer: &WlBuffer, renderer: &mut R, + offscreen: Option<&mut R::Framebuffer<'_>>, dt: &'d mut OutputDamageTracker, mut age: usize, additional_damage: Vec>, @@ -224,18 +249,11 @@ pub fn render_workspace_to_buffer( common: &mut Common, output: &Output, handle: (WorkspaceHandle, usize), - ) -> Result, DTError<::Error>> + ) -> Result, DTError> where - R: Renderer - + ImportAll - + ImportMem - + ExportMem - + Bind - + Offscreen - + Blit - + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, - ::Error: FromGlesError, + R: Renderer + ImportAll + ImportMem + ExportMem + Bind + Blit + AsGlowRenderer, + R::TextureId: Send + Clone + 'static, + R::Error: FromGlesError, CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, @@ -273,10 +291,12 @@ pub fn render_workspace_to_buffer( }); if let Ok(dmabuf) = get_dmabuf(buffer) { - render_workspace::<_, _, GlesRenderbuffer>( + let mut dmabuf = dmabuf.clone(); + let mut fb = renderer.bind(&mut dmabuf).map_err(DTError::Rendering)?; + render_workspace( None, renderer, - dmabuf.clone(), + &mut fb, dt, age, additional_damage, @@ -291,23 +311,12 @@ pub fn render_workspace_to_buffer( ) .map(|res| res.0) } else { - let size = buffer_dimensions(buffer).unwrap(); - let format = - with_buffer_contents(buffer, |_, _, data| shm_format_to_fourcc(data.format)) - .map_err(|err| { - DTError::Rendering(::Error::from_gles_error( - GlesError::BufferAccessError(err), - )) - })? - .expect("We should be able to convert all hardcoded shm screencopy formats"); - let render_buffer = - Offscreen::::create_buffer(renderer, format, size) - .map_err(DTError::Rendering)?; + let target = offscreen.expect("shm buffers should have an offscreen target"); age = 0; - render_workspace::<_, _, GlesRenderbuffer>( + render_workspace( None, renderer, - render_buffer, + target, dt, age, additional_damage, @@ -359,15 +368,16 @@ pub fn render_workspace_to_buffer( }; let result = match renderer { RendererRef::Glow(renderer) => { - match render_session::<_, _>( + match render_session::<_, _, GlesRenderbuffer>( renderer, session.user_data().get::().unwrap(), frame, transform, - |buffer, renderer, dt, age, additional_damage| { + |buffer, renderer, offscreen, dt, age, additional_damage| { render_fn( buffer, renderer, + offscreen, dt, age, additional_damage, @@ -386,15 +396,16 @@ pub fn render_workspace_to_buffer( } } RendererRef::GlMulti(mut renderer) => { - match render_session::<_, _>( + match render_session::<_, _, GlesRenderbuffer>( &mut renderer, session.user_data().get::().unwrap(), frame, transform, - |buffer, renderer, dt, age, additional_damage| { + |buffer, renderer, offscreen, dt, age, additional_damage| { render_fn( buffer, renderer, + offscreen, dt, age, additional_damage, @@ -458,25 +469,19 @@ pub fn render_window_to_buffer( fn render_fn<'d, R>( buffer: &WlBuffer, renderer: &mut R, + offscreen: Option<&mut R::Framebuffer<'_>>, dt: &'d mut OutputDamageTracker, - mut age: usize, + age: usize, additional_damage: Vec>, draw_cursor: bool, common: &mut Common, window: &CosmicSurface, geometry: Rectangle, - ) -> Result, DTError<::Error>> + ) -> Result, DTError> where - R: Renderer - + ImportAll - + ImportMem - + ExportMem - + Bind - + Offscreen - + Blit - + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, - ::Error: FromGlesError, + R: Renderer + ImportAll + ImportMem + ExportMem + Bind + Blit + AsGlowRenderer, + R::TextureId: Send + Clone + 'static, + R::Error: FromGlesError, CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, { @@ -557,25 +562,15 @@ pub fn render_window_to_buffer( } if let Ok(dmabuf) = get_dmabuf(buffer) { - renderer.bind(dmabuf.clone()).map_err(DTError::Rendering)?; + let mut dmabuf_clone = dmabuf.clone(); + let mut fb = renderer + .bind(&mut dmabuf_clone) + .map_err(DTError::Rendering)?; + dt.render_output(renderer, &mut fb, age, &elements, Color32F::TRANSPARENT) } else { - let size = buffer_dimensions(buffer).unwrap(); - let format = - with_buffer_contents(buffer, |_, _, data| shm_format_to_fourcc(data.format)) - .map_err(|err| { - DTError::Rendering(::Error::from_gles_error( - GlesError::BufferAccessError(err), - )) - })? - .expect("We should be able to convert all hardcoded shm screencopy formats"); - let render_buffer = - Offscreen::::create_buffer(renderer, format, size) - .map_err(DTError::Rendering)?; - age = 0; - renderer.bind(render_buffer).map_err(DTError::Rendering)?; + let fb = offscreen.expect("shm buffer should have an offscreen target"); + dt.render_output(renderer, fb, 0, &elements, Color32F::TRANSPARENT) } - - dt.render_output(renderer, age, &elements, Color32F::TRANSPARENT) } let common = &mut state.common; @@ -607,15 +602,16 @@ pub fn render_window_to_buffer( } }; let result = match renderer { - RendererRef::Glow(renderer) => match render_session::<_, _>( + RendererRef::Glow(renderer) => match render_session::<_, _, GlesRenderbuffer>( renderer, session.user_data().get::().unwrap(), frame, Transform::Normal, - |buffer, renderer, dt, age, additional_damage| { + |buffer, renderer, offscreen, dt, age, additional_damage| { render_fn( buffer, renderer, + offscreen, dt, age, additional_damage, @@ -632,15 +628,16 @@ pub fn render_window_to_buffer( None } }, - RendererRef::GlMulti(mut renderer) => match render_session::<_, _>( + RendererRef::GlMulti(mut renderer) => match render_session::<_, _, GlesRenderbuffer>( &mut renderer, session.user_data().get::().unwrap(), frame, Transform::Normal, - |buffer, renderer, dt, age, additional_damage| { + |buffer, renderer, offscreen, dt, age, additional_damage| { render_fn( buffer, renderer, + offscreen, dt, age, additional_damage, @@ -697,23 +694,17 @@ pub fn render_cursor_to_buffer( fn render_fn<'d, R>( buffer: &WlBuffer, renderer: &mut R, + offscreen: Option<&mut R::Framebuffer<'_>>, dt: &'d mut OutputDamageTracker, - mut age: usize, + age: usize, additional_damage: Vec>, common: &mut Common, seat: &Seat, - ) -> Result, DTError<::Error>> + ) -> Result, DTError> where - R: Renderer - + ImportAll - + ImportMem - + ExportMem - + Bind - + Offscreen - + Blit - + AsGlowRenderer, - ::TextureId: Send + Clone + 'static, - ::Error: FromGlesError, + R: Renderer + ImportAll + ImportMem + ExportMem + Bind + Blit + AsGlowRenderer, + R::TextureId: Send + Clone + 'static, + R::Error: FromGlesError, CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, { @@ -743,25 +734,15 @@ pub fn render_cursor_to_buffer( ); if let Ok(dmabuf) = get_dmabuf(buffer) { - renderer.bind(dmabuf.clone()).map_err(DTError::Rendering)?; + let mut dmabuf_clone = dmabuf.clone(); + let mut fb = renderer + .bind(&mut dmabuf_clone) + .map_err(DTError::Rendering)?; + dt.render_output(renderer, &mut fb, age, &elements, [0.0, 0.0, 0.0, 0.0]) } else { - let size = buffer_dimensions(buffer).unwrap(); - let format = - with_buffer_contents(buffer, |_, _, data| shm_format_to_fourcc(data.format)) - .map_err(|err| { - DTError::Rendering(::Error::from_gles_error( - GlesError::BufferAccessError(err), - )) - })? - .expect("We should be able to convert all hardcoded shm screencopy formats"); - let render_buffer = - Offscreen::::create_buffer(renderer, format, size) - .map_err(DTError::Rendering)?; - age = 0; - renderer.bind(render_buffer).map_err(DTError::Rendering)?; + let fb = offscreen.expect("shm buffers should have offscreen target"); + dt.render_output(renderer, fb, 0, &elements, [0.0, 0.0, 0.0, 0.0]) } - - dt.render_output(renderer, age, &elements, [0.0, 0.0, 0.0, 0.0]) } let common = &mut state.common; @@ -775,13 +756,22 @@ pub fn render_cursor_to_buffer( }; let result = match renderer { RendererRef::Glow(renderer) => { - match render_session::<_, _>( + match render_session::<_, _, GlesRenderbuffer>( renderer, session.user_data().get::().unwrap(), frame, Transform::Normal, - |buffer, renderer, dt, age, additional_damage| { - render_fn(buffer, renderer, dt, age, additional_damage, common, seat) + |buffer, renderer, offscreen, dt, age, additional_damage| { + render_fn( + buffer, + renderer, + offscreen, + dt, + age, + additional_damage, + common, + seat, + ) }, ) { Ok(frame) => frame, @@ -792,13 +782,22 @@ pub fn render_cursor_to_buffer( } } RendererRef::GlMulti(mut renderer) => { - match render_session::<_, _>( + match render_session::<_, _, GlesRenderbuffer>( &mut renderer, session.user_data().get::().unwrap(), frame, Transform::Normal, - |buffer, renderer, dt, age, additional_damage| { - render_fn(buffer, renderer, dt, age, additional_damage, common, seat) + |buffer, renderer, offscreen, dt, age, additional_damage| { + render_fn( + buffer, + renderer, + offscreen, + dt, + age, + additional_damage, + common, + seat, + ) }, ) { Ok(frame) => frame,