autocommit 2022-04-21 18:25:34 CEST
This commit is contained in:
parent
0d414a5336
commit
32fe8b64ca
8 changed files with 133 additions and 28 deletions
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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")]
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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")]
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue