Skip to content
Snippets Groups Projects
  1. Jun 20, 2024
  2. Jun 18, 2024
    • Lyude Paul's avatar
    • Lyude Paul's avatar
      WIP: Integrate kms::device::PendingDevice into KMS API · b95b9c5d
      Lyude Paul authored
      TODO: This should be split across the patches for introducing various
      modesetting objects
      
      Anyway - this switches all static mode objects away from using
      &kms::device::Device for registration over to &kms::device::PendingDevice -
      essentially using types to do state tracking to prevent such mode objects
      from being created any time post-registration
      b95b9c5d
    • Lyude Paul's avatar
      WIP: rust: drm: Add the ability to register a KMS device · 02a86f0c
      Lyude Paul authored
      Using the PendingDevice interface we just added, we can now introduce a
      method for registering a modesetting device safely. As well, add a
      simple helper function to check whether KMS has been setup for a device -
      which we use to ensure proper resource destruction and prevent UB from
      calling `PendingDevice::setup_kms()` more then once.
      
      (TODO: this needs to be moved to the beginning of the series)
      02a86f0c
    • Lyude Paul's avatar
      rust: drm: Introduce PendingDevice · de9c76ec
      Lyude Paul authored
      DRM devices generally have to perform a number of initialization steps
      before they're ready to be registered with userspace. This means that in
      order to expose safe bindings for performing these steps, we need to be
      able to make it impossible to use those bindings at any point other then
      between device creation and registration.
      
      To accomplish this, we introduce a new PendingDevice type. This type can be
      used identically to a normal drm::device::Device, except that it also
      exposes bindings for methods that can only be called before registration.
      We then modify the constructors for `Registration` to ensure that they
      require handing over ownership of the `PendingDevice` - thus ensuring
      safety.
      de9c76ec
    • Lyude Paul's avatar
      rust: drm: Separate DRM device creation and registration · 1be89f18
      Lyude Paul authored
      
      With most DRM drivers, especially modesetting drivers, there can be a lot
      of device initialization that we want to complete before actually exposing
      the device to userspace. Otherwise, we risk exposing an incomplete and
      incorrect view of the device to userspace if our initialization races with
      userspace.
      
      So, separate the creation of devices from registering them.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      1be89f18
    • Lyude Paul's avatar
      rust: Add device::Device::name() · ca7b8f40
      Lyude Paul authored
      
      Just a simple binding for retrieving the name of the device through
      dev_name().
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      ca7b8f40
    • Lyude Paul's avatar
      WIP: Add simple registration of platform devices · 9b95d933
      Lyude Paul authored
      TODO:
      * The idea for this came from Maíra originally, and they should probably be
        the commit author (we'll fix that before final submission because credit
        is important :3, right now it's just a bit easier to rewrite the commit)
      9b95d933
    • Lyude Paul's avatar
      rust/drm/kms: Add RawPlaneState::rotation() · f960cedd
      Lyude Paul authored
      
      A binding for retrieving the current rotation of a DRM plane state.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      f960cedd
    • Lyude Paul's avatar
      rust/drm/kms: Add simplify_rotation() binding · 9683f9e9
      Lyude Paul authored
      
      Just a binding for drm_simplify_rotation(). We add this in a new module
      blend.rs in order to match the layout of the C side of things.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      9683f9e9
    • Lyude Paul's avatar
      rust/drm/kms: Add aliases for ROTATE_* and REFLECT_* · 8f3f245c
      Lyude Paul authored
      
      Just add some short-hand aliases to the raw bindings, since that's
      basically all we need. We put this in a new mode.rs module to match the
      layout of the C side of KMS.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      8f3f245c
    • Lyude Paul's avatar
      rust/drm/kms: Add RawPlaneState::src() and dst() · 0505d06c
      Lyude Paul authored
      
      Bindings for returning the src and dst rectangles for an atomic plane
      state.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      0505d06c
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add KmsDriver::fbdev_generic_setup() · fea92b56
      Lyude Paul authored
      
      Add a binding for drm_fbdev_generic_setup() - which should be called during
      driver initialization to setup an fbdev device. Note that we just re-use
      the preferred_depth specified in our ModeConfigInfo.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      fea92b56
    • Lyude Paul's avatar
      rust/drm/kms: Add KmsDriver::mode_config_reset() · e5d497ba
      Lyude Paul authored
      
      This is just a binding around drm_mode_config_reset(), which should be
      called during initialization of a modesetting driver if it doesn't
      read-back hardware state.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      e5d497ba
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add ShadowPlaneState<T> · f21a75e5
      Lyude Paul authored
      
      Since RVKMS uses drm_shadow_plane_state instead of the normal
      drm_plane_state, let's add bindings to allow drivers to use this using the
      PlaneStateHelper trait that we introduced before.
      
      Of course, all of the normal methods available to DRM planes are also
      available on shadow planes through the use of AsRawPlaneState and friends.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      
      TODO:
      * Make sure that documentation is consistent and finished
      f21a75e5
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add DriverPlane::prepare_fb() and cleanup_fb() · fdac573c
      Lyude Paul authored
      
      Add optional trait methods for DRM's prepare_fb() and cleanup_fb()
      callbacks now that we have proper Framebuffer bindings.
      
      TODO:
      * Write documentation
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      fdac573c
    • Lyude Paul's avatar
      rust/drm/kms: Add RawPlane::framebuffer() · 5facc1b1
      Lyude Paul authored
      
      Returns the Framebuffer currently assigned in an atomic plane state.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      5facc1b1
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add basic framebuffer bindings · d04196f7
      Lyude Paul authored
      
      We're about to add some FB related callbacks to planes now, so let's
      introduce our bindings for Framebuffer objects. Just like Connectors, these
      use RcModeObject.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      d04196f7
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add DriverPlane::atomic_update() · a993fb23
      Lyude Paul authored
      A mandatory trait method used for implementing DRM's atomic plane update
      callback. This is currently only mandatory because with our current
      bindings, DRM will crash without this.
      
      TODO: See if we can fix that and make it only mandatory in certain
      situations.
      a993fb23
    • Lyude Paul's avatar
      WIP: rust/kms/drm: Add RawPlaneState::atomic_helper_check() · 7d14b824
      Lyude Paul authored
      
      Add a binding for DRM's plane state atomic check helper.
      
      TODO:
      * Finish up documentation (we need to document parameters too! I think?)
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      7d14b824
    • Lyude Paul's avatar
      rust/drm/kms: Add RawPlaneState::crtc() · 35f8b8a0
      Lyude Paul authored
      
      Add a binding for retrieving an opaque reference to the CRTC currently set
      for an atomic plane state.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      35f8b8a0
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add DriverPlane::atomic_check() · f2876fbb
      Lyude Paul authored
      
      Optional trait method for implementing a plane's atomic_check().
      
      TODO:
      * Documentation
      * Figure out if we can make this non-mandatory?
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      f2876fbb
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Introduce DriverCrtc::atomic_check() · abdc785c
      Lyude Paul authored
      
      An optional trait method for implementing a CRTC's atomic state check.
      
      TODO: Write documentation
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      abdc785c
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add atomic state bindings · 53a99b7f
      Lyude Paul authored
      
      Next up is introducing bindings that we can use to represent the global DRM
      atomic state, along with all of the various object states contained within.
      We do this by introducing a few new concepts: borrowed states, atomic state
      mutators, and atomic state composers.
      
      To understand these, we need to quickly touch upon the general life of an
      atomic commit. Assuming a driver does its own internal atomic commit, the
      procedure looks something like this:
      
      * Allocate a new atomic state
      * Duplicate the atomic state of each mode object we want to mutate, and add
        the duplicated state to the new atomic state
      * Check (possibly more then once) the atomic state, possibly modifying it
        along the way
      * Commit the atomic state to software (we'll call this commit time). At
        this point no new objects can be added to the state
      * Finish committing the atomic state to hardware asynchronously
      
      With this in mind, we introduce AtomicStateMutator and AtomicStateComposer
      (along with leaky variants intended for uses in FFI calls). An
      AtomicStateMutator allows mutating an atomic state but does not allow for
      adding new objects to the state. Subsequently, an AtomicStateComposer
      allows for both mutating an atomic state and adding new mode objects. We
      control when we expose each of these types in order to implement the
      limitations required by the aforementioned example.
      
      Note as well that AtomicStateComposer is intended to eventually be usable
      directly by drivers. In this scenario, a driver will be able to create an
      AtomicStateComposer (the equivalent of allocating an atomic state in C) and
      then commit it by passing it to our DRM bindings by-value, insuring that
      once the commit process begins it is impossible to keep using the
      AtomicStateComposer.
      
      The next part of this is allowing users to modify the atomic states of all
      of the objects contained within an atomic state. Since it's an extremely
      common usecase for objects to mutate the atomic state of multiple objects
      at once in an unpredictable order, we need a mechanism that will allow us
      to hand out &mut references to each state while ensuring at runtime that we
      do not break rust's data aliasing rules (which disallow us from ever having
      more then one &mut reference to the same piece of data).
      
      We do this by introducing the concept of a "borrowed" state. This is a very
      similar concept to RefCell, where it is ensured during runtime that when a
      &mut reference is taken out another one cannot be created until the
      corresponding Ref object has been dropped. Our equivalent Ref types are
      BorrowedConnectorState, BorrowedCrtcState, and BorrowedPlaneState.
      
      Each one of these types can be used in the same manner as a Ref - no
      additional borrows for an atomic state may be taken until the existing one
      has been dropped. Subsequently, all of these types implement their
      respective AsRaw* and FromRaw* counter-parts - and allow dereferencing to
      each driver-private data structure for fully qualified borrows (like
      BorrowedCrtcState<'a, CrtcState<T>>. This allows a pretty clean way of
      mutating multiple states at once without ever breaking rust's mutability
      rules.
      
      We'll use all of these types over the next few commits to begin introducing
      various atomic modeset callbacks to each mode object type.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      
      TODO:
      * Make sure we have documentation everywhere
      * Make sure that we also eventually add upcasting capabilities to borrowed
        types
      53a99b7f
    • Lyude Paul's avatar
      rust/drm/kms: Introduce OpaqueEncoder · 2a16cbc5
      Lyude Paul authored
      
      Same thing as OpaquePlane, but for encoders now.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      2a16cbc5
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add RawPlane and RawPlaneState · 95321864
      Lyude Paul authored
      Same thing as RawCrtc and RawCrtcState, but for DRM planes now
      95321864
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add RawCrtc and RawCrtcState · 4a4ff89d
      Lyude Paul authored
      
      Same thing as RawConnector and RawConnectorState, just for CRTCs now.
      
      TODO:
      * Complete documentation
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      4a4ff89d
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add RawConnector and RawConnectorState · 0c26f066
      Lyude Paul authored
      
      Now that we have more then one way to refer to connectors, we also want to
      ensure that any methods which are common to any kind of connector type can
      be used on all connector representations. This is where RawConnector and
      RawConnectorState come in: we implement these traits for any type which
      implements AsRawConnector or AsRawConnectorState respectively.
      
      TODO:
      * Documentation
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      0c26f066
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add OpaquePlane and OpaquePlaneState · 006c69f1
      Lyude Paul authored
      
      Same thing as OpaqueCrtc and OpaqueCrtcState, but for plane states now.
      
      TODO:
      * Make sure that we have conversion functions to go back and forth from the
        Opaque versions and non-opaque versions. Currently we only have this for
        upcasting from OpaquePlane
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      006c69f1
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add OpaqueCrtc and OpaqueCrtcState · d53ef21c
      Lyude Paul authored
      
      This is the same thing as OpaqueConnector and OpaqueConnectorState, but for
      CRTCs now.
      
      TODO:
      * Add some of the missing functions we currently mention in documentation,
        mainly from_opaque()
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      d53ef21c
    • Lyude Paul's avatar
      rust/drm/kms: Add OpaqueConnector and OpaqueConnectorState · 2830d565
      Lyude Paul authored
      
      Since we allow drivers to have multiple implementations of DriverConnector
      and DriverConnectorState (in C, the equivalent of this is having multiple
      structs which embed drm_connector) - there are some situations we will run
      into where it's not possible for us to know the corresponding
      DriverConnector or DriverConnectorState for a given connector. The most
      obvious one is iterating through all connectors on a KMS device.
      
      So, take advantage of the various connector traits we added to introduce
      OpaqueConnector<> and OpaqueConnectorState<> which both can be used as a
      DRM connector and connector state respectively without needing to know the
      corresponding traits.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      2830d565
    • Lyude Paul's avatar
      WIP: rust/kernel/drm: Add ConnectorGuard::set_preferred_mode · 5d926484
      Lyude Paul authored
      
      Add a wrapper for `drm_set_preferred_mode()` for our new
      `ConnectorGuard` type so we can set the preferred mode for RVKMS
      connectors.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      5d926484
    • Lyude Paul's avatar
      rust/drm/kms: Add ModeConfigGuard and ConnectorGuard types · 56eddcd6
      Lyude Paul authored
      
      Next up is filling out some of the basic connector hotplugging callbacks -
      which we'll need for setting up the fbdev helpers for KMS devices. Note
      that connector hotplugging in DRM follows a BFL scheme: pretty much all
      probing is protected under the mighty drm_device->mode_config.lock, which
      of course is a bit counter-intuitive to rust's locking schemes where data
      is always associated with its lock.
      
      Since that lock is embedded in an FFI type and not a rust type, we need to
      introduce our own wrapper type that acts as a lock acquisition for this.
      This brings us to introducing a few new types:
      
      * ModeConfigGuard - the most basic lock guard, as long as this object is
        alive we are guaranteed to be holding drm_device->mode_config.lock. This
        object doesn't do much else on its own currently.
      * UnsafeModeConfigGuard - exactly the same as ModeConfigGuard, but does not
        lock or unlock drm_device->mode_config.lock on its own and relies on the
        caller to do it. This is only useful for FFI callbacks, and can be used
        as a ModeConfigGuard through it's Deref implementation
      * ConnectorGuard - an object which corresponds to a specific typed DRM
        connector. This can only be acquired with a ModeConfigGuard, and will be
        used to allow calling methods that are only safe to call with
        drm_device->mode_config.lock held. Since it implements
        Deref<Target=Connector<T>> as well, it can also be used for any other
        operations that would normally be available on a DRM connector.
      
      And finally, we add the DriverConnector::get_modes() trait method which
      drivers can use to implement the drm_connector_helper_funcs.get_modes
      callback. Note that while we make this trait method mandatory, we only do
      so for the time being since VKMS doesn't do very much with DRM connectors -
      and as such we have no need yet to implement alternative connector probing
      schemes outside of get_modes().
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      56eddcd6
    • Lyude Paul's avatar
      rust/drm/kms/connector: Add .attach_encoder() · 1c0dc42c
      Lyude Paul authored
      
      This adds a simple binding for completing the last step of creating a DRM
      connector - attaching its encoder. This function should only be called
      before the connector is registered, and DRM should enforce this itself by
      returning an error if a driver tries to add an encoder to an
      already-registered DRM connector.
      
      Note that unlike most of the methods we'll be adding to DRM mode objects,
      this is directly implemented on the Connector<T> type since I don't really
      think it would make sense for us to allow this operation on an
      OpaqueConnector (a DRM connector without a known DriverConnector
      implementation, something we'll be adding in the next few commits).
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      1c0dc42c
    • Lyude Paul's avatar
      WIP: rust/drm: Add super basic fourcc bindings · 2cd5419a
      Lyude Paul authored
      While we don't have proper bindings for specifying more then literally one
      fourcc format, this is just enough to get us by for the time being.
      
      TODO:
      * Better commit message
      * Come up with some way of automating this, there's a heck of a lot of
        fourcc formats and I think trying to manually add bindings for each one
        is a bad idea
      * Documentation
      2cd5419a
    • Lyude Paul's avatar
      rust/drm/kms: Add basic bindings for DRM encoders · 883b2a66
      Lyude Paul authored
      
      The last thing we need to be able to register a KMS driver is the ability
      to create DRM encoders, so let's add bindings for that. Again, these
      bindings follow the same general pattern as CRTCs, planes, and connector
      with one difference: encoders don't have an atomic state.
      
      Note that not having an atomic state doesn't mean there aren't plenty of
      valid usecases for a driver to stick private data within a DRM encoder,
      hence why we reuse the aforementioned pattern.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      883b2a66
    • Lyude Paul's avatar
      rust/drm/kms: Introduce basic DRM CRTC bindings · def91e5c
      Lyude Paul authored
      This introduces basic bindings for DRM CRTCs which follow the same general
      pattern as connectors and planes (e.g. AsRawCrtc, AsRawCrtcState, etc.).
      
      This should be the last mode object we're introducing for the time being
      with its own atomic state. Note that we've not added bindings for private
      modesetting objects yet, but I don't think those will be needed for rvkms -
      and the same general patterns we're using here should work for adding
      private modesetting objects.
      
      TODO: Make sure that docs are consistent
      def91e5c
    • Lyude Paul's avatar
      rust/drm/kms: Add basic DRM plane bindings · f20e09a2
      Lyude Paul authored
      
      The next step is adding a set of basic bindings to create a plane, which
      has to happen before we can create a CRTC (since we need to be able to at
      least specify a primary plane for a CRTC upon creation). This mostly
      follows the same general pattern as connectors (AsRawPlane,
      AsRawPlaneState, etc.).
      
      There is one major difference with planes vs. other types of atomic mode
      objects: drm_plane_state isn't the only base plane struct used in DRM
      drivers, as some drivers will use helpers like drm_shadow_plane_state which
      have a drm_plane_state embedded within them.
      
      Since we'll eventually be adding bindings for shadow planes, we introduce a
      PlaneStateHelper trait - which represents any data type which can be used
      as the main wrapping structure around a drm_plane_state - and we implement
      this trait for PlaneState<T>. This trait can be used in our C callbacks to
      allow for drivers to use different wrapping structures without needing to
      implement a separate set of FFI callbacks for each type. Currently planes
      are the only type I'm aware of which do this.
      
      TODO: Verify documentation is up to snuff, consider dropping redundant
      Driver associated types?
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      f20e09a2
    • Lyude Paul's avatar
      rust/drm/kms: Introduce Connector<T> and ConnectorState<T> · 0739495f
      Lyude Paul authored
      We start off by introducing wrappers for the first important type of mode
      object: a DRM display connector. This introduces Connector<T:
      DriverConnector> and ConnectorState<T: DriverConnectorState>. Both
      DriverConnector and DriverConnectorState must be implemented by KMS
      drivers, and a driver may have as many implementations of these two traits
      as it needs. This also introduces the general data pattern we'll be using
      for all of the core mode objects that can be used in atomic commits.
      
      It's important to note that both Connector<T> and ConnectorState<T> are
      intended to be "subclassable". To explain what this means, we need to look
      at how a DRM driver normally uses objects like DRM connectors.
      
      Typically, a driver in C will define its connectors like so:
      
      struct foo_connector {
        struct drm_connector base;
        int bar;
      }
      
      Note that we have a drm_connector struct embedded in foo_connector, but we
      have data which comes after it which is defined by the driver. This is
      important for a number of reasons: connectors can have their own mutexes
      and various other hardware-specific information that a driver may want
      access to at any time. The same goes for drm_connector_state, where drivers
      will subclass this struct in the same way. It's worth noting as well that
      it isn't uncommon for a driver to have multiple types of connectors, but
      we'll handle in a later commit.
      
      As a result, we've designed Connector<T> and ConnectorState<T> so that for
      both types: a DRM driver can add custom data into the T. As well, there's
      some basic limitations on how this data may be accessed:
      
      * Data within the `DriverConnector` struct is pinned in order to allow
        mutexes and other structs which need pinning to be stored within it. As
        well, it is impossible to get a direct mutable reference to the data
        within DriverConnector - as there's no locks for doing so which would
        cause a race condition.
      * Data within the `DriverConnectorState` struct is currently not pinned.
        While it's not unheard of for a driver to put something like a mutex in
        its atomic states, (VKMS actually does this in some spots) this quickly
        complicates things especially with nonblocking modesets - and doesn't
        really fit into the philosophy of an atomic state anyway. We may add
        support for this in the future later if this does end up being needed,
        but for now we hold back in order to make it much easier for drivers to
        access private data within the atomic state.
        As well, the functions we provide for converting to/from raw connector
        state pointers are notably different from many other rust types in the
        kernel. Instead of converting raw state pointers to raw ConnectorState<T>
        pointers, we allow for direct immutable and mutable references. The
        reason for this is that it makes accessing private driver data in the
        state much easier, and unlike Connector<T> - we can actually uphold
        all of the required data aliasing rules thanks to states only being
        mutable by a single thread before they've been swapped in.
        Note that currently, we don't provide a way to access said private data
        for ConnectorState<T> since allowing direct access to a &mut
        ConnectorState<T> could allow a caller to modify portions of
        drm_connector_state which are meant to be invariant throughout the
        lifetime of the connector state. We'll address this in the next few
        commits when we introduce the global atomic state type.
      
      And finally - we introduce the following internal traits for the crate side
      of things:
      
        * AsRawConnector - any type which can spit out a *mut
          bindings::drm_connector or be recovered from one
        * AsRawConnectorState - any type which can return a reference to a
          bindings::drm_connector_state
        * private::AsRawConnectorState - just methods for AsRawConnectorState
          that we don't want to be accessible to our users (since they could be
          used to introduce UB)
        * FromRawConnectorState - any type which can be recovered from a raw
          pointer to a bindings::drm_connector_state
      
      The reason for having AsRawConnectorState and FromRawConnectorState as
      separate traits unlike AsRawConnector is due to the fact that we'll
      introduce objects later on which can be used as DRM connector states, but
      cannot be directly derived from a *mut bindings::drm_connector_state
      because they hold additional state or have additional side-effects.
      
      Likewise, we'll also have other objects which can be used as raw DRM
      connectors - hence AsRawConnector.
      
      TODO: Make sure docs are consistent
      0739495f
    • Lyude Paul's avatar
      rust/drm/kms: Introduce the main ModeConfigObject traits · 09945a93
      Lyude Paul authored
      The KMS API has a very consistent idea of a "mode config object", which
      includes any object with a bindings::drm_mode_object struct embedded in it.
      These objects have their own object IDs which DRM exposes to userspace, and
      we introduce the ModeConfigObject trait to represent any object matching
      these characteristics.
      
      One slightly less consistent trait of these objects however: some mode
      objects have a reference count, while others don't. Since rust requires
      that we are able to define the lifetime of an object up-front, we introduce
      two other super-traits of ModeConfigObject for this:
      
      * StaticModeObject - this trait represents any mode object which does not
        have a reference count of its own. Such objects can be considered to
        share the lifetime of their parent KMS device
      * RcModeObject - this trait represents any mode object which does have its
        own reference count. Objects implementing this trait get a free blanket
        implementation of AlwaysRefCounted, and as such can be used with the ARef
        container without us having to implement AlwaysRefCounted for each
        individual mode object.
      
      This will be able to handle most lifetimes we'll need with one exception:
      it's entirely possible a driver may want to hold a "owned" reference to a
      static mode object. We allow for this by introducing the KmsRef container,
      which grabs an owned refcount to the parent KMS device of a
      StaticModeObject and holds a pointer to said object - essentially allowing
      it to act identically to an owned refcount by preventing the device's
      lifetime from ending until the KmsRef is dropped. I choose not to use
      AlwaysRefCounted for this as holding a refcount to the device has its own
      set of implications since if you forget to drop the KmsRef the device will
      never be destroyed.
      09945a93
Loading