aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src/renderer')
-rw-r--r--alacritty/src/renderer/mod.rs61
-rw-r--r--alacritty/src/renderer/platform.rs22
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),