aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/display/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src/display/mod.rs')
-rw-r--r--alacritty/src/display/mod.rs61
1 files changed, 56 insertions, 5 deletions
diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs
index 6c685a2a..9f11ccf6 100644
--- a/alacritty/src/display/mod.rs
+++ b/alacritty/src/display/mod.rs
@@ -8,7 +8,10 @@ use std::num::NonZeroU32;
use std::ops::{Deref, DerefMut};
use std::time::{Duration, Instant};
+use glutin::config::GetGlConfig;
use glutin::context::{NotCurrentContext, PossiblyCurrentContext};
+use glutin::display::GetGlDisplay;
+use glutin::error::ErrorKind;
use glutin::prelude::*;
use glutin::surface::{Surface, SwapInterval, WindowSurface};
@@ -33,6 +36,7 @@ use alacritty_terminal::term::{
};
use alacritty_terminal::vte::ansi::{CursorShape, NamedColor};
+use crate::config::debug::RendererPreference;
use crate::config::font::Font;
use crate::config::window::Dimensions;
#[cfg(not(windows))]
@@ -49,7 +53,7 @@ use crate::display::window::Window;
use crate::event::{Event, EventType, Mouse, SearchState};
use crate::message_bar::{MessageBuffer, MessageType};
use crate::renderer::rects::{RenderLine, RenderLines, RenderRect};
-use crate::renderer::{self, GlyphCache, Renderer};
+use crate::renderer::{self, platform, GlyphCache, Renderer};
use crate::scheduler::{Scheduler, TimerId, Topic};
use crate::string::{ShortenDirection, StrShortener};
@@ -385,6 +389,7 @@ pub struct Display {
hint_mouse_point: Option<Point>,
renderer: ManuallyDrop<Renderer>,
+ renderer_preference: Option<RendererPreference>,
surface: ManuallyDrop<Surface<WindowSurface>>,
@@ -421,7 +426,7 @@ impl Display {
}
// Create the GL surface to draw into.
- let surface = renderer::platform::create_gl_surface(
+ let surface = platform::create_gl_surface(
&gl_context,
window.inner_size(),
window.raw_window_handle(),
@@ -513,6 +518,7 @@ impl Display {
context: ManuallyDrop::new(Replaceable::new(context)),
visual_bell: VisualBell::from(&config.bell),
renderer: ManuallyDrop::new(renderer),
+ renderer_preference: config.debug.renderer,
surface: ManuallyDrop::new(surface),
colors: List::from(&config.colors),
frame_timer: FrameTimer::new(),
@@ -552,10 +558,55 @@ impl Display {
}
}
- pub fn make_current(&self) {
- if !self.context.get().is_current() {
- self.context.make_current(&self.surface).expect("failed to make context current")
+ pub fn make_current(&mut self) {
+ let is_current = self.context.get().is_current();
+
+ // Attempt to make the context current if it's not.
+ let context_loss = if is_current {
+ self.renderer.was_context_reset()
+ } else {
+ match self.context.make_current(&self.surface) {
+ Err(err) if err.error_kind() == ErrorKind::ContextLost => {
+ info!("Context lost for window {:?}", self.window.id());
+ true
+ },
+ _ => false,
+ }
+ };
+
+ if !context_loss {
+ return;
+ }
+
+ let gl_display = self.context.display();
+ let gl_config = self.context.config();
+ let raw_window_handle = Some(self.window.raw_window_handle());
+ let context = platform::create_gl_context(&gl_display, &gl_config, raw_window_handle)
+ .expect("failed to recreate context.");
+
+ // Drop the old context and renderer.
+ unsafe {
+ ManuallyDrop::drop(&mut self.renderer);
+ ManuallyDrop::drop(&mut self.context);
}
+
+ // Activate new context.
+ let context = context.treat_as_possibly_current();
+ self.context = ManuallyDrop::new(Replaceable::new(context));
+ self.context.make_current(&self.surface).expect("failed to reativate context after reset.");
+
+ // Recreate renderer.
+ let renderer = Renderer::new(&self.context, self.renderer_preference)
+ .expect("failed to recreate renderer after reset");
+ self.renderer = ManuallyDrop::new(renderer);
+
+ // Resize the renderer.
+ self.renderer.resize(&self.size_info);
+
+ self.reset_glyph_cache();
+ self.damage_tracker.frame().mark_fully_damaged();
+
+ debug!("Recovered window {:?} from gpu reset", self.window.id());
}
fn swap_buffers(&self) {