diff options
Diffstat (limited to 'alacritty/src/renderer')
-rw-r--r-- | alacritty/src/renderer/mod.rs | 61 | ||||
-rw-r--r-- | alacritty/src/renderer/platform.rs | 22 |
2 files changed, 65 insertions, 18 deletions
diff --git a/alacritty/src/renderer/mod.rs b/alacritty/src/renderer/mod.rs index 3362db42..92998e58 100644 --- a/alacritty/src/renderer/mod.rs +++ b/alacritty/src/renderer/mod.rs @@ -9,7 +9,7 @@ use ahash::RandomState; use crossfont::Metrics; use glutin::context::{ContextApi, GlContext, PossiblyCurrentContext}; use glutin::display::{GetGlDisplay, GlDisplay}; -use log::{debug, error, info, warn, LevelFilter}; +use log::{debug, info, LevelFilter}; use unicode_width::UnicodeWidthChar; use alacritty_terminal::index::Point; @@ -97,6 +97,7 @@ enum TextRendererProvider { pub struct Renderer { text_renderer: TextRendererProvider, rect_renderer: RectRenderer, + robustness: bool, } /// Wrapper around gl::GetString with error checking and reporting. @@ -144,6 +145,9 @@ impl Renderer { info!("Running on {renderer}"); info!("OpenGL version {gl_version}, shader_version {shader_version}"); + // Check if robustness is supported. + let robustness = Self::supports_robustness(); + let is_gles_context = matches!(context.context_api(), ContextApi::Gles(_)); // Use the config option to enforce a particular renderer configuration. @@ -175,7 +179,7 @@ impl Renderer { } } - Ok(Self { text_renderer, rect_renderer }) + Ok(Self { text_renderer, rect_renderer, robustness }) } pub fn draw_cells<I: Iterator<Item = RenderableCell>>( @@ -281,6 +285,49 @@ impl Renderer { } } + /// Get the context reset status. + pub fn was_context_reset(&self) -> bool { + // If robustness is not supported, don't use its functions. + if !self.robustness { + return false; + } + + let status = unsafe { gl::GetGraphicsResetStatus() }; + if status == gl::NO_ERROR { + false + } else { + let reason = match status { + gl::GUILTY_CONTEXT_RESET_KHR => "guilty", + gl::INNOCENT_CONTEXT_RESET_KHR => "innocent", + gl::UNKNOWN_CONTEXT_RESET_KHR => "unknown", + _ => "invalid", + }; + + info!("GPU reset ({})", reason); + + true + } + } + + fn supports_robustness() -> bool { + let mut notification_strategy = 0; + if GlExtensions::contains("GL_KHR_robustness") { + unsafe { + gl::GetIntegerv(gl::RESET_NOTIFICATION_STRATEGY_KHR, &mut notification_strategy); + } + } else { + notification_strategy = gl::NO_RESET_NOTIFICATION_KHR as gl::types::GLint; + } + + if notification_strategy == gl::LOSE_CONTEXT_ON_RESET_KHR as gl::types::GLint { + info!("GPU reset notifications are enabled"); + true + } else { + info!("GPU reset notifications are disabled"); + false + } + } + pub fn finish(&self) { unsafe { gl::Finish(); @@ -349,7 +396,7 @@ impl GlExtensions { extern "system" fn gl_debug_log( _: gl::types::GLenum, - kind: gl::types::GLenum, + _: gl::types::GLenum, _: gl::types::GLuint, _: gl::types::GLenum, _: gl::types::GLsizei, @@ -357,11 +404,5 @@ extern "system" fn gl_debug_log( _: *mut std::os::raw::c_void, ) { let msg = unsafe { CStr::from_ptr(msg).to_string_lossy() }; - match kind { - gl::DEBUG_TYPE_ERROR | gl::DEBUG_TYPE_UNDEFINED_BEHAVIOR => { - error!("[gl_render] {}", msg) - }, - gl::DEBUG_TYPE_DEPRECATED_BEHAVIOR => warn!("[gl_render] {}", msg), - _ => debug!("[gl_render] {}", msg), - } + debug!("[gl_render] {}", msg); } diff --git a/alacritty/src/renderer/platform.rs b/alacritty/src/renderer/platform.rs index 87ed29c2..3b2e2fce 100644 --- a/alacritty/src/renderer/platform.rs +++ b/alacritty/src/renderer/platform.rs @@ -4,9 +4,9 @@ use std::num::NonZeroU32; use glutin::config::{ColorBufferType, Config, ConfigTemplateBuilder, GetGlConfig}; use glutin::context::{ - ContextApi, ContextAttributesBuilder, GlProfile, NotCurrentContext, Version, + ContextApi, ContextAttributesBuilder, GlProfile, NotCurrentContext, Robustness, Version, }; -use glutin::display::{Display, DisplayApiPreference, GetGlDisplay}; +use glutin::display::{Display, DisplayApiPreference, DisplayFeatures, GetGlDisplay}; use glutin::error::Result as GlutinResult; use glutin::prelude::*; use glutin::surface::{Surface, SurfaceAttributesBuilder, WindowSurface}; @@ -110,18 +110,24 @@ pub fn create_gl_context( raw_window_handle: Option<RawWindowHandle>, ) -> GlutinResult<NotCurrentContext> { let debug = log::max_level() >= LevelFilter::Debug; + let mut builder = ContextAttributesBuilder::new().with_debug(debug); + + // Try to enable robustness. + if gl_display.supported_features().contains(DisplayFeatures::CONTEXT_ROBUSTNESS) { + builder = builder.with_robustness(Robustness::RobustLoseContextOnReset); + } + let mut profiles = [ - ContextAttributesBuilder::new() - .with_debug(debug) + builder + .clone() .with_context_api(ContextApi::OpenGl(Some(Version::new(3, 3)))) .build(raw_window_handle), // Try gles before OpenGL 2.1 as it tends to be more stable. - ContextAttributesBuilder::new() - .with_debug(debug) + builder + .clone() .with_context_api(ContextApi::Gles(Some(Version::new(2, 0)))) .build(raw_window_handle), - ContextAttributesBuilder::new() - .with_debug(debug) + builder .with_profile(GlProfile::Compatibility) .with_context_api(ContextApi::OpenGl(Some(Version::new(2, 1)))) .build(raw_window_handle), |