From e7bb6c2ea78b719dde491515698e5707a50773b2 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Thu, 24 Mar 2022 12:13:30 +0300 Subject: [PATCH] Persist OpenGL context creation flags This commit persists OpenGL context creation flags from previous window build attempts saving time in multiwindow context. It also creates window as srgb by default, since it's what Alacritty is rendering in. For reference [1] and [2]. Moreover the fallback for 10 bit colors is also added. [1] - https://github.com/alacritty/alacritty/issues/4939 and [2] - https://github.com/alacritty/alacritty/issues/3756. Fixes #4703. --- CHANGELOG.md | 2 ++ alacritty/src/display/window.rs | 55 +++++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d5defa06f..47b5e433fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Creating the IPC socket failing if WAYLAND_DISPLAY contains an absolute path - Crash when resetting the terminal while in vi mode - `font.glyph_offset` not live reloading +- Failure when running on 10-bit color system +- The colors being slightly different when using srgb displays on macOS ## 0.10.1 diff --git a/alacritty/src/display/window.rs b/alacritty/src/display/window.rs index 2d473999c8..cf10f81182 100644 --- a/alacritty/src/display/window.rs +++ b/alacritty/src/display/window.rs @@ -27,7 +27,9 @@ use { use std::fmt::{self, Display, Formatter}; use std::ops::{Deref, DerefMut}; +use std::sync::atomic::{AtomicU8, Ordering}; +use bitflags::bitflags; #[cfg(target_os = "macos")] use cocoa::base::{id, NO, YES}; use glutin::dpi::{PhysicalPosition, PhysicalSize}; @@ -62,6 +64,17 @@ static WINDOW_ICON: &[u8] = include_bytes!("../../alacritty.png"); #[cfg(windows)] const IDI_ICON: WORD = 0x101; +/// Context creation flags from probing config. +static GL_CONTEXT_CREATION_FLAGS: AtomicU8 = AtomicU8::new(GlContextFlags::SRGB.bits); + +bitflags! { + pub struct GlContextFlags: u8 { + const EMPTY = 0b000000000; + const SRGB = 0b0000_0001; + const DEEP_COLOR = 0b0000_0010; + } +} + /// Window errors. #[derive(Debug)] pub enum Error { @@ -119,7 +132,7 @@ impl From for Error { fn create_gl_window( mut window: WindowBuilder, event_loop: &EventLoopWindowTarget, - srgb: bool, + flags: GlContextFlags, vsync: bool, dimensions: Option>, ) -> Result> { @@ -127,11 +140,16 @@ fn create_gl_window( window = window.with_inner_size(dimensions); } - let windowed_context = ContextBuilder::new() - .with_srgb(srgb) + let mut windowed_context_builder = ContextBuilder::new() + .with_srgb(flags.contains(GlContextFlags::SRGB)) .with_vsync(vsync) - .with_hardware_acceleration(None) - .build_windowed(window, event_loop)?; + .with_hardware_acceleration(None); + + if flags.contains(GlContextFlags::DEEP_COLOR) { + windowed_context_builder = windowed_context_builder.with_pixel_format(30, 2); + } + + let windowed_context = windowed_context_builder.build_windowed(window, event_loop)?; // Make the context current so OpenGL operations can run. let windowed_context = unsafe { windowed_context.make_current().map_err(|(_, err)| err)? }; @@ -188,11 +206,28 @@ impl Window { #[cfg(any(not(feature = "wayland"), target_os = "macos", windows))] let is_wayland = false; - let windowed_context = - create_gl_window(window_builder.clone(), event_loop, false, !is_wayland, size) - .or_else(|_| { - create_gl_window(window_builder, event_loop, true, !is_wayland, size) - })?; + let mut windowed_context = None; + let current_flags = + GlContextFlags::from_bits_truncate(GL_CONTEXT_CREATION_FLAGS.load(Ordering::Relaxed)); + for flags in [ + current_flags, + GlContextFlags::EMPTY, + GlContextFlags::SRGB | GlContextFlags::DEEP_COLOR, + GlContextFlags::DEEP_COLOR, + ] { + windowed_context = Some(create_gl_window( + window_builder.clone(), + event_loop, + flags, + !is_wayland, + size, + )); + if windowed_context.as_ref().unwrap().is_ok() { + GL_CONTEXT_CREATION_FLAGS.store(flags.bits, Ordering::Relaxed); + break; + } + } + let windowed_context = windowed_context.unwrap()?; // Text cursor. let current_mouse_cursor = CursorIcon::Text;