From a42f1f58333a9899d36e18e641f3f52517dd58b1 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Wed, 29 Apr 2015 23:05:47 -0400 Subject: [PATCH 1/2] Implemented gl_core flag --- Cargo.toml | 2 +- build.rs | 1 + src/api/cocoa/mod.rs | 29 ++++++++++++++--------------- src/api/glx/mod.rs | 12 ++++++++++-- src/api/win32/init.rs | 16 ++++++++++++++++ src/lib.rs | 19 +++++++++++++++++++ src/window.rs | 12 +++++++++--- 7 files changed, 70 insertions(+), 21 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f059badf..aa417094 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "glutin" -version = "0.0.27" +version = "0.0.28" authors = ["tomaka "] description = "Cross-plaform OpenGL context provider." keywords = ["windowing", "opengl"] diff --git a/build.rs b/build.rs index 4f96710a..3f5fcbec 100644 --- a/build.rs +++ b/build.rs @@ -52,6 +52,7 @@ fn main() { khronos_api::GLX_XML, vec![ "GLX_ARB_create_context".to_string(), + "GLX_ARB_create_context_profile".to_string(), "GLX_ARB_framebuffer_sRGB".to_string(), "GLX_EXT_framebuffer_sRGB".to_string(), "GLX_EXT_swap_control".to_string(), diff --git a/src/api/cocoa/mod.rs b/src/api/cocoa/mod.rs index 7114a872..bbc110dd 100644 --- a/src/api/cocoa/mod.rs +++ b/src/api/cocoa/mod.rs @@ -9,6 +9,7 @@ use libc; use Api; use BuilderAttribs; +use CreationError; use GlContext; use GlRequest; use PixelFormat; @@ -334,7 +335,6 @@ impl Window { Some(window) => window, None => { return Err(OsError(format!("Couldn't create NSWindow"))); }, }; - let view = match Window::create_view(*window) { Some(view) => view, None => { return Err(OsError(format!("Couldn't create NSView"))); }, @@ -469,18 +469,17 @@ impl Window { } } - fn create_context(view: id, builder: &BuilderAttribs) -> (Option, Option) { - let profile = match builder.gl_version { - GlRequest::Latest => NSOpenGLProfileVersion4_1Core as u32, - GlRequest::Specific(Api::OpenGl, (1 ... 2, _)) => NSOpenGLProfileVersionLegacy as u32, - GlRequest::Specific(Api::OpenGl, (3, 0)) => NSOpenGLProfileVersionLegacy as u32, - GlRequest::Specific(Api::OpenGl, (3, 1 ... 2)) => NSOpenGLProfileVersion3_2Core as u32, - GlRequest::Specific(Api::OpenGl, _) => NSOpenGLProfileVersion4_1Core as u32, - GlRequest::Specific(_, _) => panic!("Only the OpenGL API is supported"), // FIXME: return Result - GlRequest::GlThenGles { opengl_version: (1 ... 2, _), .. } => NSOpenGLProfileVersionLegacy as u32, - GlRequest::GlThenGles { opengl_version: (3, 0), .. } => NSOpenGLProfileVersionLegacy as u32, - GlRequest::GlThenGles { opengl_version: (3, 1 ... 2), .. } => NSOpenGLProfileVersion3_2Core as u32, - GlRequest::GlThenGles { .. } => NSOpenGLProfileVersion4_1Core as u32, + fn create_context(view: id, builder: &BuilderAttribs) -> Result<(Option, Option), CreationError> { + let profile = match (builder.gl_version, builder.gl_version.to_gl_version(), builder.gl_core) { + (GlRequest::Latest, _, Some(false)) => NSOpenGLProfileVersionLegacy as u32, + (GlRequest::Latest, _, _) => NSOpenGLProfileVersion4_1Core as u32, + (_, Some(1 ... 2, _), Some(true)) | + (_, Some(3 ... 4, _), Some(false)) => + return Err(CreationError::NotSupported), + (_, Some(1 ... 2, _), _) => NSOpenGLProfileVersionLegacy as u32, + (_, Some(3, 0 ... 2), _) => NSOpenGLProfileVersion3_2Core as u32, + (_, Some(3 ... 4, _), _) => NSOpenGLProfileVersion4_1Core as u32, + _ => return Err(CreationError::NotSupported), }; // NOTE: OS X no longer has the concept of setting individual @@ -517,7 +516,7 @@ impl Window { // attribute list must be null terminated. attributes.push(0); - unsafe { + Ok(unsafe { let pixelformat = IdRef::new(NSOpenGLPixelFormat::alloc(nil).initWithAttributes_(&attributes)); if let Some(pixelformat) = pixelformat.non_nil() { @@ -575,7 +574,7 @@ impl Window { } else { (None, None) } - } + }) } pub fn is_closed(&self) -> bool { diff --git a/src/api/glx/mod.rs b/src/api/glx/mod.rs index 7aa77e7a..b0efc379 100644 --- a/src/api/glx/mod.rs +++ b/src/api/glx/mod.rs @@ -52,6 +52,16 @@ impl Context { }, } + if let Some(core) = builder.gl_core { + attributes.push(ffi::glx_extra::CONTEXT_PROFILE_MASK_ARB as libc::c_int); + attributes.push(if core { + ffi::glx_extra::CONTEXT_CORE_PROFILE_BIT_ARB + } else { + ffi::glx_extra::CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB + } as libc::c_int + ); + } + if builder.gl_debug { attributes.push(ffi::glx_extra::CONTEXT_FLAGS_ARB as libc::c_int); attributes.push(ffi::glx_extra::CONTEXT_DEBUG_BIT_ARB as libc::c_int); @@ -184,8 +194,6 @@ unsafe impl Sync for Context {} impl Drop for Context { fn drop(&mut self) { - use std::ptr; - unsafe { // we don't call MakeCurrent(0, 0) because we are not sure that the context // is still the current one diff --git a/src/api/win32/init.rs b/src/api/win32/init.rs index 39b9d97e..3837069c 100644 --- a/src/api/win32/init.rs +++ b/src/api/win32/init.rs @@ -374,6 +374,22 @@ unsafe fn create_context(extra: Option<(&gl::wgl_extra::Wgl, &BuilderAttribs<'st }, } + if let Some(core) = builder.gl_core { + if is_extension_supported(extra_functions, hdc, + "WGL_ARB_create_context_profile") + { + attributes.push(gl::wgl_extra::CONTEXT_PROFILE_MASK_ARB as libc::c_int); + attributes.push(if core { + gl::wgl_extra::CONTEXT_CORE_PROFILE_BIT_ARB + } else { + gl::wgl_extra::CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB + } as libc::c_int + ); + } else { + return Err(CreationError::NotSupported); + } + } + if builder.gl_debug { attributes.push(gl::wgl_extra::CONTEXT_FLAGS_ARB as libc::c_int); attributes.push(gl::wgl_extra::CONTEXT_DEBUG_BIT_ARB as libc::c_int); diff --git a/src/lib.rs b/src/lib.rs index be660993..713efefa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -161,6 +161,22 @@ pub enum GlRequest { }, } +impl GlRequest { + /// Extract the desktop GL version, if any. + pub fn to_gl_version(&self) -> Option<(u8, u8)> { + match self { + &GlRequest::Specific(Api::OpenGl, version) => Some(version), + &GlRequest::GlThenGles { opengl_version: version, .. } => Some(version), + _ => None, + } + } +} + +/// The minimum core profile GL context. Useful for getting the minimum +/// required GL version while still running on OSX, which often forbids +/// the compatibility profile features. +pub static GL_CORE: GlRequest = GlRequest::Specific(Api::OpenGl, (3, 2)); + #[derive(Debug, Copy, Clone)] pub enum MouseCursor { /// The platform-dependent default cursor. @@ -261,6 +277,7 @@ pub struct BuilderAttribs<'a> { title: String, monitor: Option, gl_version: GlRequest, + gl_core: Option, gl_debug: bool, vsync: bool, visible: bool, @@ -283,6 +300,7 @@ impl BuilderAttribs<'static> { title: "glutin window".to_string(), monitor: None, gl_version: GlRequest::Latest, + gl_core: None, gl_debug: cfg!(debug_assertions), vsync: false, visible: true, @@ -309,6 +327,7 @@ impl<'a> BuilderAttribs<'a> { title: self.title, monitor: self.monitor, gl_version: self.gl_version, + gl_core: self.gl_core, gl_debug: self.gl_debug, vsync: self.vsync, visible: self.visible, diff --git a/src/window.rs b/src/window.rs index 7508f329..8898e1ec 100644 --- a/src/window.rs +++ b/src/window.rs @@ -67,6 +67,12 @@ impl<'a> WindowBuilder<'a> { self } + /// Sets the Core/Compatibility flag of the created OpenGL context. + pub fn with_gl_core_profile(mut self, core: bool) -> WindowBuilder<'a> { + self.attribs.gl_core = Some(core); + self + } + /// Sets the *debug* flag for the OpenGL context. /// /// The default value for this flag is `cfg!(debug_assertions)`, which means that it's enabled @@ -124,9 +130,9 @@ impl<'a> WindowBuilder<'a> { self } - /// Sets whether sRGB should be enabled on the window. `None` means "I don't care". - pub fn with_srgb(mut self, srgb_enabled: Option) -> WindowBuilder<'a> { - self.attribs.srgb = srgb_enabled; + /// Sets whether sRGB should be enabled on the window. + pub fn with_srgb(mut self, srgb: bool) -> WindowBuilder<'a> { + self.attribs.srgb = Some(srgb); self } From 171986c7e86063862d16208296c011cd5828bcad Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 30 Apr 2015 23:06:22 -0400 Subject: [PATCH 2/2] Introduced GlProfile enum --- src/api/cocoa/mod.rs | 9 +++++---- src/api/glx/mod.rs | 16 +++++++++------- src/api/win32/init.rs | 16 +++++++++------- src/lib.rs | 15 ++++++++++++--- src/window.rs | 13 +++++++------ 5 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/api/cocoa/mod.rs b/src/api/cocoa/mod.rs index bbc110dd..a58001de 100644 --- a/src/api/cocoa/mod.rs +++ b/src/api/cocoa/mod.rs @@ -11,6 +11,7 @@ use Api; use BuilderAttribs; use CreationError; use GlContext; +use GlProfile; use GlRequest; use PixelFormat; use native_monitor::NativeMonitorId; @@ -470,11 +471,11 @@ impl Window { } fn create_context(view: id, builder: &BuilderAttribs) -> Result<(Option, Option), CreationError> { - let profile = match (builder.gl_version, builder.gl_version.to_gl_version(), builder.gl_core) { - (GlRequest::Latest, _, Some(false)) => NSOpenGLProfileVersionLegacy as u32, + let profile = match (builder.gl_version, builder.gl_version.to_gl_version(), builder.gl_profile) { + (GlRequest::Latest, _, Some(GlProfile::Compatibility)) => NSOpenGLProfileVersionLegacy as u32, (GlRequest::Latest, _, _) => NSOpenGLProfileVersion4_1Core as u32, - (_, Some(1 ... 2, _), Some(true)) | - (_, Some(3 ... 4, _), Some(false)) => + (_, Some(1 ... 2, _), Some(GlProfile::Core)) | + (_, Some(3 ... 4, _), Some(GlProfile::Compatibility)) => return Err(CreationError::NotSupported), (_, Some(1 ... 2, _), _) => NSOpenGLProfileVersionLegacy as u32, (_, Some(3, 0 ... 2), _) => NSOpenGLProfileVersion3_2Core as u32, diff --git a/src/api/glx/mod.rs b/src/api/glx/mod.rs index b0efc379..cb61dfa7 100644 --- a/src/api/glx/mod.rs +++ b/src/api/glx/mod.rs @@ -3,6 +3,7 @@ use BuilderAttribs; use CreationError; use GlContext; +use GlProfile; use GlRequest; use Api; use PixelFormat; @@ -52,14 +53,15 @@ impl Context { }, } - if let Some(core) = builder.gl_core { + if let Some(profile) = builder.gl_profile { + let flag = match profile { + GlProfile::Compatibility => + ffi::glx_extra::CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + GlProfile::Core => + ffi::glx_extra::CONTEXT_CORE_PROFILE_BIT_ARB, + }; attributes.push(ffi::glx_extra::CONTEXT_PROFILE_MASK_ARB as libc::c_int); - attributes.push(if core { - ffi::glx_extra::CONTEXT_CORE_PROFILE_BIT_ARB - } else { - ffi::glx_extra::CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB - } as libc::c_int - ); + attributes.push(flag as libc::c_int); } if builder.gl_debug { diff --git a/src/api/win32/init.rs b/src/api/win32/init.rs index 3837069c..e5b0b3a0 100644 --- a/src/api/win32/init.rs +++ b/src/api/win32/init.rs @@ -17,6 +17,7 @@ use BuilderAttribs; use CreationError; use CreationError::OsError; use CursorState; +use GlProfile; use GlRequest; use PixelFormat; @@ -374,17 +375,18 @@ unsafe fn create_context(extra: Option<(&gl::wgl_extra::Wgl, &BuilderAttribs<'st }, } - if let Some(core) = builder.gl_core { + if let Some(profile) = builder.gl_profile { if is_extension_supported(extra_functions, hdc, "WGL_ARB_create_context_profile") { + let flag = match profile { + GlProfile::Compatibility => + gl::wgl_extra::CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + GlProfile::Core => + gl::wgl_extra::CONTEXT_CORE_PROFILE_BIT_ARB, + }; attributes.push(gl::wgl_extra::CONTEXT_PROFILE_MASK_ARB as libc::c_int); - attributes.push(if core { - gl::wgl_extra::CONTEXT_CORE_PROFILE_BIT_ARB - } else { - gl::wgl_extra::CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB - } as libc::c_int - ); + attributes.push(flag as libc::c_int); } else { return Err(CreationError::NotSupported); } diff --git a/src/lib.rs b/src/lib.rs index 713efefa..d52077d2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -137,6 +137,15 @@ pub enum Api { WebGl, } +/// Describes the requested OpenGL context profiles. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum GlProfile { + /// Include all the immediate more functions and definitions. + Compatibility, + /// Include all the future-compatible functions and definitions. + Core, +} + /// Describes the OpenGL API and version that are being requested when a context is created. #[derive(Debug, Copy, Clone)] pub enum GlRequest { @@ -277,7 +286,7 @@ pub struct BuilderAttribs<'a> { title: String, monitor: Option, gl_version: GlRequest, - gl_core: Option, + gl_profile: Option, gl_debug: bool, vsync: bool, visible: bool, @@ -300,7 +309,7 @@ impl BuilderAttribs<'static> { title: "glutin window".to_string(), monitor: None, gl_version: GlRequest::Latest, - gl_core: None, + gl_profile: None, gl_debug: cfg!(debug_assertions), vsync: false, visible: true, @@ -327,7 +336,7 @@ impl<'a> BuilderAttribs<'a> { title: self.title, monitor: self.monitor, gl_version: self.gl_version, - gl_core: self.gl_core, + gl_profile: self.gl_profile, gl_debug: self.gl_debug, vsync: self.vsync, visible: self.visible, diff --git a/src/window.rs b/src/window.rs index 8898e1ec..c21b82dc 100644 --- a/src/window.rs +++ b/src/window.rs @@ -7,6 +7,7 @@ use CreationError; use CursorState; use Event; use GlContext; +use GlProfile; use GlRequest; use MouseCursor; use PixelFormat; @@ -67,9 +68,9 @@ impl<'a> WindowBuilder<'a> { self } - /// Sets the Core/Compatibility flag of the created OpenGL context. - pub fn with_gl_core_profile(mut self, core: bool) -> WindowBuilder<'a> { - self.attribs.gl_core = Some(core); + /// Sets the desired OpenGL context profile. + pub fn with_gl_profile(mut self, profile: GlProfile) -> WindowBuilder<'a> { + self.attribs.gl_profile = Some(profile); self } @@ -130,9 +131,9 @@ impl<'a> WindowBuilder<'a> { self } - /// Sets whether sRGB should be enabled on the window. - pub fn with_srgb(mut self, srgb: bool) -> WindowBuilder<'a> { - self.attribs.srgb = Some(srgb); + /// Sets whether sRGB should be enabled on the window. `None` means "I don't care". + pub fn with_srgb(mut self, srgb_enabled: Option) -> WindowBuilder<'a> { + self.attribs.srgb = srgb_enabled; self }