mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 06:41:31 +11:00
Merge pull request #523 from tomaka/egl-split
Split creating an EGL context in two parts
This commit is contained in:
commit
896640f2e0
|
@ -111,8 +111,8 @@ impl Window {
|
||||||
return Err(OsError(format!("Android's native window is null")));
|
return Err(OsError(format!("Android's native window is null")));
|
||||||
}
|
}
|
||||||
|
|
||||||
let context = try!(EglContext::new(egl::ffi::egl::Egl, &builder, None,
|
let context = try!(EglContext::new(egl::ffi::egl::Egl, &builder, None)
|
||||||
native_window as *const _));
|
.and_then(|p| p.finish(native_window as *const _)));
|
||||||
|
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
android_glue::add_sender(tx);
|
android_glue::add_sender(tx);
|
||||||
|
|
|
@ -26,9 +26,14 @@ pub struct Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
pub fn new(egl: ffi::egl::Egl, builder: &BuilderAttribs,
|
/// Start building an EGL context.
|
||||||
native_display: Option<ffi::EGLNativeDisplayType>,
|
///
|
||||||
native_window: ffi::EGLNativeWindowType) -> Result<Context, CreationError>
|
/// This function initializes some things and chooses the pixel format.
|
||||||
|
///
|
||||||
|
/// To finish the process, you must call `.finish(window)` on the `ContextPrototype`.
|
||||||
|
pub fn new<'a>(egl: ffi::egl::Egl, builder: &'a BuilderAttribs<'a>,
|
||||||
|
native_display: Option<ffi::EGLNativeDisplayType>)
|
||||||
|
-> Result<ContextPrototype<'a>, CreationError>
|
||||||
{
|
{
|
||||||
if builder.sharing.is_some() {
|
if builder.sharing.is_some() {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
|
@ -106,60 +111,14 @@ impl Context {
|
||||||
let configs = unsafe { try!(enumerate_configs(&egl, display, &egl_version, api, version)) };
|
let configs = unsafe { try!(enumerate_configs(&egl, display, &egl_version, api, version)) };
|
||||||
let (config_id, pixel_format) = try!(builder.choose_pixel_format(configs.into_iter()));
|
let (config_id, pixel_format) = try!(builder.choose_pixel_format(configs.into_iter()));
|
||||||
|
|
||||||
let surface = unsafe {
|
Ok(ContextPrototype {
|
||||||
let surface = egl.CreateWindowSurface(display, config_id, native_window, ptr::null());
|
builder: builder,
|
||||||
if surface.is_null() {
|
|
||||||
return Err(CreationError::OsError(format!("eglCreateWindowSurface failed")))
|
|
||||||
}
|
|
||||||
surface
|
|
||||||
};
|
|
||||||
|
|
||||||
let context = unsafe {
|
|
||||||
if let Some(version) = version {
|
|
||||||
try!(create_context(&egl, display, &egl_version, api, version, config_id,
|
|
||||||
builder.gl_debug, builder.gl_robustness))
|
|
||||||
|
|
||||||
} else if api == Api::OpenGlEs {
|
|
||||||
if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (2, 0),
|
|
||||||
config_id, builder.gl_debug, builder.gl_robustness)
|
|
||||||
{
|
|
||||||
ctxt
|
|
||||||
} else if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (1, 0),
|
|
||||||
config_id, builder.gl_debug,
|
|
||||||
builder.gl_robustness)
|
|
||||||
{
|
|
||||||
ctxt
|
|
||||||
} else {
|
|
||||||
return Err(CreationError::NotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (3, 2),
|
|
||||||
config_id, builder.gl_debug, builder.gl_robustness)
|
|
||||||
{
|
|
||||||
ctxt
|
|
||||||
} else if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (3, 1),
|
|
||||||
config_id, builder.gl_debug,
|
|
||||||
builder.gl_robustness)
|
|
||||||
{
|
|
||||||
ctxt
|
|
||||||
} else if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (1, 0),
|
|
||||||
config_id, builder.gl_debug,
|
|
||||||
builder.gl_robustness)
|
|
||||||
{
|
|
||||||
ctxt
|
|
||||||
} else {
|
|
||||||
return Err(CreationError::NotSupported);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Context {
|
|
||||||
egl: egl,
|
egl: egl,
|
||||||
display: display,
|
display: display,
|
||||||
context: context,
|
egl_version: egl_version,
|
||||||
surface: surface,
|
|
||||||
api: api,
|
api: api,
|
||||||
|
version: version,
|
||||||
|
config_id: config_id,
|
||||||
pixel_format: pixel_format,
|
pixel_format: pixel_format,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -234,6 +193,96 @@ impl Drop for Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ContextPrototype<'a> {
|
||||||
|
builder: &'a BuilderAttribs<'a>,
|
||||||
|
egl: ffi::egl::Egl,
|
||||||
|
display: ffi::egl::types::EGLDisplay,
|
||||||
|
egl_version: (ffi::egl::types::EGLint, ffi::egl::types::EGLint),
|
||||||
|
api: Api,
|
||||||
|
version: Option<(u8, u8)>,
|
||||||
|
config_id: ffi::egl::types::EGLConfig,
|
||||||
|
pixel_format: PixelFormat,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ContextPrototype<'a> {
|
||||||
|
pub fn get_native_visual_id(&self) -> ffi::egl::types::EGLint {
|
||||||
|
let mut value = unsafe { mem::uninitialized() };
|
||||||
|
let ret = unsafe { self.egl.GetConfigAttrib(self.display, self.config_id,
|
||||||
|
ffi::egl::NATIVE_VISUAL_ID
|
||||||
|
as ffi::egl::types::EGLint, &mut value) };
|
||||||
|
if ret == 0 { panic!("eglGetConfigAttrib failed") };
|
||||||
|
value
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn finish(self, native_window: ffi::EGLNativeWindowType)
|
||||||
|
-> Result<Context, CreationError>
|
||||||
|
{
|
||||||
|
let surface = unsafe {
|
||||||
|
let surface = self.egl.CreateWindowSurface(self.display, self.config_id, native_window,
|
||||||
|
ptr::null());
|
||||||
|
if surface.is_null() {
|
||||||
|
return Err(CreationError::OsError(format!("eglCreateWindowSurface failed")))
|
||||||
|
}
|
||||||
|
surface
|
||||||
|
};
|
||||||
|
|
||||||
|
let context = unsafe {
|
||||||
|
if let Some(version) = self.version {
|
||||||
|
try!(create_context(&self.egl, self.display, &self.egl_version, self.api,
|
||||||
|
version, self.config_id, self.builder.gl_debug,
|
||||||
|
self.builder.gl_robustness))
|
||||||
|
|
||||||
|
} else if self.api == Api::OpenGlEs {
|
||||||
|
if let Ok(ctxt) = create_context(&self.egl, self.display, &self.egl_version,
|
||||||
|
self.api, (2, 0), self.config_id,
|
||||||
|
self.builder.gl_debug, self.builder.gl_robustness)
|
||||||
|
{
|
||||||
|
ctxt
|
||||||
|
} else if let Ok(ctxt) = create_context(&self.egl, self.display, &self.egl_version,
|
||||||
|
self.api, (1, 0), self.config_id,
|
||||||
|
self.builder.gl_debug,
|
||||||
|
self.builder.gl_robustness)
|
||||||
|
{
|
||||||
|
ctxt
|
||||||
|
} else {
|
||||||
|
return Err(CreationError::NotSupported);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if let Ok(ctxt) = create_context(&self.egl, self.display, &self.egl_version,
|
||||||
|
self.api, (3, 2), self.config_id,
|
||||||
|
self.builder.gl_debug, self.builder.gl_robustness)
|
||||||
|
{
|
||||||
|
ctxt
|
||||||
|
} else if let Ok(ctxt) = create_context(&self.egl, self.display, &self.egl_version,
|
||||||
|
self.api, (3, 1), self.config_id,
|
||||||
|
self.builder.gl_debug,
|
||||||
|
self.builder.gl_robustness)
|
||||||
|
{
|
||||||
|
ctxt
|
||||||
|
} else if let Ok(ctxt) = create_context(&self.egl, self.display, &self.egl_version,
|
||||||
|
self.api, (1, 0), self.config_id,
|
||||||
|
self.builder.gl_debug,
|
||||||
|
self.builder.gl_robustness)
|
||||||
|
{
|
||||||
|
ctxt
|
||||||
|
} else {
|
||||||
|
return Err(CreationError::NotSupported);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Context {
|
||||||
|
egl: self.egl,
|
||||||
|
display: self.display,
|
||||||
|
context: context,
|
||||||
|
surface: surface,
|
||||||
|
api: self.api,
|
||||||
|
pixel_format: self.pixel_format,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn enumerate_configs(egl: &ffi::egl::Egl, display: ffi::egl::types::EGLDisplay,
|
unsafe fn enumerate_configs(egl: &ffi::egl::Egl, display: ffi::egl::types::EGLDisplay,
|
||||||
egl_version: &(ffi::egl::types::EGLint, ffi::egl::types::EGLint),
|
egl_version: &(ffi::egl::types::EGLint, ffi::egl::types::EGLint),
|
||||||
api: Api, version: Option<(u8, u8)>)
|
api: Api, version: Option<(u8, u8)>)
|
||||||
|
|
|
@ -169,9 +169,9 @@ impl Window {
|
||||||
try!(EglContext::new(
|
try!(EglContext::new(
|
||||||
egl,
|
egl,
|
||||||
&builder,
|
&builder,
|
||||||
Some(wayland_context.display.ptr() as *const _),
|
Some(wayland_context.display.ptr() as *const _))
|
||||||
(*shell_surface).ptr() as *const _
|
.and_then(|p| p.finish((*shell_surface).ptr() as *const _))
|
||||||
))
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let events = Arc::new(Mutex::new(VecDeque::new()));
|
let events = Arc::new(Mutex::new(VecDeque::new()));
|
||||||
|
|
|
@ -177,8 +177,8 @@ unsafe fn init(title: Vec<u16>, builder: BuilderAttribs<'static>,
|
||||||
unsafe { kernel32::GetProcAddress(dll, name.as_ptr()) as *const libc::c_void }
|
unsafe { kernel32::GetProcAddress(dll, name.as_ptr()) as *const libc::c_void }
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Ok(c) = EglContext::new(egl, &builder, Some(ptr::null()),
|
if let Ok(c) = EglContext::new(egl, &builder, Some(ptr::null()))
|
||||||
real_window.0)
|
.and_then(|p| p.finish(real_window.0))
|
||||||
{
|
{
|
||||||
Context::Egl(c)
|
Context::Egl(c)
|
||||||
|
|
||||||
|
|
|
@ -552,14 +552,14 @@ impl Window {
|
||||||
Context::Glx(try!(GlxContext::new(glx.clone(), builder, display.display, window,
|
Context::Glx(try!(GlxContext::new(glx.clone(), builder, display.display, window,
|
||||||
fb_config, visual_infos)))
|
fb_config, visual_infos)))
|
||||||
} else if let Some(ref egl) = display.egl {
|
} else if let Some(ref egl) = display.egl {
|
||||||
Context::Egl(try!(EglContext::new(egl.clone(), &builder, Some(display.display as *const _), window as *const _)))
|
Context::Egl(try!(EglContext::new(egl.clone(), &builder, Some(display.display as *const _)).and_then(|p| p.finish(window as *const _))))
|
||||||
} else {
|
} else {
|
||||||
return Err(CreationError::NotSupported);
|
return Err(CreationError::NotSupported);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
GlRequest::Specific(Api::OpenGlEs, _) => {
|
GlRequest::Specific(Api::OpenGlEs, _) => {
|
||||||
if let Some(ref egl) = display.egl {
|
if let Some(ref egl) = display.egl {
|
||||||
Context::Egl(try!(EglContext::new(egl.clone(), &builder, Some(display.display as *const _), window as *const _)))
|
Context::Egl(try!(EglContext::new(egl.clone(), &builder, Some(display.display as *const _)).and_then(|p| p.finish(window as *const _))))
|
||||||
} else {
|
} else {
|
||||||
return Err(CreationError::NotSupported);
|
return Err(CreationError::NotSupported);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue