From c2b75f293cec74532cc0115c81231ff37da812b0 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Wed, 5 Nov 2025 09:50:43 +0900 Subject: [PATCH] Try both robust and non-robust configs It was suggest to try building both robust and non-robust as a fallback due to 1.5 not mandating robustness, and also not mandating extension, so the robustness can be supported, but without the extension present. This reverts commit 7b33cbcbc287822ad0faf3744cff3db05fb20274. --- CHANGELOG.md | 1 + alacritty/src/renderer/platform.rs | 56 +++++++++++++++++------------- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5460ce9..88f79de3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its - Brief error popup when saving the config file with some editors - Subprocesses on OpenBSD now run with their CWD set to that of the shell's foreground process. +- Crash when OpenGL context resets ## 0.16.1 diff --git a/alacritty/src/renderer/platform.rs b/alacritty/src/renderer/platform.rs index 82ae0e1e..98fac452 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,35 +110,41 @@ pub fn create_gl_context( raw_window_handle: Option, ) -> GlutinResult { let debug = log::max_level() >= LevelFilter::Debug; - let builder = ContextAttributesBuilder::new().with_debug(debug); - let mut profiles = [ - builder - .clone() - .with_context_api(ContextApi::OpenGl(Some(Version::new(3, 3)))) - .build(raw_window_handle), + let apis = [ + (ContextApi::OpenGl(Some(Version::new(3, 3))), GlProfile::Core), // Try gles before OpenGL 2.1 as it tends to be more stable. - builder - .clone() - .with_context_api(ContextApi::Gles(Some(Version::new(2, 0)))) - .build(raw_window_handle), - builder - .with_profile(GlProfile::Compatibility) - .with_context_api(ContextApi::OpenGl(Some(Version::new(2, 1)))) - .build(raw_window_handle), - ] - .into_iter(); + (ContextApi::Gles(Some(Version::new(2, 0))), GlProfile::Core), + (ContextApi::OpenGl(Some(Version::new(2, 1))), GlProfile::Compatibility), + ]; - // Try the optimal config first. - let mut picked_context = - unsafe { gl_display.create_context(gl_config, &profiles.next().unwrap()) }; + let robustness = gl_display.supported_features().contains(DisplayFeatures::CONTEXT_ROBUSTNESS); + let robustness: &[Robustness] = if robustness { + &[Robustness::RobustLoseContextOnReset, Robustness::NotRobust] + } else { + &[Robustness::NotRobust] + }; - // Try the fallback ones. - while let (Err(_), Some(profile)) = (picked_context.as_ref(), profiles.next()) { - picked_context = unsafe { gl_display.create_context(gl_config, &profile) }; + // Find the first context that builds without any errors. + let mut error = None; + for (api, profile) in apis { + for robustness in robustness { + let attributes = ContextAttributesBuilder::new() + .with_debug(debug) + .with_context_api(api) + .with_profile(profile) + .with_robustness(*robustness) + .build(raw_window_handle); + + match unsafe { gl_display.create_context(gl_config, &attributes) } { + Ok(profile) => return Ok(profile), + Err(err) => error = Some(err), + } + } } - picked_context + // If no context was built successfully, return an error for the most permissive one. + Err(error.unwrap()) } pub fn create_gl_surface(