gfx-api: add support for syncobj synchronization
This commit is contained in:
parent
80a69ba7ef
commit
7e6facf4e3
20 changed files with 323 additions and 159 deletions
|
|
@ -11,8 +11,8 @@ use {
|
|||
},
|
||||
format::Format,
|
||||
gfx_api::{
|
||||
AcquireSync, GfxBlendBuffer, GfxError, GfxFormat, GfxFramebuffer, GfxTexture,
|
||||
GfxWriteModifier, ReleaseSync, SyncFile, needs_render_usage,
|
||||
AcquireSync, FdSync, GfxBlendBuffer, GfxError, GfxFormat, GfxFramebuffer, GfxTexture,
|
||||
GfxWriteModifier, ReleaseSync, needs_render_usage,
|
||||
},
|
||||
rect::{DamageQueue, Rect, Region},
|
||||
udmabuf::{Udmabuf, UdmabufError},
|
||||
|
|
@ -120,15 +120,15 @@ pub enum RenderBufferError {
|
|||
|
||||
#[derive(Default)]
|
||||
pub struct RenderBufferCopy {
|
||||
pub render_block: Option<SyncFile>,
|
||||
pub present_block: Option<SyncFile>,
|
||||
pub render_block: Option<FdSync>,
|
||||
pub present_block: Option<FdSync>,
|
||||
}
|
||||
|
||||
impl RenderBufferCopy {
|
||||
pub fn for_both(sf: Option<SyncFile>) -> Self {
|
||||
pub fn for_both(sync: Option<FdSync>) -> Self {
|
||||
Self {
|
||||
render_block: sf.clone(),
|
||||
present_block: sf,
|
||||
render_block: sync.clone(),
|
||||
present_block: sync,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -138,12 +138,12 @@ impl RenderBuffer {
|
|||
&self,
|
||||
cd: &Rc<ColorDescription>,
|
||||
region: Option<&Region>,
|
||||
sync_file: Option<SyncFile>,
|
||||
sync: Option<FdSync>,
|
||||
) -> Result<RenderBufferCopy, RenderBufferError> {
|
||||
match &self.prime {
|
||||
RenderBufferPrime::None => Ok(RenderBufferCopy {
|
||||
render_block: None,
|
||||
present_block: sync_file,
|
||||
present_block: sync,
|
||||
}),
|
||||
RenderBufferPrime::Sampling {
|
||||
dev_render_tex,
|
||||
|
|
@ -157,7 +157,7 @@ impl RenderBuffer {
|
|||
dev_render_tex,
|
||||
cd,
|
||||
None,
|
||||
AcquireSync::from_sync_file(sync_file),
|
||||
AcquireSync::from_fd_sync(sync),
|
||||
ReleaseSync::None,
|
||||
0,
|
||||
0,
|
||||
|
|
@ -175,7 +175,7 @@ impl RenderBuffer {
|
|||
..
|
||||
} => {
|
||||
let render_block = render_copy
|
||||
.execute(sync_file.as_ref(), region)
|
||||
.execute(sync.as_ref(), region)
|
||||
.map_err(RenderBufferError::CopyRenderToUdmabuf)?;
|
||||
let present_block = dev_copy
|
||||
.execute(render_block.as_ref(), region)
|
||||
|
|
@ -189,7 +189,7 @@ impl RenderBuffer {
|
|||
| RenderBufferPrime::CopyDirectPush {
|
||||
render_copy: copy, ..
|
||||
} => copy
|
||||
.execute(sync_file.as_ref(), region)
|
||||
.execute(sync.as_ref(), region)
|
||||
.map_err(RenderBufferError::CopyRenderToDev)
|
||||
.map(RenderBufferCopy::for_both),
|
||||
}
|
||||
|
|
@ -201,8 +201,8 @@ impl RenderBuffer {
|
|||
self.damage_queue.damage(&[rect]);
|
||||
}
|
||||
|
||||
pub fn clear(&self, cd: &Rc<ColorDescription>) -> Result<Option<SyncFile>, RenderBufferError> {
|
||||
let sync_file = match &self.prime {
|
||||
pub fn clear(&self, cd: &Rc<ColorDescription>) -> Result<Option<FdSync>, RenderBufferError> {
|
||||
let sync = match &self.prime {
|
||||
RenderBufferPrime::None => {
|
||||
self.render
|
||||
.fb
|
||||
|
|
@ -222,14 +222,14 @@ impl RenderBuffer {
|
|||
self.copy_to_dev(cd, None, sf)?.present_block
|
||||
}
|
||||
};
|
||||
Ok(sync_file)
|
||||
Ok(sync)
|
||||
}
|
||||
|
||||
pub fn copy_to_new(
|
||||
&self,
|
||||
new: &Self,
|
||||
cd: &Rc<ColorDescription>,
|
||||
) -> Result<Option<SyncFile>, RenderBufferError> {
|
||||
) -> Result<Option<FdSync>, RenderBufferError> {
|
||||
let old = self;
|
||||
|
||||
if (old.width, old.height) != (new.width, new.height) {
|
||||
|
|
|
|||
|
|
@ -240,13 +240,8 @@ impl MetalConnector {
|
|||
// current PresentFb if present_fb is None, potentially mutating the fb that is
|
||||
// currently being scanned out, which would render such a wait absurd.
|
||||
self.perform_screencopies(&present_fb, &node, &cd);
|
||||
if let Some(sync_file) = self.cursor_sync_file.take()
|
||||
&& let Err(e) = self.state.ring.readable(&sync_file).await
|
||||
{
|
||||
log::error!(
|
||||
"Could not wait for cursor sync file to complete: {}",
|
||||
ErrorFmt(e)
|
||||
);
|
||||
if let Some(sync) = self.cursor_sync.take() {
|
||||
sync.signaled(&self.state.ring, "cursor").await;
|
||||
}
|
||||
self.await_present_fb(present_fb.as_mut(), PresentFbWait::Scanout)
|
||||
.await;
|
||||
|
|
@ -353,19 +348,14 @@ impl MetalConnector {
|
|||
W::Render => &mut fb.copy.render_block,
|
||||
W::Scanout => &mut fb.copy.present_block,
|
||||
};
|
||||
let Some(sync_file) = field.take() else {
|
||||
let Some(sync) = field.take() else {
|
||||
return;
|
||||
};
|
||||
if let Err(e) = self.state.ring.readable(&sync_file).await {
|
||||
let name = match wait {
|
||||
W::Render => "render",
|
||||
W::Scanout => "scanout",
|
||||
};
|
||||
log::error!(
|
||||
"Could not wait for primary {name} sync file to complete: {}",
|
||||
ErrorFmt(e),
|
||||
);
|
||||
}
|
||||
let name = match wait {
|
||||
W::Render => "render",
|
||||
W::Scanout => "scanout",
|
||||
};
|
||||
sync.signaled(&self.state.ring, name).await;
|
||||
}
|
||||
|
||||
fn try_async_flip(&self) -> bool {
|
||||
|
|
@ -554,13 +544,13 @@ impl MetalConnector {
|
|||
self.state.present_hardware_cursor(node, &mut c);
|
||||
let swap_buffers = c.cursor_swap_buffer.is_some();
|
||||
self.cursor_swap_buffer.set(swap_buffers);
|
||||
if let Some(sf) = c.cursor_swap_buffer.take() {
|
||||
let sf = c
|
||||
if let Some(sync) = c.cursor_swap_buffer.take() {
|
||||
let sync = c
|
||||
.cursor_buffer
|
||||
.copy_to_dev(cd, None, sf)
|
||||
.copy_to_dev(cd, None, sync)
|
||||
.map_err(MetalError::CopyToDev)?
|
||||
.present_block;
|
||||
self.cursor_sync_file.set(sf);
|
||||
self.cursor_sync.set(sync);
|
||||
}
|
||||
let mut cursor_changed = false;
|
||||
cursor_changed |= self.cursor_enabled.replace(c.cursor_enabled) != c.cursor_enabled;
|
||||
|
|
@ -886,13 +876,13 @@ impl MetalConnector {
|
|||
tex = buffer.render.tex.clone();
|
||||
}
|
||||
Some(dsd) => {
|
||||
let sf = match &dsd.acquire_sync {
|
||||
let sync = match &dsd.acquire_sync {
|
||||
AcquireSync::None => None,
|
||||
AcquireSync::Implicit => None,
|
||||
AcquireSync::SyncFile { sync_file } => Some(sync_file.clone()),
|
||||
AcquireSync::FdSync(sync) => Some(sync.clone()),
|
||||
AcquireSync::Unnecessary => None,
|
||||
};
|
||||
copy = RenderBufferCopy::for_both(sf);
|
||||
copy = RenderBufferCopy::for_both(sync);
|
||||
fb = dsd.fb.clone();
|
||||
tex = dsd.tex.clone();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ impl MetalDeviceTransaction {
|
|||
let mut unused_crtcs = BinarySearchMap::<_, _, SIZE>::new();
|
||||
let mut unused_planes = BinarySearchMap::<_, _, SIZE>::new();
|
||||
let mut crtc_planes = BinarySearchMap::<_, _, SIZE>::new();
|
||||
let mut sync_files = vec![];
|
||||
let mut syncs = vec![];
|
||||
let slf = &mut self.common;
|
||||
for (_, crtc) in &mut slf.crtcs {
|
||||
crtc_planes.insert(crtc.obj.id, CrtcPlanes::default());
|
||||
|
|
@ -615,7 +615,7 @@ impl MetalDeviceTransaction {
|
|||
new_buffer.clear(&cd)
|
||||
};
|
||||
match res {
|
||||
Ok(sf) => sync_files.extend(sf),
|
||||
Ok(sf) => syncs.extend(sf),
|
||||
Err(e) => {
|
||||
log::warn!("Could not clear new buffer: {}", ErrorFmt(e));
|
||||
}
|
||||
|
|
@ -653,7 +653,7 @@ impl MetalDeviceTransaction {
|
|||
match res {
|
||||
Ok(sf) => {
|
||||
buffer.locked.set(true);
|
||||
sync_files.extend(sf);
|
||||
syncs.extend(sf);
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!(
|
||||
|
|
@ -753,19 +753,8 @@ impl MetalDeviceTransaction {
|
|||
plane.new = DrmPlaneState::default();
|
||||
}
|
||||
}
|
||||
for sf in sync_files {
|
||||
let mut pollfd = c::pollfd {
|
||||
fd: sf.0.raw(),
|
||||
events: c::POLLIN,
|
||||
revents: 0,
|
||||
};
|
||||
let res = uapi::poll(slice::from_mut(&mut pollfd), -1);
|
||||
if let Err(e) = res {
|
||||
log::warn!(
|
||||
"Could not wait for sync file to become readable: {}",
|
||||
ErrorFmt(e)
|
||||
);
|
||||
}
|
||||
for sync in syncs {
|
||||
sync.signaled_blocking("transaction");
|
||||
}
|
||||
Ok(MetalDeviceTransactionWithDrmState {
|
||||
common: self.common,
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ use {
|
|||
drm_feedback::DrmFeedback,
|
||||
edid::{CtaDataBlock, Descriptor, EdidExtension},
|
||||
format::{Format, XRGB8888},
|
||||
gfx_api::{GfxApi, GfxContext, GfxFramebuffer, SyncFile},
|
||||
gfx_api::{FdSync, GfxApi, GfxContext, GfxFramebuffer},
|
||||
ifs::{
|
||||
wl_output::OutputId,
|
||||
wp_presentation_feedback::{KIND_HW_COMPLETION, KIND_VSYNC, KIND_ZERO_COPY},
|
||||
|
|
@ -534,7 +534,7 @@ pub struct MetalConnector {
|
|||
pub cursor_enabled: Cell<bool>,
|
||||
pub cursor_buffers: CloneCell<Option<Rc<[RenderBuffer; 2]>>>,
|
||||
pub cursor_swap_buffer: Cell<bool>,
|
||||
pub cursor_sync_file: CloneCell<Option<SyncFile>>,
|
||||
pub cursor_sync: CloneCell<Option<FdSync>>,
|
||||
|
||||
pub drm_feedback: CloneCell<Option<Rc<DrmFeedback>>>,
|
||||
pub scanout_buffers: RefCell<AHashMap<DmaBufId, DirectScanoutCache>>,
|
||||
|
|
@ -565,7 +565,7 @@ pub struct MetalHardwareCursor {
|
|||
}
|
||||
|
||||
pub struct MetalHardwareCursorChange<'a> {
|
||||
pub cursor_swap_buffer: Option<Option<SyncFile>>,
|
||||
pub cursor_swap_buffer: Option<Option<FdSync>>,
|
||||
pub cursor_enabled: bool,
|
||||
pub cursor_x: i32,
|
||||
pub cursor_y: i32,
|
||||
|
|
@ -603,8 +603,8 @@ impl HardwareCursorUpdate for MetalHardwareCursorChange<'_> {
|
|||
self.cursor_y = y;
|
||||
}
|
||||
|
||||
fn swap_buffer(&mut self, sync_file: Option<SyncFile>) {
|
||||
self.cursor_swap_buffer = Some(sync_file);
|
||||
fn swap_buffer(&mut self, sync: Option<FdSync>) {
|
||||
self.cursor_swap_buffer = Some(sync);
|
||||
}
|
||||
|
||||
fn size(&self) -> (i32, i32) {
|
||||
|
|
@ -1127,7 +1127,7 @@ fn create_connector(
|
|||
cursor_changed: Cell::new(false),
|
||||
cursor_damage: Cell::new(false),
|
||||
cursor_swap_buffer: Cell::new(false),
|
||||
cursor_sync_file: Default::default(),
|
||||
cursor_sync: Default::default(),
|
||||
drm_feedback: Default::default(),
|
||||
scanout_buffers: Default::default(),
|
||||
active_framebuffer: Default::default(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue