mirror of
https://github.com/Smithay/smithay.git
synced 2024-09-28 03:21:14 +02:00
gbm: Force implicit modifiers for old api
Buffers created via `gbm_bo_create` might return (errornous or actual) modifiers, which can then lead to errors trying to attach them to drm or exporting in dmabuf, which will then suddenly have modifiers. So lets track if the creation method allows for modifiers or not.
This commit is contained in:
parent
f25bcd892e
commit
62edd3c3fc
2 changed files with 26 additions and 15 deletions
|
@ -87,11 +87,21 @@ impl drm::buffer::Buffer for GbmBuffer {
|
||||||
|
|
||||||
impl GbmBuffer {
|
impl GbmBuffer {
|
||||||
/// Create a [`GbmBuffer`] from an existing [`BufferObject`]
|
/// Create a [`GbmBuffer`] from an existing [`BufferObject`]
|
||||||
pub fn from_bo(bo: BufferObject<()>) -> Self {
|
///
|
||||||
|
/// `implicit` forces the object to assume the modifier is `Invalid` for cases,
|
||||||
|
/// where the buffer was allocated with an older api, that doesn't support modifiers.
|
||||||
|
///
|
||||||
|
/// Gbm might otherwise give us the underlying or a non-sensical modifier,
|
||||||
|
/// which can fail in various other apis.
|
||||||
|
pub fn from_bo(bo: BufferObject<()>, implicit: bool) -> Self {
|
||||||
let size = (bo.width().unwrap_or(0) as i32, bo.height().unwrap_or(0) as i32).into();
|
let size = (bo.width().unwrap_or(0) as i32, bo.height().unwrap_or(0) as i32).into();
|
||||||
let format = Format {
|
let format = Format {
|
||||||
code: bo.format().unwrap_or(Fourcc::Argb8888), // we got to return something, but this should never happen anyway
|
code: bo.format().unwrap_or(Fourcc::Argb8888), // we got to return something, but this should never happen anyway
|
||||||
modifier: bo.modifier().unwrap_or(Modifier::Invalid),
|
modifier: if implicit {
|
||||||
|
Modifier::Invalid
|
||||||
|
} else {
|
||||||
|
bo.modifier().unwrap_or(Modifier::Invalid)
|
||||||
|
},
|
||||||
};
|
};
|
||||||
Self { bo, size, format }
|
Self { bo, size, format }
|
||||||
}
|
}
|
||||||
|
@ -164,20 +174,21 @@ impl<A: AsFd + 'static> GbmAllocator<A> {
|
||||||
flags: GbmBufferFlags,
|
flags: GbmBufferFlags,
|
||||||
) -> Result<GbmBuffer, std::io::Error> {
|
) -> Result<GbmBuffer, std::io::Error> {
|
||||||
#[cfg(feature = "backend_gbm_has_create_with_modifiers2")]
|
#[cfg(feature = "backend_gbm_has_create_with_modifiers2")]
|
||||||
let result = self.device.create_buffer_object_with_modifiers2(
|
let result = self
|
||||||
width,
|
.device
|
||||||
height,
|
.create_buffer_object_with_modifiers2(width, height, fourcc, modifiers.iter().copied(), flags)
|
||||||
fourcc,
|
.map(|bo| GbmBuffer::from_bo(bo, false));
|
||||||
modifiers.iter().copied(),
|
|
||||||
flags,
|
|
||||||
);
|
|
||||||
|
|
||||||
#[cfg(not(feature = "backend_gbm_has_create_with_modifiers2"))]
|
#[cfg(not(feature = "backend_gbm_has_create_with_modifiers2"))]
|
||||||
let result = if (flags & !(GbmBufferFlags::SCANOUT | GbmBufferFlags::RENDERING)).is_empty() {
|
let result = if (flags & !(GbmBufferFlags::SCANOUT | GbmBufferFlags::RENDERING)).is_empty() {
|
||||||
self.device
|
self.device
|
||||||
.create_buffer_object_with_modifiers(width, height, fourcc, modifiers.iter().copied())
|
.create_buffer_object_with_modifiers(width, height, fourcc, modifiers.iter().copied())
|
||||||
|
.map(|bo| GbmBuffer::from_bo(bo, false))
|
||||||
} else if modifiers.contains(&Modifier::Invalid) || modifiers.contains(&Modifier::Linear) {
|
} else if modifiers.contains(&Modifier::Invalid) || modifiers.contains(&Modifier::Linear) {
|
||||||
return self.device.create_buffer_object(width, height, fourcc, flags);
|
return self
|
||||||
|
.device
|
||||||
|
.create_buffer_object(width, height, fourcc, flags)
|
||||||
|
.map(|bo| GbmBuffer::from_bo(bo, true));
|
||||||
} else {
|
} else {
|
||||||
return Err(std::io::Error::new(
|
return Err(std::io::Error::new(
|
||||||
std::io::ErrorKind::Other,
|
std::io::ErrorKind::Other,
|
||||||
|
@ -186,12 +197,12 @@ impl<A: AsFd + 'static> GbmAllocator<A> {
|
||||||
};
|
};
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(bo) => Ok(GbmBuffer::from_bo(bo)),
|
Ok(bo) => Ok(bo),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if modifiers.contains(&Modifier::Invalid) || modifiers.contains(&Modifier::Linear) {
|
if modifiers.contains(&Modifier::Invalid) || modifiers.contains(&Modifier::Linear) {
|
||||||
self.device
|
self.device
|
||||||
.create_buffer_object(width, height, fourcc, flags)
|
.create_buffer_object(width, height, fourcc, flags)
|
||||||
.map(GbmBuffer::from_bo)
|
.map(|bo| GbmBuffer::from_bo(bo, true))
|
||||||
} else {
|
} else {
|
||||||
Err(err)
|
Err(err)
|
||||||
}
|
}
|
||||||
|
@ -360,7 +371,7 @@ impl Dmabuf {
|
||||||
offsets,
|
offsets,
|
||||||
self.format().modifier,
|
self.format().modifier,
|
||||||
)
|
)
|
||||||
.map(GbmBuffer::from_bo)
|
.map(|bo| GbmBuffer::from_bo(bo, false))
|
||||||
} else {
|
} else {
|
||||||
gbm.import_buffer_object_from_dma_buf(
|
gbm.import_buffer_object_from_dma_buf(
|
||||||
handles[0].unwrap(),
|
handles[0].unwrap(),
|
||||||
|
@ -374,7 +385,7 @@ impl Dmabuf {
|
||||||
usage
|
usage
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.map(GbmBuffer::from_bo)
|
.map(|bo| GbmBuffer::from_bo(bo, true))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ pub fn framebuffer_from_wayland_buffer<A: AsFd + 'static>(
|
||||||
) {
|
) {
|
||||||
let bo = gbm
|
let bo = gbm
|
||||||
.import_buffer_object_from_wayland::<()>(buffer, gbm::BufferObjectFlags::SCANOUT)
|
.import_buffer_object_from_wayland::<()>(buffer, gbm::BufferObjectFlags::SCANOUT)
|
||||||
.map(GbmBuffer::from_bo)
|
.map(|bo| GbmBuffer::from_bo(bo, true))
|
||||||
.map_err(Error::Import)?;
|
.map_err(Error::Import)?;
|
||||||
let (fb, format) = framebuffer_from_bo_internal(
|
let (fb, format) = framebuffer_from_bo_internal(
|
||||||
drm,
|
drm,
|
||||||
|
|
Loading…
Reference in a new issue