From 386ee5120f88aad82e66d37553aad670c0367cf1 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Mon, 16 Sep 2024 15:28:44 +0200 Subject: [PATCH] render: use explicit sync for framebuffers --- src/backends/metal/present.rs | 27 +++++++++--- src/backends/metal/video.rs | 20 +++++++-- src/backends/x.rs | 13 ++++-- src/cursor_user.rs | 11 ++++- src/gfx_api.rs | 58 +++++++++++++++++++------ src/gfx_apis/gl.rs | 7 +-- src/gfx_apis/gl/renderer/framebuffer.rs | 9 +++- src/gfx_apis/vulkan/image.rs | 10 +++-- src/gfx_apis/vulkan/renderer.rs | 25 ++++++++--- src/ifs/jay_screencast.rs | 14 +++++- src/it/test_gfx_api.rs | 9 ++-- src/portal/ptr_gui.rs | 12 +++-- src/screenshoter.rs | 4 +- src/state.rs | 43 +++++++++++++++--- src/tree/output.rs | 37 ++++++++++++++-- 15 files changed, 235 insertions(+), 64 deletions(-) diff --git a/src/backends/metal/present.rs b/src/backends/metal/present.rs index 6a5b7fbb..e02e3b67 100644 --- a/src/backends/metal/present.rs +++ b/src/backends/metal/present.rs @@ -9,7 +9,7 @@ use { }, gfx_api::{ create_render_pass, AcquireSync, BufferResv, GfxApiOpt, GfxRenderPass, GfxTexture, - SyncFile, + ReleaseSync, SyncFile, }, theme::Color, time::Time, @@ -43,7 +43,8 @@ pub struct DirectScanoutCache { pub struct DirectScanoutData { tex: Rc, acquire_sync: AcquireSync, - _resv: Option>, + release_sync: ReleaseSync, + resv: Option>, fb: Rc, dma_buf_id: DmaBufId, position: DirectScanoutPosition, @@ -618,7 +619,8 @@ impl MetalConnector { return buffer.fb.as_ref().map(|fb| DirectScanoutData { tex: buffer.tex.upgrade().unwrap(), acquire_sync: ct.acquire_sync.clone(), - _resv: ct.buffer_resv.clone(), + release_sync: ct.release_sync, + resv: ct.buffer_resv.clone(), fb: fb.clone(), dma_buf_id: dmabuf.id, position, @@ -643,7 +645,8 @@ impl MetalConnector { Ok(fb) => Some(DirectScanoutData { tex: ct.tex.clone(), acquire_sync: ct.acquire_sync.clone(), - _resv: ct.buffer_resv.clone(), + release_sync: ct.release_sync, + resv: ct.buffer_resv.clone(), fb: Rc::new(fb), dma_buf_id: dmabuf.id, position, @@ -708,7 +711,7 @@ impl MetalConnector { None => { let sf = buffer .render_fb() - .perform_render_pass(pass) + .perform_render_pass(AcquireSync::Unnecessary, ReleaseSync::Explicit, pass) .map_err(MetalError::RenderFrame)?; sync_file = buffer.copy_to_dev(sf)?; fb = buffer.drm.clone(); @@ -748,11 +751,23 @@ impl MetalConnector { let render_hardware_cursor = self.cursor_enabled.get(); match &fb.direct_scanout_data { None => { - output.perform_screencopies(&fb.tex, render_hardware_cursor, 0, 0, None); + output.perform_screencopies( + &fb.tex, + None, + &AcquireSync::Unnecessary, + ReleaseSync::None, + render_hardware_cursor, + 0, + 0, + None, + ); } Some(dsd) => { output.perform_screencopies( &dsd.tex, + dsd.resv.as_ref(), + &dsd.acquire_sync, + dsd.release_sync, render_hardware_cursor, dsd.position.crtc_x, dsd.position.crtc_y, diff --git a/src/backends/metal/video.rs b/src/backends/metal/video.rs index d1eb10a7..12d9d147 100644 --- a/src/backends/metal/video.rs +++ b/src/backends/metal/video.rs @@ -2474,7 +2474,9 @@ impl MetalBackend { Ok(fb) => fb, Err(e) => return Err(MetalError::ImportFb(e)), }; - dev_fb.clear().map_err(MetalError::Clear)?; + dev_fb + .clear(AcquireSync::Unnecessary, ReleaseSync::None) + .map_err(MetalError::Clear)?; let (dev_tex, render_tex, render_fb, render_bo) = if dev.id == render_ctx.dev_id { let render_tex = match dev_img.to_texture() { Ok(fb) => fb, @@ -2526,7 +2528,9 @@ impl MetalBackend { Ok(fb) => fb, Err(e) => return Err(MetalError::ImportFb(e)), }; - render_fb.clear().map_err(MetalError::Clear)?; + render_fb + .clear(AcquireSync::Unnecessary, ReleaseSync::None) + .map_err(MetalError::Clear)?; let render_tex = match render_img.to_texture() { Ok(fb) => fb, Err(e) => return Err(MetalError::ImportTexture(e)), @@ -2797,9 +2801,17 @@ impl RenderBuffer { let Some(tex) = &self.dev_tex else { return Ok(sync_file); }; - let acquire_point = AcquireSync::from_sync_file(sync_file); self.dev_fb - .copy_texture(tex, acquire_point, ReleaseSync::Implicit, 0, 0) + .copy_texture( + AcquireSync::Unnecessary, + ReleaseSync::Explicit, + tex, + None, + AcquireSync::from_sync_file(sync_file), + ReleaseSync::None, + 0, + 0, + ) .map_err(MetalError::CopyToOutput) } } diff --git a/src/backends/x.rs b/src/backends/x.rs index d19f999f..21438f97 100644 --- a/src/backends/x.rs +++ b/src/backends/x.rs @@ -10,7 +10,7 @@ use { }, fixed::Fixed, format::XRGB8888, - gfx_api::{GfxContext, GfxError, GfxFramebuffer, GfxTexture}, + gfx_api::{AcquireSync, GfxContext, GfxError, GfxFramebuffer, GfxTexture, ReleaseSync}, ifs::wl_output::OutputId, state::State, utils::{ @@ -750,9 +750,14 @@ impl XBackend { image.last_serial.set(serial); if let Some(node) = self.state.root.outputs.get(&output.id) { - let res = self - .state - .present_output(&node, &image.fb.get(), &image.tex.get(), true); + let res = self.state.present_output( + &node, + &image.fb.get(), + AcquireSync::Implicit, + ReleaseSync::Implicit, + &image.tex.get(), + true, + ); if let Err(e) = res { log::error!("Could not render screen: {}", ErrorFmt(e)); return; diff --git a/src/cursor_user.rs b/src/cursor_user.rs index 44313422..7b6f99a3 100644 --- a/src/cursor_user.rs +++ b/src/cursor_user.rs @@ -3,6 +3,7 @@ use { backend::HardwareCursorUpdate, cursor::{Cursor, KnownCursor, DEFAULT_CURSOR_SIZE}, fixed::Fixed, + gfx_api::{AcquireSync, ReleaseSync}, rect::Rect, scale::Scale, state::State, @@ -497,8 +498,14 @@ impl CursorUser { } if render { let buffer = hc.get_buffer(); - let res = - buffer.render_hardware_cursor(cursor.deref(), &self.group.state, scale, transform); + let res = buffer.render_hardware_cursor( + AcquireSync::Unnecessary, + ReleaseSync::Explicit, + cursor.deref(), + &self.group.state, + scale, + transform, + ); match res { Ok(sync_file) => { hc.set_sync_file(sync_file); diff --git a/src/gfx_api.rs b/src/gfx_api.rs index 612930a1..9fe14ef3 100644 --- a/src/gfx_api.rs +++ b/src/gfx_api.rs @@ -208,13 +208,13 @@ pub enum AcquireSync { impl AcquireSync { pub fn from_sync_file(sync_file: Option) -> Self { match sync_file { - None => Self::Implicit, + None => Self::Unnecessary, Some(sync_file) => Self::SyncFile { sync_file }, } } } -#[derive(Copy, Clone, Eq, PartialEq)] +#[derive(Copy, Clone, Eq, PartialEq, Debug)] pub enum ReleaseSync { None, Implicit, @@ -260,6 +260,8 @@ pub trait GfxFramebuffer: Debug { fn render( &self, + acquire_sync: AcquireSync, + release_sync: ReleaseSync, ops: &[GfxApiOpt], clear: Option<&Color>, ) -> Result, GfxError>; @@ -279,12 +281,24 @@ pub trait GfxFramebuffer: Debug { } impl dyn GfxFramebuffer { - pub fn clear(&self) -> Result, GfxError> { - self.clear_with(0.0, 0.0, 0.0, 0.0) + pub fn clear( + &self, + acquire_sync: AcquireSync, + release_sync: ReleaseSync, + ) -> Result, GfxError> { + self.clear_with(acquire_sync, release_sync, 0.0, 0.0, 0.0, 0.0) } - pub fn clear_with(&self, r: f32, g: f32, b: f32, a: f32) -> Result, GfxError> { - self.render(&[], Some(&Color { r, g, b, a })) + pub fn clear_with( + &self, + acquire_sync: AcquireSync, + release_sync: ReleaseSync, + r: f32, + g: f32, + b: f32, + a: f32, + ) -> Result, GfxError> { + self.render(acquire_sync, release_sync, &[], Some(&Color { r, g, b, a })) } pub fn logical_size(&self, transform: Transform) -> (i32, i32) { @@ -302,7 +316,10 @@ impl dyn GfxFramebuffer { pub fn copy_texture( &self, + fb_acquire_sync: AcquireSync, + fb_release_sync: ReleaseSync, texture: &Rc, + resv: Option<&Rc>, acquire_sync: AcquireSync, release_sync: ReleaseSync, x: i32, @@ -320,16 +337,18 @@ impl dyn GfxFramebuffer { None, scale, None, - None, + resv.cloned(), acquire_sync, release_sync, ); let clear = self.format().has_alpha.then_some(&Color::TRANSPARENT); - self.render(&ops, clear) + self.render(fb_acquire_sync, fb_release_sync, &ops, clear) } pub fn render_custom( &self, + acquire_sync: AcquireSync, + release_sync: ReleaseSync, scale: Scale, clear: Option<&Color>, f: &mut dyn FnMut(&mut RendererBase), @@ -337,7 +356,7 @@ impl dyn GfxFramebuffer { let mut ops = vec![]; let mut renderer = self.renderer_base(&mut ops, scale, Transform::None); f(&mut renderer); - self.render(&ops, clear) + self.render(acquire_sync, release_sync, &ops, clear) } pub fn create_render_pass( @@ -366,12 +385,19 @@ impl dyn GfxFramebuffer { ) } - pub fn perform_render_pass(&self, pass: &GfxRenderPass) -> Result, GfxError> { - self.render(&pass.ops, pass.clear.as_ref()) + pub fn perform_render_pass( + &self, + acquire_sync: AcquireSync, + release_sync: ReleaseSync, + pass: &GfxRenderPass, + ) -> Result, GfxError> { + self.render(acquire_sync, release_sync, &pass.ops, pass.clear.as_ref()) } pub fn render_output( &self, + acquire_sync: AcquireSync, + release_sync: ReleaseSync, node: &OutputNode, state: &State, cursor_rect: Option, @@ -379,6 +405,8 @@ impl dyn GfxFramebuffer { render_hardware_cursor: bool, ) -> Result, GfxError> { self.render_node( + acquire_sync, + release_sync, node, state, cursor_rect, @@ -392,6 +420,8 @@ impl dyn GfxFramebuffer { pub fn render_node( &self, + acquire_sync: AcquireSync, + release_sync: ReleaseSync, node: &dyn Node, state: &State, cursor_rect: Option, @@ -412,11 +442,13 @@ impl dyn GfxFramebuffer { transform, None, ); - self.perform_render_pass(&pass) + self.perform_render_pass(acquire_sync, release_sync, &pass) } pub fn render_hardware_cursor( &self, + acquire_sync: AcquireSync, + release_sync: ReleaseSync, cursor: &dyn Cursor, state: &State, scale: Scale, @@ -433,7 +465,7 @@ impl dyn GfxFramebuffer { }, }; cursor.render_hardware_cursor(&mut renderer); - self.render(&ops, Some(&Color::TRANSPARENT)) + self.render(acquire_sync, release_sync, &ops, Some(&Color::TRANSPARENT)) } } diff --git a/src/gfx_apis/gl.rs b/src/gfx_apis/gl.rs index 22d2a511..3ef1e19f 100644 --- a/src/gfx_apis/gl.rs +++ b/src/gfx_apis/gl.rs @@ -73,6 +73,7 @@ use { ReleaseSync, SyncFile, }, gfx_apis::gl::{ + egl::image::EglImage, gl::texture::image_target, renderer::{ context::{GlRenderContext, TexCopyType, TexSourceType}, @@ -328,7 +329,7 @@ fn render_texture(ctx: &GlRenderContext, tex: &CopyTexture) { assert!(rc_eq(&ctx.ctx, &texture.ctx.ctx)); let gles = ctx.ctx.dpy.gles; unsafe { - handle_explicit_sync(ctx, texture, &tex.acquire_sync); + handle_explicit_sync(ctx, texture.gl.img.as_ref(), &tex.acquire_sync); (gles.glActiveTexture)(GL_TEXTURE0); @@ -395,7 +396,7 @@ fn render_texture(ctx: &GlRenderContext, tex: &CopyTexture) { } } -fn handle_explicit_sync(ctx: &GlRenderContext, texture: &Texture, sync: &AcquireSync) { +fn handle_explicit_sync(ctx: &GlRenderContext, img: Option<&Rc>, sync: &AcquireSync) { let sync_file = match sync { AcquireSync::None | AcquireSync::Implicit | AcquireSync::Unnecessary => return, AcquireSync::SyncFile { sync_file } => sync_file, @@ -417,7 +418,7 @@ fn handle_explicit_sync(ctx: &GlRenderContext, texture: &Texture, sync: &Acquire }; sync.wait(); } else { - if let Some(img) = &texture.gl.img { + if let Some(img) = img { if let Err(e) = img.dmabuf.import_sync_file(DMA_BUF_SYNC_READ, &sync_file) { log::error!("Could not import sync file into dmabuf: {}", ErrorFmt(e)); } diff --git a/src/gfx_apis/gl/renderer/framebuffer.rs b/src/gfx_apis/gl/renderer/framebuffer.rs index 67fe9b63..33071aa9 100644 --- a/src/gfx_apis/gl/renderer/framebuffer.rs +++ b/src/gfx_apis/gl/renderer/framebuffer.rs @@ -1,12 +1,13 @@ use { crate::{ format::Format, - gfx_api::{GfxApiOpt, GfxError, GfxFramebuffer, SyncFile}, + gfx_api::{AcquireSync, GfxApiOpt, GfxError, GfxFramebuffer, ReleaseSync, SyncFile}, gfx_apis::gl::{ gl::{ frame_buffer::GlFrameBuffer, sys::{GL_COLOR_BUFFER_BIT, GL_FRAMEBUFFER}, }, + handle_explicit_sync, renderer::context::GlRenderContext, run_ops, sys::{GL_ONE, GL_ONE_MINUS_SRC_ALPHA}, @@ -69,11 +70,13 @@ impl Framebuffer { pub fn render( &self, + acquire_sync: AcquireSync, ops: &[GfxApiOpt], clear: Option<&Color>, ) -> Result, RenderError> { let gles = self.ctx.ctx.dpy.gles; self.ctx.ctx.with_current(|| { + handle_explicit_sync(&self.ctx, self.gl.rb._img.as_ref(), &acquire_sync); unsafe { (gles.glBindFramebuffer)(GL_FRAMEBUFFER, self.gl.fbo); (gles.glViewport)(0, 0, self.gl.width, self.gl.height); @@ -101,10 +104,12 @@ impl GfxFramebuffer for Framebuffer { fn render( &self, + acquire_sync: AcquireSync, + _release_sync: ReleaseSync, ops: &[GfxApiOpt], clear: Option<&Color>, ) -> Result, GfxError> { - self.render(ops, clear).map_err(|e| e.into()) + self.render(acquire_sync, ops, clear).map_err(|e| e.into()) } fn copy_to_shm( diff --git a/src/gfx_apis/vulkan/image.rs b/src/gfx_apis/vulkan/image.rs index a29a16f0..6b365bba 100644 --- a/src/gfx_apis/vulkan/image.rs +++ b/src/gfx_apis/vulkan/image.rs @@ -3,9 +3,9 @@ use { clientmem::ClientMemOffset, format::Format, gfx_api::{ - AsyncShmGfxTexture, AsyncShmGfxTextureCallback, AsyncShmGfxTextureUploadCancellable, - GfxApiOpt, GfxError, GfxFramebuffer, GfxImage, GfxTexture, PendingShmUpload, - ShmGfxTexture, SyncFile, + AcquireSync, AsyncShmGfxTexture, AsyncShmGfxTextureCallback, + AsyncShmGfxTextureUploadCancellable, GfxApiOpt, GfxError, GfxFramebuffer, GfxImage, + GfxTexture, PendingShmUpload, ReleaseSync, ShmGfxTexture, SyncFile, }, gfx_apis::vulkan::{ allocator::VulkanAllocation, device::VulkanDevice, format::VulkanModifierLimits, @@ -465,11 +465,13 @@ impl GfxFramebuffer for VulkanImage { fn render( &self, + acquire_sync: AcquireSync, + release_sync: ReleaseSync, ops: &[GfxApiOpt], clear: Option<&Color>, ) -> Result, GfxError> { self.renderer - .execute(self, ops, clear) + .execute(self, acquire_sync, release_sync, ops, clear) .map_err(|e| e.into()) } diff --git a/src/gfx_apis/vulkan/renderer.rs b/src/gfx_apis/vulkan/renderer.rs index 969cb448..e4612a07 100644 --- a/src/gfx_apis/vulkan/renderer.rs +++ b/src/gfx_apis/vulkan/renderer.rs @@ -643,7 +643,11 @@ impl VulkanRenderer { } } - fn create_wait_semaphores(&self, fb: &VulkanImage) -> Result<(), VulkanError> { + fn create_wait_semaphores( + &self, + fb: &VulkanImage, + fb_acquire_sync: &AcquireSync, + ) -> Result<(), VulkanError> { zone!("create_wait_semaphores"); let mut memory = self.memory.borrow_mut(); let memory = &mut *memory; @@ -699,13 +703,13 @@ impl VulkanRenderer { &mut memory.wait_semaphore_infos, &mut memory.wait_semaphores, fb, - &AcquireSync::Implicit, + fb_acquire_sync, DMA_BUF_SYNC_WRITE, )?; Ok(()) } - fn import_release_semaphore(&self, fb: &VulkanImage) { + fn import_release_semaphore(&self, fb: &VulkanImage, fb_release_sync: ReleaseSync) { zone!("import_release_semaphore"); let memory = &mut *self.memory.borrow_mut(); let sync_file = match memory.release_sync_file.as_ref() { @@ -736,7 +740,7 @@ impl VulkanRenderer { DMA_BUF_SYNC_READ, ); } - import(fb, ReleaseSync::Implicit, None, DMA_BUF_SYNC_WRITE); + import(fb, fb_release_sync, None, DMA_BUF_SYNC_WRITE); } fn submit(&self, buf: CommandBuffer) -> Result<(), VulkanError> { @@ -838,7 +842,10 @@ impl VulkanRenderer { )?; (&*tmp_tex as &dyn GfxFramebuffer) .copy_texture( + AcquireSync::None, + ReleaseSync::None, &(tex.clone() as _), + None, AcquireSync::None, ReleaseSync::None, x, @@ -992,11 +999,13 @@ impl VulkanRenderer { pub fn execute( self: &Rc, fb: &VulkanImage, + fb_acquire_sync: AcquireSync, + fb_release_sync: ReleaseSync, opts: &[GfxApiOpt], clear: Option<&Color>, ) -> Result, VulkanError> { zone!("execute"); - let res = self.try_execute(fb, opts, clear); + let res = self.try_execute(fb, fb_acquire_sync, fb_release_sync, opts, clear); let sync_file = { let mut memory = self.memory.borrow_mut(); memory.textures.clear(); @@ -1032,6 +1041,8 @@ impl VulkanRenderer { fn try_execute( self: &Rc, fb: &VulkanImage, + fb_acquire_sync: AcquireSync, + fb_release_sync: ReleaseSync, opts: &[GfxApiOpt], clear: Option<&Color>, ) -> Result<(), VulkanError> { @@ -1047,9 +1058,9 @@ impl VulkanRenderer { self.copy_bridge_to_dmabuf(buf.buffer, fb); self.final_barriers(buf.buffer, fb); self.end_command_buffer(buf.buffer)?; - self.create_wait_semaphores(fb)?; + self.create_wait_semaphores(fb, &fb_acquire_sync)?; self.submit(buf.buffer)?; - self.import_release_semaphore(fb); + self.import_release_semaphore(fb, fb_release_sync); self.store_layouts(fb); self.create_pending_frame(buf); Ok(()) diff --git a/src/ifs/jay_screencast.rs b/src/ifs/jay_screencast.rs index 8e90ce53..d63a71bb 100644 --- a/src/ifs/jay_screencast.rs +++ b/src/ifs/jay_screencast.rs @@ -3,7 +3,9 @@ use { allocator::{AllocatorError, BufferObject, BO_USE_LINEAR, BO_USE_RENDERING}, client::{Client, ClientError}, format::XRGB8888, - gfx_api::{GfxContext, GfxError, GfxFramebuffer, GfxTexture}, + gfx_api::{ + AcquireSync, BufferResv, GfxContext, GfxError, GfxFramebuffer, GfxTexture, ReleaseSync, + }, ifs::{jay_output::JayOutput, jay_toplevel::JayToplevel, wl_buffer::WlBufferStorage}, leaks::Tracker, object::{Object, Version}, @@ -189,6 +191,8 @@ impl JayScreencast { for (idx, buffer) in buffer.deref_mut().iter_mut().enumerate() { if buffer.free { let res = buffer.fb.render_node( + AcquireSync::Implicit, + ReleaseSync::Implicit, tl.tl_as_node(), &self.client.state, Some(tl.node_absolute_position()), @@ -298,6 +302,9 @@ impl JayScreencast { &self, on: &OutputNode, texture: &Rc, + resv: Option<&Rc>, + acquire_sync: &AcquireSync, + release_sync: ReleaseSync, render_hardware_cursors: bool, x_off: i32, y_off: i32, @@ -320,7 +327,12 @@ impl JayScreencast { if buffer.free { let res = self.client.state.perform_screencopy( texture, + resv, + acquire_sync, + release_sync, &buffer.fb, + AcquireSync::Implicit, + ReleaseSync::Implicit, on.global.pos.get(), render_hardware_cursors, x_off, diff --git a/src/it/test_gfx_api.rs b/src/it/test_gfx_api.rs index 784b39c8..90157cfa 100644 --- a/src/it/test_gfx_api.rs +++ b/src/it/test_gfx_api.rs @@ -5,9 +5,10 @@ use { cpu_worker::CpuWorker, format::{Format, ARGB8888, XRGB8888}, gfx_api::{ - AsyncShmGfxTexture, AsyncShmGfxTextureCallback, CopyTexture, FillRect, FramebufferRect, - GfxApiOpt, GfxContext, GfxError, GfxFormat, GfxFramebuffer, GfxImage, GfxTexture, - GfxWriteModifier, PendingShmUpload, ResetStatus, ShmGfxTexture, SyncFile, + AcquireSync, AsyncShmGfxTexture, AsyncShmGfxTextureCallback, CopyTexture, FillRect, + FramebufferRect, GfxApiOpt, GfxContext, GfxError, GfxFormat, GfxFramebuffer, GfxImage, + GfxTexture, GfxWriteModifier, PendingShmUpload, ReleaseSync, ResetStatus, + ShmGfxTexture, SyncFile, }, rect::{Rect, Region}, theme::Color, @@ -413,6 +414,8 @@ impl GfxFramebuffer for TestGfxFb { fn render( &self, + _acquire_sync: AcquireSync, + _release_sync: ReleaseSync, ops: &[GfxApiOpt], clear: Option<&Color>, ) -> Result, GfxError> { diff --git a/src/portal/ptr_gui.rs b/src/portal/ptr_gui.rs index 5f65e332..23ba3ff6 100644 --- a/src/portal/ptr_gui.rs +++ b/src/portal/ptr_gui.rs @@ -635,13 +635,17 @@ impl WindowData { return; }; - let res = buf - .fb - .render_custom(self.scale.get(), Some(&Color::from_gray(0)), &mut |r| { + let res = buf.fb.render_custom( + AcquireSync::Implicit, + ReleaseSync::Implicit, + self.scale.get(), + Some(&Color::from_gray(0)), + &mut |r| { if let Some(content) = self.content.get() { content.render_at(r, 0.0, 0.0) } - }); + }, + ); if let Err(e) = res { log::error!("Could not render frame: {}", ErrorFmt(e)); return; diff --git a/src/screenshoter.rs b/src/screenshoter.rs index eebf9da9..076daf1f 100644 --- a/src/screenshoter.rs +++ b/src/screenshoter.rs @@ -2,7 +2,7 @@ use { crate::{ allocator::{AllocatorError, BufferObject, BufferUsage, BO_USE_RENDERING}, format::XRGB8888, - gfx_api::{needs_render_usage, GfxError}, + gfx_api::{needs_render_usage, AcquireSync, GfxError, ReleaseSync}, scale::Scale, state::State, video::drm::DrmError, @@ -77,6 +77,8 @@ pub fn take_screenshot( )?; let fb = ctx.clone().dmabuf_fb(bo.dmabuf())?; fb.render_node( + AcquireSync::Unnecessary, + ReleaseSync::Implicit, state.root.deref(), state, Some(state.root.extents.get()), diff --git a/src/state.rs b/src/state.rs index fe5f8abf..83f7fff7 100644 --- a/src/state.rs +++ b/src/state.rs @@ -27,8 +27,8 @@ use { forker::ForkerProxy, format::Format, gfx_api::{ - AcquireSync, GfxContext, GfxError, GfxFramebuffer, GfxTexture, ReleaseSync, SampleRect, - SyncFile, + AcquireSync, BufferResv, GfxContext, GfxError, GfxFramebuffer, GfxTexture, ReleaseSync, + SampleRect, SyncFile, }, gfx_apis::create_gfx_context, globals::{Globals, GlobalsError, RemovableWaylandGlobal, WaylandGlobal}, @@ -900,10 +900,14 @@ impl State { &self, output: &OutputNode, fb: &Rc, + acquire_sync: AcquireSync, + release_sync: ReleaseSync, tex: &Rc, render_hw_cursor: bool, ) -> Result, GfxError> { let sync_file = fb.render_output( + acquire_sync, + release_sync, output, self, Some(output.global.pos.get()), @@ -911,14 +915,28 @@ impl State { render_hw_cursor, )?; output.latched(); - output.perform_screencopies(tex, !render_hw_cursor, 0, 0, None); + output.perform_screencopies( + tex, + None, + &AcquireSync::Unnecessary, + ReleaseSync::None, + !render_hw_cursor, + 0, + 0, + None, + ); Ok(sync_file) } pub fn perform_screencopy( &self, src: &Rc, + resv: Option<&Rc>, + acquire_sync: &AcquireSync, + release_sync: ReleaseSync, target: &Rc, + target_acquire_sync: AcquireSync, + target_release_sync: ReleaseSync, position: Rect, render_hardware_cursors: bool, x_off: i32, @@ -947,9 +965,9 @@ impl State { size, Scale::from_int(1), None, - None, - AcquireSync::None, - ReleaseSync::Implicit, + resv.cloned(), + acquire_sync.clone(), + release_sync, ); if render_hardware_cursors { if let Some(cursor_user_group) = self.cursor_user_group_hardware_cursor.get() { @@ -963,7 +981,12 @@ impl State { } } } - target.render(&ops, Some(&Color::SOLID_BLACK)) + target.render( + target_acquire_sync, + target_release_sync, + &ops, + Some(&Color::SOLID_BLACK), + ) } fn have_hardware_cursor(&self) -> bool { @@ -980,6 +1003,7 @@ impl State { pub fn perform_shm_screencopy( &self, src: &Rc, + acquire_sync: &AcquireSync, position: Rect, x_off: i32, y_off: i32, @@ -1011,7 +1035,12 @@ impl State { .map_err(ShmScreencopyError::CreateTemporaryFb)?; self.perform_screencopy( src, + None, + acquire_sync, + ReleaseSync::None, &fb, + AcquireSync::Unnecessary, + ReleaseSync::None, position, true, x_off - capture.rect.x1(), diff --git a/src/tree/output.rs b/src/tree/output.rs index 2f774406..7f764883 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -4,7 +4,7 @@ use { client::ClientId, cursor::KnownCursor, fixed::Fixed, - gfx_api::GfxTexture, + gfx_api::{AcquireSync, BufferResv, GfxTexture, ReleaseSync}, ifs::{ jay_output::JayOutput, jay_screencast::JayScreencast, @@ -186,6 +186,9 @@ impl OutputNode { pub fn perform_screencopies( &self, tex: &Rc, + resv: Option<&Rc>, + acquire_sync: &AcquireSync, + release_sync: ReleaseSync, render_hardware_cursor: bool, x_off: i32, y_off: i32, @@ -196,15 +199,37 @@ impl OutputNode { return; } } - self.perform_wlr_screencopies(tex, render_hardware_cursor, x_off, y_off, size); + self.perform_wlr_screencopies( + tex, + resv, + acquire_sync, + release_sync, + render_hardware_cursor, + x_off, + y_off, + size, + ); for sc in self.screencasts.lock().values() { - sc.copy_texture(self, tex, render_hardware_cursor, x_off, y_off, size); + sc.copy_texture( + self, + tex, + resv, + acquire_sync, + release_sync, + render_hardware_cursor, + x_off, + y_off, + size, + ); } } pub fn perform_wlr_screencopies( &self, tex: &Rc, + resv: Option<&Rc>, + acquire_sync: &AcquireSync, + release_sync: ReleaseSync, render_hardware_cursors: bool, x_off: i32, y_off: i32, @@ -232,6 +257,7 @@ impl OutputNode { WlBufferStorage::Shm { mem, stride } => { let res = self.state.perform_shm_screencopy( tex, + acquire_sync, self.global.pos.get(), x_off, y_off, @@ -259,7 +285,12 @@ impl OutputNode { }; let res = self.state.perform_screencopy( tex, + resv, + acquire_sync, + release_sync, &fb, + AcquireSync::Implicit, + ReleaseSync::Implicit, self.global.pos.get(), render_hardware_cursors, x_off - capture.rect.x1(),