Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce MultiGPU renderer #503

Merged
merged 37 commits into from
Mar 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
7ec9c8d
renderer: Introduce Offscreen render targets
Drakulix Feb 10, 2022
32f8909
gles2: Add textures as Offscreen render targets
Drakulix Feb 10, 2022
acd26bd
gles2: Add renderbuffer as Offscreen target
Drakulix Feb 14, 2022
3b704eb
renderer: ImportShm -> ImportMem
Drakulix Feb 11, 2022
79f9f94
renderer: Introduce ExportMem trait
Drakulix Feb 10, 2022
bc973e9
egl: Add function to export egl images
Drakulix Feb 11, 2022
7bc81da
renderer: Introduce ExportDma
Drakulix Feb 11, 2022
dffc75e
allocator: Implemented for boxed variants
Drakulix Feb 10, 2022
bf0f59c
drm: Remove file descriptor from `DrmNode`
Drakulix Feb 10, 2022
2b1218f
gles2: Fix rendering of inverted textures
Drakulix Mar 1, 2022
0b20587
utils: Allow Transforms to add up
Drakulix Mar 1, 2022
a3e377e
renderer: Export/ImportMem support flipped buffers
Drakulix Mar 1, 2022
b175287
renderer: Introduce multigpu module
Drakulix Feb 18, 2022
011a357
desktop: Fix crash when accessing (dead) popups of dead windows
Drakulix Mar 1, 2022
0e5612c
desktop: Remove `Renderer: 'static` constraint
Drakulix Mar 1, 2022
075b67b
anvil: `RenderElement` is not using relative coordinates anymore
Drakulix Mar 1, 2022
4d2d17f
anvil/udev: Use MultiGPU renderer
Drakulix Mar 1, 2022
7cc6bd8
renderer: Add id() to track different textures
Drakulix Mar 2, 2022
79c52ba
renderer: Add utils::import_surface_tree
Drakulix Mar 2, 2022
72d1be3
utils: Cleanup generics of `draw_*` helpers
Drakulix Mar 2, 2022
d0ad545
anvil: Make use of early_import
Drakulix Mar 2, 2022
3446c0b
renderer: split of wl_buffer-specific `Import` fns
Drakulix Mar 2, 2022
572101f
multigpu: Remove `source` param to not depend on wl
Drakulix Mar 3, 2022
2592f6b
changelog: Add multigpu additions
Drakulix Mar 3, 2022
be5f243
gles2: Fix feature gates
Drakulix Mar 3, 2022
aff3c32
multigpu: Add AsRef/Mut to access underlying impl
Drakulix Mar 3, 2022
882c9bf
cargo: Add new renderer_multi feature
Drakulix Mar 3, 2022
2551073
wlcs_anvil: Adjust for multigpu changes
Drakulix Mar 3, 2022
1e91749
desktop: Add meta attribs to custom_elements
Drakulix Mar 3, 2022
c609baa
desktop: Allow custom_elements! to be generic
Drakulix Mar 4, 2022
1bdefca
address review comments
Drakulix Mar 7, 2022
59cffd0
space: Allow custom_elements! to cast wrapped renderers.
Drakulix Mar 9, 2022
22c5ea7
egl: Add render_node query to `EGLDevice`
Drakulix Mar 9, 2022
36020ef
egl: refactor: move node selection into EGLDevice
Drakulix Mar 9, 2022
279c2fb
anvil: Use udev-nodes for everything but rendering
Drakulix Mar 9, 2022
76946c4
anvil/udev: Fix crash on device_changed
Drakulix Mar 10, 2022
2e0ae16
anvil/udev: Allow overriding the primary gpu
Drakulix Mar 10, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ jobs:
- backend_x11
- desktop
- renderer_gl
- renderer_multi
- wayland_frontend
- xwayland
- default
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
- `EGLNativeSurface` implementations overriding `swap_buffers` now receive and additional `damage` attribute to be used with `eglSwapBuffersWithDamageEXT` if desired
- `EGLSurface::swap_buffers` now accepts an optional `damage` parameter
- `WinitGraphicsBackend` does no longer provide a `render`-method and exposes its `Renderer` directly instead including new functions `bind` and `submit` to handle swapping buffers.
- `ImportShm` was renamed to `ImportMem`
- `ImportMem` and `ImportDma` were split and do now have accompanying traits `ImportMemWl` and `ImportDmaWl` to import wayland buffers.

### Additions

Expand Down Expand Up @@ -71,6 +73,12 @@
- `backend::renderer` has a new `utils`-module that can take care of client buffer management for you.
- `EGLSurface::buffer_age` can be used to query the surface buffer age.
- `GbmBufferedSurface::reset_buffers` can now be used to reset underlying buffers.
- Added new `Offscreen` trait to create offscreen surfaces for `Renderer`s
- Added functions to `ImportMem` to upload bitmaps from memory
- Added `ExportDma` trait to export framebuffers and textures into dmabufs
- Added `ExportMem` trait to copy framebuffers and textures into memory
- Added `multigpu`-module to the renderer, which makes handling multi-gpu setups easier!
- Added `backend::renderer::utils::import_surface_tree` to be able to import buffers before rendering

#### Desktop

Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ gl_generator = { version = "0.14", optional = true }
pkg-config = { version = "0.3.17", optional = true }

[features]
default = ["backend_drm", "backend_gbm", "backend_libinput", "backend_udev", "backend_session_logind", "backend_winit", "desktop", "renderer_gl", "xwayland", "wayland_frontend", "slog-stdlog", "backend_x11"]
default = ["backend_drm", "backend_gbm", "backend_libinput", "backend_udev", "backend_session_logind", "backend_x11", "backend_winit", "desktop", "renderer_gl", "renderer_multi", "xwayland", "wayland_frontend", "slog-stdlog"]
backend_winit = ["winit", "wayland-server/dlopen", "backend_egl", "wayland-egl", "renderer_gl"]
backend_x11 = ["x11rb", "x11rb/dri3", "x11rb/xfixes", "x11rb/present", "x11rb_event_source", "backend_gbm", "backend_drm", "backend_egl"]
backend_drm = ["drm", "drm-ffi"]
Expand All @@ -75,6 +75,7 @@ backend_session_elogind = ["backend_session_logind"]
backend_session_libseat = ["backend_session", "libseat"]
desktop = ["indexmap", "wayland_frontend"]
renderer_gl = ["gl_generator", "backend_egl"]
renderer_multi = ["backend_drm"]
use_system_lib = ["wayland_frontend", "wayland-sys", "wayland-server/use_system_lib"]
wayland_frontend = ["wayland-server", "wayland-commons", "wayland-protocols", "tempfile"]
x11rb_event_source = ["x11rb"]
Expand Down
2 changes: 1 addition & 1 deletion anvil/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ gl_generator = "0.14"
default = [ "udev", "logind", "x11", "egl", "winit", "xwayland" ]
egl = [ "smithay/use_system_lib", "smithay/backend_egl" ]
winit = [ "smithay/backend_winit" ]
udev = [ "smithay/backend_libinput", "smithay/backend_udev", "smithay/backend_drm", "smithay/backend_gbm", "smithay/backend_egl", "smithay/backend_session", "input", "image", "smithay/renderer_gl", "xcursor" ]
udev = [ "smithay/backend_libinput", "smithay/backend_udev", "smithay/backend_drm", "smithay/backend_gbm", "smithay/backend_egl", "smithay/backend_session", "input", "image", "smithay/renderer_gl", "smithay/renderer_multi", "xcursor" ]
logind = [ "smithay/backend_session_logind" ]
elogind = ["logind", "smithay/backend_session_elogind" ]
libseat = ["smithay/backend_session_libseat" ]
Expand Down
107 changes: 28 additions & 79 deletions anvil/src/drawing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,9 @@

use std::sync::Mutex;

#[cfg(feature = "image")]
use image::{ImageBuffer, Rgba};
use slog::Logger;
#[cfg(feature = "image")]
use smithay::backend::renderer::gles2::{Gles2Error, Gles2Renderer, Gles2Texture};
use smithay::{
backend::{
renderer::{Frame, ImportAll, Renderer, Texture},
SwapBuffersError,
},
backend::renderer::{Frame, ImportAll, Renderer, Texture},
desktop::space::{RenderElement, SpaceOutputTuple, SurfaceTree},
reexports::wayland_server::protocol::wl_surface,
utils::{Logical, Point, Rectangle, Size, Transform},
Expand All @@ -23,17 +16,19 @@ use smithay::{

pub static CLEAR_COLOR: [f32; 4] = [0.8, 0.8, 0.9, 1.0];

pub fn draw_cursor<R, F, E, T>(
smithay::custom_elements! {
pub CustomElem<R>;
SurfaceTree=SurfaceTree,
PointerElement=PointerElement::<<R as Renderer>::TextureId>,
#[cfg(feature = "debug")]
FpsElement=FpsElement::<<R as Renderer>::TextureId>,
}

pub fn draw_cursor(
surface: wl_surface::WlSurface,
location: impl Into<Point<i32, Logical>>,
log: &Logger,
) -> impl RenderElement<R, F, E, T>
where
R: Renderer<Error = E, TextureId = T, Frame = F> + ImportAll + 'static,
F: Frame<Error = E, TextureId = T> + 'static,
E: std::error::Error + Into<SwapBuffersError> + 'static,
T: Texture + 'static,
{
) -> SurfaceTree {
let mut position = location.into();
let ret = with_states(&surface, |states| {
Some(
Expand All @@ -60,17 +55,11 @@ where
SurfaceTree { surface, position }
}

pub fn draw_dnd_icon<R, F, E, T>(
pub fn draw_dnd_icon(
surface: wl_surface::WlSurface,
location: impl Into<Point<i32, Logical>>,
log: &Logger,
) -> impl RenderElement<R, F, E, T>
where
R: Renderer<Error = E, TextureId = T, Frame = F> + ImportAll + 'static,
F: Frame<Error = E, TextureId = T> + 'static,
E: std::error::Error + Into<SwapBuffersError> + 'static,
T: Texture + 'static,
{
) -> SurfaceTree {
if get_role(&surface) != Some("dnd_icon") {
warn!(
log,
Expand All @@ -90,22 +79,20 @@ pub struct PointerElement<T: Texture> {
}

impl<T: Texture> PointerElement<T> {
pub fn new(texture: T, relative_pointer_pos: Point<i32, Logical>) -> PointerElement<T> {
pub fn new(texture: T, pointer_pos: Point<i32, Logical>) -> PointerElement<T> {
let size = texture.size().to_logical(1, Transform::Normal);
PointerElement {
texture,
position: relative_pointer_pos,
position: pointer_pos,
size,
}
}
}

impl<R, F, E, T> RenderElement<R, F, E, T> for PointerElement<T>
impl<R> RenderElement<R> for PointerElement<<R as Renderer>::TextureId>
where
R: Renderer<Error = E, TextureId = T, Frame = F> + ImportAll + 'static,
F: Frame<Error = E, TextureId = T> + 'static,
E: std::error::Error + Into<SwapBuffersError> + 'static,
T: Texture + 'static,
R: Renderer + ImportAll,
<R as Renderer>::TextureId: 'static,
{
fn id(&self) -> usize {
0
Expand All @@ -122,12 +109,12 @@ where
fn draw(
&self,
_renderer: &mut R,
frame: &mut F,
frame: &mut <R as Renderer>::Frame,
scale: f64,
location: Point<i32, Logical>,
damage: &[Rectangle<i32, Logical>],
_log: &Logger,
) -> Result<(), R::Error> {
) -> Result<(), <R as Renderer>::Error> {
frame.render_texture_at(
&self.texture,
location.to_f64().to_physical(scale).to_i32_round(),
Expand All @@ -154,12 +141,10 @@ pub struct FpsElement<T: Texture> {
}

#[cfg(feature = "debug")]
impl<R, F, E, T> RenderElement<R, F, E, T> for FpsElement<T>
impl<R> RenderElement<R> for FpsElement<<R as Renderer>::TextureId>
where
R: Renderer<Error = E, TextureId = T, Frame = F> + ImportAll + 'static,
F: Frame<Error = E, TextureId = T> + 'static,
E: std::error::Error + Into<SwapBuffersError> + 'static,
T: Texture + 'static,
R: Renderer + ImportAll,
<R as Renderer>::TextureId: 'static,
{
fn id(&self) -> usize {
0
Expand All @@ -183,12 +168,12 @@ where
fn draw(
&self,
_renderer: &mut R,
frame: &mut F,
frame: &mut <R as Renderer>::Frame,
scale: f64,
location: Point<i32, Logical>,
damage: &[Rectangle<i32, Logical>],
_log: &Logger,
) -> Result<(), R::Error> {
) -> Result<(), <R as Renderer>::Error> {
let value_str = std::cmp::min(self.value, 999).to_string();
let location = location.to_f64().to_physical(scale);
let mut offset_x = location.x;
Expand Down Expand Up @@ -237,49 +222,13 @@ where
}

#[cfg(feature = "debug")]
pub fn draw_fps<R, F, E, T>(texture: &T, value: u32) -> impl RenderElement<R, F, E, T>
pub fn draw_fps<R>(texture: &<R as Renderer>::TextureId, value: u32) -> FpsElement<<R as Renderer>::TextureId>
where
R: Renderer<Error = E, TextureId = T, Frame = F> + ImportAll + 'static,
F: Frame<Error = E, TextureId = T> + 'static,
E: std::error::Error + Into<SwapBuffersError> + 'static,
T: Texture + Clone + 'static,
R: Renderer + ImportAll,
<R as Renderer>::TextureId: Clone,
{
FpsElement {
value,
texture: texture.clone(),
}
}

#[cfg(feature = "image")]
pub fn import_bitmap<C: std::ops::Deref<Target = [u8]>>(
renderer: &mut Gles2Renderer,
image: &ImageBuffer<Rgba<u8>, C>,
) -> Result<Gles2Texture, Gles2Error> {
use smithay::backend::renderer::gles2::ffi;

renderer.with_context(|renderer, gl| unsafe {
let mut tex = 0;
gl.GenTextures(1, &mut tex);
gl.BindTexture(ffi::TEXTURE_2D, tex);
gl.TexParameteri(ffi::TEXTURE_2D, ffi::TEXTURE_WRAP_S, ffi::CLAMP_TO_EDGE as i32);
gl.TexParameteri(ffi::TEXTURE_2D, ffi::TEXTURE_WRAP_T, ffi::CLAMP_TO_EDGE as i32);
gl.TexImage2D(
ffi::TEXTURE_2D,
0,
ffi::RGBA as i32,
image.width() as i32,
image.height() as i32,
0,
ffi::RGBA,
ffi::UNSIGNED_BYTE as u32,
image.as_ptr() as *const _,
);
gl.BindTexture(ffi::TEXTURE_2D, 0);

Gles2Texture::from_raw(
renderer,
tex,
(image.width() as i32, image.height() as i32).into(),
)
})
}
11 changes: 5 additions & 6 deletions anvil/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,26 @@ use smithay::{
backend::renderer::{Frame, ImportAll, Renderer},
desktop::{
draw_window,
space::{DynamicRenderElements, RenderError, Space},
space::{RenderElement, RenderError, Space},
},
utils::{Logical, Rectangle},
wayland::output::Output,
};

use crate::{drawing::*, shell::FullscreenSurface};

pub fn render_output<R>(
pub fn render_output<R, E>(
output: &Output,
space: &mut Space,
renderer: &mut R,
age: usize,
elements: &[DynamicRenderElements<R>],
elements: &[E],
log: &slog::Logger,
) -> Result<Option<Vec<Rectangle<i32, Logical>>>, RenderError<R>>
where
R: Renderer + ImportAll + 'static,
R::Frame: 'static,
R: Renderer + ImportAll,
R::TextureId: 'static,
R::Error: 'static,
E: RenderElement<R>,
{
if let Some(window) = output
.user_data()
Expand Down
1 change: 1 addition & 0 deletions anvil/src/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ pub fn init_shell<BackendData: Backend + 'static>(
move |surface, mut ddata| {
on_commit_buffer_handler(&surface);
let anvil_state = ddata.get::<AnvilState<BackendData>>().unwrap();
anvil_state.backend_data.early_import(&surface);
let mut popups = anvil_state.popups.borrow_mut();
let space = anvil_state.space.as_ref();
space.borrow_mut().commit(&surface);
Expand Down
1 change: 1 addition & 0 deletions anvil/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,5 @@ impl<BackendData: Backend + 'static> AnvilState<BackendData> {
pub trait Backend {
fn seat_name(&self) -> String;
fn reset_buffers(&mut self, output: &Output);
fn early_import(&mut self, surface: &WlSurface);
}
Loading