use super::prelude::*;
use crate::gl::*;
use crate::wrappers::glx::*;
use std::error::Error;
use crate::platform::gl::egl::EglGlContext;
use crate::platform::gl::glx::GlxGlContext;
use crate::platform::x11::xcb_window::XcbWindow;
use crate::wrappers::egl::*;
use std::ffi::{c_void, CStr};
use std::rc::Rc;
use x11rb::protocol::xproto::Visualid;
mod egl;
mod error;
mod glx;
pub use error::GlCreationFailedError;
pub type PlatformGlContext = Rc<GlContextInner>;
pub enum GlContextInner {
Glx(GlxGlContext),
Egl(EglGlContext),
}
pub struct FbConfig {
gl_config: GlConfig,
fb_config: FbConfigInner,
}
enum FbConfigInner {
Glx { glx: Glx, config: GlxFbConfig },
Egl { display: EglDisplay, config: EglConfig },
}
pub struct WindowConfig {
pub depth: u8,
pub visual: u32,
}
impl GlContextInner {
pub fn create(
window: &XcbWindow, connection: &Rc<X11Connection>, fb_config: FbConfig,
) -> PlatformResult<Rc<GlContextInner>> {
let inner =
match fb_config.fb_config {
FbConfigInner::Glx { glx, config } => GlContextInner::Glx(GlxGlContext::create(
window,
connection,
fb_config.gl_config,
config,
glx,
)?),
FbConfigInner::Egl { display, config } => GlContextInner::Egl(
EglGlContext::create(window, &fb_config.gl_config, config, display)?,
),
};
Ok(Rc::new(inner))
}
pub fn get_fb_config_and_visual(
connection: &Rc<X11Connection>, config: GlConfig,
) -> PlatformResult<(FbConfig, WindowConfig)> {
EglGlContext::get_fb_config_and_visual(connection, config.clone())
.or_else(|_| GlxGlContext::get_fb_config_and_visual(connection, config))
}
pub unsafe fn make_current(&self) -> PlatformResult<()> {
match self {
GlContextInner::Glx(glx) => glx.make_current(),
GlContextInner::Egl(egl) => egl.make_current(),
}
}
pub unsafe fn make_not_current(&self) -> PlatformResult<()> {
match self {
GlContextInner::Glx(glx) => glx.make_not_current(),
GlContextInner::Egl(egl) => egl.make_not_current(),
}
}
pub fn get_proc_address(&self, symbol: &CStr) -> *const c_void {
match self {
GlContextInner::Glx(glx) => glx.get_proc_address(symbol),
GlContextInner::Egl(egl) => egl.get_proc_address(symbol),
}
}
pub fn swap_buffers(&self) -> PlatformResult<()> {
match self {
GlContextInner::Glx(glx) => glx.swap_buffers(),
GlContextInner::Egl(egl) => egl.swap_buffers(),
}
}
}