Skip to main content

surfman/wayland/
surface.rs

1//! A surface implementation using Wayland surfaces backed by TextureImage.
2
3use crate::base::egl::surface::{EGLBackedSurface, EGLSurfaceTexture};
4use crate::Error;
5
6use euclid::default::Size2D;
7use std::marker::PhantomData;
8use std::os::raw::c_void;
9use wayland_sys::client::wl_proxy;
10use wayland_sys::egl::{wayland_egl_handle, wl_egl_window};
11
12/// Represents a hardware buffer of pixels that can be rendered to via the CPU or GPU and either
13/// displayed in a native widget or bound to a texture for reading.
14///
15/// Surfaces come in two varieties: generic and widget surfaces. Generic surfaces can be bound to a
16/// texture but cannot be displayed in a widget (without using other APIs such as Core Animation,
17/// DirectComposition, or XPRESENT). Widget surfaces are the opposite: they can be displayed in a
18/// widget but not bound to a texture.
19///
20/// Surfaces are specific to a given context and cannot be rendered to from any context other than
21/// the one they were created with. However, they can be *read* from any context on any thread (as
22/// long as that context shares the same adapter and connection), by wrapping them in a
23/// `SurfaceTexture`.
24///
25/// Depending on the platform, each surface may be internally double-buffered.
26///
27/// Surfaces must be destroyed with the `destroy_surface()` method, or a panic will occur.
28#[derive(Debug)]
29pub struct Surface(pub(crate) EGLBackedSurface);
30
31/// Represents an OpenGL texture that wraps a surface.
32///
33/// Reading from the associated OpenGL texture reads from the surface. It is undefined behavior to
34/// write to such a texture (e.g. by binding it to a framebuffer and rendering to that
35/// framebuffer).
36///
37/// Surface textures are local to a context, but that context does not have to be the same context
38/// as that associated with the underlying surface. The texture must be destroyed with the
39/// `destroy_surface_texture()` method, or a panic will occur.
40#[derive(Debug)]
41pub struct SurfaceTexture(pub(crate) EGLSurfaceTexture);
42
43/// A wrapper for a Wayland surface, with associated size.
44#[derive(Clone)]
45pub struct NativeWidget {
46    pub(crate) wayland_surface: *mut wl_proxy,
47    pub(crate) size: Size2D<i32>,
48}
49
50unsafe impl Send for Surface {}
51
52/// Represents the CPU view of the pixel data of this surface.
53pub struct SurfaceDataGuard<'a> {
54    phantom: PhantomData<&'a ()>,
55}
56
57impl EGLBackedSurface {
58    pub(crate) fn resize_for_wayland(&mut self, size: Size2D<i32>) -> Result<(), Error> {
59        let wayland_egl_window = self.native_window()? as *mut c_void as *mut wl_egl_window;
60        unsafe {
61            (wayland_egl_handle().wl_egl_window_resize)(
62                wayland_egl_window,
63                size.width,
64                size.height,
65                0,
66                0,
67            )
68        };
69        self.resize(size);
70        Ok(())
71    }
72}