mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 05:12:40 +03:00
windows: Software frontend is now mesa llvmpipe
This is a bit of a switch-up, see this comment for more background: refs: https://github.com/wez/wezterm/issues/265#issuecomment-701882933 This commit: * Adds a pre-compiled mesa3d opengl32.dll replacement * The mesa dll is deployed to `<appdir>/mesa/opengl32.dll` which by default is ignored. * When the frontend is set to `Software` then the `mesa` directory is added to the dll search path, causing the llvmpipe renderer to be enabled. * The old software renderer implementation is available using the `OldSoftware` frontend name I'm not a huge fan of the subdirectory for the opengl32.dll, but I couldn't get it to work under a different dll name; the code thought that everything was initialized, but the window just rendered a white rectangle.
This commit is contained in:
parent
6069eabc9b
commit
e6a858664f
@ -8,6 +8,7 @@ default-run = "wezterm"
|
||||
|
||||
[build-dependencies]
|
||||
vergen = "3"
|
||||
anyhow = "1.0"
|
||||
|
||||
[target.'cfg(windows)'.build-dependencies]
|
||||
embed-resource = "1.3"
|
||||
|
6
assets/windows/mesa/README.md
Normal file
6
assets/windows/mesa/README.md
Normal file
@ -0,0 +1,6 @@
|
||||
This is a pre-built opendl32.dll for 64-bit Windows systems.
|
||||
It was obtained from <http://mesa.fdossena.com/>
|
||||
|
||||
Mesa's License text can be found here:
|
||||
https://docs.mesa3d.org/license.html
|
||||
(a mixture of largely MITish licenses)
|
BIN
assets/windows/mesa/opengl32.dll
Normal file
BIN
assets/windows/mesa/opengl32.dll
Normal file
Binary file not shown.
25
build.rs
25
build.rs
@ -1,3 +1,4 @@
|
||||
use anyhow::Context as _;
|
||||
use std::path::Path;
|
||||
use vergen::{generate_cargo_keys, ConstantsFlags};
|
||||
|
||||
@ -81,7 +82,29 @@ fn main() {
|
||||
let src_name = conhost_dir.join(name);
|
||||
|
||||
if !dest_name.exists() {
|
||||
std::fs::copy(src_name, dest_name).unwrap();
|
||||
std::fs::copy(&src_name, &dest_name)
|
||||
.context(format!(
|
||||
"copy {} -> {}",
|
||||
src_name.display(),
|
||||
dest_name.display()
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let dest_mesa = exe_output_dir.join("mesa");
|
||||
let _ = std::fs::create_dir(&dest_mesa);
|
||||
let dest_name = dest_mesa.join("opengl32.dll");
|
||||
let src_name = windows_dir.join("mesa").join("opengl32.dll");
|
||||
if !dest_name.exists() {
|
||||
std::fs::copy(&src_name, &dest_name)
|
||||
.context(format!(
|
||||
"copy {} -> {}",
|
||||
src_name.display(),
|
||||
dest_name.display()
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,9 @@ case $OSTYPE in
|
||||
assets/windows/conhost/conpty.dll \
|
||||
assets/windows/conhost/OpenConsole.exe \
|
||||
$zipdir
|
||||
mkdir $zipdir/mesa
|
||||
cp $TARGET_DIR/release/mesa/opengl32.dll \
|
||||
$zipdir/mesa
|
||||
7z a -tzip $zipname $zipdir
|
||||
iscc.exe -DMyAppVersion=${TAG_NAME#nightly} -F${instname} ci/windows-installer.iss
|
||||
;;
|
||||
|
@ -43,6 +43,7 @@ Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{
|
||||
|
||||
[Files]
|
||||
Source: "..\target\release\wezterm.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "..\target\release\mesa\opengl32.dll"; DestDir: "{app}\mesa"; Flags: ignoreversion
|
||||
Source: "..\target\release\conpty.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "..\target\release\OpenConsole.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "..\target\release\strip-ansi-escapes.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
|
@ -42,6 +42,11 @@ impl GuiFrontEnd {
|
||||
Self::try_new()
|
||||
}
|
||||
|
||||
pub fn try_new_swrast() -> anyhow::Result<Rc<dyn FrontEnd>> {
|
||||
::window::prefer_swrast();
|
||||
Self::try_new()
|
||||
}
|
||||
|
||||
pub fn try_new() -> anyhow::Result<Rc<dyn FrontEnd>> {
|
||||
#[cfg(all(unix, not(target_os = "macos")))]
|
||||
{
|
||||
@ -49,6 +54,7 @@ impl GuiFrontEnd {
|
||||
Connection::disable_wayland();
|
||||
}
|
||||
}
|
||||
|
||||
let connection = Connection::init()?;
|
||||
let front_end = Rc::new(GuiFrontEnd { connection });
|
||||
Ok(front_end)
|
||||
|
@ -16,6 +16,7 @@ pub mod muxserver;
|
||||
pub enum FrontEndSelection {
|
||||
OpenGL,
|
||||
Software,
|
||||
OldSoftware,
|
||||
MuxServer,
|
||||
Null,
|
||||
}
|
||||
@ -59,7 +60,8 @@ impl FrontEndSelection {
|
||||
let (front_end, is_gui) = match self {
|
||||
FrontEndSelection::MuxServer => (muxserver::MuxServerFrontEnd::try_new(), false),
|
||||
FrontEndSelection::Null => (muxserver::MuxServerFrontEnd::new_null(), false),
|
||||
FrontEndSelection::Software => (gui::GuiFrontEnd::try_new_no_opengl(), true),
|
||||
FrontEndSelection::Software => (gui::GuiFrontEnd::try_new_swrast(), true),
|
||||
FrontEndSelection::OldSoftware => (gui::GuiFrontEnd::try_new_no_opengl(), true),
|
||||
FrontEndSelection::OpenGL => (gui::GuiFrontEnd::try_new(), true),
|
||||
};
|
||||
|
||||
@ -73,7 +75,7 @@ impl FrontEndSelection {
|
||||
|
||||
// TODO: find or build a proc macro for this
|
||||
pub fn variants() -> Vec<&'static str> {
|
||||
vec!["OpenGL", "Software", "MuxServer", "Null"]
|
||||
vec!["OpenGL", "Software", "OldSoftware", "MuxServer", "Null"]
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,6 +86,7 @@ impl std::str::FromStr for FrontEndSelection {
|
||||
"muxserver" => Ok(FrontEndSelection::MuxServer),
|
||||
"null" => Ok(FrontEndSelection::Null),
|
||||
"software" => Ok(FrontEndSelection::Software),
|
||||
"oldsoftware" => Ok(FrontEndSelection::OldSoftware),
|
||||
"opengl" => Ok(FrontEndSelection::OpenGL),
|
||||
_ => Err(anyhow!(
|
||||
"{} is not a valid FrontEndSelection variant, possible values are {:?}",
|
||||
|
@ -1,5 +1,6 @@
|
||||
use promise::Future;
|
||||
use std::any::Any;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
pub mod bitmaps;
|
||||
pub mod color;
|
||||
pub mod connection;
|
||||
@ -292,3 +293,13 @@ pub trait WindowOpsMut {
|
||||
/// and/or in the task manager/task switcher
|
||||
fn set_icon(&mut self, _image: &dyn BitmapImage) {}
|
||||
}
|
||||
|
||||
static PREFER_SWRAST: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
pub fn prefer_swrast() {
|
||||
PREFER_SWRAST.store(true, Ordering::Release);
|
||||
}
|
||||
|
||||
pub fn is_swrast_preferred() -> bool {
|
||||
PREFER_SWRAST.load(Ordering::Acquire)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#![cfg(feature = "opengl")]
|
||||
|
||||
use super::*;
|
||||
use crate::is_swrast_preferred;
|
||||
use glium::backend::Backend;
|
||||
use std::ffi::CStr;
|
||||
use std::io::Error as IoError;
|
||||
@ -8,6 +9,7 @@ use std::os::raw::c_void;
|
||||
use std::ptr::{null, null_mut};
|
||||
use winapi::shared::windef::*;
|
||||
use winapi::um::libloaderapi::GetModuleHandleW;
|
||||
use winapi::um::libloaderapi::*;
|
||||
use winapi::um::wingdi::*;
|
||||
use winapi::um::winuser::*;
|
||||
|
||||
@ -94,8 +96,25 @@ impl WglWrapper {
|
||||
}
|
||||
|
||||
fn create() -> anyhow::Result<Self> {
|
||||
let lib = libloading::Library::new("opengl32.dll")?;
|
||||
log::trace!("loading opengl32.dll as {:?}", lib);
|
||||
if is_swrast_preferred() {
|
||||
let mesa_dir = std::env::current_exe()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join("mesa");
|
||||
let mesa_dir = wide_string(mesa_dir.to_str().unwrap());
|
||||
|
||||
unsafe {
|
||||
AddDllDirectory(mesa_dir.as_ptr());
|
||||
SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
|
||||
}
|
||||
}
|
||||
|
||||
let lib = libloading::Library::new("opengl32.dll").map_err(|e| {
|
||||
log::error!("{:?}", e);
|
||||
e
|
||||
})?;
|
||||
log::trace!("loaded {:?}", lib);
|
||||
|
||||
let get_proc_address: libloading::Symbol<GetProcAddressFunc> =
|
||||
unsafe { lib.get(b"wglGetProcAddress\0")? };
|
||||
|
Loading…
Reference in New Issue
Block a user