1
0
Fork 0
forked from wry/wry

autocommit 2022-03-12 22:58:30 CET

This commit is contained in:
Julian Orth 2022-03-12 22:58:30 +01:00
parent 21527b3e38
commit 133035e0a6
8 changed files with 41 additions and 74 deletions

View file

@ -204,7 +204,6 @@ impl MetalBackend {
return;
}
};
slf.init_drm_device(&dev);
slf.device_holder
.drm_devices
.set(dev.dev.devnum, dev.clone());

View file

@ -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<MetalDrmDevice>) {
pub fn init_drm_device(&self, dev: &Rc<MetalDrmDevice>, 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<MetalDrmDevice>,
connector: &Rc<MetalConnector>,
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<MetalConnector>) {
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<MetalConnector>) {

View file

@ -234,7 +234,7 @@ fn get_drm(con: &XcbCon) -> Result<Drm, XorgBackendError> {
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)?)
}
}

View file

@ -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<Self>),
#[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<Ustring, DrmError> {
get_device_name_from_fd2(fd).map_err(DrmError::DeviceNodeName)
}
fn reopen(fd: c::c_int, allow_downgrade: bool) -> Result<Rc<OwnedFd>, 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<Rc<OwnedFd>, 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<Self, DrmError> {
pub fn reopen(fd: c::c_int, need_primary: bool) -> Result<Self, DrmError> {
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, DrmError> {
Self::reopen(self.fd.raw(), true)
pub fn dup_render(&self) -> Result<Self, DrmError> {
Self::reopen(self.fd.raw(), false)
}
pub fn get_nodes(&self) -> Result<AHashMap<NodeType, CString>, DrmError> {
@ -252,8 +248,7 @@ impl DrmMaster {
}
}
pub fn add_fb(self: &Rc<Self>, bo: &GbmBo) -> Result<DrmFramebuffer, DrmError> {
let dma = bo.dma();
pub fn add_fb(self: &Rc<Self>, dma: &DmaBuf) -> Result<DrmFramebuffer, DrmError> {
let mut modifier = 0;
let mut flags = 0;
if dma.modifier != INVALID_MODIFIER {

View file

@ -39,27 +39,6 @@ pub const fn drm_iowr<T>(nr: u64) -> u64 {
uapi::_IOWR::<T>(DRM_IOCTL_BASE, nr)
}
const DRM_IOCTL_AUTH_MAGIC: u64 = drm_iow::<drm_auth>(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::<drm_mode_create_lease>(0xc6);
#[repr(C)]

View file

@ -119,7 +119,7 @@ unsafe fn export_bo(bo: *mut Bo) -> Result<DmaBuf, GbmError> {
impl GbmDevice {
pub fn new(drm: &Drm) -> Result<Self, GbmError> {
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)

View file

@ -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<EglDisplay>,
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 {

View file

@ -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 _]);