use crate::render::egl::display::EglDisplay; use crate::render::egl::sys::{ eglDestroyContext, eglMakeCurrent, EGLContext, EGLSurface, EGL_FALSE, EGL_TRUE, }; use crate::render::ext::GlExt; use crate::render::gl::sys::{GLint, GLuint}; use crate::render::RenderError; use std::rc::Rc; #[derive(Debug, Clone)] pub struct EglContext { pub dpy: Rc, pub ext: GlExt, pub ctx: EGLContext, pub tex_prog: GLuint, pub tex_tex: GLint, pub tex_texcoord: GLint, pub tex_pos: GLint, } impl Drop for EglContext { fn drop(&mut self) { unsafe { if eglDestroyContext(self.dpy.dpy, self.ctx) != EGL_TRUE { log::warn!("`eglDestroyContext` failed"); } } } } #[thread_local] static mut CURRENT: EGLContext = EGLContext::none(); impl EglContext { #[inline] pub fn with_current Result>( &self, f: F, ) -> Result { unsafe { if CURRENT == self.ctx { return f(); } self.with_current_slow(f) } } #[cold] unsafe fn with_current_slow Result>( &self, f: F, ) -> Result { if eglMakeCurrent( self.dpy.dpy, EGLSurface::none(), EGLSurface::none(), self.ctx, ) == EGL_FALSE { return Err(RenderError::MakeCurrent); } let prev = CURRENT; CURRENT = self.ctx; let res = f(); if eglMakeCurrent(self.dpy.dpy, EGLSurface::none(), EGLSurface::none(), prev) == EGL_FALSE { panic!("Could not restore EGLContext"); } CURRENT = prev; res } }