use glutin::api::egl::display::Display;
use glutin::api::egl::{context::PossiblyCurrentContext, surface::Surface, device::Device};
use glutin::context::{ContextApi, ContextAttributesBuilder, GlProfile, Version};
use glutin::prelude::{GlDisplay, NotCurrentGlContext, PossiblyCurrentGlContext};
use glutin::surface::{PbufferSurface, SurfaceAttributesBuilder};
use glutin::config::{ConfigSurfaceTypes, ConfigTemplateBuilder};
use std::num::NonZero;
#[derive(Debug)]
pub(crate) struct GlStateEgl {
pub(crate) context: PossiblyCurrentContext,
pub(crate) surface: Surface<PbufferSurface>,
}
impl GlStateEgl {
pub(crate) fn new(width: NonZero<u32>, height: NonZero<u32>) -> glutin::error::Result<Self> {
let device = Device::query_devices().map_err(|e|
if glutin::error::ErrorKind::NotFound == e.error_kind() {
glutin::error::ErrorKind::NotSupported("EGL was not found").into()
} else { e }
)?.next().ok_or_else(||
glutin::error::ErrorKind::NotSupported("could not find any compatible devices")
)?;
let display = unsafe { Display::with_device(&device, None)? };
let config_template = ConfigTemplateBuilder::new()
.with_surface_type(ConfigSurfaceTypes::PBUFFER)
.with_alpha_size(0)
.with_depth_size(24)
.with_stencil_size(8)
.build();
let config = unsafe { display.find_configs(config_template)?.next().ok_or_else(||
glutin::error::ErrorKind::NotSupported("could not find any compatible configs")
)}?;
let context_attrs = ContextAttributesBuilder::new()
.with_profile(GlProfile::Compatibility)
.with_context_api(ContextApi::OpenGl(Some(Version::new(2, 0))))
.build(None);
let context_not_current = unsafe { display.create_context(&config, &context_attrs)? };
let surface_attrs = SurfaceAttributesBuilder::<PbufferSurface>::new()
.build(width, height);
let surface = unsafe { display.create_pbuffer_surface(&config, &surface_attrs)? };
let context = context_not_current.make_current(&surface)?;
Ok(Self {context, surface})
}
pub(crate) fn make_current(&self) -> Result<(), glutin::error::Error> {
self.context.make_current(&self.surface)
}
}