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",
|
"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",
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue