diff options
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 65 |
1 files changed, 60 insertions, 5 deletions
@@ -46,6 +46,8 @@ extern crate dwmapi; #[macro_use] extern crate objc; #[cfg(target_os = "macos")] +extern crate cgl; +#[cfg(target_os = "macos")] extern crate cocoa; #[cfg(target_os = "macos")] extern crate core_foundation; @@ -63,6 +65,8 @@ pub use window::{AvailableMonitorsIter, MonitorID, get_available_monitors, get_p #[cfg(feature = "window")] pub use native_monitor::NativeMonitorId; +use std::io; + mod api; mod platform; mod events; @@ -73,7 +77,7 @@ mod window; /// Trait that describes objects that have access to an OpenGL context. pub trait GlContext { /// Sets the context as the current context. - unsafe fn make_current(&self); + unsafe fn make_current(&self) -> Result<(), ContextError>; /// Returns true if this context is the current one in this thread. fn is_current(&self) -> bool; @@ -84,12 +88,12 @@ pub trait GlContext { /// Swaps the buffers in case of double or triple buffering. /// /// You should call this function every time you have finished rendering, or the image - /// may not be displayed on the screen. + /// may not be displayed on the screen. /// /// **Warning**: if you enabled vsync, this function will block until the next time the screen /// is refreshed. However drivers can choose to override your vsync settings, which means that /// you can't know in advance whether `swap_buffers` will block or not. - fn swap_buffers(&self); + fn swap_buffers(&self) -> Result<(), ContextError>; /// Returns the OpenGL API being used. fn get_api(&self) -> Api; @@ -126,6 +130,13 @@ impl std::error::Error for CreationError { } } +/// Error that can happen when manipulating an OpenGL context. +#[derive(Debug)] +pub enum ContextError { + IoError(io::Error), + ContextLost, +} + /// All APIs related to OpenGL that you can possibly get while using glutin. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Api { @@ -186,6 +197,40 @@ impl GlRequest { /// the compatibility profile features. pub static GL_CORE: GlRequest = GlRequest::Specific(Api::OpenGl, (3, 2)); +/// Specifies the tolerance of the OpenGL context to faults. If you accept raw OpenGL commands +/// and/or raw shader code from an untrusted source, you should definitely care about this. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum Robustness { + /// Not everything is checked. Your application can crash if you do something wrong with your + /// shaders. + NotRobust, + + /// The driver doesn't check anything. This option is very dangerous. Please know what you're + /// doing before using it. See the `GL_KHR_no_error` extension. + /// + /// Since this option is purely an optimisation, no error will be returned if the backend + /// doesn't support it. Instead it will automatically fall back to `NotRobust`. + NoError, + + /// Everything is checked to avoid any crash. The driver will attempt to avoid any problem, + /// but if a problem occurs the behavior is implementation-defined. You are just guaranteed not + /// to get a crash. + RobustNoResetNotification, + + /// Same as `RobustNoResetNotification` but the context creation doesn't fail if it's not + /// supported. + TryRobustNoResetNotification, + + /// Everything is checked to avoid any crash. If a problem occurs, the context will enter a + /// "context lost" state. It must then be recreated. For the moment, glutin doesn't provide a + /// way to recreate a context with the same window :-/ + RobustLoseContextOnReset, + + /// Same as `RobustLoseContextOnReset` but the context creation doesn't fail if it's not + /// supported. + TryRobustLoseContextOnReset, +} + #[derive(Debug, Copy, Clone)] pub enum MouseCursor { /// The platform-dependent default cursor. @@ -288,6 +333,7 @@ pub struct BuilderAttribs<'a> { gl_version: GlRequest, gl_profile: Option<GlProfile>, gl_debug: bool, + gl_robustness: Robustness, vsync: bool, visible: bool, multisampling: Option<u16>, @@ -314,6 +360,7 @@ impl BuilderAttribs<'static> { gl_version: GlRequest::Latest, gl_profile: None, gl_debug: cfg!(debug_assertions), + gl_robustness: Robustness::NotRobust, vsync: false, visible: true, multisampling: None, @@ -345,6 +392,7 @@ impl<'a> BuilderAttribs<'a> { gl_version: self.gl_version, gl_profile: self.gl_profile, gl_debug: self.gl_debug, + gl_robustness: self.gl_robustness, vsync: self.vsync, visible: self.visible, multisampling: self.multisampling, @@ -390,8 +438,15 @@ impl<'a> BuilderAttribs<'a> { continue; } - if self.multisampling.is_some() && format.multisampling.is_none() { - continue; + if let Some(req_ms) = self.multisampling { + match format.multisampling { + Some(val) if val >= req_ms => (), + _ => continue + } + } else { + if format.multisampling.is_some() { + continue; + } } if let Some(srgb) = self.srgb { |