1
0
Fork 0
forked from wry/wry

render: remove supports_external_only

This commit is contained in:
Julian Orth 2023-11-04 12:40:40 +01:00
parent 1500b10de3
commit 283774ae4c
10 changed files with 108 additions and 58 deletions

23
Cargo.lock generated
View file

@ -322,6 +322,12 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.3.5" version = "0.3.5"
@ -386,6 +392,12 @@ version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
[[package]]
name = "hashbrown"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.4.1" version = "0.4.1"
@ -421,6 +433,16 @@ dependencies = [
"cc", "cc",
] ]
[[package]]
name = "indexmap"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]] [[package]]
name = "isnt" name = "isnt"
version = "0.1.0" version = "0.1.0"
@ -447,6 +469,7 @@ dependencies = [
"dirs", "dirs",
"futures-util", "futures-util",
"humantime", "humantime",
"indexmap",
"isnt", "isnt",
"jay-config", "jay-config",
"libloading", "libloading",

View file

@ -42,6 +42,7 @@ backtrace = "0.3.64"
chrono = "0.4.19" chrono = "0.4.19"
parking_lot = "0.12.1" parking_lot = "0.12.1"
arrayvec = "0.7.4" arrayvec = "0.7.4"
indexmap = "2.1.0"
[build-dependencies] [build-dependencies]
repc = "0.1.1" repc = "0.1.1"

View file

@ -42,7 +42,7 @@ impl DrmFeedback {
fn create_fd_data(ctx: &dyn GfxContext) -> Vec<u8> { fn create_fd_data(ctx: &dyn GfxContext) -> Vec<u8> {
let mut vec = vec![]; let mut vec = vec![];
for (format, info) in &*ctx.formats() { for (format, info) in &*ctx.formats() {
for modifier in info.modifiers.keys() { for modifier in &info.modifiers {
vec.write_u32::<NativeEndian>(*format).unwrap(); vec.write_u32::<NativeEndian>(*format).unwrap();
vec.write_u32::<NativeEndian>(0).unwrap(); vec.write_u32::<NativeEndian>(0).unwrap();
vec.write_u64::<NativeEndian>(*modifier).unwrap(); vec.write_u64::<NativeEndian>(*modifier).unwrap();

View file

@ -9,9 +9,10 @@ use {
state::State, state::State,
theme::Color, theme::Color,
tree::Node, tree::Node,
video::{dmabuf::DmaBuf, gbm::GbmDevice}, video::{dmabuf::DmaBuf, gbm::GbmDevice, Modifier},
}, },
ahash::AHashMap, ahash::AHashMap,
indexmap::IndexSet,
std::{ std::{
any::Any, any::Any,
cell::Cell, cell::Cell,
@ -277,8 +278,6 @@ pub trait GfxTexture: Debug {
pub trait GfxContext: Debug { pub trait GfxContext: Debug {
fn reset_status(&self) -> Option<ResetStatus>; fn reset_status(&self) -> Option<ResetStatus>;
fn supports_external_texture(&self) -> bool;
fn render_node(&self) -> Rc<CString>; fn render_node(&self) -> Rc<CString>;
fn formats(&self) -> Rc<AHashMap<u32, GfxFormat>>; fn formats(&self) -> Rc<AHashMap<u32, GfxFormat>>;
@ -302,14 +301,7 @@ pub trait GfxContext: Debug {
#[derive(Debug)] #[derive(Debug)]
pub struct GfxFormat { pub struct GfxFormat {
pub format: &'static Format, pub format: &'static Format,
pub implicit_external_only: bool, pub modifiers: IndexSet<Modifier>,
pub modifiers: AHashMap<u64, GfxModifier>,
}
#[derive(Debug)]
pub struct GfxModifier {
pub modifier: u64,
pub external_only: bool,
} }
#[derive(Error)] #[derive(Error)]

View file

@ -126,6 +126,8 @@ enum RenderError {
ExternalOnly, ExternalOnly,
#[error("OpenGL context does not support external textures")] #[error("OpenGL context does not support external textures")]
ExternalUnsupported, ExternalUnsupported,
#[error("OpenGL context does not support any formats")]
NoSupportedFormats,
} }
#[derive(Default)] #[derive(Default)]

View file

@ -1,6 +1,6 @@
use { use {
crate::{ crate::{
gfx_api::ResetStatus, gfx_api::{GfxFormat, ResetStatus},
gfx_apis::gl::{ gfx_apis::gl::{
egl::{ egl::{
display::EglDisplay, display::EglDisplay,
@ -17,6 +17,7 @@ use {
RenderError, RenderError,
}, },
}, },
ahash::AHashMap,
std::rc::Rc, std::rc::Rc,
}; };
@ -25,6 +26,7 @@ pub struct EglContext {
pub dpy: Rc<EglDisplay>, pub dpy: Rc<EglDisplay>,
pub ext: GlExt, pub ext: GlExt,
pub ctx: EGLContext, pub ctx: EGLContext,
pub formats: Rc<AHashMap<u32, GfxFormat>>,
} }
impl Drop for EglContext { impl Drop for EglContext {

View file

@ -1,7 +1,7 @@
use { use {
crate::{ crate::{
format::{formats, Format}, format::{formats, Format},
gfx_api::{GfxFormat, GfxModifier}, gfx_api::GfxFormat,
gfx_apis::gl::{ gfx_apis::gl::{
egl::{ egl::{
context::EglContext, context::EglContext,
@ -30,16 +30,30 @@ use {
}, },
RenderError, RenderError,
}, },
video::{dmabuf::DmaBuf, drm::Drm, gbm::GbmDevice, INVALID_MODIFIER}, video::{dmabuf::DmaBuf, drm::Drm, gbm::GbmDevice, Modifier, INVALID_MODIFIER},
}, },
ahash::AHashMap, ahash::AHashMap,
indexmap::{IndexMap, IndexSet},
std::{ptr, rc::Rc}, std::{ptr, rc::Rc},
}; };
#[derive(Debug)]
pub struct EglFormat {
pub format: &'static Format,
pub implicit_external_only: bool,
pub modifiers: IndexMap<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, GfxFormat>>, pub formats: AHashMap<u32, EglFormat>,
pub gbm: Rc<GbmDevice>, pub gbm: Rc<GbmDevice>,
pub dpy: EGLDisplay, pub dpy: EGLDisplay,
} }
@ -61,7 +75,7 @@ impl EglDisplay {
} }
let mut dpy = EglDisplay { let mut dpy = EglDisplay {
exts: DisplayExt::empty(), exts: DisplayExt::empty(),
formats: Rc::new(AHashMap::new()), formats: AHashMap::new(),
gbm: Rc::new(gbm), gbm: Rc::new(gbm),
dpy, dpy,
}; };
@ -89,7 +103,7 @@ impl EglDisplay {
if !dpy.exts.intersects(DisplayExt::KHR_SURFACELESS_CONTEXT) { if !dpy.exts.intersects(DisplayExt::KHR_SURFACELESS_CONTEXT) {
return Err(RenderError::SurfacelessContext); return Err(RenderError::SurfacelessContext);
} }
dpy.formats = Rc::new(query_formats(dpy.dpy)?); dpy.formats = query_formats(dpy.dpy)?;
Ok(Rc::new(dpy)) Ok(Rc::new(dpy))
} }
@ -109,27 +123,57 @@ impl EglDisplay {
log::warn!("EGL display does not support gpu reset notifications"); log::warn!("EGL display does not support gpu reset notifications");
} }
attrib.push(EGL_NONE); attrib.push(EGL_NONE);
unsafe { let ctx = unsafe {
let ctx = eglCreateContext( eglCreateContext(
self.dpy, self.dpy,
EGLConfig::none(), EGLConfig::none(),
EGLContext::none(), EGLContext::none(),
attrib.as_ptr(), attrib.as_ptr(),
); )
if ctx.is_none() { };
return Err(RenderError::CreateContext); if ctx.is_none() {
} return Err(RenderError::CreateContext);
let mut ctx = EglContext {
dpy: self.clone(),
ext: GlExt::empty(),
ctx,
};
ctx.ext = ctx.with_current(|| Ok(get_gl_ext()))?;
if !ctx.ext.contains(GlExt::GL_OES_EGL_IMAGE) {
return Err(RenderError::OesEglImage);
}
Ok(Rc::new(ctx))
} }
let mut ctx = EglContext {
dpy: self.clone(),
ext: GlExt::empty(),
ctx,
formats: Default::default(),
};
ctx.ext = ctx.with_current(|| Ok(get_gl_ext()))?;
if !ctx.ext.contains(GlExt::GL_OES_EGL_IMAGE) {
return Err(RenderError::OesEglImage);
}
ctx.formats = {
let mut formats = AHashMap::new();
let supports_external_only = ctx.ext.contains(GlExt::GL_OES_EGL_IMAGE_EXTERNAL);
for (&drm, format) in &self.formats {
if format.implicit_external_only && !supports_external_only {
continue;
}
let mut modifiers = IndexSet::new();
for modifier in format.modifiers.values() {
if modifier.external_only && !supports_external_only {
continue;
}
modifiers.insert(modifier.modifier);
}
if !modifiers.is_empty() {
formats.insert(
drm,
GfxFormat {
format: format.format,
modifiers,
},
);
}
}
Rc::new(formats)
};
if ctx.formats.is_empty() {
return Err(RenderError::NoSupportedFormats);
}
Ok(Rc::new(ctx))
} }
pub(in crate::gfx_apis::gl) fn import_dmabuf( pub(in crate::gfx_apis::gl) fn import_dmabuf(
@ -228,7 +272,7 @@ impl Drop for EglDisplay {
} }
} }
unsafe fn query_formats(dpy: EGLDisplay) -> Result<AHashMap<u32, GfxFormat>, 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);
@ -248,7 +292,7 @@ unsafe fn query_formats(dpy: EGLDisplay) -> Result<AHashMap<u32, GfxFormat>, Ren
let (modifiers, external_only) = query_modifiers(dpy, fmt, format)?; let (modifiers, external_only) = query_modifiers(dpy, fmt, format)?;
res.insert( res.insert(
format.drm, format.drm,
GfxFormat { EglFormat {
format, format,
implicit_external_only: external_only, implicit_external_only: external_only,
modifiers, modifiers,
@ -263,7 +307,7 @@ unsafe fn query_modifiers(
dpy: EGLDisplay, dpy: EGLDisplay,
gl_format: EGLint, gl_format: EGLint,
format: &'static Format, format: &'static Format,
) -> Result<(AHashMap<u64, GfxModifier>, bool), RenderError> { ) -> Result<(IndexMap<Modifier, EglModifier>, bool), RenderError> {
let mut mods = vec![]; let mut mods = vec![];
let mut ext_only = vec![]; let mut ext_only = vec![];
let mut num = 0; let mut num = 0;
@ -293,11 +337,11 @@ unsafe fn query_modifiers(
} }
mods.set_len(num as usize); mods.set_len(num as usize);
ext_only.set_len(num as usize); ext_only.set_len(num as usize);
let mut res = AHashMap::new(); let mut res = IndexMap::new();
for (modifier, ext_only) in mods.iter().copied().zip(ext_only.iter().copied()) { for (modifier, ext_only) in mods.iter().copied().zip(ext_only.iter().copied()) {
res.insert( res.insert(
modifier as _, modifier as _,
GfxModifier { EglModifier {
modifier: modifier as _, modifier: modifier as _,
external_only: ext_only == EGL_TRUE, external_only: ext_only == EGL_TRUE,
}, },
@ -309,7 +353,7 @@ unsafe fn query_modifiers(
} }
res.insert( res.insert(
INVALID_MODIFIER, INVALID_MODIFIER,
GfxModifier { EglModifier {
modifier: INVALID_MODIFIER, modifier: INVALID_MODIFIER,
external_only, external_only,
}, },

View file

@ -81,10 +81,6 @@ impl GlRenderContext {
self.ctx.reset_status() self.ctx.reset_status()
} }
pub fn supports_external_texture(&self) -> bool {
self.ctx.ext.contains(GlExt::GL_OES_EGL_IMAGE_EXTERNAL)
}
pub(in crate::gfx_apis::gl) fn from_drm_device(drm: &Drm) -> Result<Self, RenderError> { pub(in crate::gfx_apis::gl) fn from_drm_device(drm: &Drm) -> Result<Self, RenderError> {
let nodes = drm.get_nodes()?; let nodes = drm.get_nodes()?;
let node = match nodes let node = match nodes
@ -160,7 +156,7 @@ impl GlRenderContext {
} }
pub fn formats(&self) -> Rc<AHashMap<u32, GfxFormat>> { pub fn formats(&self) -> Rc<AHashMap<u32, GfxFormat>> {
self.ctx.dpy.formats.clone() self.ctx.formats.clone()
} }
fn dmabuf_fb(self: &Rc<Self>, buf: &DmaBuf) -> Result<Rc<Framebuffer>, RenderError> { fn dmabuf_fb(self: &Rc<Self>, buf: &DmaBuf) -> Result<Rc<Framebuffer>, RenderError> {
@ -206,10 +202,6 @@ impl GfxContext for GlRenderContext {
self.reset_status() self.reset_status()
} }
fn supports_external_texture(&self) -> bool {
self.supports_external_texture()
}
fn render_node(&self) -> Rc<CString> { fn render_node(&self) -> Rc<CString> {
self.render_node() self.render_node()
} }

View file

@ -110,7 +110,7 @@ impl ZwpLinuxBufferParamsV1 {
Some(m) => m, Some(m) => m,
_ => return Err(ZwpLinuxBufferParamsV1Error::NoPlanes), _ => return Err(ZwpLinuxBufferParamsV1Error::NoPlanes),
}; };
if !format.modifiers.contains_key(&modifier) { if !format.modifiers.contains(&modifier) {
return Err(ZwpLinuxBufferParamsV1Error::InvalidModifier(modifier)); return Err(ZwpLinuxBufferParamsV1Error::InvalidModifier(modifier));
} }
let mut dmabuf = DmaBuf { let mut dmabuf = DmaBuf {

View file

@ -42,16 +42,10 @@ 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() {
if format.implicit_external_only && !ctx.supports_external_texture() {
continue;
}
obj.send_format(format.format.drm); obj.send_format(format.format.drm);
if version >= MODIFIERS_SINCE_VERSION { if version >= MODIFIERS_SINCE_VERSION {
for modifier in format.modifiers.values() { for &modifier in &format.modifiers {
if modifier.external_only && !ctx.supports_external_texture() { obj.send_modifier(format.format.drm, modifier);
continue;
}
obj.send_modifier(format.format.drm, modifier.modifier);
} }
} }
} }