Skip to content

Commit

Permalink
Implement Send for Image
Browse files Browse the repository at this point in the history
This changes the assumptions of the crate to assert that a valid
`pixmap::Image` has a ref-count of 1, with an alpha map that has a
ref-count of 1. Consequently, `set_alpha_map` must take ownership of its
argument.

My understanding, looking at the pixmap code, is that this should ensure
it is safe to `Send` the `Image` to another thread. Of course this does
limit the API of this crate if a consumer wants to use multiple
references (though `pixman_image_ref` wasn't wrapper already), or
wants to use `set_alpha_map` while still keeping a reference to the
alpha map. The first issue can just be solved by wrapping in `Rc`,
though.

Smithay/smithay#1500
  • Loading branch information
ids1024 committed Aug 9, 2024
1 parent a7bf452 commit 0343011
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 3 deletions.
11 changes: 9 additions & 2 deletions pixman/src/image/bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ pub struct Image<'bits, 'alpha> {
_alpha: PhantomData<&'alpha ()>,
}

// SAFETY: An image is safe to `Send` if the image and its alpha map have a
// reference count of one. So references will not exist on multiple threads.
unsafe impl<'bits, 'alpha> Send for Image<'bits, 'alpha> {}

impl<'bits, 'alpha> std::ops::Deref for Image<'bits, 'alpha> {
type Target = ImageRef;

Expand Down Expand Up @@ -130,7 +134,7 @@ impl<'bits, 'a> Image<'bits, 'a> {
/// used as a src in a blit operation
pub fn set_alpha_map<'alpha: 'a>(
self,
alpha_map: &'alpha Image<'_, 'static>,
alpha_map: Image<'alpha, 'static>,
x: i16,
y: i16,
) -> Image<'bits, 'alpha> {
Expand Down Expand Up @@ -467,7 +471,10 @@ impl<'bits, 'alpha> Image<'bits, 'alpha> {
///
/// # Safety
///
/// The pointer is expected to be valid and have a ref-count of at least one.
/// The pointer is expected to be valid and have a ref-count of at *exactly* one,
/// with an alpha map (if any) that has a ref count of one. This restriction allows
/// [`Image`] to safely implement [`Send`].
///
/// Ownership of the pointer is transferred and unref will be called on drop.
pub unsafe fn from_ptr(ptr: *mut ffi::pixman_image_t) -> Self {
Self {
Expand Down
2 changes: 1 addition & 1 deletion pixman/src/image/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ macro_rules! image_type {
/// used as a src in a blit operation
pub fn set_alpha_map<'alpha: 'a>(
self,
alpha_map: &'alpha crate::Image<'_, 'static>,
alpha_map: crate::Image<'alpha, 'static>,
x: i16,
y: i16,
) -> $name<'alpha> {
Expand Down

0 comments on commit 0343011

Please sign in to comment.