Merge pull request #226 from mahkoh/screencopy
metal: perform screencopies even if only cursor position changes
This commit is contained in:
commit
cd09e57568
1 changed files with 41 additions and 13 deletions
|
|
@ -445,7 +445,7 @@ pub struct MetalConnector {
|
||||||
|
|
||||||
pub drm_feedback: CloneCell<Option<Rc<DrmFeedback>>>,
|
pub drm_feedback: CloneCell<Option<Rc<DrmFeedback>>>,
|
||||||
pub scanout_buffers: RefCell<AHashMap<DmaBufId, DirectScanoutCache>>,
|
pub scanout_buffers: RefCell<AHashMap<DmaBufId, DirectScanoutCache>>,
|
||||||
pub active_framebuffer: OpaqueCell<Option<PresentFb>>,
|
pub active_framebuffer: RefCell<Option<PresentFb>>,
|
||||||
pub next_framebuffer: OpaqueCell<Option<PresentFb>>,
|
pub next_framebuffer: OpaqueCell<Option<PresentFb>>,
|
||||||
pub direct_scanout_active: Cell<bool>,
|
pub direct_scanout_active: Cell<bool>,
|
||||||
}
|
}
|
||||||
|
|
@ -572,6 +572,7 @@ pub struct DirectScanoutPosition {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PresentFb {
|
pub struct PresentFb {
|
||||||
fb: Rc<DrmFramebuffer>,
|
fb: Rc<DrmFramebuffer>,
|
||||||
|
tex: Rc<dyn GfxTexture>,
|
||||||
direct_scanout_data: Option<DirectScanoutData>,
|
direct_scanout_data: Option<DirectScanoutData>,
|
||||||
sync_file: Option<SyncFile>,
|
sync_file: Option<SyncFile>,
|
||||||
}
|
}
|
||||||
|
|
@ -847,16 +848,7 @@ impl MetalConnector {
|
||||||
&& self.dev.is_render_device();
|
&& self.dev.is_render_device();
|
||||||
let mut direct_scanout_data = None;
|
let mut direct_scanout_data = None;
|
||||||
if try_direct_scanout {
|
if try_direct_scanout {
|
||||||
if let Some(dsd) = self.prepare_direct_scanout(&pass, plane) {
|
direct_scanout_data = self.prepare_direct_scanout(&pass, plane);
|
||||||
output.perform_screencopies(
|
|
||||||
&dsd.tex,
|
|
||||||
!render_hw_cursor,
|
|
||||||
dsd.position.crtc_x,
|
|
||||||
dsd.position.crtc_y,
|
|
||||||
Some((dsd.position.crtc_width, dsd.position.crtc_height)),
|
|
||||||
);
|
|
||||||
direct_scanout_data = Some(dsd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let direct_scanout_active = direct_scanout_data.is_some();
|
let direct_scanout_active = direct_scanout_data.is_some();
|
||||||
if self.direct_scanout_active.replace(direct_scanout_active) != direct_scanout_active {
|
if self.direct_scanout_active.replace(direct_scanout_active) != direct_scanout_active {
|
||||||
|
|
@ -868,14 +860,15 @@ impl MetalConnector {
|
||||||
}
|
}
|
||||||
let sync_file;
|
let sync_file;
|
||||||
let fb;
|
let fb;
|
||||||
|
let tex;
|
||||||
match &direct_scanout_data {
|
match &direct_scanout_data {
|
||||||
None => {
|
None => {
|
||||||
let sf = buffer_fb
|
let sf = buffer_fb
|
||||||
.perform_render_pass(pass)
|
.perform_render_pass(pass)
|
||||||
.map_err(MetalError::RenderFrame)?;
|
.map_err(MetalError::RenderFrame)?;
|
||||||
sync_file = buffer.copy_to_dev(sf)?;
|
sync_file = buffer.copy_to_dev(sf)?;
|
||||||
output.perform_screencopies(&buffer.render_tex, !render_hw_cursor, 0, 0, None);
|
|
||||||
fb = buffer.drm.clone();
|
fb = buffer.drm.clone();
|
||||||
|
tex = buffer.render_tex.clone();
|
||||||
}
|
}
|
||||||
Some(dsd) => {
|
Some(dsd) => {
|
||||||
sync_file = match &dsd.acquire_sync {
|
sync_file = match &dsd.acquire_sync {
|
||||||
|
|
@ -885,10 +878,12 @@ impl MetalConnector {
|
||||||
AcquireSync::Unnecessary => None,
|
AcquireSync::Unnecessary => None,
|
||||||
};
|
};
|
||||||
fb = dsd.fb.clone();
|
fb = dsd.fb.clone();
|
||||||
|
tex = dsd.tex.clone();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(PresentFb {
|
Ok(PresentFb {
|
||||||
fb,
|
fb,
|
||||||
|
tex,
|
||||||
direct_scanout_data,
|
direct_scanout_data,
|
||||||
sync_file,
|
sync_file,
|
||||||
})
|
})
|
||||||
|
|
@ -1032,6 +1027,7 @@ impl MetalConnector {
|
||||||
.discard_presentation_feedback();
|
.discard_presentation_feedback();
|
||||||
Err(MetalError::Commit(e))
|
Err(MetalError::Commit(e))
|
||||||
} else {
|
} else {
|
||||||
|
self.perform_screencopies(&new_fb);
|
||||||
if let Some(fb) = new_fb {
|
if let Some(fb) = new_fb {
|
||||||
if fb.direct_scanout_data.is_none() {
|
if fb.direct_scanout_data.is_none() {
|
||||||
self.next_buffer.fetch_add(1);
|
self.next_buffer.fetch_add(1);
|
||||||
|
|
@ -1050,6 +1046,38 @@ impl MetalConnector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn perform_screencopies(&self, new_fb: &Option<PresentFb>) {
|
||||||
|
let Some(output) = self.state.root.outputs.get(&self.connector_id) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let active_fb;
|
||||||
|
let fb = match &new_fb {
|
||||||
|
Some(f) => f,
|
||||||
|
None => {
|
||||||
|
active_fb = self.active_framebuffer.borrow();
|
||||||
|
match &*active_fb {
|
||||||
|
None => return,
|
||||||
|
Some(f) => f,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
Some(dsd) => {
|
||||||
|
output.perform_screencopies(
|
||||||
|
&dsd.tex,
|
||||||
|
render_hardware_cursor,
|
||||||
|
dsd.position.crtc_x,
|
||||||
|
dsd.position.crtc_y,
|
||||||
|
Some((dsd.position.crtc_width, dsd.position.crtc_height)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update_drm_feedback(&self) {
|
pub fn update_drm_feedback(&self) {
|
||||||
let fb = self.compute_drm_feedback();
|
let fb = self.compute_drm_feedback();
|
||||||
self.drm_feedback.set(fb);
|
self.drm_feedback.set(fb);
|
||||||
|
|
@ -2174,7 +2202,7 @@ impl MetalBackend {
|
||||||
};
|
};
|
||||||
connector.can_present.set(true);
|
connector.can_present.set(true);
|
||||||
if let Some(fb) = connector.next_framebuffer.take() {
|
if let Some(fb) = connector.next_framebuffer.take() {
|
||||||
connector.active_framebuffer.set(Some(fb));
|
*connector.active_framebuffer.borrow_mut() = Some(fb);
|
||||||
}
|
}
|
||||||
if connector.has_damage.get() || connector.cursor_changed.get() {
|
if connector.has_damage.get() || connector.cursor_changed.get() {
|
||||||
connector.schedule_present();
|
connector.schedule_present();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue