<NME> mod.rs
<BEF> //! This module represents abstraction on top the linux direct rendering manager api (drm).
//!
//! ## [`DrmDevice`]
//!
//! A device exposes certain properties, which are directly derived
//! from the *device* as perceived by the direct rendering manager api (drm). These resources consists
//! out of connectors, encoders, framebuffers, planes and crtcs.
//!
//! [`crtc`](drm::control::crtc)s represent scanout engines of the device pointer to one framebuffer.
//! Their responsibility is to read the data of the framebuffer and export it into an "Encoder".
//! The number of crtc's represent the number of independent output devices the hardware may handle.
//!
//! On modern graphic cards it is better to think about the `crtc` as some sort of rendering engine.
//! You can only have so many different pictures, you may display, as you have `crtc`s, but a single image
//! may be put onto multiple displays.
//!
//! An [`encoder`](drm::control::encoder) encodes the data of connected crtcs into a video signal for a fixed set of connectors.
//! E.g. you might have an analog encoder based on a DAG for VGA ports, but another one for digital ones.
//! Also not every encoder might be connected to every crtc.
//!
//! A [`connector`](drm::control::connector) represents a port on your computer, possibly with a connected monitor, TV, capture card, etc.
//!
//! A [`framebuffer`](drm::control::framebuffer) represents a buffer you may display, see `DrmSurface` below.
//!
//! A [`plane`](drm::control::plane) adds another layer on top of the crtcs, which allow us to layer multiple images on top of each other more efficiently
//! then by combining the rendered images in the rendering phase, e.g. via OpenGL. Planes have to be explicitly used by the user to be useful.
//! Every device has at least one primary plane used to display an image to the whole crtc. Additionally cursor and overlay planes may be present.
//! Cursor planes are usually very restricted in size and meant to be used for hardware cursors, while overlay planes may
//! be used for performance reasons to display any overlay on top of the image, e.g. the top-most windows.
//! Overlay planes may have a bunch of weird limitation, that you cannot query, e.g. only working on round pixel coordinates.
//! You code should never rely on a fixed set of overlay planes, but always have a fallback solution in place.
//!
//! The main functionality of a `Device` in smithay is to give access to all these properties for the user to
//! choose an appropriate rendering configuration. What that means is defined by the requirements and constraints documented
//! in the specific device implementations. The second functionality is the creation of a `Surface`.
//! Surface creation requires a `crtc` (which cannot be the same as another existing `Surface`'s crtc), a plane,
//! as well as a `Mode` and a set of `connectors`.
//!
//! smithay does not make sure that `connectors` are not already in use by another `Surface`. Overlapping `connector`-Sets may
//! be an error or result in undefined rendering behavior depending on the `Surface` implementation.
//!
//! ## [`DrmSurface`]
//!
//! extern crate smithay;
//! extern crate wayland_server;
//!
//! use drm::control::{Device as ControlDevice, ResourceInfo};
//! use drm::control::connector::{Info as ConnectorInfo, State as ConnectorState};
//! use drm::control::encoder::{Info as EncoderInfo};
//! use std::fs::OpenOptions;
//! use smithay::backend::drm::{DrmDevice, DrmBackend};
//! use wayland_server::StateToken;
//!
//! # fn main() {
//!
//! let (_display, mut event_loop) = wayland_server::create_display();
//!
//! // Open the drm device
//! let mut options = OpenOptions::new();
//! options.read(true);
//! options.write(true);
//! let mut device = DrmDevice::new_from_file(
//!     options.open("/dev/dri/card0").unwrap(), // try to detect it properly
//!     None /*put a logger here*/
//! ).unwrap();
//!
pub use error::Error as DrmError;
pub use node::{CreateDrmNodeError, DrmNode, NodeType};
#[cfg(feature = "backend_gbm")]
pub use surface::gbm::{Error as GbmBufferedSurfaceError, GbmBufferedSurface};
pub use surface::DrmSurface;

use drm::control::{crtc, plane, Device as ControlDevice, PlaneType};

/// A set of planes as supported by a crtc
#[derive(Debug)]
pub struct Planes {
    /// The primary plane of the crtc (automatically selected for [DrmDevice::create_surface])
    pub primary: plane::Handle,
    /// The cursor plane of the crtc, if available
    pub cursor: Option<plane::Handle>,
    /// Overlay planes supported by the crtc, if available
    pub overlay: Vec<plane::Handle>,
}

fn planes(
    dev: &impl ControlDevice,
    crtc: &crtc::Handle,
//! let mode = connector_info.modes()[0];
//!
//! // Create the backend
//! let backend: StateToken<DrmBackend> = device.create_backend(
//!     event_loop.state(),
//!     crtc,
//!     mode,
//!     vec![connector_info.handle()]
//! ).unwrap().clone();
//! # }
//! ```
//!

    let resources = dev.resource_handles().map_err(|source| DrmError::Access {
        errmsg: "Error loading resource handles",
        dev: dev.dev_path(),
        source,
    })?;

    for plane in planes {
        let info = dev.get_plane(plane).map_err(|source| DrmError::Access {
            errmsg: "Failed to get plane information",
            dev: dev.dev_path(),
            source,
        })?;
        let filter = info.possible_crtcs();
        if resources.filter_crtcs(filter).contains(crtc) {
//! # extern crate smithay;
//! # extern crate wayland_server;
//! #
//! # use drm::control::{Device as ControlDevice, ResourceInfo};
//! # use drm::control::connector::{Info as ConnectorInfo, State as ConnectorState};
//! use drm::control::crtc::{Handle as CrtcHandle};
//! use drm::result::Error as DrmError;
//! # use std::fs::OpenOptions;
//! # use std::time::Duration;
//! use smithay::backend::drm::{DrmDevice, DrmBackend, DrmHandler, drm_device_bind};
//! use smithay::backend::graphics::egl::EGLGraphicsBackend;
//! use wayland_server::{StateToken, StateProxy};
//! #
//! # fn main() {
//! #
    let (ids, vals) = props.as_props_and_values();
    for (&id, &val) in ids.iter().zip(vals.iter()) {
//! # let mut options = OpenOptions::new();
//! # options.read(true);
//! # options.write(true);
//! # let mut device = DrmDevice::new_from_file(
//! #     options.open("/dev/dri/card0").unwrap(), // try to detect it properly
//! #     None /*put a logger here*/
//! # ).unwrap();
//! #
                x if x == (PlaneType::Cursor as u64) => PlaneType::Cursor,
                _ => PlaneType::Overlay,
            });
        }
//! #     .unwrap();
//! # let crtc = res_handles.crtcs()[0];
//! # let mode = connector_info.modes()[0];
//! # let backend: StateToken<DrmBackend> = device.create_backend(
//! #     event_loop.state(),
//! #     crtc,
//! #     mode,
//! #     vec![connector_info.handle()]
//! # ).unwrap().clone();
//!
//! struct MyDrmHandler;
//!
//! impl DrmHandler<DrmBackend> for MyDrmHandler {
//!     fn ready<'a, S: Into<StateProxy<'a>>>(
//!         &mut self,
//!         state: S,
//!         _device: &mut DrmDevice<DrmBackend>,
//!         backend: &StateToken<DrmBackend>,
//!         _crtc: CrtcHandle,
//!         _frame: u32,
//!         _duration: Duration)
//!     {
//!         // render surfaces and swap again
//!         state.into().get(backend).swap_buffers().unwrap();
//!     }
//!     fn error<'a, S: Into<StateProxy<'a>>>(
//!         &mut self,
//!         _state: S,
//!         device: &mut DrmDevice<DrmBackend>,
//!         error: DrmError)
//!     {
//!         panic!("DrmDevice errored: {}", error);
//! }
//!
//! // render something (like clear_color)
//! event_loop.state().get(&backend).swap_buffers().unwrap();
//!
//! let device_token = event_loop.state().insert(device);
//! let _source = drm_device_bind(&mut event_loop, device_token, MyDrmHandler).unwrap();
//!
//! event_loop.run().unwrap();
//! # }

<MSG> Fix drm doc-test for new egl buffer changes

<DFF> @@ -44,23 +44,37 @@
 //! extern crate smithay;
 //! extern crate wayland_server;
 //!
+//! use drm::Device as BasicDevice;
 //! use drm::control::{Device as ControlDevice, ResourceInfo};
 //! use drm::control::connector::{Info as ConnectorInfo, State as ConnectorState};
 //! use drm::control::encoder::{Info as EncoderInfo};
-//! use std::fs::OpenOptions;
+//! use std::fs::{File, OpenOptions};
+//! use std::os::unix::io::RawFd;
+//! use std::os::unix::io::AsRawFd;
 //! use smithay::backend::drm::{DrmDevice, DrmBackend};
 //! use wayland_server::StateToken;
 //!
-//! # fn main() {
+//! #[derive(Debug)]
+//! pub struct Card(File);
+//!
+//! impl AsRawFd for Card {
+//!     fn as_raw_fd(&self) -> RawFd {
+//!         self.0.as_raw_fd()
+//!     }
+//! }
+//!
+//! impl BasicDevice for Card {}
+//! impl ControlDevice for Card {}
 //!
+//! # fn main() {
 //! let (_display, mut event_loop) = wayland_server::create_display();
 //!
 //! // Open the drm device
 //! let mut options = OpenOptions::new();
 //! options.read(true);
 //! options.write(true);
-//! let mut device = DrmDevice::new_from_file(
-//!     options.open("/dev/dri/card0").unwrap(), // try to detect it properly
+//! let mut device = DrmDevice::new(
+//!     Card(options.open("/dev/dri/card0").unwrap()), // try to detect it properly
 //!     None /*put a logger here*/
 //! ).unwrap();
 //!
@@ -89,12 +103,11 @@
 //! let mode = connector_info.modes()[0];
 //!
 //! // Create the backend
-//! let backend: StateToken<DrmBackend> = device.create_backend(
-//!     event_loop.state(),
+//! let backend = device.create_backend(
 //!     crtc,
 //!     mode,
 //!     vec![connector_info.handle()]
-//! ).unwrap().clone();
+//! ).unwrap();
 //! # }
 //! ```
 //!
@@ -116,15 +129,27 @@
 //! # extern crate smithay;
 //! # extern crate wayland_server;
 //! #
+//! # use drm::Device as BasicDevice;
 //! # use drm::control::{Device as ControlDevice, ResourceInfo};
 //! # use drm::control::connector::{Info as ConnectorInfo, State as ConnectorState};
 //! use drm::control::crtc::{Handle as CrtcHandle};
 //! use drm::result::Error as DrmError;
-//! # use std::fs::OpenOptions;
+//! # use std::fs::{File, OpenOptions};
+//! # use std::os::unix::io::RawFd;
+//! # use std::os::unix::io::AsRawFd;
 //! # use std::time::Duration;
 //! use smithay::backend::drm::{DrmDevice, DrmBackend, DrmHandler, drm_device_bind};
 //! use smithay::backend::graphics::egl::EGLGraphicsBackend;
-//! use wayland_server::{StateToken, StateProxy};
+//! #
+//! # #[derive(Debug)]
+//! # pub struct Card(File);
+//! # impl AsRawFd for Card {
+//! #     fn as_raw_fd(&self) -> RawFd {
+//! #         self.0.as_raw_fd()
+//! #     }
+//! # }
+//! # impl BasicDevice for Card {}
+//! # impl ControlDevice for Card {}
 //! #
 //! # fn main() {
 //! #
@@ -133,8 +158,8 @@
 //! # let mut options = OpenOptions::new();
 //! # options.read(true);
 //! # options.write(true);
-//! # let mut device = DrmDevice::new_from_file(
-//! #     options.open("/dev/dri/card0").unwrap(), // try to detect it properly
+//! # let mut device = DrmDevice::new(
+//! #     Card(options.open("/dev/dri/card0").unwrap()), // try to detect it properly
 //! #     None /*put a logger here*/
 //! # ).unwrap();
 //! #
@@ -145,32 +170,28 @@
 //! #     .unwrap();
 //! # let crtc = res_handles.crtcs()[0];
 //! # let mode = connector_info.modes()[0];
-//! # let backend: StateToken<DrmBackend> = device.create_backend(
-//! #     event_loop.state(),
+//! # let backend = device.create_backend(
 //! #     crtc,
 //! #     mode,
 //! #     vec![connector_info.handle()]
-//! # ).unwrap().clone();
+//! # ).unwrap();
 //!
-//! struct MyDrmHandler;
+//! struct MyDrmHandler(DrmBackend<Card>);
 //!
-//! impl DrmHandler<DrmBackend> for MyDrmHandler {
-//!     fn ready<'a, S: Into<StateProxy<'a>>>(
+//! impl DrmHandler<Card> for MyDrmHandler {
+//!     fn ready(
 //!         &mut self,
-//!         state: S,
-//!         _device: &mut DrmDevice<DrmBackend>,
-//!         backend: &StateToken<DrmBackend>,
+//!         _device: &mut DrmDevice<Card>,
 //!         _crtc: CrtcHandle,
 //!         _frame: u32,
 //!         _duration: Duration)
 //!     {
 //!         // render surfaces and swap again
-//!         state.into().get(backend).swap_buffers().unwrap();
+//!         self.0.swap_buffers().unwrap();
 //!     }
-//!     fn error<'a, S: Into<StateProxy<'a>>>(
+//!     fn error(
 //!         &mut self,
-//!         _state: S,
-//!         device: &mut DrmDevice<DrmBackend>,
+//!         device: &mut DrmDevice<Card>,
 //!         error: DrmError)
 //!     {
 //!         panic!("DrmDevice errored: {}", error);
@@ -178,10 +199,10 @@
 //! }
 //!
 //! // render something (like clear_color)
-//! event_loop.state().get(&backend).swap_buffers().unwrap();
+//! backend.swap_buffers().unwrap();
 //!
 //! let device_token = event_loop.state().insert(device);
-//! let _source = drm_device_bind(&mut event_loop, device_token, MyDrmHandler).unwrap();
+//! let _source = drm_device_bind(&mut event_loop, device_token, MyDrmHandler(backend)).unwrap();
 //!
 //! event_loop.run().unwrap();
 //! # }

Fix drm doc-test for new egl buffer changes