1
0
Fork 0
forked from wry/wry

render: use explicit sync for framebuffers

This commit is contained in:
Julian Orth 2024-09-16 15:28:44 +02:00
parent 1bc344dcc2
commit 386ee5120f
15 changed files with 235 additions and 64 deletions

View file

@ -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<dyn GfxTexture>,
acquire_sync: AcquireSync,
_resv: Option<Rc<dyn BufferResv>>,
release_sync: ReleaseSync,
resv: Option<Rc<dyn BufferResv>>,
fb: Rc<DrmFramebuffer>,
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,

View file

@ -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)
}
}

View file

@ -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;

View file

@ -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);

View file

@ -208,13 +208,13 @@ pub enum AcquireSync {
impl AcquireSync {
pub fn from_sync_file(sync_file: Option<SyncFile>) -> 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<Option<SyncFile>, GfxError>;
@ -279,12 +281,24 @@ pub trait GfxFramebuffer: Debug {
}
impl dyn GfxFramebuffer {
pub fn clear(&self) -> Result<Option<SyncFile>, GfxError> {
self.clear_with(0.0, 0.0, 0.0, 0.0)
pub fn clear(
&self,
acquire_sync: AcquireSync,
release_sync: ReleaseSync,
) -> Result<Option<SyncFile>, 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<Option<SyncFile>, 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<Option<SyncFile>, 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<dyn GfxTexture>,
resv: Option<&Rc<dyn BufferResv>>,
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<Option<SyncFile>, GfxError> {
self.render(&pass.ops, pass.clear.as_ref())
pub fn perform_render_pass(
&self,
acquire_sync: AcquireSync,
release_sync: ReleaseSync,
pass: &GfxRenderPass,
) -> Result<Option<SyncFile>, 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<Rect>,
@ -379,6 +405,8 @@ impl dyn GfxFramebuffer {
render_hardware_cursor: bool,
) -> Result<Option<SyncFile>, 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<Rect>,
@ -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))
}
}

View file

@ -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<EglImage>>, 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));
}

View file

@ -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<Option<SyncFile>, 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<Option<SyncFile>, 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(

View file

@ -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<Option<SyncFile>, GfxError> {
self.renderer
.execute(self, ops, clear)
.execute(self, acquire_sync, release_sync, ops, clear)
.map_err(|e| e.into())
}

View file

@ -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<Self>,
fb: &VulkanImage,
fb_acquire_sync: AcquireSync,
fb_release_sync: ReleaseSync,
opts: &[GfxApiOpt],
clear: Option<&Color>,
) -> Result<Option<SyncFile>, 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<Self>,
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(())

View file

@ -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<dyn GfxTexture>,
resv: Option<&Rc<dyn BufferResv>>,
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,

View file

@ -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<Option<SyncFile>, GfxError> {

View file

@ -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;

View file

@ -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()),

View file

@ -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<dyn GfxFramebuffer>,
acquire_sync: AcquireSync,
release_sync: ReleaseSync,
tex: &Rc<dyn GfxTexture>,
render_hw_cursor: bool,
) -> Result<Option<SyncFile>, 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<dyn GfxTexture>,
resv: Option<&Rc<dyn BufferResv>>,
acquire_sync: &AcquireSync,
release_sync: ReleaseSync,
target: &Rc<dyn GfxFramebuffer>,
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<dyn GfxTexture>,
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(),

View file

@ -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<dyn GfxTexture>,
resv: Option<&Rc<dyn BufferResv>>,
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<dyn GfxTexture>,
resv: Option<&Rc<dyn BufferResv>>,
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(),