Provide a Display handle to graphics::Compositor

This commit is contained in:
Nico Just 2025-10-23 15:19:45 +02:00 committed by Héctor Ramón Jiménez
parent b9eeb34a12
commit 8374c6baa8
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
5 changed files with 51 additions and 24 deletions

View file

@ -18,23 +18,25 @@ pub trait Compositor: Sized {
type Surface;
/// Creates a new [`Compositor`].
fn new<W: Window + Clone>(
fn new(
settings: Settings,
compatible_window: W,
display: impl Display + Clone,
compatible_window: impl Window + Clone,
shell: Shell,
) -> impl Future<Output = Result<Self, Error>> {
Self::with_backend(settings, compatible_window, shell, None)
Self::with_backend(settings, display, compatible_window, shell, None)
}
/// Creates a new [`Compositor`] with a backend preference.
///
/// If the backend does not match the preference, it will return
/// [`Error::GraphicsAdapterNotFound`].
fn with_backend<W: Window + Clone>(
_settings: Settings,
_compatible_window: W,
_shell: Shell,
_backend: Option<&str>,
fn with_backend(
settings: Settings,
display: impl Display + Clone,
compatible_window: impl Window + Clone,
shell: Shell,
backend: Option<&str>,
) -> impl Future<Output = Result<Self, Error>>;
/// Creates a [`Self::Renderer`] for the [`Compositor`].
@ -110,6 +112,15 @@ impl<T> Window for T where
{
}
/// An owned display handle that can be used in a [`Compositor`].
///
/// This is just a convenient super trait of the `raw-window-handle`
/// trait.
pub trait Display: HasDisplayHandle + MaybeSend + MaybeSync + 'static {}
impl<T> Display for T where T: HasDisplayHandle + MaybeSend + MaybeSync + 'static
{}
/// Defines the default compositor of a renderer.
pub trait Default {
/// The compositor of the renderer.
@ -152,9 +163,10 @@ impl Compositor for () {
type Renderer = ();
type Surface = ();
async fn with_backend<W: Window + Clone>(
async fn with_backend(
_settings: Settings,
_compatible_window: W,
_display: impl Display,
_compatible_window: impl Window + Clone,
_shell: Shell,
_preferred_backend: Option<&str>,
) -> Result<Self, Error> {

View file

@ -264,9 +264,10 @@ where
type Renderer = Renderer<A::Renderer, B::Renderer>;
type Surface = Surface<A::Surface, B::Surface>;
async fn with_backend<W: compositor::Window + Clone>(
async fn with_backend(
settings: graphics::Settings,
compatible_window: W,
display: impl compositor::Display + Clone,
compatible_window: impl compositor::Window + Clone,
shell: Shell,
backend: Option<&str>,
) -> Result<Self, graphics::Error> {
@ -296,6 +297,7 @@ where
for backend in candidates.iter().map(Option::as_deref) {
match A::with_backend(
settings,
display.clone(),
compatible_window.clone(),
shell.clone(),
backend,
@ -310,6 +312,7 @@ where
match B::with_backend(
settings,
display.clone(),
compatible_window.clone(),
shell.clone(),
backend,

View file

@ -9,13 +9,13 @@ use std::collections::VecDeque;
use std::num::NonZeroU32;
pub struct Compositor {
context: softbuffer::Context<Box<dyn compositor::Window>>,
context: softbuffer::Context<Box<dyn compositor::Display>>,
settings: Settings,
}
pub struct Surface {
window: softbuffer::Surface<
Box<dyn compositor::Window>,
Box<dyn compositor::Display>,
Box<dyn compositor::Window>,
>,
clip_mask: tiny_skia::Mask,
@ -28,15 +28,16 @@ impl crate::graphics::Compositor for Compositor {
type Renderer = Renderer;
type Surface = Surface;
async fn with_backend<W: compositor::Window>(
async fn with_backend(
settings: graphics::Settings,
compatible_window: W,
display: impl compositor::Display,
_compatible_window: impl compositor::Window,
_shell: Shell,
backend: Option<&str>,
) -> Result<Self, Error> {
match backend {
None | Some("tiny-skia") | Some("tiny_skia") => {
Ok(new(settings.into(), compatible_window))
Ok(new(settings.into(), display))
}
Some(backend) => Err(Error::GraphicsAdapterNotFound {
backend: "tiny-skia",
@ -134,12 +135,12 @@ impl crate::graphics::Compositor for Compositor {
}
}
pub fn new<W: compositor::Window>(
pub fn new(
settings: Settings,
compatible_window: W,
display: impl compositor::Display,
) -> Compositor {
#[allow(unsafe_code)]
let context = softbuffer::Context::new(Box::new(compatible_window) as _)
let context = softbuffer::Context::new(Box::new(display) as _)
.expect("Create softbuffer context");
Compositor { context, settings }

View file

@ -261,9 +261,10 @@ impl graphics::Compositor for Compositor {
type Renderer = Renderer;
type Surface = wgpu::Surface<'static>;
async fn with_backend<W: compositor::Window>(
async fn with_backend(
settings: graphics::Settings,
compatible_window: W,
_display: impl compositor::Display,
compatible_window: impl compositor::Window,
shell: Shell,
backend: Option<&str>,
) -> Result<Self, graphics::Error> {

View file

@ -76,11 +76,13 @@ where
let settings = program.settings();
let window_settings = program.window();
let graphics_settings = settings.clone().into();
let event_loop = EventLoop::with_user_event()
.build()
.expect("Create event loop");
let graphics_settings = settings.clone().into();
let display_handle = event_loop.owned_display_handle();
let (proxy, worker) = Proxy::new(event_loop.create_proxy());
#[cfg(feature = "debug")]
@ -131,6 +133,7 @@ where
proxy.clone(),
event_receiver,
control_sender,
display_handle,
is_daemon,
graphics_settings,
settings.fonts,
@ -511,6 +514,7 @@ async fn run_instance<P>(
mut proxy: Proxy<P::Message>,
mut event_receiver: mpsc::UnboundedReceiver<Event<Action<P::Message>>>,
mut control_sender: mpsc::UnboundedSender<Control>,
display_handle: winit::event_loop::OwnedDisplayHandle,
is_daemon: bool,
graphics_settings: graphics::Settings,
default_fonts: Vec<Cow<'static, [u8]>>,
@ -595,6 +599,7 @@ async fn run_instance<P>(
let create_compositor = {
let window = window.clone();
let display_handle = display_handle.clone();
let proxy = proxy.clone();
let default_fonts = default_fonts.clone();
@ -602,7 +607,12 @@ async fn run_instance<P>(
let shell = Shell::new(proxy.clone());
let mut compositor =
<P::Renderer as compositor::Default>::Compositor::new(graphics_settings, window, shell).await;
<P::Renderer as compositor::Default>::Compositor::new(
graphics_settings,
display_handle,
window,
shell,
).await;
if let Ok(compositor) = &mut compositor {
for font in default_fonts {