diff --git a/src/backends/metal/monitor.rs b/src/backends/metal/monitor.rs index 6d123fbd..3badcece 100644 --- a/src/backends/metal/monitor.rs +++ b/src/backends/metal/monitor.rs @@ -204,7 +204,6 @@ impl MetalBackend { return; } }; - slf.init_drm_device(&dev); slf.device_holder .drm_devices .set(dev.dev.devnum, dev.clone()); diff --git a/src/backends/metal/video.rs b/src/backends/metal/video.rs index ac7b1acf..3970b01e 100644 --- a/src/backends/metal/video.rs +++ b/src/backends/metal/video.rs @@ -1,11 +1,6 @@ use crate::async_engine::{AsyncFd, SpawnedFuture}; use crate::backend::{BackendEvent, Output, OutputId}; -use crate::drm::drm::{ - ConnectorStatus, ConnectorType, DrmBlob, DrmConnector, DrmCrtc, DrmEncoder, DrmError, DrmEvent, - DrmFb, DrmFramebuffer, DrmMaster, DrmModeInfo, DrmObject, DrmPlane, DrmProperty, - DrmPropertyDefinition, DrmPropertyType, PropBlob, DRM_CLIENT_CAP_ATOMIC, - DRM_MODE_ATOMIC_ALLOW_MODESET, DRM_MODE_ATOMIC_NONBLOCK, DRM_MODE_PAGE_FLIP_EVENT, -}; +use crate::drm::drm::{ConnectorStatus, ConnectorType, DrmBlob, DrmConnector, DrmCrtc, DrmEncoder, DrmError, DrmEvent, DrmFb, DrmFramebuffer, DrmMaster, DrmModeInfo, DrmObject, DrmPlane, DrmProperty, DrmPropertyDefinition, DrmPropertyType, PropBlob, DRM_CLIENT_CAP_ATOMIC, DRM_MODE_ATOMIC_ALLOW_MODESET, DRM_MODE_ATOMIC_NONBLOCK, DRM_MODE_PAGE_FLIP_EVENT, Change}; use crate::drm::gbm::{GbmDevice, GBM_BO_USE_RENDERING, GBM_BO_USE_SCANOUT}; use crate::drm::{ModifiedFormat, INVALID_MODIFIER}; use crate::format::{Format, XRGB8888}; @@ -469,7 +464,20 @@ impl MetalBackend { let slf = Rc::new(MetalDrmDevice { dev, connectors }); - self.reset_drm_device(&slf)?; + let mut changes = master.change(DRM_MODE_ATOMIC_ALLOW_MODESET); + + self.reset_drm_device(&slf, &mut changes); + self.init_drm_device(&slf, &mut changes); + + if let Err(e) = changes.commit(0) { + return Err(MetalError::Configure(e)); + } + + for connector in slf.connectors.values() { + if connector.primary_plane.get().is_some() { + self.start_connector(connector); + } + } let handler = self .state @@ -477,7 +485,7 @@ impl MetalBackend { .spawn(self.clone().handle_drm_events(slf.clone())); slf.dev.handle_events.handle_events.set(Some(handler)); - self.state.render_ctx.set(Some(egl)); + self.state.set_render_ctx(&egl); Ok(slf) } @@ -531,8 +539,7 @@ impl MetalBackend { self.present(&connector); } - fn reset_drm_device(&self, dev: &MetalDrmDevice) -> Result<(), DrmError> { - let mut changes = dev.dev.master.change(DRM_MODE_ATOMIC_ALLOW_MODESET); + fn reset_drm_device(&self, dev: &MetalDrmDevice, changes: &mut Change) { for connector in dev.connectors.values() { if connector.crtc_id.value.take().is_some() { changes.change_object(connector.id, |c| { @@ -560,15 +567,11 @@ impl MetalBackend { } }) } - if let Err(e) = changes.commit(0) { - return Err(DrmError::ResetFailed(Box::new(e))); - } - Ok(()) } - pub fn init_drm_device(&self, dev: &Rc) { + pub fn init_drm_device(&self, dev: &Rc, changes: &mut Change) { for connector in dev.connectors.values() { - if let Err(e) = self.init_drm_connector(dev, connector) { + if let Err(e) = self.init_drm_connector(dev, connector, changes) { log::error!("Could not initialize drm connector: {}", ErrorFmt(e)); } } @@ -604,11 +607,11 @@ impl MetalBackend { Ok(b) => b, Err(e) => return Err(MetalError::ScanoutBuffer(e)), }; - let drm_fb = match connector.master.add_fb(&bo) { + let drm_fb = match connector.master.add_fb(bo.dma()) { Ok(fb) => Rc::new(fb), Err(e) => return Err(MetalError::Framebuffer(e)), }; - let egl_fb = match dev.dev.egl.dmabuf_fb(&bo.dma()) { + let egl_fb = match dev.dev.egl.dmabuf_fb(bo.dma()) { Ok(fb) => fb, Err(e) => return Err(MetalError::ImportFb(e)), }; @@ -622,6 +625,7 @@ impl MetalBackend { &self, dev: &Rc, connector: &Rc, + changes: &mut Change, ) -> Result<(), MetalError> { if connector.connection != ConnectorStatus::Connected { return Ok(()); @@ -661,7 +665,6 @@ impl MetalBackend { mode.hdisplay as _, mode.vdisplay as _, )?; - let mut changes = connector.master.change(DRM_MODE_ATOMIC_ALLOW_MODESET); changes.change_object(connector.id, |c| { c.change(connector.crtc_id.id, crtc.id.0 as _); }); @@ -681,9 +684,6 @@ impl MetalBackend { c.change(primary_plane.src_w.id, (mode.hdisplay as u64) << 16); c.change(primary_plane.src_h.id, (mode.vdisplay as u64) << 16); }); - if let Err(e) = changes.commit(0) { - return Err(MetalError::Configure(e)); - } primary_plane.fb_id.value.set(buffers[0].drm.id()); primary_plane.crtc_id.value.set(crtc.id); primary_plane.crtc_x.value.set(0); @@ -702,6 +702,11 @@ impl MetalBackend { crtc.active.value.set(true); crtc.mode_id.value.set(mode_blob.id()); crtc.mode_blob.set(Some(Rc::new(mode_blob))); + Ok(()) + } + + fn start_connector(&self, connector: &Rc) { + let mode = connector.mode.get().unwrap(); self.state .backend_events .push(BackendEvent::NewOutput(connector.clone())); @@ -712,7 +717,6 @@ impl MetalBackend { mode ); self.present(connector); - Ok(()) } fn present(&self, connector: &Rc) { diff --git a/src/backends/xorg.rs b/src/backends/xorg.rs index fe96cd4a..4519d65a 100644 --- a/src/backends/xorg.rs +++ b/src/backends/xorg.rs @@ -234,7 +234,7 @@ fn get_drm(con: &XcbCon) -> Result { assert!(res.nfd == 1); let fd = *con.dri.xcb_dri3_open_reply_fds(con.c, &mut *res); let fd = OwnedFd::new(fd); - Ok(Drm::reopen(fd.raw(), true)?) + Ok(Drm::reopen(fd.raw(), false)?) } } diff --git a/src/drm/drm.rs b/src/drm/drm.rs index 446d561e..5d5c45c4 100644 --- a/src/drm/drm.rs +++ b/src/drm/drm.rs @@ -2,7 +2,7 @@ mod sys; use crate::drm::drm::sys::{ create_lease, drm_event, drm_event_vblank, drm_mode_modeinfo, gem_close, get_cap, - get_device_name_from_fd2, get_minor_name_from_fd, get_node_type_from_fd, get_nodes, is_master, + get_device_name_from_fd2, get_minor_name_from_fd, get_node_type_from_fd, get_nodes, mode_addfb2, mode_atomic, mode_create_blob, mode_destroy_blob, mode_get_resources, mode_getconnector, mode_getencoder, mode_getplane, mode_getplaneresources, mode_getproperty, mode_obj_getproperties, mode_rmfb, prime_fd_to_handle, set_client_cap, DRM_DISPLAY_MODE_LEN, @@ -23,7 +23,6 @@ use std::rc::{Rc, Weak}; use thiserror::Error; use uapi::{c, Errno, OwnedFd, Ustring}; -use crate::drm::gbm::GbmBo; use crate::drm::INVALID_MODIFIER; use crate::utils::stack::Stack; use crate::utils::syncqueue::SyncQueue; @@ -32,6 +31,7 @@ pub use sys::{ DRM_CLIENT_CAP_ATOMIC, DRM_MODE_ATOMIC_ALLOW_MODESET, DRM_MODE_ATOMIC_NONBLOCK, DRM_MODE_PAGE_FLIP_EVENT, }; +use crate::drm::dma::DmaBuf; #[derive(Debug, Error)] pub enum DrmError { @@ -79,8 +79,6 @@ pub enum DrmError { InvalidPlaneType(u64), #[error("Plane type property has an invalid property type")] InvalidPlaneTypeProperty, - #[error("Could not reset drm objects")] - ResetFailed(#[source] Box), #[error("Could not create a framebuffer")] AddFb(#[source] OsError), #[error("Could not convert prime fd to gem handle")] @@ -99,15 +97,13 @@ fn device_node_name(fd: c::c_int) -> Result { get_device_name_from_fd2(fd).map_err(DrmError::DeviceNodeName) } -fn reopen(fd: c::c_int, allow_downgrade: bool) -> Result, DrmError> { - if is_master(fd) && allow_downgrade { - if let Ok((fd, _)) = create_lease(fd, &[], c::O_CLOEXEC as _) { - return Ok(Rc::new(fd)); - } +fn reopen(fd: c::c_int, need_primary: bool) -> Result, DrmError> { + if let Ok((fd, _)) = create_lease(fd, &[], c::O_CLOEXEC as _) { + return Ok(Rc::new(fd)); } let path = if get_node_type_from_fd(fd).map_err(DrmError::GetDeviceType)? == NodeType::Render { uapi::format_ustr!("/proc/self/fd/{}", fd) - } else if allow_downgrade { + } else if !need_primary { render_node_name(fd)? } else { device_node_name(fd)? @@ -123,9 +119,9 @@ pub struct Drm { } impl Drm { - pub fn reopen(fd: c::c_int, allow_downgrade: bool) -> Result { + pub fn reopen(fd: c::c_int, need_primary: bool) -> Result { Ok(Self { - fd: reopen(fd, allow_downgrade)?, + fd: reopen(fd, need_primary)?, }) } @@ -137,8 +133,8 @@ impl Drm { self.fd.raw() } - pub fn dup_unprivileged(&self) -> Result { - Self::reopen(self.fd.raw(), true) + pub fn dup_render(&self) -> Result { + Self::reopen(self.fd.raw(), false) } pub fn get_nodes(&self) -> Result, DrmError> { @@ -252,8 +248,7 @@ impl DrmMaster { } } - pub fn add_fb(self: &Rc, bo: &GbmBo) -> Result { - let dma = bo.dma(); + pub fn add_fb(self: &Rc, dma: &DmaBuf) -> Result { let mut modifier = 0; let mut flags = 0; if dma.modifier != INVALID_MODIFIER { diff --git a/src/drm/drm/sys.rs b/src/drm/drm/sys.rs index f1de584b..5a1869ac 100644 --- a/src/drm/drm/sys.rs +++ b/src/drm/drm/sys.rs @@ -39,27 +39,6 @@ pub const fn drm_iowr(nr: u64) -> u64 { uapi::_IOWR::(DRM_IOCTL_BASE, nr) } -const DRM_IOCTL_AUTH_MAGIC: u64 = drm_iow::(0x11); - -pub type drm_magic_t = c::c_int; - -#[repr(C)] -struct drm_auth { - magic: drm_magic_t, -} - -pub fn auth_magic(fd: c::c_int, magic: drm_magic_t) -> Result<(), OsError> { - let mut auth = drm_auth { magic }; - unsafe { ioctl(fd, DRM_IOCTL_AUTH_MAGIC, &mut auth).map(drop) } -} - -pub fn is_master(fd: c::c_int) -> bool { - match auth_magic(fd, 0) { - Err(OsError(c::EACCES)) => false, - _ => true, - } -} - const DRM_IOCTL_MODE_CREATE_LEASE: u64 = drm_iowr::(0xc6); #[repr(C)] diff --git a/src/drm/gbm.rs b/src/drm/gbm.rs index 9a38b9a5..c26370d0 100644 --- a/src/drm/gbm.rs +++ b/src/drm/gbm.rs @@ -119,7 +119,7 @@ unsafe fn export_bo(bo: *mut Bo) -> Result { impl GbmDevice { pub fn new(drm: &Drm) -> Result { - let drm = drm.dup_unprivileged()?; + let drm = drm.dup_render()?; let dev = unsafe { gbm_create_device(drm.raw()) }; if dev.is_null() { Err(GbmError::CreateDevice) diff --git a/src/render/egl/context.rs b/src/render/egl/context.rs index e1b0917c..97980e67 100644 --- a/src/render/egl/context.rs +++ b/src/render/egl/context.rs @@ -3,7 +3,6 @@ use crate::render::egl::sys::{ eglDestroyContext, eglMakeCurrent, EGLContext, EGLSurface, EGL_FALSE, EGL_TRUE, }; use crate::render::ext::GlExt; -use crate::render::gl::sys::{GLint, GLuint}; use crate::render::RenderError; use std::rc::Rc; @@ -12,11 +11,6 @@ pub struct EglContext { pub dpy: Rc, pub ext: GlExt, pub ctx: EGLContext, - - pub tex_prog: GLuint, - pub tex_tex: GLint, - pub tex_texcoord: GLint, - pub tex_pos: GLint, } impl Drop for EglContext { diff --git a/src/render/egl/display.rs b/src/render/egl/display.rs index 2ee30140..770a5dfb 100644 --- a/src/render/egl/display.rs +++ b/src/render/egl/display.rs @@ -48,10 +48,6 @@ impl EglDisplay { dpy: self.clone(), ext: GlExt::empty(), ctx, - tex_prog: 0, - tex_tex: 0, - tex_texcoord: 0, - tex_pos: 0, }; ctx.ext = ctx.with_current(|| Ok(get_gl_ext()))?; // if !ctx.ext.contains(GlExt::GL_OES_EGL_IMAGE) { @@ -100,7 +96,7 @@ impl EglDisplay { }, ]; - let mut attribs = vec![]; + let mut attribs = Vec::with_capacity(19); attribs.extend_from_slice(&[EGL_WIDTH, buf.width]); attribs.extend_from_slice(&[EGL_HEIGHT, buf.height]); attribs.extend_from_slice(&[EGL_LINUX_DRM_FOURCC_EXT, buf.format.drm as _]);