autocommit 2022-03-12 22:58:30 CET
This commit is contained in:
parent
21527b3e38
commit
133035e0a6
8 changed files with 41 additions and 74 deletions
|
|
@ -204,7 +204,6 @@ impl MetalBackend {
|
|||
return;
|
||||
}
|
||||
};
|
||||
slf.init_drm_device(&dev);
|
||||
slf.device_holder
|
||||
.drm_devices
|
||||
.set(dev.dev.devnum, dev.clone());
|
||||
|
|
|
|||
|
|
@ -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>) {
|
||||
|
|
|
|||
|
|
@ -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)?)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 _]);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue