allocator: don't require render usage for bridged buffers
This commit is contained in:
parent
1bacaa7b02
commit
bf65da4c76
15 changed files with 152 additions and 54 deletions
|
|
@ -12,8 +12,8 @@ use {
|
||||||
edid::Descriptor,
|
edid::Descriptor,
|
||||||
format::{Format, ARGB8888, XRGB8888},
|
format::{Format, ARGB8888, XRGB8888},
|
||||||
gfx_api::{
|
gfx_api::{
|
||||||
AcquireSync, BufferResv, GfxApiOpt, GfxContext, GfxFramebuffer, GfxRenderPass,
|
needs_render_usage, AcquireSync, BufferResv, GfxApiOpt, GfxContext, GfxFramebuffer,
|
||||||
GfxTexture, ReleaseSync, SyncFile,
|
GfxRenderPass, GfxTexture, ReleaseSync, SyncFile,
|
||||||
},
|
},
|
||||||
ifs::{
|
ifs::{
|
||||||
wl_output::OutputId,
|
wl_output::OutputId,
|
||||||
|
|
@ -46,7 +46,7 @@ use {
|
||||||
ahash::{AHashMap, AHashSet},
|
ahash::{AHashMap, AHashSet},
|
||||||
arrayvec::ArrayVec,
|
arrayvec::ArrayVec,
|
||||||
bstr::{BString, ByteSlice},
|
bstr::{BString, ByteSlice},
|
||||||
indexmap::{indexset, IndexSet},
|
indexmap::{indexset, IndexMap, IndexSet},
|
||||||
isnt::std_1::collections::IsntHashMap2Ext,
|
isnt::std_1::collections::IsntHashMap2Ext,
|
||||||
jay_config::video::GfxApi,
|
jay_config::video::GfxApi,
|
||||||
once_cell::sync::Lazy,
|
once_cell::sync::Lazy,
|
||||||
|
|
@ -2853,18 +2853,24 @@ impl MetalBackend {
|
||||||
None => return Err(MetalError::MissingDevFormat(format.name)),
|
None => return Err(MetalError::MissingDevFormat(format.name)),
|
||||||
Some(f) => f,
|
Some(f) => f,
|
||||||
};
|
};
|
||||||
let possible_modifiers: Vec<_> = dev_gfx_format
|
let possible_modifiers: IndexMap<_, _> = dev_gfx_format
|
||||||
.write_modifiers
|
.write_modifiers
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|m| plane_modifiers.contains(*m))
|
.filter(|(m, _)| plane_modifiers.contains(*m))
|
||||||
.copied()
|
.map(|(m, v)| (*m, v))
|
||||||
.collect();
|
.collect();
|
||||||
if possible_modifiers.is_empty() {
|
if possible_modifiers.is_empty() {
|
||||||
log::warn!("Scanout modifiers: {:?}", plane_modifiers);
|
log::warn!("Scanout modifiers: {:?}", plane_modifiers);
|
||||||
log::warn!("DEV GFX modifiers: {:?}", dev_gfx_format.write_modifiers);
|
log::warn!(
|
||||||
|
"DEV GFX modifiers: {:?}",
|
||||||
|
dev_gfx_format.write_modifiers.keys()
|
||||||
|
);
|
||||||
return Err(MetalError::MissingDevModifier(format.name));
|
return Err(MetalError::MissingDevModifier(format.name));
|
||||||
}
|
}
|
||||||
let mut usage = GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT;
|
let mut usage = GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT;
|
||||||
|
if !needs_render_usage(possible_modifiers.values().copied()) {
|
||||||
|
usage &= !GBM_BO_USE_RENDERING;
|
||||||
|
}
|
||||||
if cursor {
|
if cursor {
|
||||||
usage |= GBM_BO_USE_LINEAR;
|
usage |= GBM_BO_USE_LINEAR;
|
||||||
};
|
};
|
||||||
|
|
@ -2873,7 +2879,7 @@ impl MetalBackend {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
format,
|
format,
|
||||||
&possible_modifiers,
|
possible_modifiers.keys(),
|
||||||
usage,
|
usage,
|
||||||
);
|
);
|
||||||
let dev_bo = match dev_bo {
|
let dev_bo = match dev_bo {
|
||||||
|
|
@ -2906,27 +2912,30 @@ impl MetalBackend {
|
||||||
None => return Err(MetalError::MissingRenderFormat(format.name)),
|
None => return Err(MetalError::MissingRenderFormat(format.name)),
|
||||||
Some(f) => f,
|
Some(f) => f,
|
||||||
};
|
};
|
||||||
let possible_modifiers: Vec<_> = render_gfx_format
|
let possible_modifiers: IndexMap<_, _> = render_gfx_format
|
||||||
.write_modifiers
|
.write_modifiers
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|m| dev_gfx_format.read_modifiers.contains(*m))
|
.filter(|(m, _)| dev_gfx_format.read_modifiers.contains(*m))
|
||||||
.copied()
|
.map(|(m, v)| (*m, v))
|
||||||
.collect();
|
.collect();
|
||||||
if possible_modifiers.is_empty() {
|
if possible_modifiers.is_empty() {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"Render GFX modifiers: {:?}",
|
"Render GFX modifiers: {:?}",
|
||||||
render_gfx_format.write_modifiers
|
render_gfx_format.write_modifiers.keys()
|
||||||
);
|
);
|
||||||
log::warn!("DEV GFX modifiers: {:?}", dev_gfx_format.read_modifiers);
|
log::warn!("DEV GFX modifiers: {:?}", dev_gfx_format.read_modifiers);
|
||||||
return Err(MetalError::MissingRenderModifier(format.name));
|
return Err(MetalError::MissingRenderModifier(format.name));
|
||||||
}
|
}
|
||||||
usage = GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR;
|
usage = GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR;
|
||||||
|
if !needs_render_usage(possible_modifiers.values().copied()) {
|
||||||
|
usage &= !GBM_BO_USE_RENDERING;
|
||||||
|
}
|
||||||
let render_bo = render_ctx.gbm.create_bo(
|
let render_bo = render_ctx.gbm.create_bo(
|
||||||
&self.state.dma_buf_ids,
|
&self.state.dma_buf_ids,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
format,
|
format,
|
||||||
&possible_modifiers,
|
possible_modifiers.keys(),
|
||||||
usage,
|
usage,
|
||||||
);
|
);
|
||||||
let render_bo = match render_bo {
|
let render_bo = match render_bo {
|
||||||
|
|
|
||||||
|
|
@ -389,7 +389,7 @@ impl XBackend {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
XRGB8888,
|
XRGB8888,
|
||||||
&format.write_modifiers,
|
format.write_modifiers.keys(),
|
||||||
GBM_BO_USE_RENDERING,
|
GBM_BO_USE_RENDERING,
|
||||||
)?;
|
)?;
|
||||||
let dma = bo.dmabuf();
|
let dma = bo.dmabuf();
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ use {
|
||||||
video::{dmabuf::DmaBuf, drm::sync_obj::SyncObjCtx, Modifier},
|
video::{dmabuf::DmaBuf, drm::sync_obj::SyncObjCtx, Modifier},
|
||||||
},
|
},
|
||||||
ahash::AHashMap,
|
ahash::AHashMap,
|
||||||
indexmap::IndexSet,
|
indexmap::{IndexMap, IndexSet},
|
||||||
jay_config::video::{GfxApi, Transform},
|
jay_config::video::{GfxApi, Transform},
|
||||||
std::{
|
std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
|
|
@ -570,11 +570,20 @@ pub trait GfxContext: Debug {
|
||||||
fn sync_obj_ctx(&self) -> Option<&Rc<SyncObjCtx>>;
|
fn sync_obj_ctx(&self) -> Option<&Rc<SyncObjCtx>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct GfxWriteModifier {
|
||||||
|
pub needs_render_usage: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn needs_render_usage<'a>(mut modifiers: impl Iterator<Item = &'a GfxWriteModifier>) -> bool {
|
||||||
|
modifiers.any(|m| m.needs_render_usage)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GfxFormat {
|
pub struct GfxFormat {
|
||||||
pub format: &'static Format,
|
pub format: &'static Format,
|
||||||
pub read_modifiers: IndexSet<Modifier>,
|
pub read_modifiers: IndexSet<Modifier>,
|
||||||
pub write_modifiers: IndexSet<Modifier>,
|
pub write_modifiers: IndexMap<Modifier, GfxWriteModifier>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error)]
|
#[derive(Error)]
|
||||||
|
|
@ -594,13 +603,15 @@ impl GfxFormat {
|
||||||
format: self.format,
|
format: self.format,
|
||||||
read_modifiers: self
|
read_modifiers: self
|
||||||
.read_modifiers
|
.read_modifiers
|
||||||
.intersection(&other.write_modifiers)
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
|
.filter(|m| other.write_modifiers.contains_key(m))
|
||||||
.collect(),
|
.collect(),
|
||||||
write_modifiers: self
|
write_modifiers: self
|
||||||
.write_modifiers
|
.write_modifiers
|
||||||
.intersection(&other.read_modifiers)
|
.iter()
|
||||||
.copied()
|
.map(|(m, v)| (*m, v.clone()))
|
||||||
|
.filter(|(m, _)| other.read_modifiers.contains(m))
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
format::{formats, Format},
|
format::{formats, Format},
|
||||||
gfx_api::GfxFormat,
|
gfx_api::{GfxFormat, GfxWriteModifier},
|
||||||
gfx_apis::gl::{
|
gfx_apis::gl::{
|
||||||
egl::{
|
egl::{
|
||||||
context::EglContext,
|
context::EglContext,
|
||||||
|
|
@ -173,13 +173,18 @@ impl EglDisplay {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let mut read_modifiers = IndexSet::new();
|
let mut read_modifiers = IndexSet::new();
|
||||||
let mut write_modifiers = IndexSet::new();
|
let mut write_modifiers = IndexMap::new();
|
||||||
for modifier in format.modifiers.values() {
|
for modifier in format.modifiers.values() {
|
||||||
if modifier.external_only && !supports_external_only {
|
if modifier.external_only && !supports_external_only {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if !modifier.external_only {
|
if !modifier.external_only {
|
||||||
write_modifiers.insert(modifier.modifier);
|
write_modifiers.insert(
|
||||||
|
modifier.modifier,
|
||||||
|
GfxWriteModifier {
|
||||||
|
needs_render_usage: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
read_modifiers.insert(modifier.modifier);
|
read_modifiers.insert(modifier.modifier);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use {
|
||||||
format::{Format, XRGB8888},
|
format::{Format, XRGB8888},
|
||||||
gfx_api::{
|
gfx_api::{
|
||||||
AcquireSync, BufferResv, BufferResvUser, GfxApiOpt, GfxFormat, GfxFramebuffer,
|
AcquireSync, BufferResv, BufferResvUser, GfxApiOpt, GfxFormat, GfxFramebuffer,
|
||||||
GfxTexture, ReleaseSync, SyncFile,
|
GfxTexture, GfxWriteModifier, ReleaseSync, SyncFile,
|
||||||
},
|
},
|
||||||
gfx_apis::vulkan::{
|
gfx_apis::vulkan::{
|
||||||
allocator::VulkanAllocator,
|
allocator::VulkanAllocator,
|
||||||
|
|
@ -158,7 +158,14 @@ impl VulkanDevice {
|
||||||
.modifiers
|
.modifiers
|
||||||
.values()
|
.values()
|
||||||
.filter(|m| m.render_limits.is_some())
|
.filter(|m| m.render_limits.is_some())
|
||||||
.map(|m| m.modifier)
|
.map(|m| {
|
||||||
|
(
|
||||||
|
m.modifier,
|
||||||
|
GfxWriteModifier {
|
||||||
|
needs_render_usage: !m.render_needs_bridge,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ impl Global for JayCompositorGlobal {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn version(&self) -> u32 {
|
fn version(&self) -> u32 {
|
||||||
8
|
9
|
||||||
}
|
}
|
||||||
|
|
||||||
fn required_caps(&self) -> ClientCaps {
|
fn required_caps(&self) -> ClientCaps {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ use {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const FORMATS_SINCE: Version = Version(7);
|
pub const FORMATS_SINCE: Version = Version(7);
|
||||||
|
pub const WRITE_MODIFIER_2_SINCE: Version = Version(9);
|
||||||
|
|
||||||
pub struct JayRenderCtx {
|
pub struct JayRenderCtx {
|
||||||
pub id: JayRenderCtxId,
|
pub id: JayRenderCtxId,
|
||||||
|
|
@ -30,12 +31,21 @@ impl JayRenderCtx {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
format: format.format.drm,
|
format: format.format.drm,
|
||||||
});
|
});
|
||||||
for modifier in &format.write_modifiers {
|
for (modifier, gwm) in &format.write_modifiers {
|
||||||
self.client.event(WriteModifier {
|
if self.version >= WRITE_MODIFIER_2_SINCE {
|
||||||
self_id: self.id,
|
self.client.event(WriteModifier2 {
|
||||||
format: format.format.drm,
|
self_id: self.id,
|
||||||
modifier: *modifier,
|
format: format.format.drm,
|
||||||
});
|
modifier: *modifier,
|
||||||
|
needs_render_usage: gwm.needs_render_usage as _,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
self.client.event(WriteModifier {
|
||||||
|
self_id: self.id,
|
||||||
|
format: format.format.drm,
|
||||||
|
modifier: *modifier,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for modifier in &format.read_modifiers {
|
for modifier in &format.read_modifiers {
|
||||||
self.client.event(ReadModifier {
|
self.client.event(ReadModifier {
|
||||||
|
|
|
||||||
|
|
@ -414,10 +414,10 @@ impl JayScreencast {
|
||||||
}
|
}
|
||||||
let mut usage = BO_USE_RENDERING;
|
let mut usage = BO_USE_RENDERING;
|
||||||
let modifiers = match self.linear.get() {
|
let modifiers = match self.linear.get() {
|
||||||
true if format.write_modifiers.contains(&LINEAR_MODIFIER) => {
|
true if format.write_modifiers.contains_key(&LINEAR_MODIFIER) => {
|
||||||
vec![LINEAR_MODIFIER]
|
vec![LINEAR_MODIFIER]
|
||||||
}
|
}
|
||||||
true if format.write_modifiers.contains(&INVALID_MODIFIER) => {
|
true if format.write_modifiers.contains_key(&INVALID_MODIFIER) => {
|
||||||
usage |= BO_USE_LINEAR;
|
usage |= BO_USE_LINEAR;
|
||||||
vec![INVALID_MODIFIER]
|
vec![INVALID_MODIFIER]
|
||||||
}
|
}
|
||||||
|
|
@ -425,7 +425,7 @@ impl JayScreencast {
|
||||||
false if format.write_modifiers.is_empty() => {
|
false if format.write_modifiers.is_empty() => {
|
||||||
return Err(JayScreencastError::XRGB8888Writing)
|
return Err(JayScreencastError::XRGB8888Writing)
|
||||||
}
|
}
|
||||||
false => format.write_modifiers.iter().copied().collect(),
|
false => format.write_modifiers.keys().copied().collect(),
|
||||||
};
|
};
|
||||||
let buffer = ctx.allocator().create_bo(
|
let buffer = ctx.allocator().create_bo(
|
||||||
&self.client.state.dma_buf_ids,
|
&self.client.state.dma_buf_ids,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use {
|
||||||
format::{Format, ARGB8888, XRGB8888},
|
format::{Format, ARGB8888, XRGB8888},
|
||||||
gfx_api::{
|
gfx_api::{
|
||||||
CopyTexture, FillRect, FramebufferRect, GfxApiOpt, GfxContext, GfxError, GfxFormat,
|
CopyTexture, FillRect, FramebufferRect, GfxApiOpt, GfxContext, GfxError, GfxFormat,
|
||||||
GfxFramebuffer, GfxImage, GfxTexture, ResetStatus, SyncFile,
|
GfxFramebuffer, GfxImage, GfxTexture, GfxWriteModifier, ResetStatus, SyncFile,
|
||||||
},
|
},
|
||||||
rect::Rect,
|
rect::Rect,
|
||||||
theme::Color,
|
theme::Color,
|
||||||
|
|
@ -55,7 +55,18 @@ impl TestGfxCtx {
|
||||||
GfxFormat {
|
GfxFormat {
|
||||||
format: f,
|
format: f,
|
||||||
read_modifiers: modifiers.clone(),
|
read_modifiers: modifiers.clone(),
|
||||||
write_modifiers: modifiers.clone(),
|
write_modifiers: modifiers
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.map(|m| {
|
||||||
|
(
|
||||||
|
m,
|
||||||
|
GfxWriteModifier {
|
||||||
|
needs_render_usage: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -323,7 +323,7 @@ fn finish_display_connect(dpy: Rc<PortalDisplayPrelude>) {
|
||||||
con: dpy.con.clone(),
|
con: dpy.con.clone(),
|
||||||
owner: Default::default(),
|
owner: Default::default(),
|
||||||
caps: Default::default(),
|
caps: Default::default(),
|
||||||
version: Version(version.min(7)),
|
version: Version(version.min(9)),
|
||||||
});
|
});
|
||||||
dpy.con.add_object(jc.clone());
|
dpy.con.add_object(jc.clone());
|
||||||
dpy.registry.request_bind(name, jc.version.0, jc.deref());
|
dpy.registry.request_bind(name, jc.version.0, jc.deref());
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ mod screencast_gui;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
allocator::{AllocatorError, BufferObject, BO_USE_RENDERING},
|
allocator::{AllocatorError, BufferObject, BufferUsage, BO_USE_RENDERING},
|
||||||
dbus::{prelude::Variant, DbusObject, DictEntry, DynamicType, PendingReply},
|
dbus::{prelude::Variant, DbusObject, DictEntry, DynamicType, PendingReply},
|
||||||
format::{Format, XRGB8888},
|
format::{Format, XRGB8888},
|
||||||
ifs::jay_screencast::CLIENT_BUFFERS_SINCE,
|
ifs::jay_screencast::CLIENT_BUFFERS_SINCE,
|
||||||
|
|
@ -204,7 +204,7 @@ impl PwClientNodeOwner for StartingScreencast {
|
||||||
}
|
}
|
||||||
let ptl_format = PwClientNodePortSupportedFormat {
|
let ptl_format = PwClientNodePortSupportedFormat {
|
||||||
format: format.format,
|
format: format.format,
|
||||||
modifiers: format.write_modifiers.iter().copied().collect(),
|
modifiers: format.write_modifiers.keys().copied().collect(),
|
||||||
};
|
};
|
||||||
supported_formats.formats.push(ptl_format);
|
supported_formats.formats.push(ptl_format);
|
||||||
}
|
}
|
||||||
|
|
@ -380,13 +380,28 @@ impl StartedScreencast {
|
||||||
let Some(ctx) = self.dpy.render_ctx.get() else {
|
let Some(ctx) = self.dpy.render_ctx.get() else {
|
||||||
return Err(BufferAllocationError::NoRenderContext);
|
return Err(BufferAllocationError::NoRenderContext);
|
||||||
};
|
};
|
||||||
|
let mut usage = BO_USE_RENDERING;
|
||||||
|
if let Some(sf) = &ctx.server_formats {
|
||||||
|
if let Some(format) = sf.get(&format.drm) {
|
||||||
|
let no_render_usage = modifiers.iter().all(|m| {
|
||||||
|
format
|
||||||
|
.write_modifiers
|
||||||
|
.get(m)
|
||||||
|
.map(|w| !w.needs_render_usage)
|
||||||
|
.unwrap_or(false)
|
||||||
|
});
|
||||||
|
if no_render_usage {
|
||||||
|
usage = BufferUsage::none();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
let buffer = ctx.ctx.ctx.allocator().create_bo(
|
let buffer = ctx.ctx.ctx.allocator().create_bo(
|
||||||
&self.dpy.state.dma_buf_ids,
|
&self.dpy.state.dma_buf_ids,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
format,
|
format,
|
||||||
modifiers,
|
modifiers,
|
||||||
BO_USE_RENDERING,
|
usage,
|
||||||
)?;
|
)?;
|
||||||
Ok(buffer)
|
Ok(buffer)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
allocator::{BufferObject, BO_USE_RENDERING},
|
allocator::{BufferObject, BufferUsage, BO_USE_RENDERING},
|
||||||
async_engine::{Phase, SpawnedFuture},
|
async_engine::{Phase, SpawnedFuture},
|
||||||
cursor::KnownCursor,
|
cursor::KnownCursor,
|
||||||
fixed::Fixed,
|
fixed::Fixed,
|
||||||
format::ARGB8888,
|
format::ARGB8888,
|
||||||
gfx_api::{AcquireSync, GfxContext, GfxFramebuffer, ReleaseSync},
|
gfx_api::{needs_render_usage, AcquireSync, GfxContext, GfxFramebuffer, ReleaseSync},
|
||||||
ifs::zwlr_layer_shell_v1::OVERLAY,
|
ifs::zwlr_layer_shell_v1::OVERLAY,
|
||||||
portal::ptl_display::{PortalDisplay, PortalOutput, PortalSeat},
|
portal::ptl_display::{PortalDisplay, PortalOutput, PortalSeat},
|
||||||
renderer::renderer_base::RendererBase,
|
renderer::renderer_base::RendererBase,
|
||||||
|
|
@ -723,7 +723,11 @@ impl WindowData {
|
||||||
log::error!("Render context cannot render to ARGB8888 format");
|
log::error!("Render context cannot render to ARGB8888 format");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let modifiers: Vec<_> = format.write_modifiers.iter().copied().collect();
|
let modifiers: Vec<_> = format.write_modifiers.keys().copied().collect();
|
||||||
|
let mut usage = BO_USE_RENDERING;
|
||||||
|
if !needs_render_usage(format.write_modifiers.values()) {
|
||||||
|
usage = BufferUsage::none();
|
||||||
|
}
|
||||||
for _ in 0..NUM_BUFFERS {
|
for _ in 0..NUM_BUFFERS {
|
||||||
let bo = match ctx.ctx.ctx.allocator().create_bo(
|
let bo = match ctx.ctx.ctx.allocator().create_bo(
|
||||||
&self.dpy.state.dma_buf_ids,
|
&self.dpy.state.dma_buf_ids,
|
||||||
|
|
@ -731,7 +735,7 @@ impl WindowData {
|
||||||
height,
|
height,
|
||||||
ARGB8888,
|
ARGB8888,
|
||||||
&modifiers,
|
&modifiers,
|
||||||
BO_USE_RENDERING,
|
usage,
|
||||||
) {
|
) {
|
||||||
Ok(b) => b,
|
Ok(b) => b,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
allocator::{AllocatorError, BufferObject, BO_USE_RENDERING},
|
allocator::{AllocatorError, BufferObject, BufferUsage, BO_USE_RENDERING},
|
||||||
format::XRGB8888,
|
format::XRGB8888,
|
||||||
gfx_api::GfxError,
|
gfx_api::{needs_render_usage, GfxError},
|
||||||
scale::Scale,
|
scale::Scale,
|
||||||
state::State,
|
state::State,
|
||||||
video::drm::DrmError,
|
video::drm::DrmError,
|
||||||
},
|
},
|
||||||
|
indexmap::IndexMap,
|
||||||
jay_config::video::Transform,
|
jay_config::video::Transform,
|
||||||
std::{ops::Deref, rc::Rc},
|
std::{ops::Deref, rc::Rc},
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
|
|
@ -49,17 +50,22 @@ pub fn take_screenshot(
|
||||||
return Err(ScreenshooterError::EmptyDisplay);
|
return Err(ScreenshooterError::EmptyDisplay);
|
||||||
}
|
}
|
||||||
let formats = ctx.formats();
|
let formats = ctx.formats();
|
||||||
let modifiers: Vec<_> = match formats.get(&XRGB8888.drm) {
|
let modifiers: IndexMap<_, _> = match formats.get(&XRGB8888.drm) {
|
||||||
None => return Err(ScreenshooterError::XRGB8888),
|
None => return Err(ScreenshooterError::XRGB8888),
|
||||||
Some(f) => f
|
Some(f) => f
|
||||||
.write_modifiers
|
.write_modifiers
|
||||||
.intersection(&f.read_modifiers)
|
.iter()
|
||||||
.copied()
|
.filter(|(m, _)| f.read_modifiers.contains(*m))
|
||||||
.collect(),
|
.collect(),
|
||||||
};
|
};
|
||||||
if modifiers.is_empty() {
|
if modifiers.is_empty() {
|
||||||
return Err(ScreenshooterError::Modifiers);
|
return Err(ScreenshooterError::Modifiers);
|
||||||
}
|
}
|
||||||
|
let mut usage = BO_USE_RENDERING;
|
||||||
|
if !needs_render_usage(modifiers.values().copied()) {
|
||||||
|
usage = BufferUsage::none();
|
||||||
|
}
|
||||||
|
let modifiers: Vec<_> = modifiers.keys().copied().copied().collect();
|
||||||
let allocator = ctx.allocator();
|
let allocator = ctx.allocator();
|
||||||
let bo = allocator.create_bo(
|
let bo = allocator.create_bo(
|
||||||
&state.dma_buf_ids,
|
&state.dma_buf_ids,
|
||||||
|
|
@ -67,7 +73,7 @@ pub fn take_screenshot(
|
||||||
extents.height(),
|
extents.height(),
|
||||||
XRGB8888,
|
XRGB8888,
|
||||||
&modifiers,
|
&modifiers,
|
||||||
BO_USE_RENDERING,
|
usage,
|
||||||
)?;
|
)?;
|
||||||
let fb = ctx.clone().dmabuf_fb(bo.dmabuf())?;
|
let fb = ctx.clone().dmabuf_fb(bo.dmabuf())?;
|
||||||
fb.render_node(
|
fb.render_node(
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
format::formats,
|
format::formats,
|
||||||
gfx_api::GfxFormat,
|
gfx_api::{GfxFormat, GfxWriteModifier},
|
||||||
ifs::jay_render_ctx::FORMATS_SINCE,
|
ifs::jay_render_ctx::FORMATS_SINCE,
|
||||||
object::Version,
|
object::Version,
|
||||||
utils::clonecell::CloneCell,
|
utils::clonecell::CloneCell,
|
||||||
|
video::Modifier,
|
||||||
wire::{jay_render_ctx::*, JayRenderCtxId},
|
wire::{jay_render_ctx::*, JayRenderCtxId},
|
||||||
wl_usr::{usr_object::UsrObject, UsrCon},
|
wl_usr::{usr_object::UsrObject, UsrCon},
|
||||||
},
|
},
|
||||||
|
|
@ -29,6 +30,16 @@ pub trait UsrJayRenderCtxOwner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl UsrJayRenderCtx {
|
||||||
|
fn add_write_modifier(&self, format: u32, modifier: Modifier, needs_render_usage: bool) {
|
||||||
|
if let Some(format) = self.formats.borrow_mut().get_mut(&format) {
|
||||||
|
format
|
||||||
|
.write_modifiers
|
||||||
|
.insert(modifier, GfxWriteModifier { needs_render_usage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl JayRenderCtxEventHandler for UsrJayRenderCtx {
|
impl JayRenderCtxEventHandler for UsrJayRenderCtx {
|
||||||
type Error = Infallible;
|
type Error = Infallible;
|
||||||
|
|
||||||
|
|
@ -57,9 +68,7 @@ impl JayRenderCtxEventHandler for UsrJayRenderCtx {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_modifier(&self, ev: WriteModifier, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
fn write_modifier(&self, ev: WriteModifier, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
if let Some(format) = self.formats.borrow_mut().get_mut(&ev.format) {
|
self.add_write_modifier(ev.format, ev.modifier, true);
|
||||||
format.write_modifiers.insert(ev.modifier);
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,6 +85,11 @@ impl JayRenderCtxEventHandler for UsrJayRenderCtx {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn write_modifier2(&self, ev: WriteModifier2, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
|
self.add_write_modifier(ev.format, ev.modifier, ev.needs_render_usage != 0);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
usr_object_base! {
|
usr_object_base! {
|
||||||
|
|
|
||||||
|
|
@ -27,3 +27,9 @@ event write_modifier (since = 7) {
|
||||||
event format (since = 7) {
|
event format (since = 7) {
|
||||||
format: u32,
|
format: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event write_modifier2 (since = 9) {
|
||||||
|
format: u32,
|
||||||
|
modifier: pod(u64),
|
||||||
|
needs_render_usage: u32,
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue