<commit_before>//! Wayland specific EGL functionality - EGL based `WlBuffer`s.
//!
//! The types of this module can be used to initialize hardware acceleration rendering
//! based on EGL for clients as it may enabled usage of `EGLImage` based `WlBuffer`s.
//!
//! To use it bind any backend implementing the `EGLWaylandExtensions` trait, that shall do the
//! rendering (so pick a fast one), to the `wayland_server::Display` of your compositor.
//! Note only one backend may be bould to any `Display` at any time.
//!
//! You may then use the resulting `EGLDisplay` to recieve `EGLImages` of an egl-based `WlBuffer`
//! for rendering.

use backend::graphics::egl::{ffi, native, EGLContext, EglExtensionNotSupportedError};
use backend::graphics::egl::error::*;
use backend::graphics::egl::ffi::egl::types::EGLImage;
use nix::libc::c_uint;
use std::fmt;
use std::rc::{Rc, Weak};
use wayland_server::{Display, Resource};
use wayland_server::protocol::wl_buffer::{self, WlBuffer};
use wayland_sys::server::wl_display;

/// Error that can occur when accessing an EGL buffer
pub enum BufferAccessError {
    /// The corresponding Context is not alive anymore
    ContextLost,
    /// This buffer is not managed by the EGL buffer
    NotManaged(Resource<WlBuffer>),
    /// Failed to create EGLImages from the buffer
    EGLImageCreationFailed,
    /// The required EGL extension is not supported by the underlying EGL implementation
    EglExtensionNotSupported(EglExtensionNotSupportedError),
}

impl fmt::Debug for BufferAccessError {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> ::std::result::Result<(), fmt::Error> {
        match *self {
            BufferAccessError::ContextLost => write!(formatter, "BufferAccessError::ContextLost"),
            BufferAccessError::NotManaged(_) => write!(formatter, "BufferAccessError::NotManaged"),
            BufferAccessError::EGLImageCreationFailed => {
                write!(formatter, "BufferAccessError::EGLImageCreationFailed")
            }
            BufferAccessError::EglExtensionNotSupported(ref err) => write!(formatter, "{:?}", err),
        }
    }
}

impl fmt::Display for BufferAccessError {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> ::std::result::Result<(), fmt::Error> {
        use std::error::Error;
        match *self {
            BufferAccessError::ContextLost
            | BufferAccessError::NotManaged(_)
            | BufferAccessError::EGLImageCreationFailed => write!(formatter, "{}", self.description()),
            BufferAccessError::EglExtensionNotSupported(ref err) => err.fmt(formatter),
        }
    }
}

impl ::std::error::Error for BufferAccessError {
    fn description(&self) -> &str {
        match *self {
            BufferAccessError::ContextLost => "The corresponding context was lost",
            BufferAccessError::NotManaged(_) => "This buffer is not mananged by EGL",
            BufferAccessError::EGLImageCreationFailed => "Failed to create EGLImages from the buffer",
            BufferAccessError::EglExtensionNotSupported(ref err) => err.description(),
        }
    }

    fn cause(&self) -> Option<&::std::error::Error> {
        match *self {
            BufferAccessError::EglExtensionNotSupported(ref err) => Some(err),
            _ => None,
        }
    }
}

impl From<EglExtensionNotSupportedError> for BufferAccessError {
    fn from(error: EglExtensionNotSupportedError) -> Self {
        BufferAccessError::EglExtensionNotSupported(error)
    }
}

/// Error that might happen when binding an `EGLImage` to a gl texture
#[derive(Debug, Clone, PartialEq)]
pub enum TextureCreationError {
    /// The given plane index is out of bounds
    PlaneIndexOutOfBounds,
    /// The OpenGL context has been lost and needs to be recreated.
    ///
    /// All the objects associated to it (textures, buffers, programs, etc.)
    /// need to be recreated from scratch.
    ///
    /// Operations will have no effect. Functions that read textures, buffers, etc.
    /// from OpenGL will return uninitialized data instead.
    ///
    /// A context loss usually happens on mobile devices when the user puts the
    /// application on sleep and wakes it up later. However any OpenGL implementation
    /// can theoretically lose the context at any time.
    ContextLost,
    /// Failed to bind the EGLImage to the given texture
    ///
    /// The given argument is the gl error code
    TextureBindingFailed(u32),
}

impl fmt::Display for TextureCreationError {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> ::std::result::Result<(), fmt::Error> {
        use std::error::Error;
        match *self {
            TextureCreationError::ContextLost => write!(formatter, "{}", self.description()),
            TextureCreationError::PlaneIndexOutOfBounds => write!(formatter, "{}", self.description()),
            TextureCreationError::TextureBindingFailed(code) => write!(
                formatter,
                "{}. Gl error code: {:?}",
                self.description(),
                code
            ),
        }
    }
}

impl ::std::error::Error for TextureCreationError {
    fn description(&self) -> &str {
        match *self {
            TextureCreationError::ContextLost => "The context has been lost, it needs to be recreated",
            TextureCreationError::PlaneIndexOutOfBounds => "This buffer is not mananged by EGL",
            TextureCreationError::TextureBindingFailed(_) => "Failed to create EGLImages from the buffer",
        }
    }

    fn cause(&self) -> Option<&::std::error::Error> {
        None
    }
}

/// Texture format types
#[repr(i32)]
#[allow(non_camel_case_types)]
pub enum Format {
    /// RGB format
    RGB = ffi::egl::TEXTURE_RGB as i32,
    /// RGB + alpha channel format
    RGBA = ffi::egl::TEXTURE_RGBA as i32,
    /// External format
    External = ffi::egl::TEXTURE_EXTERNAL_WL,
    /// 2-plane Y and UV format
    Y_UV = ffi::egl::TEXTURE_Y_UV_WL,
    /// 3-plane Y, U and V format
    Y_U_V = ffi::egl::TEXTURE_Y_U_V_WL,
    /// 2-plane Y and XUXV format<commit_msg>wayland.backend.egl: derive Debug for Format<commit_after>//! Wayland specific EGL functionality - EGL based `WlBuffer`s.
//!
//! The types of this module can be used to initialize hardware acceleration rendering
//! based on EGL for clients as it may enabled usage of `EGLImage` based `WlBuffer`s.
//!
//! To use it bind any backend implementing the `EGLWaylandExtensions` trait, that shall do the
//! rendering (so pick a fast one), to the `wayland_server::Display` of your compositor.
//! Note only one backend may be bould to any `Display` at any time.
//!
//! You may then use the resulting `EGLDisplay` to recieve `EGLImages` of an egl-based `WlBuffer`
//! for rendering.

use backend::graphics::egl::{ffi, native, EGLContext, EglExtensionNotSupportedError};
use backend::graphics::egl::error::*;
use backend::graphics::egl::ffi::egl::types::EGLImage;
use nix::libc::c_uint;
use std::fmt;
use std::rc::{Rc, Weak};
use wayland_server::{Display, Resource};
use wayland_server::protocol::wl_buffer::{self, WlBuffer};
use wayland_sys::server::wl_display;

/// Error that can occur when accessing an EGL buffer
pub enum BufferAccessError {
    /// The corresponding Context is not alive anymore
    ContextLost,
    /// This buffer is not managed by the EGL buffer
    NotManaged(Resource<WlBuffer>),
    /// Failed to create EGLImages from the buffer
    EGLImageCreationFailed,
    /// The required EGL extension is not supported by the underlying EGL implementation
    EglExtensionNotSupported(EglExtensionNotSupportedError),
}

impl fmt::Debug for BufferAccessError {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> ::std::result::Result<(), fmt::Error> {
        match *self {
            BufferAccessError::ContextLost => write!(formatter, "BufferAccessError::ContextLost"),
            BufferAccessError::NotManaged(_) => write!(formatter, "BufferAccessError::NotManaged"),
            BufferAccessError::EGLImageCreationFailed => {
                write!(formatter, "BufferAccessError::EGLImageCreationFailed")
            }
            BufferAccessError::EglExtensionNotSupported(ref err) => write!(formatter, "{:?}", err),
        }
    }
}

impl fmt::Display for BufferAccessError {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> ::std::result::Result<(), fmt::Error> {
        use std::error::Error;
        match *self {
            BufferAccessError::ContextLost
            | BufferAccessError::NotManaged(_)
            | BufferAccessError::EGLImageCreationFailed => write!(formatter, "{}", self.description()),
            BufferAccessError::EglExtensionNotSupported(ref err) => err.fmt(formatter),
        }
    }
}

impl ::std::error::Error for BufferAccessError {
    fn description(&self) -> &str {
        match *self {
            BufferAccessError::ContextLost => "The corresponding context was lost",
            BufferAccessError::NotManaged(_) => "This buffer is not mananged by EGL",
            BufferAccessError::EGLImageCreationFailed => "Failed to create EGLImages from the buffer",
            BufferAccessError::EglExtensionNotSupported(ref err) => err.description(),
        }
    }

    fn cause(&self) -> Option<&::std::error::Error> {
        match *self {
            BufferAccessError::EglExtensionNotSupported(ref err) => Some(err),
            _ => None,
        }
    }
}

impl From<EglExtensionNotSupportedError> for BufferAccessError {
    fn from(error: EglExtensionNotSupportedError) -> Self {
        BufferAccessError::EglExtensionNotSupported(error)
    }
}

/// Error that might happen when binding an `EGLImage` to a gl texture
#[derive(Debug, Clone, PartialEq)]
pub enum TextureCreationError {
    /// The given plane index is out of bounds
    PlaneIndexOutOfBounds,
    /// The OpenGL context has been lost and needs to be recreated.
    ///
    /// All the objects associated to it (textures, buffers, programs, etc.)
    /// need to be recreated from scratch.
    ///
    /// Operations will have no effect. Functions that read textures, buffers, etc.
    /// from OpenGL will return uninitialized data instead.
    ///
    /// A context loss usually happens on mobile devices when the user puts the
    /// application on sleep and wakes it up later. However any OpenGL implementation
    /// can theoretically lose the context at any time.
    ContextLost,
    /// Failed to bind the EGLImage to the given texture
    ///
    /// The given argument is the gl error code
    TextureBindingFailed(u32),
}

impl fmt::Display for TextureCreationError {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> ::std::result::Result<(), fmt::Error> {
        use std::error::Error;
        match *self {
            TextureCreationError::ContextLost => write!(formatter, "{}", self.description()),
            TextureCreationError::PlaneIndexOutOfBounds => write!(formatter, "{}", self.description()),
            TextureCreationError::TextureBindingFailed(code) => write!(
                formatter,
                "{}. Gl error code: {:?}",
                self.description(),
                code
            ),
        }
    }
}

impl ::std::error::Error for TextureCreationError {
    fn description(&self) -> &str {
        match *self {
            TextureCreationError::ContextLost => "The context has been lost, it needs to be recreated",
            TextureCreationError::PlaneIndexOutOfBounds => "This buffer is not mananged by EGL",
            TextureCreationError::TextureBindingFailed(_) => "Failed to create EGLImages from the buffer",
        }
    }

    fn cause(&self) -> Option<&::std::error::Error> {
        None
    }
}

/// Texture format types
#[repr(i32)]
#[allow(non_camel_case_types)]
#[derive(Debug)]
pub enum Format {
    /// RGB format
    RGB = ffi::egl::TEXTURE_RGB as i32,
    /// RGB + alpha channel format
    RGBA = ffi::egl::TEXTURE_RGBA as i32,
    /// External format
    External = ffi::egl::TEXTURE_EXTERNAL_WL,
    /// 2-plane Y and UV format
    Y_UV = ffi::egl::TEXTURE_Y_UV_WL,
    /// 3-plane Y, U and V format
    Y_U_V = ffi::egl::TEXTURE_Y_U_V_WL,
    /// 2-plane Y and XUXV format
{'fraction_non_alphanumeric': 0.12088274044795784, 'fraction_numerical': 0.0018115942028985507, 'mean_word_length': 3.128144119646499, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7571049', 'n_tokens_mistral': 3446, 'n_tokens_neox': 3327, 'n_words': 1014}