drm::driver::{AllocImpl, AllocOps},
error::{to_result, Result},
prelude::*,
- types::{ARef, Opaque},
+ types::{ARef, AlwaysRefCounted, Opaque},
};
use core::{mem, ops::Deref, ptr::NonNull};
}
/// Trait that represents a GEM object subtype
-pub trait IntoGEMObject: Sized + super::private::Sealed {
+pub trait IntoGEMObject: Sized + super::private::Sealed + AlwaysRefCounted {
/// Owning driver for this type
type Driver: drm::Driver;
unsafe fn as_ref<'a>(self_ptr: *mut bindings::drm_gem_object) -> &'a Self;
}
+// SAFETY: All gem objects are refcounted.
+unsafe impl<T: IntoGEMObject> AlwaysRefCounted for T {
+ fn inc_ref(&self) {
+ // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
+ unsafe { bindings::drm_gem_object_get(self.as_raw()) };
+ }
+
+ unsafe fn dec_ref(obj: NonNull<Self>) {
+ // SAFETY: We either hold the only refcount on `obj`, or one of many - meaning that no one
+ // else could possibly hold a mutable reference to `obj` and thus this immutable reference
+ // is safe.
+ let obj = unsafe { obj.as_ref() }.as_raw();
+
+ // SAFETY:
+ // - The safety requirements guarantee that the refcount is non-zero.
+ // - We hold no references to `obj` now, making it safe for us to potentially deallocate it.
+ unsafe { bindings::drm_gem_object_put(obj) };
+ }
+}
+
/// Trait which must be implemented by drivers using base GEM objects.
pub trait DriverObject: BaseDriverObject<Object<Self>> {
/// Parent `Driver` for this object.
}
/// Base operations shared by all GEM object classes
-pub trait BaseObject
-where
- Self: crate::types::AlwaysRefCounted + IntoGEMObject,
-{
+pub trait BaseObject: IntoGEMObject {
/// Returns the size of the object in bytes.
fn size(&self) -> usize {
// SAFETY: `self.as_raw()` is guaranteed to be a pointer to a valid `struct drm_gem_object`.
}
}
-impl<T> BaseObject for T where Self: crate::types::AlwaysRefCounted + IntoGEMObject {}
+impl<T: IntoGEMObject> BaseObject for T {}
/// A base GEM object.
///
}
}
-// SAFETY: Instances of `Object<T>` are always reference-counted.
-unsafe impl<T: DriverObject> crate::types::AlwaysRefCounted for Object<T> {
- fn inc_ref(&self) {
- // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
- unsafe { bindings::drm_gem_object_get(self.as_raw()) };
- }
-
- unsafe fn dec_ref(obj: NonNull<Self>) {
- // SAFETY: `obj` is a valid pointer to an `Object<T>`.
- let obj = unsafe { obj.as_ref() };
-
- // SAFETY: The safety requirements guarantee that the refcount is non-zero.
- unsafe { bindings::drm_gem_object_put(obj.as_raw()) }
- }
-}
-
impl<T: DriverObject> super::private::Sealed for Object<T> {}
impl<T: DriverObject> Deref for Object<T> {