1
0
Fork 0
forked from wry/wry

metal: allow configuring color space and transfer function

This commit is contained in:
Julian Orth 2025-03-11 14:54:35 +01:00
parent 04f280aabe
commit bb56efb968
38 changed files with 1365 additions and 160 deletions

View file

@ -7,6 +7,7 @@ use {
MetalConnector, MetalCrtc, MetalHardwareCursorChange, MetalPlane, RenderBuffer,
},
},
cmm::cmm_description::ColorDescription,
gfx_api::{
AcquireSync, BufferResv, GfxApiOpt, GfxRenderPass, GfxTexture, ReleaseSync, SyncFile,
create_render_pass,
@ -176,10 +177,13 @@ impl MetalConnector {
};
let buffer = &buffers[self.next_buffer.get() % buffers.len()];
let cd = node.global.color_description.get();
let linear_cd = node.global.linear_color_description.get();
if self.has_damage.get() > 0 || self.cursor_damage.get() {
node.schedule.commit_cursor();
}
self.latch_cursor(&node)?;
self.latch_cursor(&node, &cd)?;
let cursor_programming = self.compute_cursor_programming();
let latched = self.latch(&node, buffer);
node.latched(self.try_async_flip());
@ -191,11 +195,11 @@ impl MetalConnector {
let mut present_fb = None;
let mut direct_scanout_id = None;
if let Some(latched) = &latched {
let fb = self.prepare_present_fb(buffer, &plane, latched, true)?;
let fb = self.prepare_present_fb(&cd, &linear_cd, buffer, &plane, latched, true)?;
direct_scanout_id = fb.direct_scanout_data.as_ref().map(|d| d.dma_buf_id);
present_fb = Some(fb);
}
self.perform_screencopies(&present_fb, &node);
self.perform_screencopies(&present_fb, &node, &cd);
if let Some(sync_file) = self.cursor_sync_file.take() {
if let Err(e) = self.state.ring.readable(&sync_file).await {
log::error!(
@ -214,8 +218,14 @@ impl MetalConnector {
);
if res.is_err() {
if let Some(dsd_id) = direct_scanout_id {
let fb =
self.prepare_present_fb(buffer, &plane, latched.as_ref().unwrap(), false)?;
let fb = self.prepare_present_fb(
&cd,
&linear_cd,
buffer,
&plane,
latched.as_ref().unwrap(),
false,
)?;
present_fb = Some(fb);
self.await_present_fb(present_fb.as_mut()).await;
res = self.program_connector(
@ -432,7 +442,11 @@ impl MetalConnector {
res.map_err(MetalError::Commit)
}
fn latch_cursor(&self, node: &Rc<OutputNode>) -> Result<(), MetalError> {
fn latch_cursor(
&self,
node: &Rc<OutputNode>,
cd: &Rc<ColorDescription>,
) -> Result<(), MetalError> {
if !self.cursor_damage.take() {
return Ok(());
}
@ -451,9 +465,7 @@ impl MetalConnector {
};
self.state.present_hardware_cursor(node, &mut c);
if c.cursor_swap_buffer {
c.sync_file = c
.cursor_buffer
.copy_to_dev(&self.state.color_manager, c.sync_file)?;
c.sync_file = c.cursor_buffer.copy_to_dev(cd, c.sync_file)?;
}
self.cursor_swap_buffer.set(c.cursor_swap_buffer);
if c.sync_file.is_some() {
@ -544,6 +556,7 @@ impl MetalConnector {
&self,
pass: &GfxRenderPass,
plane: &Rc<MetalPlane>,
cd: &Rc<ColorDescription>,
) -> Option<DirectScanoutData> {
let ct = 'ct: {
let mut ops = pass.ops.iter().rev();
@ -560,7 +573,7 @@ impl MetalConnector {
}
return None;
};
if !ct.cd.embeds_into(self.state.color_manager.srgb_srgb()) {
if !ct.cd.embeds_into(cd) {
// Direct scanout requires embeddable color descriptions.
return None;
}
@ -717,6 +730,8 @@ impl MetalConnector {
fn prepare_present_fb(
&self,
cd: &Rc<ColorDescription>,
linear_cd: &Rc<ColorDescription>,
buffer: &RenderBuffer,
plane: &Rc<MetalPlane>,
latched: &Latched,
@ -733,7 +748,7 @@ impl MetalConnector {
&& self.dev.is_render_device();
let mut direct_scanout_data = None;
if try_direct_scanout {
direct_scanout_data = self.prepare_direct_scanout(&latched.pass, plane);
direct_scanout_data = self.prepare_direct_scanout(&latched.pass, plane, cd);
}
let direct_scanout_active = direct_scanout_data.is_some();
if self.direct_scanout_active.replace(direct_scanout_active) != direct_scanout_active {
@ -753,14 +768,14 @@ impl MetalConnector {
.perform_render_pass(
AcquireSync::Unnecessary,
ReleaseSync::Explicit,
self.state.color_manager.srgb_srgb(),
cd,
&latched.pass,
&latched.damage,
buffer.blend_buffer.as_ref(),
self.state.color_manager.srgb_linear(),
linear_cd,
)
.map_err(MetalError::RenderFrame)?;
sync_file = buffer.copy_to_dev(&self.state.color_manager, sf)?;
sync_file = buffer.copy_to_dev(cd, sf)?;
fb = buffer.drm.clone();
tex = buffer.render_tex.clone();
}
@ -783,7 +798,12 @@ impl MetalConnector {
})
}
fn perform_screencopies(&self, new_fb: &Option<PresentFb>, output: &OutputNode) {
fn perform_screencopies(
&self,
new_fb: &Option<PresentFb>,
output: &OutputNode,
cd: &Rc<ColorDescription>,
) {
let active_fb;
let fb = match &new_fb {
Some(f) => f,
@ -800,7 +820,7 @@ impl MetalConnector {
None => {
output.perform_screencopies(
&fb.tex,
self.state.color_manager.srgb_srgb(),
cd,
None,
&AcquireSync::Unnecessary,
ReleaseSync::None,
@ -813,7 +833,7 @@ impl MetalConnector {
Some(dsd) => {
output.perform_screencopies(
&dsd.tex,
self.state.color_manager.srgb_srgb(),
cd,
dsd.resv.as_ref(),
&dsd.acquire_sync,
dsd.release_sync,