glutin: a window and a GL context
Before any toolkit, someone had to open a window from Rust.
Before wgpu, getting pixels on screen from a Rust program meant OpenGL, and OpenGL needs a context: the object your driver uses to remember drawing state. glutin creates those contexts. Notably it does not create windows. You describe the framebuffer you want, and the platform finds the closest match.
use glutin::config::ConfigTemplateBuilder;
fn main() {
// Describe the framebuffer you want; the platform picks the closest match.
let template = ConfigTemplateBuilder::new()
.with_alpha_size(8)
.with_multisampling(4)
.build();
// `template` is later passed to Display::find_configs(template).
let _ = template;
} That separation of concerns is the pattern the rest of the stack copies. glutin is handed a raw display handle, the same kind of handle any window library can produce, and turns it into an OpenGL display. On a Mac that means Apple's CGL, which is what this snippet printed when run.
#[cfg(target_os = "macos")]
fn main() -> book_error::Result<()> {
use glutin::display::{Display, DisplayApiPreference, GlDisplay};
use raw_window_handle::{AppKitDisplayHandle, RawDisplayHandle};
// glutin never creates windows. It is handed a raw display handle (the
// same one winit exposes) and gives back an OpenGL display for it.
let raw = RawDisplayHandle::AppKit(AppKitDisplayHandle::new());
// SAFETY: the handle describes this process's own AppKit display.
let display = unsafe { Display::new(raw, DisplayApiPreference::Cgl) }?;
println!("GL display: {}", display.version_string());
Ok(())
}
#[cfg(not(target_os = "macos"))]
fn main() {} GL display: Apple CGLglutin is now a supporting character. egui's eframe still depends on it for its OpenGL (glow) backend, but newer toolkits mostly target wgpu, which is why it sits at 260 dependents rather than thousands. It is a good example of a primitive that did its job, and whose job has been absorbed by a higher-level one.