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