metal: split video leases and cursors
This commit is contained in:
parent
3c7ba1a7b7
commit
097eb2e8d3
3 changed files with 136 additions and 126 deletions
|
|
@ -1,3 +1,11 @@
|
||||||
|
mod hardware_cursor;
|
||||||
|
mod lease;
|
||||||
|
|
||||||
|
pub use {
|
||||||
|
hardware_cursor::{MetalHardwareCursor, MetalHardwareCursorChange},
|
||||||
|
lease::{MetalLease, MetalLeaseData},
|
||||||
|
};
|
||||||
|
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
async_engine::{Phase, SpawnedFuture},
|
async_engine::{Phase, SpawnedFuture},
|
||||||
|
|
@ -415,80 +423,6 @@ impl ConnectorDisplayData {
|
||||||
|
|
||||||
linear_ids!(MetalLeaseIds, MetalLeaseId, u64);
|
linear_ids!(MetalLeaseIds, MetalLeaseId, u64);
|
||||||
|
|
||||||
pub struct MetalLeaseData {
|
|
||||||
pub lease: DrmLease,
|
|
||||||
pub _lessee: Rc<dyn BackendDrmLessee>,
|
|
||||||
pub connectors: Vec<Rc<MetalConnector>>,
|
|
||||||
pub crtcs: Vec<Rc<MetalCrtc>>,
|
|
||||||
pub planes: Vec<Rc<MetalPlane>>,
|
|
||||||
pub revoked: Cell<bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MetalLeaseData {
|
|
||||||
fn try_revoke(&self) -> bool {
|
|
||||||
if self.revoked.get() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
let res = self.lease.try_revoke();
|
|
||||||
if res {
|
|
||||||
self.revoked.set(res);
|
|
||||||
for c in &self.connectors {
|
|
||||||
c.lease.take();
|
|
||||||
if let Err(e) = c.update_properties() {
|
|
||||||
log::error!("Could not update connector properties: {}", ErrorFmt(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for c in &self.crtcs {
|
|
||||||
c.lease.take();
|
|
||||||
if let Err(e) = c.update_properties() {
|
|
||||||
log::error!("Could not update crtc properties: {}", ErrorFmt(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for p in &self.planes {
|
|
||||||
p.lease.take();
|
|
||||||
if let Err(e) = p.update_properties() {
|
|
||||||
log::error!("Could not update plane properties: {}", ErrorFmt(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MetalLease {
|
|
||||||
dev: Rc<MetalDrmDevice>,
|
|
||||||
id: MetalLeaseId,
|
|
||||||
fd: Rc<OwnedFd>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for MetalLease {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if let Some(lease) = self.dev.leases.remove(&self.id) {
|
|
||||||
if !self.dev.paused.get() {
|
|
||||||
for c in &lease.connectors {
|
|
||||||
match c.frontend_state.get() {
|
|
||||||
FrontState::Removed
|
|
||||||
| FrontState::Disconnected
|
|
||||||
| FrontState::Connected { .. } => {}
|
|
||||||
FrontState::Unavailable => {
|
|
||||||
c.send_event(ConnectorEvent::Available);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !lease.try_revoke() {
|
|
||||||
self.dev.leases_to_break.set(self.id, lease);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BackendDrmLease for MetalLease {
|
|
||||||
fn fd(&self) -> &Rc<OwnedFd> {
|
|
||||||
&self.fd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum FrontState {
|
pub enum FrontState {
|
||||||
Removed,
|
Removed,
|
||||||
|
|
@ -564,58 +498,6 @@ impl Debug for MetalConnector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MetalHardwareCursor {
|
|
||||||
pub connector: Rc<MetalConnector>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MetalHardwareCursorChange<'a> {
|
|
||||||
pub cursor_swap_buffer: Option<Option<FdSync>>,
|
|
||||||
pub cursor_enabled: bool,
|
|
||||||
pub cursor_x: i32,
|
|
||||||
pub cursor_y: i32,
|
|
||||||
pub cursor_buffer: &'a RenderBuffer,
|
|
||||||
pub cursor_size: (i32, i32),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for MetalHardwareCursor {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("MetalHardwareCursor")
|
|
||||||
.finish_non_exhaustive()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HardwareCursor for MetalHardwareCursor {
|
|
||||||
fn damage(&self) {
|
|
||||||
self.connector.cursor_damage.set(true);
|
|
||||||
if self.connector.buffers_idle.get() && self.connector.crtc_idle.get() {
|
|
||||||
self.connector.schedule_present();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HardwareCursorUpdate for MetalHardwareCursorChange<'_> {
|
|
||||||
fn set_enabled(&mut self, enabled: bool) {
|
|
||||||
self.cursor_enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_buffer(&self) -> Rc<dyn GfxFramebuffer> {
|
|
||||||
self.cursor_buffer.render.fb.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_position(&mut self, x: i32, y: i32) {
|
|
||||||
self.cursor_x = x;
|
|
||||||
self.cursor_y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn swap_buffer(&mut self, sync: Option<FdSync>) {
|
|
||||||
self.cursor_swap_buffer = Some(sync);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size(&self) -> (i32, i32) {
|
|
||||||
self.cursor_size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ConnectorFutures {
|
pub struct ConnectorFutures {
|
||||||
pub _present: SpawnedFuture<()>,
|
pub _present: SpawnedFuture<()>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
53
src/backends/metal/video/hardware_cursor.rs
Normal file
53
src/backends/metal/video/hardware_cursor.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub struct MetalHardwareCursor {
|
||||||
|
pub connector: Rc<MetalConnector>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MetalHardwareCursorChange<'a> {
|
||||||
|
pub cursor_swap_buffer: Option<Option<FdSync>>,
|
||||||
|
pub cursor_enabled: bool,
|
||||||
|
pub cursor_x: i32,
|
||||||
|
pub cursor_y: i32,
|
||||||
|
pub cursor_buffer: &'a RenderBuffer,
|
||||||
|
pub cursor_size: (i32, i32),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for MetalHardwareCursor {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("MetalHardwareCursor")
|
||||||
|
.finish_non_exhaustive()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HardwareCursor for MetalHardwareCursor {
|
||||||
|
fn damage(&self) {
|
||||||
|
self.connector.cursor_damage.set(true);
|
||||||
|
if self.connector.buffers_idle.get() && self.connector.crtc_idle.get() {
|
||||||
|
self.connector.schedule_present();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HardwareCursorUpdate for MetalHardwareCursorChange<'_> {
|
||||||
|
fn set_enabled(&mut self, enabled: bool) {
|
||||||
|
self.cursor_enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_buffer(&self) -> Rc<dyn GfxFramebuffer> {
|
||||||
|
self.cursor_buffer.render.fb.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_position(&mut self, x: i32, y: i32) {
|
||||||
|
self.cursor_x = x;
|
||||||
|
self.cursor_y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn swap_buffer(&mut self, sync: Option<FdSync>) {
|
||||||
|
self.cursor_swap_buffer = Some(sync);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size(&self) -> (i32, i32) {
|
||||||
|
self.cursor_size
|
||||||
|
}
|
||||||
|
}
|
||||||
75
src/backends/metal/video/lease.rs
Normal file
75
src/backends/metal/video/lease.rs
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub struct MetalLeaseData {
|
||||||
|
pub lease: DrmLease,
|
||||||
|
pub _lessee: Rc<dyn BackendDrmLessee>,
|
||||||
|
pub connectors: Vec<Rc<MetalConnector>>,
|
||||||
|
pub crtcs: Vec<Rc<MetalCrtc>>,
|
||||||
|
pub planes: Vec<Rc<MetalPlane>>,
|
||||||
|
pub revoked: Cell<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MetalLeaseData {
|
||||||
|
pub(super) fn try_revoke(&self) -> bool {
|
||||||
|
if self.revoked.get() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let res = self.lease.try_revoke();
|
||||||
|
if res {
|
||||||
|
self.revoked.set(res);
|
||||||
|
for c in &self.connectors {
|
||||||
|
c.lease.take();
|
||||||
|
if let Err(e) = c.update_properties() {
|
||||||
|
log::error!("Could not update connector properties: {}", ErrorFmt(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for c in &self.crtcs {
|
||||||
|
c.lease.take();
|
||||||
|
if let Err(e) = c.update_properties() {
|
||||||
|
log::error!("Could not update crtc properties: {}", ErrorFmt(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for p in &self.planes {
|
||||||
|
p.lease.take();
|
||||||
|
if let Err(e) = p.update_properties() {
|
||||||
|
log::error!("Could not update plane properties: {}", ErrorFmt(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MetalLease {
|
||||||
|
pub(super) dev: Rc<MetalDrmDevice>,
|
||||||
|
pub(super) id: MetalLeaseId,
|
||||||
|
pub(super) fd: Rc<OwnedFd>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for MetalLease {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if let Some(lease) = self.dev.leases.remove(&self.id) {
|
||||||
|
if !self.dev.paused.get() {
|
||||||
|
for c in &lease.connectors {
|
||||||
|
match c.frontend_state.get() {
|
||||||
|
FrontState::Removed
|
||||||
|
| FrontState::Disconnected
|
||||||
|
| FrontState::Connected { .. } => {}
|
||||||
|
FrontState::Unavailable => {
|
||||||
|
c.send_event(ConnectorEvent::Available);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !lease.try_revoke() {
|
||||||
|
self.dev.leases_to_break.set(self.id, lease);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BackendDrmLease for MetalLease {
|
||||||
|
fn fd(&self) -> &Rc<OwnedFd> {
|
||||||
|
&self.fd
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue