use super::device::{Adapter, Device, NativeDevice};
use super::surface::NativeWidget;
use crate::egl;
use crate::egl::types::{EGLAttrib, EGLDisplay};
use crate::info::GLApi;
use crate::platform::generic::egl::device::EGL_FUNCTIONS;
use crate::platform::generic::egl::ffi::EGL_PLATFORM_SURFACELESS_MESA;
use crate::Error;
use euclid::default::Size2D;
use std::os::raw::c_void;
use std::sync::Arc;
#[derive(Clone)]
pub struct Connection {
pub(crate) native_connection: Arc<NativeConnectionWrapper>,
}
#[derive(Clone)]
pub struct NativeConnection(Arc<NativeConnectionWrapper>);
pub struct NativeConnectionWrapper {
pub(crate) egl_display: EGLDisplay,
}
unsafe impl Send for NativeConnectionWrapper {}
unsafe impl Sync for NativeConnectionWrapper {}
impl Connection {
#[inline]
pub fn new() -> Result<Connection, Error> {
unsafe {
EGL_FUNCTIONS.with(|egl| {
let egl_display_attributes = [egl::NONE as EGLAttrib];
let egl_display = egl.GetPlatformDisplay(
EGL_PLATFORM_SURFACELESS_MESA,
egl::DEFAULT_DISPLAY as *mut c_void,
egl_display_attributes.as_ptr(),
);
if egl_display == egl::NO_DISPLAY {
return Err(Error::ConnectionFailed);
}
let (mut egl_major_version, mut egl_minor_version) = (0, 0);
let ok =
egl.Initialize(egl_display, &mut egl_major_version, &mut egl_minor_version);
if ok == egl::FALSE {
return Err(Error::ConnectionFailed);
}
let native_connection =
NativeConnection(Arc::new(NativeConnectionWrapper { egl_display }));
Connection::from_native_connection(native_connection)
})
}
}
#[inline]
pub unsafe fn from_native_connection(
native_connection: NativeConnection,
) -> Result<Connection, Error> {
Ok(Connection {
native_connection: native_connection.0,
})
}
#[inline]
pub fn native_connection(&self) -> NativeConnection {
NativeConnection(self.native_connection.clone())
}
#[inline]
pub fn gl_api(&self) -> GLApi {
GLApi::GL
}
#[inline]
pub fn create_adapter(&self) -> Result<Adapter, Error> {
self.create_hardware_adapter()
}
#[inline]
pub fn create_hardware_adapter(&self) -> Result<Adapter, Error> {
Ok(Adapter::hardware())
}
#[inline]
pub fn create_low_power_adapter(&self) -> Result<Adapter, Error> {
Ok(Adapter::low_power())
}
#[inline]
pub fn create_software_adapter(&self) -> Result<Adapter, Error> {
Ok(Adapter::software())
}
#[inline]
pub fn create_device(&self, adapter: &Adapter) -> Result<Device, Error> {
Device::new(self, adapter)
}
#[inline]
pub unsafe fn create_device_from_native_device(
&self,
_: NativeDevice,
) -> Result<Device, Error> {
Device::new(self, &self.create_adapter()?)
}
#[cfg(feature = "sm-raw-window-handle-05")]
pub fn from_raw_display_handle(_: rwh_05::RawDisplayHandle) -> Result<Connection, Error> {
Err(Error::IncompatibleNativeWidget)
}
#[cfg(feature = "sm-raw-window-handle-06")]
pub fn from_display_handle(_: rwh_06::DisplayHandle) -> Result<Connection, Error> {
Err(Error::IncompatibleNativeWidget)
}
pub unsafe fn create_native_widget_from_ptr(
&self,
_raw: *mut c_void,
_size: Size2D<i32>,
) -> NativeWidget {
NativeWidget
}
#[cfg(feature = "sm-raw-window-handle-05")]
#[inline]
pub fn create_native_widget_from_raw_window_handle(
&self,
_: rwh_05::RawWindowHandle,
_size: Size2D<i32>,
) -> Result<NativeWidget, Error> {
Err(Error::IncompatibleNativeWidget)
}
#[cfg(feature = "sm-raw-window-handle-06")]
#[inline]
pub fn create_native_widget_from_window_handle(
&self,
_: rwh_06::WindowHandle,
_size: Size2D<i32>,
) -> Result<NativeWidget, Error> {
Err(Error::IncompatibleNativeWidget)
}
}