1
0
Fork 0
forked from wry/wry

metal: split video object model

This commit is contained in:
kossLAN 2026-05-29 21:19:57 -04:00
parent 774177390e
commit 7a49da0a48
No known key found for this signature in database
5 changed files with 424 additions and 354 deletions

View file

@ -1,6 +1,7 @@
mod copy_device;
mod hardware_cursor;
mod lease;
mod model;
mod properties;
#[allow(unused_imports)]
@ -8,6 +9,12 @@ pub use {
copy_device::CopyDeviceHolder,
hardware_cursor::{MetalHardwareCursor, MetalHardwareCursorChange},
lease::{MetalLease, MetalLeaseData},
model::{
ConnectorDisplayData, ConnectorFutures, FrontState, HandleEvents, MetalConnector,
MetalCrtc, MetalDrmDevice, MetalDrmDeviceData, MetalEncoder, MetalLeaseId, MetalLeaseIds,
MetalPlane, MetalRenderContext, PendingDrmDevice, PersistentDisplayData, PlaneFormat,
PlaneType,
},
properties::{DefaultProperty, TypedProperty},
};
@ -17,13 +24,13 @@ use properties::{
use {
crate::{
async_engine::{Phase, SpawnedFuture},
async_engine::Phase,
backend::{
BackendColorSpace, BackendConnectorState, BackendDrmDevice, BackendDrmLease,
BackendDrmLessee, BackendEotfs, BackendEvent, BackendGammaLut, BackendGammaLutElement,
BackendColorSpace, BackendConnectorState, BackendDrmDevice, BackendDrmLessee,
BackendEotfs, BackendEvent, BackendGammaLut, BackendGammaLutElement,
BackendLuminance, CONCAP_CONNECTOR, CONCAP_MODE_SETTING, CONCAP_PHYSICAL_DISPLAY,
Connector, ConnectorCaps, ConnectorEvent, ConnectorId, ConnectorKernelId, DrmDeviceId,
HardwareCursor, HardwareCursorUpdate, Mode, MonitorInfo, OutputId,
Mode, MonitorInfo, OutputId,
transaction::{
BackendConnectorTransaction, BackendConnectorTransactionError,
BackendConnectorTransactionType, BackendConnectorTransactionTypeDyn,
@ -31,37 +38,32 @@ use {
},
backends::metal::{
MetalBackend, MetalError,
allocator::RenderBuffer,
present::{
DEFAULT_POST_COMMIT_MARGIN, DEFAULT_PRE_COMMIT_MARGIN, DirectScanoutCache,
POST_COMMIT_MARGIN_DELTA, PresentFb,
DEFAULT_POST_COMMIT_MARGIN, DEFAULT_PRE_COMMIT_MARGIN, POST_COMMIT_MARGIN_DELTA,
},
transaction::{DrmConnectorState, DrmCrtcState, DrmPlaneState, MetalDeviceTransaction},
},
cmm::{cmm_description::ColorDescription, cmm_primaries::Primaries},
copy_device::{CopyDevice, CopyDeviceRegistry},
cmm::cmm_primaries::Primaries,
drm_feedback::DrmFeedback,
edid::{CtaDataBlock, Descriptor, EdidExtension},
format::{Format, XRGB8888},
gfx_api::{FdSync, GfxApi, GfxContext, GfxFramebuffer},
format::XRGB8888,
gfx_api::GfxApi,
ifs::wp_presentation_feedback::{KIND_HW_COMPLETION, KIND_VSYNC, KIND_ZERO_COPY},
state::State,
tree::OutputNode,
udev::UdevDevice,
utils::{
asyncevent::AsyncEvent, binary_search_map::BinarySearchMap, bitflags::BitflagsExt,
cell_ext::CellExt, clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt,
geometric_decay::GeometricDecay, numcell::NumCell, on_change::OnChange,
opaque_cell::OpaqueCell, ordered_float::F64, oserror::OsError,
binary_search_map::BinarySearchMap, bitflags::BitflagsExt, cell_ext::CellExt,
clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt,
geometric_decay::GeometricDecay, numcell::NumCell, ordered_float::F64,
oserror::OsError,
},
video::{
INVALID_MODIFIER, Modifier,
dmabuf::DmaBufId,
INVALID_MODIFIER,
drm::{
ConnectorStatus, ConnectorType, DRM_CLIENT_CAP_ATOMIC, DrmBlob, DrmCardResources,
DrmConnector, DrmCrtc, DrmEncoder, DrmError, DrmEvent, DrmFb, DrmLease, DrmMaster,
DrmModeInfo, DrmObject, DrmPlane, DrmProperty, DrmPropertyDefinition,
DrmPropertyType, DrmVersion, HDMI_EOTF_TRADITIONAL_GAMMA_SDR, drm_mode_modeinfo,
DrmConnector, DrmCrtc, DrmEncoder, DrmError, DrmEvent, DrmFb, DrmMaster,
DrmObject, DrmPlane, DrmProperty, DrmPropertyDefinition, DrmPropertyType,
DrmVersion, HDMI_EOTF_TRADITIONAL_GAMMA_SDR, drm_mode_modeinfo,
hdr_output_metadata,
},
gbm::GbmDevice,
@ -69,82 +71,18 @@ use {
},
ahash::{AHashMap, AHashSet},
bstr::{BString, ByteSlice},
indexmap::{IndexSet, indexset},
indexmap::indexset,
isnt::std_1::collections::IsntHashMapExt,
std::{
cell::{Cell, OnceCell, RefCell},
cell::{Cell, RefCell},
collections::hash_map::Entry,
ffi::CString,
fmt::{Debug, Formatter},
mem,
ops::DerefMut,
rc::Rc,
},
uapi::{
OwnedFd,
c::{self, dev_t},
},
uapi::c::{self, dev_t},
};
pub struct PendingDrmDevice {
pub id: DrmDeviceId,
pub devnum: c::dev_t,
pub devnode: CString,
}
#[derive(Debug)]
pub struct MetalRenderContext {
pub dev_id: DrmDeviceId,
pub gfx: Rc<dyn GfxContext>,
pub gbm: Rc<GbmDevice>,
pub devnode: CString,
pub copy_device: Rc<CopyDeviceHolder>,
}
pub struct MetalDrmDevice {
pub backend: Rc<MetalBackend>,
pub id: DrmDeviceId,
pub devnum: c::dev_t,
pub devnode: CString,
pub master: Rc<DrmMaster>,
pub supports_kms: bool,
pub crtcs: AHashMap<DrmCrtc, Rc<MetalCrtc>>,
pub encoders: AHashMap<DrmEncoder, Rc<MetalEncoder>>,
pub planes: AHashMap<DrmPlane, Rc<MetalPlane>>,
pub cursor_width: u64,
pub cursor_height: u64,
pub supports_async_commit: bool,
pub gbm: Rc<GbmDevice>,
pub handle_events: HandleEvents,
pub ctx: CloneCell<Rc<MetalRenderContext>>,
pub copy_device: Rc<CopyDeviceHolder>,
pub on_change: OnChange<crate::backend::DrmEvent>,
pub direct_scanout_enabled: Cell<Option<bool>>,
pub is_nvidia: bool,
pub _is_amd: bool,
pub lease_ids: MetalLeaseIds,
pub leases: CopyHashMap<MetalLeaseId, MetalLeaseData>,
pub leases_to_break: CopyHashMap<MetalLeaseId, MetalLeaseData>,
pub paused: Cell<bool>,
pub min_post_commit_margin: Cell<u64>,
}
impl Debug for MetalDrmDevice {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MetalDrmDevice").finish_non_exhaustive()
}
}
impl MetalDrmDevice {
pub fn is_render_device(&self) -> bool {
if let Some(ctx) = self.backend.ctx.get() {
return ctx.dev_id == self.id;
}
false
}
}
impl BackendDrmDevice for MetalDrmDevice {
fn id(&self) -> DrmDeviceId {
self.id
@ -326,180 +264,6 @@ impl BackendDrmDevice for MetalDrmDevice {
}
}
pub struct HandleEvents {
pub handle_events: Cell<Option<SpawnedFuture<()>>>,
}
impl Debug for HandleEvents {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("HandleEvents").finish_non_exhaustive()
}
}
#[derive(Debug)]
pub struct MetalDrmDeviceData {
pub dev: Rc<MetalDrmDevice>,
pub connectors: CopyHashMap<DrmConnector, Rc<MetalConnector>>,
pub futures: CopyHashMap<DrmConnector, ConnectorFutures>,
}
#[derive(Debug)]
pub struct PersistentDisplayData {
pub state: RefCell<BackendConnectorState>,
}
#[derive(Debug)]
pub struct ConnectorDisplayData {
pub crtc_id: DrmProperty,
pub crtcs: BinarySearchMap<DrmCrtc, Rc<MetalCrtc>, 8>,
pub first_mode: Mode,
pub modes: Vec<DrmModeInfo>,
pub persistent: Rc<PersistentDisplayData>,
pub refresh: u32,
pub non_desktop: bool,
pub non_desktop_effective: bool,
pub vrr_capable: bool,
pub _vrr_refresh_max_nsec: u64,
pub default_properties: Vec<DefaultProperty>,
pub untyped_properties: AHashMap<DrmProperty, u64>,
pub connector_id: ConnectorKernelId,
pub output_id: Rc<OutputId>,
pub connection: ConnectorStatus,
pub mm_width: u32,
pub mm_height: u32,
pub _subpixel: u32,
pub supports_bt2020: bool,
pub supports_pq: bool,
pub primaries: Primaries,
pub luminance: Option<BackendLuminance>,
pub colorspace: Option<DrmProperty>,
pub hdr_metadata: Option<DrmProperty>,
pub drm_state: DrmConnectorState,
}
impl ConnectorDisplayData {
fn update_refresh(&mut self, dev: &MetalDrmDevice) {
self.refresh = 0;
if self.drm_state.crtc_id.is_none() {
return;
}
let Some(crtc) = dev.crtcs.get(&self.drm_state.crtc_id) else {
return;
};
let drm_state = &*crtc.drm_state.borrow();
let Some(mode) = &drm_state.mode else {
return;
};
let refresh_rate_mhz = mode.refresh_rate_millihz();
if refresh_rate_mhz != 0 {
self.refresh = (1_000_000_000_000u64 / refresh_rate_mhz as u64) as u32;
}
}
fn update_non_desktop_effective(&mut self) {
let state = &*self.persistent.state.borrow();
self.non_desktop_effective =
!state.enabled || state.non_desktop_override.unwrap_or(self.non_desktop);
}
pub fn update_cached_fields(&mut self, dev: &MetalDrmDevice) {
self.update_refresh(dev);
self.update_non_desktop_effective();
}
}
linear_ids!(MetalLeaseIds, MetalLeaseId, u64);
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum FrontState {
Removed,
Disconnected,
Connected { non_desktop: bool },
Unavailable,
}
pub struct MetalConnector {
pub id: DrmConnector,
pub kernel_id: Cell<ConnectorKernelId>,
pub master: Rc<DrmMaster>,
pub state: Rc<State>,
pub dev: Rc<MetalDrmDevice>,
pub backend: Rc<MetalBackend>,
pub connector_id: ConnectorId,
pub buffers: CloneCell<Option<Rc<[RenderBuffer; 2]>>>,
pub color_description: CloneCell<Rc<ColorDescription>>,
pub lease: Cell<Option<MetalLeaseId>>,
pub buffers_idle: Cell<bool>,
pub crtc_idle: Cell<bool>,
pub has_damage: NumCell<u64>,
pub cursor_changed: Cell<bool>,
pub cursor_damage: Cell<bool>,
pub next_vblank_nsec: Cell<u64>,
pub display: RefCell<ConnectorDisplayData>,
pub frontend_state: Cell<FrontState>,
pub primary_plane: CloneCell<Option<Rc<MetalPlane>>>,
pub cursor_plane: CloneCell<Option<Rc<MetalPlane>>>,
pub crtc: CloneCell<Option<Rc<MetalCrtc>>>,
pub on_change: OnChange<ConnectorEvent>,
pub present_trigger: AsyncEvent,
pub cursor_x: Cell<i32>,
pub cursor_y: Cell<i32>,
pub cursor_enabled: Cell<bool>,
pub cursor_buffers: CloneCell<Option<Rc<[RenderBuffer; 2]>>>,
pub cursor_swap_buffer: Cell<bool>,
pub cursor_sync: CloneCell<Option<FdSync>>,
pub drm_feedback: CloneCell<Option<Rc<DrmFeedback>>>,
pub scanout_buffers: RefCell<AHashMap<DmaBufId, DirectScanoutCache>>,
pub active_framebuffer: RefCell<Option<PresentFb>>,
pub next_framebuffer: OpaqueCell<Option<PresentFb>>,
pub direct_scanout_active: Cell<bool>,
pub version: NumCell<u64>,
pub expected_sequence: Cell<Option<u64>>,
pub pre_commit_margin: Cell<u64>,
pub pre_commit_margin_decay: GeometricDecay,
pub post_commit_margin: Cell<u64>,
pub post_commit_margin_decay: GeometricDecay,
pub vblank_miss_sec: Cell<u32>,
pub vblank_miss_this_sec: NumCell<u32>,
pub presentation_is_sync: Cell<bool>,
pub presentation_is_zero_copy: Cell<bool>,
}
impl Debug for MetalConnector {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MetalConnnector").finish_non_exhaustive()
}
}
pub struct ConnectorFutures {
pub _present: SpawnedFuture<()>,
}
impl Debug for ConnectorFutures {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ConnectorFutures").finish_non_exhaustive()
}
}
impl MetalConnector {
pub fn send_connected(self: &Rc<Self>) {
let dd = &*self.display.borrow();
@ -792,95 +556,6 @@ impl Connector for MetalConnector {
}
}
pub struct MetalCrtc {
pub id: DrmCrtc,
pub idx: usize,
pub master: Rc<DrmMaster>,
pub default_properties: Vec<DefaultProperty>,
pub untyped_properties: RefCell<AHashMap<DrmProperty, u64>>,
pub lease: Cell<Option<MetalLeaseId>>,
pub possible_planes: BinarySearchMap<DrmPlane, Rc<MetalPlane>, 8>,
pub connector: CloneCell<Option<Rc<MetalConnector>>>,
pub pending_flip: CloneCell<Option<Rc<MetalConnector>>>,
pub active: DrmProperty,
pub mode_id: DrmProperty,
pub vrr_enabled: DrmProperty,
pub out_fence_ptr: DrmProperty,
pub gamma_lut: Option<DrmProperty>,
pub gamma_lut_size: Option<u32>,
pub drm_state: RefCell<DrmCrtcState>,
pub sequence: Cell<u64>,
pub have_queued_sequence: Cell<bool>,
pub needs_vblank_emulation: Cell<bool>,
}
impl Debug for MetalCrtc {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MetalCrtc").finish_non_exhaustive()
}
}
#[derive(Debug)]
pub struct MetalEncoder {
pub id: DrmEncoder,
pub crtcs: AHashMap<DrmCrtc, Rc<MetalCrtc>>,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum PlaneType {
Overlay,
Primary,
Cursor,
}
#[derive(Debug)]
pub struct PlaneFormat {
pub format: &'static Format,
pub modifiers: IndexSet<Modifier>,
}
pub struct MetalPlane {
pub id: DrmPlane,
pub master: Rc<DrmMaster>,
pub default_properties: Vec<DefaultProperty>,
pub untyped_properties: RefCell<AHashMap<DrmProperty, u64>>,
pub ty: PlaneType,
pub possible_crtcs: u32,
pub formats: AHashMap<u32, PlaneFormat>,
pub lease: Cell<Option<MetalLeaseId>>,
pub mode_w: Cell<i32>,
pub mode_h: Cell<i32>,
pub crtc_id: DrmProperty,
pub crtc_x: DrmProperty,
pub crtc_y: DrmProperty,
pub crtc_w: DrmProperty,
pub crtc_h: DrmProperty,
pub src_x: DrmProperty,
pub src_y: DrmProperty,
pub src_w: DrmProperty,
pub src_h: DrmProperty,
pub in_fence_fd: DrmProperty,
pub fb_id: DrmProperty,
pub drm_state: RefCell<DrmPlaneState>,
}
impl Debug for MetalPlane {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MetalPlane").finish_non_exhaustive()
}
}
fn get_connectors(
backend: &Rc<MetalBackend>,
dev: &Rc<MetalDrmDevice>,

View file

@ -1,4 +1,15 @@
use super::*;
use {
crate::{
copy_device::{CopyDevice, CopyDeviceRegistry},
utils::errorfmt::ErrorFmt,
},
std::{
cell::OnceCell,
fmt::{Debug, Formatter},
rc::Rc,
},
uapi::c::dev_t,
};
pub struct CopyDeviceHolder {
pub registry: Rc<CopyDeviceRegistry>,

View file

@ -1,4 +1,15 @@
use super::*;
use {
super::MetalConnector,
crate::{
backend::{HardwareCursor, HardwareCursorUpdate},
backends::metal::allocator::RenderBuffer,
gfx_api::{FdSync, GfxFramebuffer},
},
std::{
fmt::{Debug, Formatter},
rc::Rc,
},
};
pub struct MetalHardwareCursor {
pub connector: Rc<MetalConnector>,

View file

@ -1,4 +1,13 @@
use super::*;
use {
super::{FrontState, MetalConnector, MetalCrtc, MetalDrmDevice, MetalLeaseId, MetalPlane},
crate::{
backend::{BackendDrmLease, BackendDrmLessee, ConnectorEvent},
utils::errorfmt::ErrorFmt,
video::drm::DrmLease,
},
std::{cell::Cell, rc::Rc},
uapi::OwnedFd,
};
pub struct MetalLeaseData {
pub lease: DrmLease,

View file

@ -0,0 +1,364 @@
use {
super::{copy_device::CopyDeviceHolder, lease::MetalLeaseData, properties::DefaultProperty},
crate::{
async_engine::SpawnedFuture,
backend::{
BackendConnectorState, BackendLuminance, ConnectorEvent, ConnectorId,
ConnectorKernelId, DrmDeviceId, DrmEvent, Mode, OutputId,
},
backends::metal::{
MetalBackend,
allocator::RenderBuffer,
present::{DirectScanoutCache, PresentFb},
transaction::{DrmConnectorState, DrmCrtcState, DrmPlaneState},
},
cmm::{cmm_description::ColorDescription, cmm_primaries::Primaries},
drm_feedback::DrmFeedback,
format::Format,
gfx_api::{FdSync, GfxContext},
state::State,
utils::{
asyncevent::AsyncEvent, binary_search_map::BinarySearchMap, clonecell::CloneCell,
copyhashmap::CopyHashMap, geometric_decay::GeometricDecay, numcell::NumCell,
on_change::OnChange, opaque_cell::OpaqueCell,
},
video::{
Modifier,
dmabuf::DmaBufId,
drm::{
ConnectorStatus, DrmConnector, DrmCrtc, DrmEncoder, DrmMaster, DrmModeInfo,
DrmObject, DrmPlane, DrmProperty,
},
gbm::GbmDevice,
},
},
ahash::AHashMap,
indexmap::IndexSet,
std::{
cell::{Cell, RefCell},
ffi::CString,
fmt::{Debug, Formatter},
rc::Rc,
},
uapi::c,
};
pub struct PendingDrmDevice {
pub id: DrmDeviceId,
pub devnum: c::dev_t,
pub devnode: CString,
}
#[derive(Debug)]
pub struct MetalRenderContext {
pub dev_id: DrmDeviceId,
pub gfx: Rc<dyn GfxContext>,
pub gbm: Rc<GbmDevice>,
pub devnode: CString,
pub copy_device: Rc<CopyDeviceHolder>,
}
pub struct MetalDrmDevice {
pub backend: Rc<MetalBackend>,
pub id: DrmDeviceId,
pub devnum: c::dev_t,
pub devnode: CString,
pub master: Rc<DrmMaster>,
pub supports_kms: bool,
pub crtcs: AHashMap<DrmCrtc, Rc<MetalCrtc>>,
pub encoders: AHashMap<DrmEncoder, Rc<MetalEncoder>>,
pub planes: AHashMap<DrmPlane, Rc<MetalPlane>>,
pub cursor_width: u64,
pub cursor_height: u64,
pub supports_async_commit: bool,
pub gbm: Rc<GbmDevice>,
pub handle_events: HandleEvents,
pub ctx: CloneCell<Rc<MetalRenderContext>>,
pub copy_device: Rc<CopyDeviceHolder>,
pub on_change: OnChange<DrmEvent>,
pub direct_scanout_enabled: Cell<Option<bool>>,
pub is_nvidia: bool,
pub _is_amd: bool,
pub lease_ids: MetalLeaseIds,
pub leases: CopyHashMap<MetalLeaseId, MetalLeaseData>,
pub leases_to_break: CopyHashMap<MetalLeaseId, MetalLeaseData>,
pub paused: Cell<bool>,
pub min_post_commit_margin: Cell<u64>,
}
impl Debug for MetalDrmDevice {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MetalDrmDevice").finish_non_exhaustive()
}
}
impl MetalDrmDevice {
pub fn is_render_device(&self) -> bool {
if let Some(ctx) = self.backend.ctx.get() {
return ctx.dev_id == self.id;
}
false
}
}
pub struct HandleEvents {
pub handle_events: Cell<Option<SpawnedFuture<()>>>,
}
impl Debug for HandleEvents {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("HandleEvents").finish_non_exhaustive()
}
}
#[derive(Debug)]
pub struct MetalDrmDeviceData {
pub dev: Rc<MetalDrmDevice>,
pub connectors: CopyHashMap<DrmConnector, Rc<MetalConnector>>,
pub futures: CopyHashMap<DrmConnector, ConnectorFutures>,
}
#[derive(Debug)]
pub struct PersistentDisplayData {
pub state: RefCell<BackendConnectorState>,
}
#[derive(Debug)]
pub struct ConnectorDisplayData {
pub crtc_id: DrmProperty,
pub crtcs: BinarySearchMap<DrmCrtc, Rc<MetalCrtc>, 8>,
pub first_mode: Mode,
pub modes: Vec<DrmModeInfo>,
pub persistent: Rc<PersistentDisplayData>,
pub refresh: u32,
pub non_desktop: bool,
pub non_desktop_effective: bool,
pub vrr_capable: bool,
pub _vrr_refresh_max_nsec: u64,
pub default_properties: Vec<DefaultProperty>,
pub untyped_properties: AHashMap<DrmProperty, u64>,
pub connector_id: ConnectorKernelId,
pub output_id: Rc<OutputId>,
pub connection: ConnectorStatus,
pub mm_width: u32,
pub mm_height: u32,
pub _subpixel: u32,
pub supports_bt2020: bool,
pub supports_pq: bool,
pub primaries: Primaries,
pub luminance: Option<BackendLuminance>,
pub colorspace: Option<DrmProperty>,
pub hdr_metadata: Option<DrmProperty>,
pub drm_state: DrmConnectorState,
}
impl ConnectorDisplayData {
fn update_refresh(&mut self, dev: &MetalDrmDevice) {
self.refresh = 0;
if self.drm_state.crtc_id.is_none() {
return;
}
let Some(crtc) = dev.crtcs.get(&self.drm_state.crtc_id) else {
return;
};
let drm_state = &*crtc.drm_state.borrow();
let Some(mode) = &drm_state.mode else {
return;
};
let refresh_rate_mhz = mode.refresh_rate_millihz();
if refresh_rate_mhz != 0 {
self.refresh = (1_000_000_000_000u64 / refresh_rate_mhz as u64) as u32;
}
}
fn update_non_desktop_effective(&mut self) {
let state = &*self.persistent.state.borrow();
self.non_desktop_effective =
!state.enabled || state.non_desktop_override.unwrap_or(self.non_desktop);
}
pub fn update_cached_fields(&mut self, dev: &MetalDrmDevice) {
self.update_refresh(dev);
self.update_non_desktop_effective();
}
}
linear_ids!(MetalLeaseIds, MetalLeaseId, u64);
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum FrontState {
Removed,
Disconnected,
Connected { non_desktop: bool },
Unavailable,
}
pub struct MetalConnector {
pub id: DrmConnector,
pub kernel_id: Cell<ConnectorKernelId>,
pub master: Rc<DrmMaster>,
pub state: Rc<State>,
pub dev: Rc<MetalDrmDevice>,
pub backend: Rc<MetalBackend>,
pub connector_id: ConnectorId,
pub buffers: CloneCell<Option<Rc<[RenderBuffer; 2]>>>,
pub color_description: CloneCell<Rc<ColorDescription>>,
pub lease: Cell<Option<MetalLeaseId>>,
pub buffers_idle: Cell<bool>,
pub crtc_idle: Cell<bool>,
pub has_damage: NumCell<u64>,
pub cursor_changed: Cell<bool>,
pub cursor_damage: Cell<bool>,
pub next_vblank_nsec: Cell<u64>,
pub display: RefCell<ConnectorDisplayData>,
pub frontend_state: Cell<FrontState>,
pub primary_plane: CloneCell<Option<Rc<MetalPlane>>>,
pub cursor_plane: CloneCell<Option<Rc<MetalPlane>>>,
pub crtc: CloneCell<Option<Rc<MetalCrtc>>>,
pub on_change: OnChange<ConnectorEvent>,
pub present_trigger: AsyncEvent,
pub cursor_x: Cell<i32>,
pub cursor_y: Cell<i32>,
pub cursor_enabled: Cell<bool>,
pub cursor_buffers: CloneCell<Option<Rc<[RenderBuffer; 2]>>>,
pub cursor_swap_buffer: Cell<bool>,
pub cursor_sync: CloneCell<Option<FdSync>>,
pub drm_feedback: CloneCell<Option<Rc<DrmFeedback>>>,
pub scanout_buffers: RefCell<AHashMap<DmaBufId, DirectScanoutCache>>,
pub active_framebuffer: RefCell<Option<PresentFb>>,
pub next_framebuffer: OpaqueCell<Option<PresentFb>>,
pub direct_scanout_active: Cell<bool>,
pub version: NumCell<u64>,
pub expected_sequence: Cell<Option<u64>>,
pub pre_commit_margin: Cell<u64>,
pub pre_commit_margin_decay: GeometricDecay,
pub post_commit_margin: Cell<u64>,
pub post_commit_margin_decay: GeometricDecay,
pub vblank_miss_sec: Cell<u32>,
pub vblank_miss_this_sec: NumCell<u32>,
pub presentation_is_sync: Cell<bool>,
pub presentation_is_zero_copy: Cell<bool>,
}
impl Debug for MetalConnector {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MetalConnnector").finish_non_exhaustive()
}
}
pub struct ConnectorFutures {
pub _present: SpawnedFuture<()>,
}
impl Debug for ConnectorFutures {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ConnectorFutures").finish_non_exhaustive()
}
}
pub struct MetalCrtc {
pub id: DrmCrtc,
pub idx: usize,
pub master: Rc<DrmMaster>,
pub default_properties: Vec<DefaultProperty>,
pub untyped_properties: RefCell<AHashMap<DrmProperty, u64>>,
pub lease: Cell<Option<MetalLeaseId>>,
pub possible_planes: BinarySearchMap<DrmPlane, Rc<MetalPlane>, 8>,
pub connector: CloneCell<Option<Rc<MetalConnector>>>,
pub pending_flip: CloneCell<Option<Rc<MetalConnector>>>,
pub active: DrmProperty,
pub mode_id: DrmProperty,
pub vrr_enabled: DrmProperty,
pub out_fence_ptr: DrmProperty,
pub gamma_lut: Option<DrmProperty>,
pub gamma_lut_size: Option<u32>,
pub drm_state: RefCell<DrmCrtcState>,
pub sequence: Cell<u64>,
pub have_queued_sequence: Cell<bool>,
pub needs_vblank_emulation: Cell<bool>,
}
impl Debug for MetalCrtc {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MetalCrtc").finish_non_exhaustive()
}
}
#[derive(Debug)]
pub struct MetalEncoder {
pub id: DrmEncoder,
pub crtcs: AHashMap<DrmCrtc, Rc<MetalCrtc>>,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum PlaneType {
Overlay,
Primary,
Cursor,
}
#[derive(Debug)]
pub struct PlaneFormat {
pub format: &'static Format,
pub modifiers: IndexSet<Modifier>,
}
pub struct MetalPlane {
pub id: DrmPlane,
pub master: Rc<DrmMaster>,
pub default_properties: Vec<DefaultProperty>,
pub untyped_properties: RefCell<AHashMap<DrmProperty, u64>>,
pub ty: PlaneType,
pub possible_crtcs: u32,
pub formats: AHashMap<u32, PlaneFormat>,
pub lease: Cell<Option<MetalLeaseId>>,
pub mode_w: Cell<i32>,
pub mode_h: Cell<i32>,
pub crtc_id: DrmProperty,
pub crtc_x: DrmProperty,
pub crtc_y: DrmProperty,
pub crtc_w: DrmProperty,
pub crtc_h: DrmProperty,
pub src_x: DrmProperty,
pub src_y: DrmProperty,
pub src_w: DrmProperty,
pub src_h: DrmProperty,
pub in_fence_fd: DrmProperty,
pub fb_id: DrmProperty,
pub drm_state: RefCell<DrmPlaneState>,
}
impl Debug for MetalPlane {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MetalPlane").finish_non_exhaustive()
}
}