wp-presentation: implement version 2
This commit is contained in:
parent
de47705a32
commit
03dce4af06
8 changed files with 51 additions and 16 deletions
|
|
@ -15,7 +15,7 @@ use {
|
|||
MetalBackend, MetalError,
|
||||
},
|
||||
drm_feedback::DrmFeedback,
|
||||
edid::Descriptor,
|
||||
edid::{CtaDataBlock, Descriptor, EdidExtension},
|
||||
format::{Format, ARGB8888, XRGB8888},
|
||||
gfx_api::{
|
||||
needs_render_usage, AcquireSync, GfxContext, GfxFramebuffer, GfxTexture, ReleaseSync,
|
||||
|
|
@ -331,6 +331,7 @@ pub struct ConnectorDisplayData {
|
|||
pub non_desktop: bool,
|
||||
pub non_desktop_effective: bool,
|
||||
pub vrr_capable: bool,
|
||||
pub _vrr_refresh_max_nsec: u64,
|
||||
|
||||
pub connector_id: ConnectorKernelId,
|
||||
pub output_id: Rc<OutputId>,
|
||||
|
|
@ -1129,6 +1130,7 @@ fn create_connector_display_data(
|
|||
let mut name = String::new();
|
||||
let mut manufacturer = String::new();
|
||||
let mut serial_number = String::new();
|
||||
let mut vrr_refresh_max_nsec = u64::MAX;
|
||||
let connector_id = ConnectorKernelId {
|
||||
ty: ConnectorType::from_drm(info.connector_type),
|
||||
idx: info.connector_type_id,
|
||||
|
|
@ -1194,6 +1196,28 @@ fn create_connector_display_data(
|
|||
);
|
||||
serial_number = edid.base_block.id_serial_number.to_string();
|
||||
}
|
||||
let min_vrr_hz = 'fetch_min_hz: {
|
||||
for ext in &edid.extension_blocks {
|
||||
if let EdidExtension::CtaV3(cta) = ext {
|
||||
for data_block in &cta.data_blocks {
|
||||
if let CtaDataBlock::VendorAmd(amd) = data_block {
|
||||
break 'fetch_min_hz amd.minimum_refresh_hz as u64;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for desc in &edid.base_block.descriptors {
|
||||
if let Some(desc) = desc {
|
||||
if let Descriptor::DisplayRangeLimitsAndAdditionalTiming(timings) = desc {
|
||||
break 'fetch_min_hz timings.vertical_field_rate_min as u64;
|
||||
}
|
||||
}
|
||||
}
|
||||
0
|
||||
};
|
||||
if min_vrr_hz > 0 {
|
||||
vrr_refresh_max_nsec = 1_000_000_000 / min_vrr_hz;
|
||||
}
|
||||
}
|
||||
let output_id = Rc::new(OutputId::new(
|
||||
connector_id.to_string(),
|
||||
|
|
@ -1249,6 +1273,7 @@ fn create_connector_display_data(
|
|||
non_desktop,
|
||||
non_desktop_effective: non_desktop_override.unwrap_or(non_desktop),
|
||||
vrr_capable,
|
||||
_vrr_refresh_max_nsec: vrr_refresh_max_nsec,
|
||||
connection,
|
||||
mm_width: info.mm_width,
|
||||
mm_height: info.mm_height,
|
||||
|
|
@ -2002,17 +2027,14 @@ impl MetalBackend {
|
|||
if connector.presentation_is_zero_copy.get() {
|
||||
flags |= KIND_ZERO_COPY;
|
||||
}
|
||||
let refresh = match crtc.vrr_enabled.value.get() {
|
||||
true => 0,
|
||||
false => dd.refresh,
|
||||
};
|
||||
if let Some(g) = &global {
|
||||
g.presented(
|
||||
tv_sec as _,
|
||||
tv_usec * 1000,
|
||||
refresh,
|
||||
dd.refresh,
|
||||
connector.sequence.get(),
|
||||
flags,
|
||||
crtc.vrr_enabled.value.get(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1161,32 +1161,28 @@ pub struct EdidBaseBlock {
|
|||
#[derive(Debug)]
|
||||
pub enum EdidExtension {
|
||||
Unknown,
|
||||
#[expect(dead_code)]
|
||||
CtaV3(CtaExtensionV3),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CtaExtensionV3 {
|
||||
#[expect(dead_code)]
|
||||
pub data_blocks: Vec<CtaDataBlock>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CtaDataBlock {
|
||||
Unknown,
|
||||
#[expect(dead_code)]
|
||||
VendorAmd(CtaAmdVendorDataBlock),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[expect(dead_code)]
|
||||
pub struct CtaAmdVendorDataBlock {
|
||||
pub minimum_refresh_hz: u8,
|
||||
#[expect(dead_code)]
|
||||
pub maximum_refresh_hz: u8,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[expect(dead_code)]
|
||||
pub struct EdidFile {
|
||||
pub base_block: EdidBaseBlock,
|
||||
pub extension_blocks: Vec<EdidExtension>,
|
||||
|
|
|
|||
|
|
@ -301,6 +301,7 @@ impl PresentationListener for ExtImageCopyCaptureSessionV1 {
|
|||
_refresh: u32,
|
||||
_seq: u64,
|
||||
_flags: u32,
|
||||
_vrr: bool,
|
||||
) {
|
||||
self.presentation_listener.detach();
|
||||
let Some(frame) = self.frame.get() else {
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ use {
|
|||
zwlr_layer_surface_v1::{PendingLayerSurfaceData, ZwlrLayerSurfaceV1Error},
|
||||
},
|
||||
wp_content_type_v1::ContentType,
|
||||
wp_presentation_feedback::WpPresentationFeedback,
|
||||
wp_presentation_feedback::{WpPresentationFeedback, VRR_REFRESH_SINCE},
|
||||
zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1,
|
||||
},
|
||||
leaks::Tracker,
|
||||
|
|
@ -2135,6 +2135,7 @@ impl PresentationListener for WlSurface {
|
|||
refresh: u32,
|
||||
seq: u64,
|
||||
flags: u32,
|
||||
vrr: bool,
|
||||
) {
|
||||
let bindings = output.global.bindings.borrow();
|
||||
let bindings = bindings.get(&self.client.id);
|
||||
|
|
@ -2144,6 +2145,10 @@ impl PresentationListener for WlSurface {
|
|||
pf.send_sync_output(binding);
|
||||
}
|
||||
}
|
||||
let mut refresh = refresh;
|
||||
if vrr && pf.version < VRR_REFRESH_SINCE {
|
||||
refresh = 0;
|
||||
}
|
||||
pf.send_presented(tv_sec, tv_nsec, refresh, seq, flags);
|
||||
let _ = pf.client.remove_obj(&*pf);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ impl Global for WpPresentationGlobal {
|
|||
}
|
||||
|
||||
fn version(&self) -> u32 {
|
||||
1
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ pub const KIND_HW_CLOCK: u32 = 0x2;
|
|||
pub const KIND_HW_COMPLETION: u32 = 0x4;
|
||||
pub const KIND_ZERO_COPY: u32 = 0x8;
|
||||
|
||||
pub const VRR_REFRESH_SINCE: Version = Version(2);
|
||||
|
||||
impl WpPresentationFeedback {
|
||||
pub fn send_sync_output(&self, output: &WlOutput) {
|
||||
self.client.event(SyncOutput {
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ pub trait PresentationListener {
|
|||
refresh: u32,
|
||||
seq: u64,
|
||||
flags: u32,
|
||||
vrr: bool,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -158,9 +159,17 @@ impl OutputNode {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn presented(&self, tv_sec: u64, tv_nsec: u32, refresh: u32, seq: u64, flags: u32) {
|
||||
pub fn presented(
|
||||
&self,
|
||||
tv_sec: u64,
|
||||
tv_nsec: u32,
|
||||
refresh: u32,
|
||||
seq: u64,
|
||||
flags: u32,
|
||||
vrr: bool,
|
||||
) {
|
||||
for listener in self.presentation_event.iter() {
|
||||
listener.presented(self, tv_sec, tv_nsec, refresh, seq, flags);
|
||||
listener.presented(self, tv_sec, tv_nsec, refresh, seq, flags, vrr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue