1
0
Fork 0
forked from wry/wry

autocommit 2022-04-21 18:25:34 CEST

This commit is contained in:
Julian Orth 2022-04-21 18:25:34 +02:00
parent 0d414a5336
commit 32fe8b64ca
8 changed files with 133 additions and 28 deletions

View file

@ -121,7 +121,7 @@ impl WlDrm {
}; };
let formats = ctx.formats(); let formats = ctx.formats();
let format = match formats.get(&req.format) { let format = match formats.get(&req.format) {
Some(f) => *f, Some(f) => f.format,
None => return Err(CreatePrimeBufferError::InvalidFormat(req.format)), None => return Err(CreatePrimeBufferError::InvalidFormat(req.format)),
}; };
let mut dmabuf = DmaBuf { let mut dmabuf = DmaBuf {

View file

@ -11,8 +11,9 @@ use {
render::Renderer, render::Renderer,
state::State, state::State,
tree::{ tree::{
FindTreeResult, FoundNode, Node, NodeId, NodeVisitor, SizedNode, SizedToplevelNode, FindTreeResult, FoundNode, FullscreenData, Node, NodeId, NodeVisitor,
ToplevelData, ToplevelNode, WorkspaceNode, SizedFullscreenNode, SizedNode, SizedToplevelNode, ToplevelData, ToplevelNode,
WorkspaceNode,
}, },
utils::{ utils::{
clonecell::CloneCell, copyhashmap::CopyHashMap, linkedlist::LinkedNode, clonecell::CloneCell, copyhashmap::CopyHashMap, linkedlist::LinkedNode,
@ -31,7 +32,6 @@ use {
}, },
thiserror::Error, thiserror::Error,
}; };
use crate::tree::{FullscreenData, SizedFullscreenNode};
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum XInputModel { pub enum XInputModel {
@ -508,10 +508,15 @@ impl SizedToplevelNode for Xwindow {
fn set_fullscreen(self: &Rc<Self>, fullscreen: bool) { fn set_fullscreen(self: &Rc<Self>, fullscreen: bool) {
if fullscreen { if fullscreen {
if let Some(ws) = self.workspace.get() { if let Some(ws) = self.workspace.get() {
self.fullscreen_data.set_fullscreen(&self.data.state, self.clone(), &ws.output.get()); self.fullscreen_data.set_fullscreen(
&self.data.state,
self.clone(),
&ws.output.get(),
);
} }
} else { } else {
self.fullscreen_data.unset_fullscreen(&self.data.state, self.clone()); self.fullscreen_data
.unset_fullscreen(&self.data.state, self.clone());
} }
} }
@ -538,7 +543,12 @@ impl SizedFullscreenNode for Xwindow {
} }
fn title(&self) -> String { fn title(&self) -> String {
self.data.info.title.borrow_mut().clone().unwrap_or_default() self.data
.info
.title
.borrow_mut()
.clone()
.unwrap_or_default()
} }
} }

View file

@ -11,7 +11,6 @@ use {
}, },
video::{ video::{
dmabuf::{DmaBuf, DmaBufPlane}, dmabuf::{DmaBuf, DmaBufPlane},
INVALID_MODIFIER,
}, },
wire::{zwp_linux_buffer_params_v1::*, WlBufferId, ZwpLinuxBufferParamsV1Id}, wire::{zwp_linux_buffer_params_v1::*, WlBufferId, ZwpLinuxBufferParamsV1Id},
}, },
@ -37,6 +36,7 @@ pub struct ZwpLinuxBufferParamsV1 {
pub parent: Rc<ZwpLinuxDmabufV1>, pub parent: Rc<ZwpLinuxDmabufV1>,
planes: RefCell<AHashMap<u32, Add>>, planes: RefCell<AHashMap<u32, Add>>,
used: Cell<bool>, used: Cell<bool>,
modifier: Cell<Option<u64>>,
pub tracker: Tracker<Self>, pub tracker: Tracker<Self>,
} }
@ -47,6 +47,7 @@ impl ZwpLinuxBufferParamsV1 {
parent: parent.clone(), parent: parent.clone(),
planes: RefCell::new(Default::default()), planes: RefCell::new(Default::default()),
used: Cell::new(false), used: Cell::new(false),
modifier: Cell::new(None),
tracker: Default::default(), tracker: Default::default(),
} }
} }
@ -71,8 +72,9 @@ impl ZwpLinuxBufferParamsV1 {
fn add(self: &Rc<Self>, parser: MsgParser<'_, '_>) -> Result<(), AddError> { fn add(self: &Rc<Self>, parser: MsgParser<'_, '_>) -> Result<(), AddError> {
let req: Add = self.parent.client.parse(&**self, parser)?; let req: Add = self.parent.client.parse(&**self, parser)?;
let modifier = ((req.modifier_hi as u64) << 32) | req.modifier_lo as u64; let modifier = ((req.modifier_hi as u64) << 32) | req.modifier_lo as u64;
if modifier != INVALID_MODIFIER { match self.modifier.get() {
return Err(AddError::InvalidModifier(modifier)); Some(m) if m != modifier => return Err(AddError::MixedModifiers(modifier, m)),
_ => self.modifier.set(Some(modifier)),
} }
let plane = req.plane_idx; let plane = req.plane_idx;
if plane > MAX_PLANE { if plane > MAX_PLANE {
@ -98,14 +100,21 @@ impl ZwpLinuxBufferParamsV1 {
}; };
let formats = ctx.formats(); let formats = ctx.formats();
let format = match formats.get(&format) { let format = match formats.get(&format) {
Some(f) => *f, Some(f) => f,
None => return Err(DoCreateError::InvalidFormat(format)), None => return Err(DoCreateError::InvalidFormat(format)),
}; };
let modifier = match self.modifier.get() {
Some(m) => m,
_ => return Err(DoCreateError::NoPlanes),
};
if !format.modifiers.contains_key(&modifier) {
return Err(DoCreateError::InvalidModifier(modifier));
}
let mut dmabuf = DmaBuf { let mut dmabuf = DmaBuf {
width, width,
height, height,
format, format: format.format,
modifier: INVALID_MODIFIER, modifier,
planes: vec![], planes: vec![],
}; };
let mut planes: Vec<_> = self.planes.borrow_mut().drain().map(|v| v.1).collect(); let mut planes: Vec<_> = self.planes.borrow_mut().drain().map(|v| v.1).collect();
@ -128,7 +137,7 @@ impl ZwpLinuxBufferParamsV1 {
let buffer = Rc::new(WlBuffer::new_dmabuf( let buffer = Rc::new(WlBuffer::new_dmabuf(
buffer_id, buffer_id,
&self.parent.client, &self.parent.client,
format, format.format,
&img, &img,
)); ));
track!(self.parent.client, buffer); track!(self.parent.client, buffer);
@ -223,8 +232,8 @@ pub enum AddError {
MaxPlane, MaxPlane,
#[error(transparent)] #[error(transparent)]
ClientError(Box<ClientError>), ClientError(Box<ClientError>),
#[error("The modifier {0} is not supported")] #[error("Tried to add a plane with modifier {0} that differs from a previous modifier {1}")]
InvalidModifier(u64), MixedModifiers(u64, u64),
#[error("The plane {0} was already set")] #[error("The plane {0} was already set")]
AlreadySet(u32), AlreadySet(u32),
} }
@ -239,6 +248,10 @@ pub enum DoCreateError {
NoRenderContext, NoRenderContext,
#[error("The format {0} is not supported")] #[error("The format {0} is not supported")]
InvalidFormat(u32), InvalidFormat(u32),
#[error("No planes were added")]
NoPlanes,
#[error("The modifier {0} is not supported")]
InvalidModifier(u64),
#[error("Plane {0} was not set")] #[error("Plane {0} was not set")]
MissingPlane(usize), MissingPlane(usize),
#[error("Could not import the buffer")] #[error("Could not import the buffer")]

View file

@ -6,7 +6,6 @@ use {
leaks::Tracker, leaks::Tracker,
object::Object, object::Object,
utils::buffd::{MsgParser, MsgParserError}, utils::buffd::{MsgParser, MsgParserError},
video::INVALID_MODIFIER,
wire::{zwp_linux_dmabuf_v1::*, ZwpLinuxDmabufV1Id}, wire::{zwp_linux_dmabuf_v1::*, ZwpLinuxDmabufV1Id},
}, },
std::rc::Rc, std::rc::Rc,
@ -39,9 +38,11 @@ impl ZwpLinuxDmabufV1Global {
if let Some(ctx) = client.state.render_ctx.get() { if let Some(ctx) = client.state.render_ctx.get() {
let formats = ctx.formats(); let formats = ctx.formats();
for format in formats.values() { for format in formats.values() {
obj.send_format(format.drm); obj.send_format(format.format.drm);
if version >= MODIFIERS_SINCE_VERSION { if version >= MODIFIERS_SINCE_VERSION {
obj.send_modifier(format.drm, INVALID_MODIFIER); for modifier in format.modifiers.values() {
obj.send_modifier(format.format.drm, modifier.modifier);
}
} }
} }
} }

View file

@ -80,6 +80,8 @@ pub enum RenderError {
SurfacelessContext, SurfacelessContext,
#[error("`eglQueryDmaBufFormatsEXT` failed")] #[error("`eglQueryDmaBufFormatsEXT` failed")]
QueryDmaBufFormats, QueryDmaBufFormats,
#[error("`eglQueryDmaBufModifiersEXT` failed")]
QueryDmaBufModifiers,
#[error(transparent)] #[error(transparent)]
DrmError(#[from] DrmError), DrmError(#[from] DrmError),
#[error("The GLES driver does not support the XRGB8888 format")] #[error("The GLES driver does not support the XRGB8888 format")]

View file

@ -26,16 +26,28 @@ use {
sys::{eglInitialize, EGL_PLATFORM_GBM_KHR}, sys::{eglInitialize, EGL_PLATFORM_GBM_KHR},
RenderError, RenderError,
}, },
video::{dmabuf::DmaBuf, drm::Drm, gbm::GbmDevice, INVALID_MODIFIER}, video::{dmabuf::DmaBuf, drm::Drm, gbm::GbmDevice, INVALID_MODIFIER, LINEAR_MODIFIER},
}, },
ahash::AHashMap, ahash::{AHashMap},
std::{ptr, rc::Rc}, std::{ptr, rc::Rc},
}; };
#[derive(Debug)]
pub struct EglFormat {
pub format: &'static Format,
pub modifiers: AHashMap<u64, EglModifier>,
}
#[derive(Debug)]
pub struct EglModifier {
pub modifier: u64,
pub external_only: bool,
}
#[derive(Debug)] #[derive(Debug)]
pub struct EglDisplay { pub struct EglDisplay {
pub exts: DisplayExt, pub exts: DisplayExt,
pub formats: Rc<AHashMap<u32, &'static Format>>, pub formats: Rc<AHashMap<u32, EglFormat>>,
pub gbm: Rc<GbmDevice>, pub gbm: Rc<GbmDevice>,
pub dpy: EGLDisplay, pub dpy: EGLDisplay,
} }
@ -201,7 +213,7 @@ impl Drop for EglDisplay {
} }
} }
unsafe fn query_formats(dpy: EGLDisplay) -> Result<AHashMap<u32, &'static Format>, RenderError> { unsafe fn query_formats(dpy: EGLDisplay) -> Result<AHashMap<u32, EglFormat>, RenderError> {
let mut vec = vec![]; let mut vec = vec![];
let mut num = 0; let mut num = 0;
let res = PROCS.eglQueryDmaBufFormatsEXT(dpy, num, ptr::null_mut(), &mut num); let res = PROCS.eglQueryDmaBufFormatsEXT(dpy, num, ptr::null_mut(), &mut num);
@ -218,8 +230,73 @@ unsafe fn query_formats(dpy: EGLDisplay) -> Result<AHashMap<u32, &'static Format
let formats = formats(); let formats = formats();
for fmt in vec { for fmt in vec {
if let Some(format) = formats.get(&(fmt as u32)) { if let Some(format) = formats.get(&(fmt as u32)) {
res.insert(format.drm, *format); res.insert(format.drm, EglFormat {
format: *format,
modifiers: query_modifiers(dpy, fmt)?,
});
} }
} }
Ok(res) Ok(res)
} }
unsafe fn query_modifiers(
dpy: EGLDisplay,
format: EGLint,
) -> Result<AHashMap<u64, EglModifier>, RenderError> {
let mut mods = vec![];
let mut ext_only = vec![];
let mut num = 0;
let res = PROCS.eglQueryDmaBufModifiersEXT(
dpy,
format,
num,
ptr::null_mut(),
ptr::null_mut(),
&mut num,
);
if res != EGL_TRUE {
return Err(RenderError::QueryDmaBufModifiers);
}
mods.reserve_exact(num as usize);
ext_only.reserve_exact(num as usize);
let res = PROCS.eglQueryDmaBufModifiersEXT(
dpy,
format,
num,
mods.as_mut_ptr(),
ext_only.as_mut_ptr(),
&mut num,
);
if res != EGL_TRUE {
return Err(RenderError::QueryDmaBufModifiers);
}
mods.set_len(num as usize);
ext_only.set_len(num as usize);
let mut res = AHashMap::new();
res.insert(
INVALID_MODIFIER,
EglModifier {
modifier: INVALID_MODIFIER,
external_only: false,
},
);
if mods.is_empty() {
res.insert(
LINEAR_MODIFIER,
EglModifier {
modifier: LINEAR_MODIFIER,
external_only: false,
},
);
}
for (modifier, ext_only) in mods.iter().copied().zip(ext_only.iter().copied()) {
res.insert(
modifier as _,
EglModifier {
modifier: modifier as _,
external_only: ext_only == EGL_TRUE,
},
);
}
Ok(res)
}

View file

@ -24,6 +24,7 @@ use {
}, },
uapi::ustr, uapi::ustr,
}; };
use crate::render::egl::display::EglFormat;
pub(super) struct TexProg { pub(super) struct TexProg {
pub(super) prog: GlProgram, pub(super) prog: GlProgram,
@ -116,7 +117,7 @@ impl RenderContext {
self.render_node.clone() self.render_node.clone()
} }
pub fn formats(&self) -> Rc<AHashMap<u32, &'static Format>> { pub fn formats(&self) -> Rc<AHashMap<u32, EglFormat>> {
self.ctx.dpy.formats.clone() self.ctx.dpy.formats.clone()
} }

View file

@ -7,7 +7,7 @@ use {
}, },
rect::Rect, rect::Rect,
state::State, state::State,
tree::{Node, SizedNode}, tree::{Node, SizedNode, ToplevelNode},
utils::{bitflags::BitflagsExt, errorfmt::ErrorFmt, linkedlist::LinkedList}, utils::{bitflags::BitflagsExt, errorfmt::ErrorFmt, linkedlist::LinkedList},
wire::WlSurfaceId, wire::WlSurfaceId,
wire_xcon::{ wire_xcon::{
@ -47,7 +47,6 @@ use {
}, },
uapi::OwnedFd, uapi::OwnedFd,
}; };
use crate::tree::{ToplevelNode};
atoms! { atoms! {
Atoms; Atoms;
@ -369,7 +368,9 @@ impl Wm {
XWaylandEvent::Activate(window) => self.activate_window(Some(&window)).await, XWaylandEvent::Activate(window) => self.activate_window(Some(&window)).await,
XWaylandEvent::ActivateRoot => self.activate_window(None).await, XWaylandEvent::ActivateRoot => self.activate_window(None).await,
XWaylandEvent::Close(window) => self.close_window(&window).await, XWaylandEvent::Close(window) => self.close_window(&window).await,
XWaylandEvent::SetFullscreen(window, fullscreen) => self.set_fullscreen(&window, fullscreen).await, XWaylandEvent::SetFullscreen(window, fullscreen) => {
self.set_fullscreen(&window, fullscreen).await
}
} }
} }