render: remove supports_external_only
This commit is contained in:
parent
1500b10de3
commit
283774ae4c
10 changed files with 108 additions and 58 deletions
23
Cargo.lock
generated
23
Cargo.lock
generated
|
|
@ -322,6 +322,12 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.5"
|
||||
|
|
@ -386,6 +392,12 @@ version = "0.28.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
|
|
@ -421,6 +433,16 @@ dependencies = [
|
|||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "isnt"
|
||||
version = "0.1.0"
|
||||
|
|
@ -447,6 +469,7 @@ dependencies = [
|
|||
"dirs",
|
||||
"futures-util",
|
||||
"humantime",
|
||||
"indexmap",
|
||||
"isnt",
|
||||
"jay-config",
|
||||
"libloading",
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ backtrace = "0.3.64"
|
|||
chrono = "0.4.19"
|
||||
parking_lot = "0.12.1"
|
||||
arrayvec = "0.7.4"
|
||||
indexmap = "2.1.0"
|
||||
|
||||
[build-dependencies]
|
||||
repc = "0.1.1"
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ impl DrmFeedback {
|
|||
fn create_fd_data(ctx: &dyn GfxContext) -> Vec<u8> {
|
||||
let mut vec = vec![];
|
||||
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>(0).unwrap();
|
||||
vec.write_u64::<NativeEndian>(*modifier).unwrap();
|
||||
|
|
|
|||
|
|
@ -9,9 +9,10 @@ use {
|
|||
state::State,
|
||||
theme::Color,
|
||||
tree::Node,
|
||||
video::{dmabuf::DmaBuf, gbm::GbmDevice},
|
||||
video::{dmabuf::DmaBuf, gbm::GbmDevice, Modifier},
|
||||
},
|
||||
ahash::AHashMap,
|
||||
indexmap::IndexSet,
|
||||
std::{
|
||||
any::Any,
|
||||
cell::Cell,
|
||||
|
|
@ -277,8 +278,6 @@ pub trait GfxTexture: Debug {
|
|||
pub trait GfxContext: Debug {
|
||||
fn reset_status(&self) -> Option<ResetStatus>;
|
||||
|
||||
fn supports_external_texture(&self) -> bool;
|
||||
|
||||
fn render_node(&self) -> Rc<CString>;
|
||||
|
||||
fn formats(&self) -> Rc<AHashMap<u32, GfxFormat>>;
|
||||
|
|
@ -302,14 +301,7 @@ pub trait GfxContext: Debug {
|
|||
#[derive(Debug)]
|
||||
pub struct GfxFormat {
|
||||
pub format: &'static Format,
|
||||
pub implicit_external_only: bool,
|
||||
pub modifiers: AHashMap<u64, GfxModifier>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GfxModifier {
|
||||
pub modifier: u64,
|
||||
pub external_only: bool,
|
||||
pub modifiers: IndexSet<Modifier>,
|
||||
}
|
||||
|
||||
#[derive(Error)]
|
||||
|
|
|
|||
|
|
@ -126,6 +126,8 @@ enum RenderError {
|
|||
ExternalOnly,
|
||||
#[error("OpenGL context does not support external textures")]
|
||||
ExternalUnsupported,
|
||||
#[error("OpenGL context does not support any formats")]
|
||||
NoSupportedFormats,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use {
|
||||
crate::{
|
||||
gfx_api::ResetStatus,
|
||||
gfx_api::{GfxFormat, ResetStatus},
|
||||
gfx_apis::gl::{
|
||||
egl::{
|
||||
display::EglDisplay,
|
||||
|
|
@ -17,6 +17,7 @@ use {
|
|||
RenderError,
|
||||
},
|
||||
},
|
||||
ahash::AHashMap,
|
||||
std::rc::Rc,
|
||||
};
|
||||
|
||||
|
|
@ -25,6 +26,7 @@ pub struct EglContext {
|
|||
pub dpy: Rc<EglDisplay>,
|
||||
pub ext: GlExt,
|
||||
pub ctx: EGLContext,
|
||||
pub formats: Rc<AHashMap<u32, GfxFormat>>,
|
||||
}
|
||||
|
||||
impl Drop for EglContext {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use {
|
||||
crate::{
|
||||
format::{formats, Format},
|
||||
gfx_api::{GfxFormat, GfxModifier},
|
||||
gfx_api::GfxFormat,
|
||||
gfx_apis::gl::{
|
||||
egl::{
|
||||
context::EglContext,
|
||||
|
|
@ -30,16 +30,30 @@ use {
|
|||
},
|
||||
RenderError,
|
||||
},
|
||||
video::{dmabuf::DmaBuf, drm::Drm, gbm::GbmDevice, INVALID_MODIFIER},
|
||||
video::{dmabuf::DmaBuf, drm::Drm, gbm::GbmDevice, Modifier, INVALID_MODIFIER},
|
||||
},
|
||||
ahash::AHashMap,
|
||||
indexmap::{IndexMap, IndexSet},
|
||||
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)]
|
||||
pub struct EglDisplay {
|
||||
pub exts: DisplayExt,
|
||||
pub formats: Rc<AHashMap<u32, GfxFormat>>,
|
||||
pub formats: AHashMap<u32, EglFormat>,
|
||||
pub gbm: Rc<GbmDevice>,
|
||||
pub dpy: EGLDisplay,
|
||||
}
|
||||
|
|
@ -61,7 +75,7 @@ impl EglDisplay {
|
|||
}
|
||||
let mut dpy = EglDisplay {
|
||||
exts: DisplayExt::empty(),
|
||||
formats: Rc::new(AHashMap::new()),
|
||||
formats: AHashMap::new(),
|
||||
gbm: Rc::new(gbm),
|
||||
dpy,
|
||||
};
|
||||
|
|
@ -89,7 +103,7 @@ impl EglDisplay {
|
|||
if !dpy.exts.intersects(DisplayExt::KHR_SURFACELESS_CONTEXT) {
|
||||
return Err(RenderError::SurfacelessContext);
|
||||
}
|
||||
dpy.formats = Rc::new(query_formats(dpy.dpy)?);
|
||||
dpy.formats = query_formats(dpy.dpy)?;
|
||||
|
||||
Ok(Rc::new(dpy))
|
||||
}
|
||||
|
|
@ -109,27 +123,57 @@ impl EglDisplay {
|
|||
log::warn!("EGL display does not support gpu reset notifications");
|
||||
}
|
||||
attrib.push(EGL_NONE);
|
||||
unsafe {
|
||||
let ctx = eglCreateContext(
|
||||
let ctx = unsafe {
|
||||
eglCreateContext(
|
||||
self.dpy,
|
||||
EGLConfig::none(),
|
||||
EGLContext::none(),
|
||||
attrib.as_ptr(),
|
||||
);
|
||||
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))
|
||||
)
|
||||
};
|
||||
if ctx.is_none() {
|
||||
return Err(RenderError::CreateContext);
|
||||
}
|
||||
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(
|
||||
|
|
@ -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 num = 0;
|
||||
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)?;
|
||||
res.insert(
|
||||
format.drm,
|
||||
GfxFormat {
|
||||
EglFormat {
|
||||
format,
|
||||
implicit_external_only: external_only,
|
||||
modifiers,
|
||||
|
|
@ -263,7 +307,7 @@ unsafe fn query_modifiers(
|
|||
dpy: EGLDisplay,
|
||||
gl_format: EGLint,
|
||||
format: &'static Format,
|
||||
) -> Result<(AHashMap<u64, GfxModifier>, bool), RenderError> {
|
||||
) -> Result<(IndexMap<Modifier, EglModifier>, bool), RenderError> {
|
||||
let mut mods = vec![];
|
||||
let mut ext_only = vec![];
|
||||
let mut num = 0;
|
||||
|
|
@ -293,11 +337,11 @@ unsafe fn query_modifiers(
|
|||
}
|
||||
mods.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()) {
|
||||
res.insert(
|
||||
modifier as _,
|
||||
GfxModifier {
|
||||
EglModifier {
|
||||
modifier: modifier as _,
|
||||
external_only: ext_only == EGL_TRUE,
|
||||
},
|
||||
|
|
@ -309,7 +353,7 @@ unsafe fn query_modifiers(
|
|||
}
|
||||
res.insert(
|
||||
INVALID_MODIFIER,
|
||||
GfxModifier {
|
||||
EglModifier {
|
||||
modifier: INVALID_MODIFIER,
|
||||
external_only,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -81,10 +81,6 @@ impl GlRenderContext {
|
|||
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> {
|
||||
let nodes = drm.get_nodes()?;
|
||||
let node = match nodes
|
||||
|
|
@ -160,7 +156,7 @@ impl GlRenderContext {
|
|||
}
|
||||
|
||||
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> {
|
||||
|
|
@ -206,10 +202,6 @@ impl GfxContext for GlRenderContext {
|
|||
self.reset_status()
|
||||
}
|
||||
|
||||
fn supports_external_texture(&self) -> bool {
|
||||
self.supports_external_texture()
|
||||
}
|
||||
|
||||
fn render_node(&self) -> Rc<CString> {
|
||||
self.render_node()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ impl ZwpLinuxBufferParamsV1 {
|
|||
Some(m) => m,
|
||||
_ => return Err(ZwpLinuxBufferParamsV1Error::NoPlanes),
|
||||
};
|
||||
if !format.modifiers.contains_key(&modifier) {
|
||||
if !format.modifiers.contains(&modifier) {
|
||||
return Err(ZwpLinuxBufferParamsV1Error::InvalidModifier(modifier));
|
||||
}
|
||||
let mut dmabuf = DmaBuf {
|
||||
|
|
|
|||
|
|
@ -42,16 +42,10 @@ impl ZwpLinuxDmabufV1Global {
|
|||
if let Some(ctx) = client.state.render_ctx.get() {
|
||||
let formats = ctx.formats();
|
||||
for format in formats.values() {
|
||||
if format.implicit_external_only && !ctx.supports_external_texture() {
|
||||
continue;
|
||||
}
|
||||
obj.send_format(format.format.drm);
|
||||
if version >= MODIFIERS_SINCE_VERSION {
|
||||
for modifier in format.modifiers.values() {
|
||||
if modifier.external_only && !ctx.supports_external_texture() {
|
||||
continue;
|
||||
}
|
||||
obj.send_modifier(format.format.drm, modifier.modifier);
|
||||
for &modifier in &format.modifiers {
|
||||
obj.send_modifier(format.format.drm, modifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue